Quantcast

Moving initial code over to new repo

Failcoder [10-19-16 - 14:14]
Moving initial code over to new repo
Filename
.gitignore
.pkgmeta
LICENSE
README.md
SVUITheme_Simple/LICENSE.txt
SVUITheme_Simple/ROUND-SIMPLE.blp
SVUITheme_Simple/SVUITheme_Simple.lua
SVUITheme_Simple/SVUITheme_Simple.toc
SVUITheme_Simple/SVUITheme_Simple.xml
SVUI_!Core/Bindings.xml
SVUI_!Core/License.txt
SVUI_!Core/SVUI_!Core.toc
SVUI_!Core/SVUI_!Core.xml
SVUI_!Core/assets/backgrounds/BUTTON.blp
SVUI_!Core/assets/backgrounds/DARK.blp
SVUI_!Core/assets/backgrounds/DEFAULT.blp
SVUI_!Core/assets/backgrounds/MODEL.blp
SVUI_!Core/assets/backgrounds/TRANSPARENT.blp
SVUI_!Core/assets/backgrounds/art/ART1.blp
SVUI_!Core/assets/backgrounds/art/ART2.blp
SVUI_!Core/assets/backgrounds/art/ART3.blp
SVUI_!Core/assets/backgrounds/art/ART4.blp
SVUI_!Core/assets/backgrounds/art/ART5.blp
SVUI_!Core/assets/backgrounds/art/ART6.blp
SVUI_!Core/assets/backgrounds/pattern/PATTERN1.blp
SVUI_!Core/assets/backgrounds/pattern/PATTERN10.blp
SVUI_!Core/assets/backgrounds/pattern/PATTERN11.blp
SVUI_!Core/assets/backgrounds/pattern/PATTERN12.blp
SVUI_!Core/assets/backgrounds/pattern/PATTERN13.blp
SVUI_!Core/assets/backgrounds/pattern/PATTERN14.blp
SVUI_!Core/assets/backgrounds/pattern/PATTERN2.blp
SVUI_!Core/assets/backgrounds/pattern/PATTERN3.blp
SVUI_!Core/assets/backgrounds/pattern/PATTERN4.blp
SVUI_!Core/assets/backgrounds/pattern/PATTERN5.blp
SVUI_!Core/assets/backgrounds/pattern/PATTERN6.blp
SVUI_!Core/assets/backgrounds/pattern/PATTERN7.blp
SVUI_!Core/assets/backgrounds/pattern/PATTERN8.blp
SVUI_!Core/assets/backgrounds/pattern/PATTERN9.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-BG1.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-BG10.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-BG11.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-BG12.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-BG13.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-BG14.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-BG15.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-BG16.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-BG17.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-BG2.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-BG3.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-BG4.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-BG5.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-BG6.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-BG7.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-BG8.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-BG9.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG1.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG10.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG11.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG12.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG13.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG14.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG15.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG16.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG17.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG2.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG3.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG4.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG5.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG6.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG7.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG8.blp
SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG9.blp
SVUI_!Core/assets/backgrounds/window/COMPOSITE1-BOTTOMLEFT.blp
SVUI_!Core/assets/backgrounds/window/COMPOSITE1-BOTTOMRIGHT.blp
SVUI_!Core/assets/backgrounds/window/COMPOSITE1-TOPLEFT.blp
SVUI_!Core/assets/backgrounds/window/COMPOSITE1-TOPRIGHT.blp
SVUI_!Core/assets/backgrounds/window/COMPOSITE2-BOTTOMLEFT.blp
SVUI_!Core/assets/backgrounds/window/COMPOSITE2-BOTTOMRIGHT.blp
SVUI_!Core/assets/backgrounds/window/COMPOSITE2-TOPLEFT.blp
SVUI_!Core/assets/backgrounds/window/COMPOSITE2-TOPRIGHT.blp
SVUI_!Core/assets/borders/DEFAULT.blp
SVUI_!Core/assets/borders/INSET.blp
SVUI_!Core/assets/borders/SHADOW.blp
SVUI_!Core/assets/borders/TEXTURED.blp
SVUI_!Core/assets/buttons/CHECK-BG.blp
SVUI_!Core/assets/buttons/CHECK-DISABLED.blp
SVUI_!Core/assets/buttons/CHECK.blp
SVUI_!Core/assets/buttons/RADIO.blp
SVUI_!Core/assets/buttons/ROUND-BG.blp
SVUI_!Core/assets/buttons/ROUND-BORDER.blp
SVUI_!Core/assets/buttons/SCROLLBAR-DOWN.blp
SVUI_!Core/assets/buttons/SCROLLBAR-KNOB.blp
SVUI_!Core/assets/buttons/SCROLLBAR-UP.blp
SVUI_!Core/assets/buttons/SETUP-ARROW.blp
SVUI_!Core/assets/buttons/SETUP-OPTION.blp
SVUI_!Core/assets/fonts/Alert.ttf
SVUI_!Core/assets/fonts/Boom.ttf
SVUI_!Core/assets/fonts/Caps.ttf
SVUI_!Core/assets/fonts/Classic.ttf
SVUI_!Core/assets/fonts/Combat.ttf
SVUI_!Core/assets/fonts/Combat2.ttf
SVUI_!Core/assets/fonts/Combo.ttf
SVUI_!Core/assets/fonts/DAMAGE_TEXT_FONT.ttf
SVUI_!Core/assets/fonts/Default.ttf
SVUI_!Core/assets/fonts/Dialog.ttf
SVUI_!Core/assets/fonts/Dyslexic.ttf
SVUI_!Core/assets/fonts/Flash.ttf
SVUI_!Core/assets/fonts/Invisible.ttf
SVUI_!Core/assets/fonts/Narrative.ttf
SVUI_!Core/assets/fonts/Numbers.ttf
SVUI_!Core/assets/fonts/Pixel.ttf
SVUI_!Core/assets/fonts/SFX.ttf
SVUI_!Core/assets/fonts/Zone.ttf
SVUI_!Core/assets/icons/CLOSE.blp
SVUI_!Core/assets/icons/EXIT.blp
SVUI_!Core/assets/icons/FAVORITE-STAR.blp
SVUI_!Core/assets/icons/MOVE-DOWN.blp
SVUI_!Core/assets/icons/MOVE-LEFT.blp
SVUI_!Core/assets/icons/MOVE-RIGHT.blp
SVUI_!Core/assets/icons/MOVE-UP.blp
SVUI_!Core/assets/icons/SVUI.blp
SVUI_!Core/assets/icons/THEME.blp
SVUI_!Core/assets/icons/VS.blp
SVUI_!Core/assets/sounds/SuperVillain.mp3
SVUI_!Core/assets/sounds/beer30.mp3
SVUI_!Core/assets/sounds/toasty.mp3
SVUI_!Core/assets/sounds/whisper.mp3
SVUI_!Core/assets/statusbars/BUTTON.blp
SVUI_!Core/assets/statusbars/DEFAULT.blp
SVUI_!Core/assets/statusbars/FLAT.blp
SVUI_!Core/assets/statusbars/GLOSS.blp
SVUI_!Core/assets/statusbars/GLOWING.blp
SVUI_!Core/assets/statusbars/GRADIENT.blp
SVUI_!Core/assets/statusbars/HALFTONE.blp
SVUI_!Core/assets/statusbars/LAZER.blp
SVUI_!Core/assets/statusbars/SMOOTH.blp
SVUI_!Core/assets/statusbars/TEXTURED.blp
SVUI_!Core/assets/textures/Affected/AFFECTED1.blp
SVUI_!Core/assets/textures/Affected/AFFECTED2.blp
SVUI_!Core/assets/textures/Affected/AFFECTED3.blp
SVUI_!Core/assets/textures/Affected/AFFECTED4.blp
SVUI_!Core/assets/textures/Affected/AFFECTED5.blp
SVUI_!Core/assets/textures/Alert/ALERT-BG-2.blp
SVUI_!Core/assets/textures/Alert/ALERT-BG.blp
SVUI_!Core/assets/textures/Alert/ALERT-BOTTOM.blp
SVUI_!Core/assets/textures/Alert/ALERT-BURST.blp
SVUI_!Core/assets/textures/Alert/ALERT-FULL.blp
SVUI_!Core/assets/textures/Alert/ALERT-ICON-BORDER.blp
SVUI_!Core/assets/textures/Alert/ALERT-LEFT-2.blp
SVUI_!Core/assets/textures/Alert/ALERT-LEFT.blp
SVUI_!Core/assets/textures/Alert/ALERT-RIGHT-2.blp
SVUI_!Core/assets/textures/Alert/ALERT-RIGHT.blp
SVUI_!Core/assets/textures/Alert/ALERT-TOP.blp
SVUI_!Core/assets/textures/Alert/SAVED-BG.blp
SVUI_!Core/assets/textures/Alert/SAVED-FG.blp
SVUI_!Core/assets/textures/CHATBUBBLE-BACKDROP.blp
SVUI_!Core/assets/textures/CHATBUBBLE-BG.blp
SVUI_!Core/assets/textures/CHATBUBBLE-TAIL-DOWN.blp
SVUI_!Core/assets/textures/CHATBUBBLE-TAIL-LEFT.blp
SVUI_!Core/assets/textures/CHATBUBBLE-TAIL-RIGHT.blp
SVUI_!Core/assets/textures/CHATBUBBLE-TAIL-UP.blp
SVUI_!Core/assets/textures/CHATBUBBLE-TAIL.blp
SVUI_!Core/assets/textures/DIALOGBOX-HEADER.blp
SVUI_!Core/assets/textures/DROPDOWN-DIVIDER.blp
SVUI_!Core/assets/textures/Dock/DOCK-ICON-ADDON.blp
SVUI_!Core/assets/textures/Dock/DOCK-ICON-BREAKSTUFF.blp
SVUI_!Core/assets/textures/Dock/DOCK-ICON-CHAT.blp
SVUI_!Core/assets/textures/Dock/DOCK-ICON-GARRISON.blp
SVUI_!Core/assets/textures/Dock/DOCK-ICON-HEARTH.blp
SVUI_!Core/assets/textures/Dock/DOCK-ICON-HENCHMAN.blp
SVUI_!Core/assets/textures/Dock/DOCK-ICON-OPTIONS.blp
SVUI_!Core/assets/textures/Dock/DOCK-ICON-POWER.blp
SVUI_!Core/assets/textures/Dock/DOCK-ICON-QUESTS.blp
SVUI_!Core/assets/textures/Dock/DOCK-ICON-RAIDTOOL.blp
SVUI_!Core/assets/textures/Dock/DOCK-ICON-SIZE.blp
SVUI_!Core/assets/textures/Dock/DOCK-ICON-SNACK.blp
SVUI_!Core/assets/textures/Dock/DOCK-ICON-SPECSWAP.blp
SVUI_!Core/assets/textures/Dock/DOCK-SPARKS-1.blp
SVUI_!Core/assets/textures/Dock/DOCK-SPARKS-2.blp
SVUI_!Core/assets/textures/Dock/DOCK-SPARKS-3.blp
SVUI_!Core/assets/textures/Dock/LABEL-DUR.blp
SVUI_!Core/assets/textures/Dock/LABEL-REP.blp
SVUI_!Core/assets/textures/Dock/LABEL-XP.blp
SVUI_!Core/assets/textures/Dock/PROFESSIONS.blp
SVUI_!Core/assets/textures/Doodads/AFK-BG.blp
SVUI_!Core/assets/textures/Doodads/AFK-NARRATIVE.blp
SVUI_!Core/assets/textures/Doodads/COMICS-TYPE1.blp
SVUI_!Core/assets/textures/Doodads/COMICS-TYPE2.blp
SVUI_!Core/assets/textures/Doodads/COMICS-TYPE3-BG.blp
SVUI_!Core/assets/textures/Doodads/COMICS-TYPE3.blp
SVUI_!Core/assets/textures/Doodads/DRUNK-PARTYTIME.blp
SVUI_!Core/assets/textures/Doodads/HENCHMEN-CALLOUT.blp
SVUI_!Core/assets/textures/Doodads/HENCHMEN-MINION-SWITCH.blp
SVUI_!Core/assets/textures/Doodads/HENCHMEN-OPTION-LEFT.blp
SVUI_!Core/assets/textures/Doodads/HENCHMEN-OPTION-RIGHT.blp
SVUI_!Core/assets/textures/Doodads/HENCHMEN-SPEECH.blp
SVUI_!Core/assets/textures/Doodads/HENCHMEN-SRSLY.blp
SVUI_!Core/assets/textures/Doodads/HENCHMEN-SUBOPTION.blp
SVUI_!Core/assets/textures/Doodads/HENCHMEN-WTF.blp
SVUI_!Core/assets/textures/Doodads/MENTALO-BUTTON1.blp
SVUI_!Core/assets/textures/Doodads/MENTALO-BUTTON2.blp
SVUI_!Core/assets/textures/Doodads/MENTALO-ENERGY.blp
SVUI_!Core/assets/textures/Doodads/MENTALO-HAND-OFF.blp
SVUI_!Core/assets/textures/Doodads/MENTALO-HAND-ON.blp
SVUI_!Core/assets/textures/Doodads/MENTALO-OFF.blp
SVUI_!Core/assets/textures/Doodads/MENTALO-ON.blp
SVUI_!Core/assets/textures/Doodads/PLAYER-AFK.blp
SVUI_!Core/assets/textures/Doodads/QUESTION.blp
SVUI_!Core/assets/textures/Doodads/RESPONSE.blp
SVUI_!Core/assets/textures/Doodads/THREAT-BAR-ELEMENTS.blp
SVUI_!Core/assets/textures/Doodads/THREAT-BAR.blp
SVUI_!Core/assets/textures/Doodads/TOASTY.blp
SVUI_!Core/assets/textures/Doodads/UNIT-XRAY-CLOSE.blp
SVUI_!Core/assets/textures/Doodads/UNIT-XRAY.blp
SVUI_!Core/assets/textures/EMPTY.blp
SVUI_!Core/assets/textures/NPC-NAMETAG.blp
SVUI_!Core/assets/textures/Numbers/TYPE1/NUM0.blp
SVUI_!Core/assets/textures/Numbers/TYPE1/NUM1.blp
SVUI_!Core/assets/textures/Numbers/TYPE1/NUM2.blp
SVUI_!Core/assets/textures/Numbers/TYPE1/NUM3.blp
SVUI_!Core/assets/textures/Numbers/TYPE1/NUM4.blp
SVUI_!Core/assets/textures/Numbers/TYPE1/NUM5.blp
SVUI_!Core/assets/textures/Numbers/TYPE1/NUM6.blp
SVUI_!Core/assets/textures/Numbers/TYPE1/NUM7.blp
SVUI_!Core/assets/textures/Numbers/TYPE1/NUM8.blp
SVUI_!Core/assets/textures/Numbers/TYPE1/NUM9.blp
SVUI_!Core/assets/textures/Numbers/TYPE2/NUM1.blp
SVUI_!Core/assets/textures/Numbers/TYPE2/NUM2.blp
SVUI_!Core/assets/textures/Numbers/TYPE2/NUM3.blp
SVUI_!Core/assets/textures/Numbers/TYPE2/NUM4.blp
SVUI_!Core/assets/textures/Numbers/TYPE2/NUM5.blp
SVUI_!Core/assets/textures/SPLASH.blp
SVUI_!Core/assets/textures/TITLE-HIGHLIGHT.blp
SVUI_!Core/assets/textures/WorldState-CaptureBar.blp
SVUI_!Core/filtering/_load.xml
SVUI_!Core/filtering/class_filters/deathknight.lua
SVUI_!Core/filtering/class_filters/druid.lua
SVUI_!Core/filtering/class_filters/hunter.lua
SVUI_!Core/filtering/class_filters/mage.lua
SVUI_!Core/filtering/class_filters/monk.lua
SVUI_!Core/filtering/class_filters/paladin.lua
SVUI_!Core/filtering/class_filters/pets.lua
SVUI_!Core/filtering/class_filters/priest.lua
SVUI_!Core/filtering/class_filters/race.lua
SVUI_!Core/filtering/class_filters/rogue.lua
SVUI_!Core/filtering/class_filters/shaman.lua
SVUI_!Core/filtering/class_filters/warlock.lua
SVUI_!Core/filtering/class_filters/warrior.lua
SVUI_!Core/filtering/defaults.lua
SVUI_!Core/guide/_template/config.ld
SVUI_!Core/guide/_template/images.css
SVUI_!Core/guide/_template/ldoc.css
SVUI_!Core/guide/_template/ldoc.ltp
SVUI_!Core/guide/_template/svui.css
SVUI_!Core/guide/docs/addons/SVUI_Core.html
SVUI_!Core/guide/docs/index.html
SVUI_!Core/guide/docs/ldoc.css
SVUI_!Core/guide/docs/libraries/AceVillain.html
SVUI_!Core/guide/docs/libraries/LUA.html
SVUI_!Core/guide/docs/libraries/Librarian.html
SVUI_!Core/guide/docs/manual/doc.md.html
SVUI_!Core/language/_load.xml
SVUI_!Core/language/chinese_ui.lua
SVUI_!Core/language/english_ui.lua
SVUI_!Core/language/french_ui.lua
SVUI_!Core/language/german_ui.lua
SVUI_!Core/language/italian_ui.lua
SVUI_!Core/language/korean_ui.lua
SVUI_!Core/language/portuguese_ui.lua
SVUI_!Core/language/russian_ui.lua
SVUI_!Core/language/spanish_ui.lua
SVUI_!Core/language/taiwanese_ui.lua
SVUI_!Core/libs/AceConfig-3.0/AceConfig-3.0.lua
SVUI_!Core/libs/AceConfig-3.0/AceConfig-3.0.xml
SVUI_!Core/libs/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.lua
SVUI_!Core/libs/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.xml
SVUI_!Core/libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua
SVUI_!Core/libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.xml
SVUI_!Core/libs/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.lua
SVUI_!Core/libs/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.xml
SVUI_!Core/libs/AceGUI-3.0/AceGUI-3.0.lua
SVUI_!Core/libs/AceGUI-3.0/AceGUI-3.0.xml
SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-BlizOptionsGroup.lua
SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-DropDownGroup.lua
SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-Frame.lua
SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-InlineGroup.lua
SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-ScrollFrame.lua
SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-SimpleGroup.lua
SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-TabGroup.lua
SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-TreeGroup.lua
SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-Window.lua
SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-Button.lua
SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-CheckBox.lua
SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-ColorPicker.lua
SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown-Items.lua
SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown.lua
SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-EditBox.lua
SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-Heading.lua
SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-Icon.lua
SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-InteractiveLabel.lua
SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-Keybinding.lua
SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-Label.lua
SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-MultiLineEditBox.lua
SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-Slider.lua
SVUI_!Core/libs/AceVillain-1.0/AceVillain-1.0.lua
SVUI_!Core/libs/AceVillain-1.0/AceVillain-1.0.toc
SVUI_!Core/libs/AceVillain-1.0/AceVillain-1.0.xml
SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIContainer-DropDownGroup.lua
SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIContainer-Frame.lua
SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIContainer-InlineGroup.lua
SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIContainer-TabGroup.lua
SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIContainer-TreeGroup.lua
SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIWidget-Button.lua
SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIWidget-CheckBox.lua
SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIWidget-DropDown.lua
SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIWidget-EditBox.lua
SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIWidget-Heading.lua
SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIWidget-Keybinding.lua
SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIWidget-MultiLineEditBox.lua
SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIWidget-Slider.lua
SVUI_!Core/libs/AceVillain-1.0/widgets/shared/BackgroundWidget.lua
SVUI_!Core/libs/AceVillain-1.0/widgets/shared/BorderWidget.lua
SVUI_!Core/libs/AceVillain-1.0/widgets/shared/FontWidget.lua
SVUI_!Core/libs/AceVillain-1.0/widgets/shared/SoundWidget.lua
SVUI_!Core/libs/AceVillain-1.0/widgets/shared/StatusbarWidget.lua
SVUI_!Core/libs/CallbackHandler-1.0/CallbackHandler-1.0.lua
SVUI_!Core/libs/CallbackHandler-1.0/CallbackHandler-1.0.toc
SVUI_!Core/libs/LibSharedMedia-3.0/LibSharedMedia-3.0.lua
SVUI_!Core/libs/LibSharedMedia-3.0/LibSharedMedia-3.0.toc
SVUI_!Core/libs/_Librarian/Librarian.lua
SVUI_!Core/libs/_SVUI_Lib/Animate.lua
SVUI_!Core/libs/_SVUI_Lib/Events.lua
SVUI_!Core/libs/_SVUI_Lib/External.lua
SVUI_!Core/libs/_SVUI_Lib/LUA.lua
SVUI_!Core/libs/_SVUI_Lib/Linguist.lua
SVUI_!Core/libs/_SVUI_Lib/Parser.lua
SVUI_!Core/libs/_SVUI_Lib/Registry.lua
SVUI_!Core/libs/_SVUI_Lib/Sounds.lua
SVUI_!Core/libs/_SVUI_Lib/SpecialFX.lua
SVUI_!Core/libs/_SVUI_Lib/Timers.lua
SVUI_!Core/libs/_SVUI_Lib/_SVUI_Lib.xml
SVUI_!Core/libs/_load.xml
SVUI_!Core/setup/_load.xml
SVUI_!Core/setup/installer.lua
SVUI_!Core/setup/presets.lua
SVUI_!Core/setup/theme_select.lua
SVUI_!Core/system/_docklets/breakstuff.lua
SVUI_!Core/system/_docklets/garrison.lua
SVUI_!Core/system/_docklets/misc.lua
SVUI_!Core/system/_docklets/profession.lua
SVUI_!Core/system/_docklets/raidleader.lua
SVUI_!Core/system/_reports/bags.lua
SVUI_!Core/system/_reports/cta.lua
SVUI_!Core/system/_reports/dps.lua
SVUI_!Core/system/_reports/durability.lua
SVUI_!Core/system/_reports/experience.lua
SVUI_!Core/system/_reports/friends.lua
SVUI_!Core/system/_reports/gold.lua
SVUI_!Core/system/_reports/guild.lua
SVUI_!Core/system/_reports/hps.lua
SVUI_!Core/system/_reports/reputation.lua
SVUI_!Core/system/_reports/system.lua
SVUI_!Core/system/_reports/template.lua
SVUI_!Core/system/_reports/time.lua
SVUI_!Core/system/_reports/tokens.lua
SVUI_!Core/system/alerts.lua
SVUI_!Core/system/api.lua
SVUI_!Core/system/automations.lua
SVUI_!Core/system/core.lua
SVUI_!Core/system/credits.lua
SVUI_!Core/system/damage_text.lua
SVUI_!Core/system/debug.lua
SVUI_!Core/system/dock.lua
SVUI_!Core/system/dropdown.lua
SVUI_!Core/system/errors.lua
SVUI_!Core/system/funstuff.lua
SVUI_!Core/system/gear.lua
SVUI_!Core/system/henchmen.lua
SVUI_!Core/system/layout.lua
SVUI_!Core/system/letsride.lua
SVUI_!Core/system/mail.lua
SVUI_!Core/system/media.lua
SVUI_!Core/system/misc.lua
SVUI_!Core/system/overrides.lua
SVUI_!Core/system/profile.lua
SVUI_!Core/system/reports.lua
SVUI_!Core/system/slash.lua
SVUI_!Core/system/utilities.lua
SVUI_!Core/xml/docks.xml
SVUI_!Core/xml/fonts.xml
SVUI_!Core/xml/styles.xml
SVUI_!Core/xml/templates.xml
SVUI_!Core/xml/widgets.xml
SVUI_!Options/License.txt
SVUI_!Options/SVUI_!Options.lua
SVUI_!Options/SVUI_!Options.toc
SVUI_!Options/SVUI_!Options.xml
SVUI_!Options/UnitFrames.lua
SVUI_ActionBars/LICENSE.txt
SVUI_ActionBars/Loader.lua
SVUI_ActionBars/SVUI_ActionBars.lua
SVUI_ActionBars/SVUI_ActionBars.toc
SVUI_ActionBars/SVUI_ActionBars.xml
SVUI_ActionBars/assets/MICROMENU.blp
SVUI_ActionBars/components/keybind.lua
SVUI_ActionBars/components/micro.lua
SVUI_ActionBars/components/totem.lua
SVUI_ActionBars/components/zone.lua
SVUI_ActionBars/libs/CallbackHandler-1.0/CallbackHandler-1.0.lua
SVUI_ActionBars/libs/LibActionButton-1.0/LibActionButton-1.0.lua
SVUI_ActionBars/libs/LibStub/LibStub.lua
SVUI_ActionBars/libs/_load.xml
SVUI_Auras/LICENSE.txt
SVUI_Auras/Loader.lua
SVUI_Auras/SVUI_Auras.lua
SVUI_Auras/SVUI_Auras.toc
SVUI_Auras/SVUI_Auras.xml
SVUI_Auras/assets/AURA-CRIT.blp
SVUI_Auras/assets/AURA-HASTE.blp
SVUI_Auras/assets/AURA-HEART.blp
SVUI_Auras/assets/AURA-MASTERY.blp
SVUI_Auras/assets/AURA-MULTISTRIKE.blp
SVUI_Auras/assets/AURA-POWER.blp
SVUI_Auras/assets/AURA-SPELL.blp
SVUI_Auras/assets/AURA-STATS.blp
SVUI_Auras/assets/AURA-VERSATILITY.blp
SVUI_Auras/components/procs.lua
SVUI_Chat/LICENSE.txt
SVUI_Chat/Loader.lua
SVUI_Chat/SVUI_Chat.lua
SVUI_Chat/SVUI_Chat.toc
SVUI_Chat/SVUI_Chat.xml
SVUI_Chat/assets/CHAT-SCROLL.blp
SVUI_Chat/assets/CHAT-SVUI-LOGO.blp
SVUI_Chat/assets/CHAT-WHISPER.blp
SVUI_Chat/assets/CHATBUBBLE-BACKDROP.blp
SVUI_Chat/assets/CHATBUBBLE-BG.blp
SVUI_Chat/assets/CHATBUBBLE-TAIL.blp
SVUI_Chat/assets/DOCK-ICON-CHAT.blp
SVUI_Chat/assets/Emoticons/SVUI_Chat_Logo.blp
SVUI_Chat/assets/Emoticons/alert.blp
SVUI_Chat/assets/Emoticons/alert2.blp
SVUI_Chat/assets/Emoticons/angry.blp
SVUI_Chat/assets/Emoticons/broken_heart.blp
SVUI_Chat/assets/Emoticons/grin.blp
SVUI_Chat/assets/Emoticons/happy.blp
SVUI_Chat/assets/Emoticons/heart.blp
SVUI_Chat/assets/Emoticons/hmm.blp
SVUI_Chat/assets/Emoticons/middle_finger.blp
SVUI_Chat/assets/Emoticons/sad.blp
SVUI_Chat/assets/Emoticons/surprise.blp
SVUI_Chat/assets/Emoticons/tongue.blp
SVUI_Chat/assets/Emoticons/weepy.blp
SVUI_Chat/assets/Emoticons/winky.blp
SVUI_Chat/assets/whisper.mp3
SVUI_Chat/components/bubbles.lua
SVUI_CraftOMatic/Bindings.xml
SVUI_CraftOMatic/License.txt
SVUI_CraftOMatic/Loader.lua
SVUI_CraftOMatic/SVUI_CraftOMatic.lua
SVUI_CraftOMatic/SVUI_CraftOMatic.toc
SVUI_CraftOMatic/SVUI_CraftOMatic.xml
SVUI_CraftOMatic/artwork/DOCK-LABORER.blp
SVUI_CraftOMatic/artwork/LABORER-COOKING.blp
SVUI_CraftOMatic/artwork/LABORER-FARMING.blp
SVUI_CraftOMatic/artwork/LABORER-FISHING.blp
SVUI_CraftOMatic/artwork/LABORER-SURVEY.blp
SVUI_CraftOMatic/components/_load.xml
SVUI_CraftOMatic/components/archaeology.lua
SVUI_CraftOMatic/components/cooking.lua
SVUI_CraftOMatic/components/farming.lua
SVUI_CraftOMatic/components/fishing.lua
SVUI_FightOMatic/Bindings.xml
SVUI_FightOMatic/License.txt
SVUI_FightOMatic/Loader.lua
SVUI_FightOMatic/SVUI_FightOMatic.lua
SVUI_FightOMatic/SVUI_FightOMatic.toc
SVUI_FightOMatic/SVUI_FightOMatic.xml
SVUI_FightOMatic/artwork/DOCK-PVP.blp
SVUI_FightOMatic/artwork/PVP-INCOMING.blp
SVUI_FightOMatic/artwork/PVP-INFO.blp
SVUI_FightOMatic/artwork/PVP-RADIO.blp
SVUI_FightOMatic/artwork/PVP-SAFE.blp
SVUI_FightOMatic/artwork/PVP-SCANNER.blp
SVUI_FightOMatic/artwork/PVP-UTILITIES.blp
SVUI_Inventory/LICENSE.txt
SVUI_Inventory/Loader.lua
SVUI_Inventory/SVUI_Inventory.lua
SVUI_Inventory/SVUI_Inventory.toc
SVUI_Inventory/SVUI_Inventory.xml
SVUI_Inventory/assets/BAGS-BAGS.blp
SVUI_Inventory/assets/BAGS-CLEANUP.blp
SVUI_Inventory/assets/BAGS-DEPOSIT.blp
SVUI_Inventory/assets/BAGS-PURCHASE.blp
SVUI_Inventory/assets/BAGS-REAGENTS.blp
SVUI_Inventory/assets/BAGS-SORT.blp
SVUI_Inventory/assets/BAGS-STACK.blp
SVUI_Inventory/assets/BAGS-TRANSFER.blp
SVUI_Inventory/assets/BAGS-VENDOR.blp
SVUI_Inventory/components/organization.lua
SVUI_Inventory/components/sorting.lua
SVUI_Maps/LICENSE.txt
SVUI_Maps/Loader.lua
SVUI_Maps/SVUI_Maps.lua
SVUI_Maps/SVUI_Maps.toc
SVUI_Maps/SVUI_Maps.xml
SVUI_Maps/assets/DEFAULT-OBJECTICONS.blp
SVUI_Maps/assets/MINIMAP-CALENDAR.blp
SVUI_Maps/assets/MINIMAP-MAIL.blp
SVUI_Maps/assets/MINIMAP-OBJECTICONS.blp
SVUI_Maps/assets/MINIMAP-ROUND.blp
SVUI_Maps/assets/MINIMAP-TRACKING.blp
SVUI_Maps/assets/MINIMAP_ARROW.blp
SVUI_Maps/assets/MINIMAP_CORPSE_ARROW.blp
SVUI_Maps/assets/MINIMAP_GUIDE_ARROW.blp
SVUI_Maps/assets/MINIMAP_MASK_RECTANGLE.blp
SVUI_Maps/assets/MINIMAP_MASK_SQUARE.blp
SVUI_Maps/assets/MINIMAP_ROTATE_ARROW.blp
SVUI_NamePlates/LICENSE.txt
SVUI_NamePlates/Loader.lua
SVUI_NamePlates/OLD_SVUI_NamePlates.lua
SVUI_NamePlates/SVUI_NamePlates.lua
SVUI_NamePlates/SVUI_NamePlates.toc
SVUI_NamePlates/SVUI_NamePlates.xml
SVUI_NamePlates/assets/COMBO-POINT.blp
SVUI_NamePlates/assets/PLATE-BOTTOM.blp
SVUI_NamePlates/assets/PLATE-LEFT.blp
SVUI_NamePlates/assets/PLATE-RIGHT.blp
SVUI_NamePlates/assets/PLATE-ROLES.blp
SVUI_NamePlates/assets/PLATE-TOP.blp
SVUI_NamePlates/components/healers.lua
SVUI_PKG.toc
SVUI_QuestTracker/LICENSE.txt
SVUI_QuestTracker/Loader.lua
SVUI_QuestTracker/SVUI_QuestTracker.lua
SVUI_QuestTracker/SVUI_QuestTracker.toc
SVUI_QuestTracker/SVUI_QuestTracker.xml
SVUI_QuestTracker/assets/DOCK-ICON-QUESTS.blp
SVUI_QuestTracker/assets/QUEST-BUTTON-ART.blp
SVUI_QuestTracker/assets/QUEST-COMPLETE-ICON.blp
SVUI_QuestTracker/assets/QUEST-INCOMPLETE-ICON.blp
SVUI_QuestTracker/components/achievements.lua
SVUI_QuestTracker/components/active.lua
SVUI_QuestTracker/components/bonus.lua
SVUI_QuestTracker/components/button.lua
SVUI_QuestTracker/components/popups.lua
SVUI_QuestTracker/components/quests.lua
SVUI_QuestTracker/components/scenario.lua
SVUI_Skins/License.txt
SVUI_Skins/Loader.lua
SVUI_Skins/SVUI_Skins.lua
SVUI_Skins/SVUI_Skins.toc
SVUI_Skins/SVUI_Skins.xml
SVUI_Skins/artwork/Arch-Progress-Bg.blp
SVUI_Skins/artwork/Arch-Progress-Fill.blp
SVUI_Skins/artwork/ArcheologyToast.blp
SVUI_Skins/artwork/DOCK-ICON-ADDON.blp
SVUI_Skins/artwork/FAVORITE-STAR.blp
SVUI_Skins/artwork/FOLLOWER-LEVEL.blp
SVUI_Skins/artwork/FOLLOWER-RING.blp
SVUI_Skins/artwork/UI-LFG-ICON-ROLES.blp
SVUI_Skins/artwork/UI-LFG-ICONS-ROLEBACKGROUNDS.blp
SVUI_Skins/components/_load.xml
SVUI_Skins/components/addons/ACP.lua
SVUI_Skins/components/addons/Ace3.lua
SVUI_Skins/components/addons/AdiBags.lua
SVUI_Skins/components/addons/Altoholic.lua
SVUI_Skins/components/addons/AtlasLoot.lua
SVUI_Skins/components/addons/AuctionLite.lua
SVUI_Skins/components/addons/BigWigs.lua
SVUI_Skins/components/addons/Bugsack.lua
SVUI_Skins/components/addons/Clique.lua
SVUI_Skins/components/addons/Cooline.lua
SVUI_Skins/components/addons/DBM.lua
SVUI_Skins/components/addons/DXE.lua
SVUI_Skins/components/addons/Details.lua
SVUI_Skins/components/addons/LightHeaded.lua
SVUI_Skins/components/addons/MasterPlan.lua
SVUI_Skins/components/addons/Mogit.lua
SVUI_Skins/components/addons/Omen.lua
SVUI_Skins/components/addons/Outfitter.lua
SVUI_Skins/components/addons/Postal.lua
SVUI_Skins/components/addons/Quartz.lua
SVUI_Skins/components/addons/Recount.lua
SVUI_Skins/components/addons/SVUI_!Options.lua
SVUI_Skins/components/addons/SexyCooldown.lua
SVUI_Skins/components/addons/Skada.lua
SVUI_Skins/components/addons/Storyline.lua
SVUI_Skins/components/addons/TinyDPS.lua
SVUI_Skins/components/addons/TomTom.lua
SVUI_Skins/components/addons/TradeSkillDW.lua
SVUI_Skins/components/addons/VEM.lua
SVUI_Skins/components/addons/Zygor.lua
SVUI_Skins/components/addons/_load.xml
SVUI_Skins/components/addons/alDamageMeter.lua
SVUI_Skins/components/atlas.lua
SVUI_Skins/components/atlas/_load.xml
SVUI_Skins/components/atlas/garrison.lua
SVUI_Skins/components/blizzard/_load.xml
SVUI_Skins/components/blizzard/achievement.lua
SVUI_Skins/components/blizzard/alert.lua
SVUI_Skins/components/blizzard/archeology.lua
SVUI_Skins/components/blizzard/auctionhouse.lua
SVUI_Skins/components/blizzard/barbershop.lua
SVUI_Skins/components/blizzard/battlefield.lua
SVUI_Skins/components/blizzard/blackmarket.lua
SVUI_Skins/components/blizzard/calendar.lua
SVUI_Skins/components/blizzard/challenges.lua
SVUI_Skins/components/blizzard/character.lua
SVUI_Skins/components/blizzard/chat.lua
SVUI_Skins/components/blizzard/collections.lua
SVUI_Skins/components/blizzard/encounterjournal.lua
SVUI_Skins/components/blizzard/friends.lua
SVUI_Skins/components/blizzard/garrison.lua
SVUI_Skins/components/blizzard/guild.lua
SVUI_Skins/components/blizzard/help.lua
SVUI_Skins/components/blizzard/inspect.lua
SVUI_Skins/components/blizzard/itemsocketing.lua
SVUI_Skins/components/blizzard/itemupgrade.lua
SVUI_Skins/components/blizzard/keybinding.lua
SVUI_Skins/components/blizzard/lfd.lua
SVUI_Skins/components/blizzard/macro.lua
SVUI_Skins/components/blizzard/misc.lua
SVUI_Skins/components/blizzard/petbattle.lua
SVUI_Skins/components/blizzard/petjournal.lua
SVUI_Skins/components/blizzard/pvp.lua
SVUI_Skins/components/blizzard/quest.lua
SVUI_Skins/components/blizzard/raid.lua
SVUI_Skins/components/blizzard/reforging.lua
SVUI_Skins/components/blizzard/social.lua
SVUI_Skins/components/blizzard/spellbook.lua
SVUI_Skins/components/blizzard/store.lua
SVUI_Skins/components/blizzard/system.lua
SVUI_Skins/components/blizzard/talents.lua
SVUI_Skins/components/blizzard/timemanager.lua
SVUI_Skins/components/blizzard/tradeskill.lua
SVUI_Skins/components/blizzard/trainer.lua
SVUI_Skins/components/blizzard/transmog.lua
SVUI_Skins/components/blizzard/voidstorage.lua
SVUI_Skins/components/blizzard/worldmap.lua
SVUI_Skins/components/docklet.lua
SVUI_Tooltip/LICENSE.txt
SVUI_Tooltip/Loader.lua
SVUI_Tooltip/SVUI_Tooltip.lua
SVUI_Tooltip/SVUI_Tooltip.toc
SVUI_Tooltip/SVUI_Tooltip.xml
SVUI_Tooltip/assets/MINITIP-BG.blp
SVUI_Tooltip/assets/MINITIP-LEFT.blp
SVUI_Tooltip/assets/MINITIP-RIGHT.blp
SVUI_Tooltip/assets/TOOLTIP.blp
SVUI_Tooltip/assets/TT-BOTTOM.blp
SVUI_Tooltip/assets/TT-LEFT.blp
SVUI_Tooltip/assets/TT-RIGHT.blp
SVUI_Tooltip/assets/TT-TOP.blp
SVUI_TrackOMatic/Bindings.xml
SVUI_TrackOMatic/License.txt
SVUI_TrackOMatic/Loader.lua
SVUI_TrackOMatic/SVUI_TrackOMatic.lua
SVUI_TrackOMatic/SVUI_TrackOMatic.toc
SVUI_TrackOMatic/SVUI_TrackOMatic.xml
SVUI_TrackOMatic/artwork/DOODAD-ARROW.blp
SVUI_TrackOMatic/artwork/DOODAD-BG.blp
SVUI_TrackOMatic/artwork/DOODAD-BORDER.blp
SVUI_TrackOMatic/artwork/DOODAD-RADAR.blp
SVUI_TrackOMatic/artwork/GPS-ARROW.blp
SVUI_TrackOMatic/artwork/QUEST-COMPASS-ARROW.blp
SVUI_TrackOMatic/artwork/QUEST-COMPASS-BG.blp
SVUI_TrackOMatic/components/_load.xml
SVUI_TrackOMatic/components/guides.lua
SVUI_TrackOMatic/components/triangulate.lua
SVUI_TrackOMatic/components/unitframe_gps.lua
SVUI_UnitFrames/LICENSE.txt
SVUI_UnitFrames/Loader.lua
SVUI_UnitFrames/SVUI_UnitFrames.lua
SVUI_UnitFrames/SVUI_UnitFrames.toc
SVUI_UnitFrames/SVUI_UnitFrames.xml
SVUI_UnitFrames/assets/Border/ELITE-BOTTOM.blp
SVUI_UnitFrames/assets/Border/ELITE-RIGHT.blp
SVUI_UnitFrames/assets/Border/ELITE-TOP.blp
SVUI_UnitFrames/assets/Castbar/CHANNEL-REVERSED.blp
SVUI_UnitFrames/assets/Castbar/CHANNEL.blp
SVUI_UnitFrames/assets/Castbar/HADOUKEN-REVERSED.blp
SVUI_UnitFrames/assets/Castbar/HADOUKEN.blp
SVUI_UnitFrames/assets/Castbar/SHIELD.blp
SVUI_UnitFrames/assets/Castbar/SKULLS-REVERSED.blp
SVUI_UnitFrames/assets/Castbar/SKULLS.blp
SVUI_UnitFrames/assets/Class/COMBO-ANIMATION.blp
SVUI_UnitFrames/assets/Class/COMBO-POINT-SMALL.blp
SVUI_UnitFrames/assets/Class/DEATHKNIGHT-BLOOD.blp
SVUI_UnitFrames/assets/Class/DEATHKNIGHT-DEATH.blp
SVUI_UnitFrames/assets/Class/DEATHKNIGHT-FROST.blp
SVUI_UnitFrames/assets/Class/DEATHKNIGHT-UNHOLY.blp
SVUI_UnitFrames/assets/Class/DRUID-BITE.blp
SVUI_UnitFrames/assets/Class/DRUID-CLAW-DOWN.blp
SVUI_UnitFrames/assets/Class/DRUID-CLAW-UP.blp
SVUI_UnitFrames/assets/Class/DRUID-MOON.blp
SVUI_UnitFrames/assets/Class/DRUID-SUN.blp
SVUI_UnitFrames/assets/Class/HUNTER-TRAP-BG.blp
SVUI_UnitFrames/assets/Class/HUNTER-TRAP.blp
SVUI_UnitFrames/assets/Class/MAGE-CHARGE.blp
SVUI_UnitFrames/assets/Class/MAGE-ICICLE-1.blp
SVUI_UnitFrames/assets/Class/MAGE-ICICLE-2.blp
SVUI_UnitFrames/assets/Class/MAGE-ICICLE-3.blp
SVUI_UnitFrames/assets/Class/MAGE-ICICLE-4.blp
SVUI_UnitFrames/assets/Class/MAGE-ICICLE-5.blp
SVUI_UnitFrames/assets/Class/MONK-STAGGER-BAR.blp
SVUI_UnitFrames/assets/Class/MONK-STAGGER-BG.blp
SVUI_UnitFrames/assets/Class/MONK-STAGGER-FG.blp
SVUI_UnitFrames/assets/Class/MONK-STAGGER-ICON.blp
SVUI_UnitFrames/assets/Class/MONK.blp
SVUI_UnitFrames/assets/Class/ORB-BG.blp
SVUI_UnitFrames/assets/Class/ORB.blp
SVUI_UnitFrames/assets/Class/PALADIN-HAMMER-BG.blp
SVUI_UnitFrames/assets/Class/PALADIN-HAMMER-FG.blp
SVUI_UnitFrames/assets/Class/PRIEST.blp
SVUI_UnitFrames/assets/Class/ROGUE-ANTICIPATION.blp
SVUI_UnitFrames/assets/Class/ROGUE-SMOKE.blp
SVUI_UnitFrames/assets/Class/ROGUE.blp
SVUI_UnitFrames/assets/Class/RUNES-BG.blp
SVUI_UnitFrames/assets/Class/RUNES-FG.blp
SVUI_UnitFrames/assets/Class/SHAMAN-AIR.blp
SVUI_UnitFrames/assets/Class/SHAMAN-EARTH.blp
SVUI_UnitFrames/assets/Class/SHAMAN-FIRE.blp
SVUI_UnitFrames/assets/Class/SHAMAN-WATER.blp
SVUI_UnitFrames/assets/Class/SWIRL.blp
SVUI_UnitFrames/assets/Class/VORTEX.blp
SVUI_UnitFrames/assets/Class/WARLOCK-EMBER-FG.blp
SVUI_UnitFrames/assets/Class/WARLOCK-EMBER.blp
SVUI_UnitFrames/assets/Class/WARLOCK-SHARD-BG.blp
SVUI_UnitFrames/assets/Class/WARLOCK-SHARD-FG.blp
SVUI_UnitFrames/assets/Class/WARLOCK-SHARD.blp
SVUI_UnitFrames/assets/GroupNumbers/0.blp
SVUI_UnitFrames/assets/GroupNumbers/1.blp
SVUI_UnitFrames/assets/GroupNumbers/2.blp
SVUI_UnitFrames/assets/GroupNumbers/3.blp
SVUI_UnitFrames/assets/GroupNumbers/4.blp
SVUI_UnitFrames/assets/GroupNumbers/5.blp
SVUI_UnitFrames/assets/GroupNumbers/6.blp
SVUI_UnitFrames/assets/GroupNumbers/7.blp
SVUI_UnitFrames/assets/GroupNumbers/8.blp
SVUI_UnitFrames/assets/GroupNumbers/9.blp
SVUI_UnitFrames/assets/RAID-ICONS.blp
SVUI_UnitFrames/assets/TARGET-DC.blp
SVUI_UnitFrames/assets/TARGET-DEAD.blp
SVUI_UnitFrames/assets/TARGET-TAPPED.blp
SVUI_UnitFrames/assets/UNIT-AFFLICTED.blp
SVUI_UnitFrames/assets/UNIT-AGGRO.blp
SVUI_UnitFrames/assets/UNIT-DC.blp
SVUI_UnitFrames/assets/UNIT-DEAD.blp
SVUI_UnitFrames/assets/UNIT-FRIENDS-BAR.blp
SVUI_UnitFrames/assets/UNIT-FRIENDS-BG.blp
SVUI_UnitFrames/assets/UNIT-FRIENDSHIP.blp
SVUI_UnitFrames/assets/UNIT-HEALTH-ANIMATION.blp
SVUI_UnitFrames/assets/UNIT-LML.blp
SVUI_UnitFrames/assets/UNIT-PLAYER-STATE.blp
SVUI_UnitFrames/assets/UNIT-ROLES.blp
SVUI_UnitFrames/assets/UNIT-STUNNED-LG.blp
SVUI_UnitFrames/assets/UNIT-STUNNED.blp
SVUI_UnitFrames/assets/UNIT-TAPPED.blp
SVUI_UnitFrames/assets/UNIT-XRAY-CLOSE.blp
SVUI_UnitFrames/assets/UNIT-XRAY.blp
SVUI_UnitFrames/bodyguard.lua
SVUI_UnitFrames/class_resources/deathknight.lua
SVUI_UnitFrames/class_resources/demonhunter.lua
SVUI_UnitFrames/class_resources/druid.lua
SVUI_UnitFrames/class_resources/hunter.lua
SVUI_UnitFrames/class_resources/mage.lua
SVUI_UnitFrames/class_resources/monk.lua
SVUI_UnitFrames/class_resources/paladin.lua
SVUI_UnitFrames/class_resources/priest.lua
SVUI_UnitFrames/class_resources/rogue.lua
SVUI_UnitFrames/class_resources/shaman.lua
SVUI_UnitFrames/class_resources/warlock.lua
SVUI_UnitFrames/class_resources/warrior.lua
SVUI_UnitFrames/elements/auras.lua
SVUI_UnitFrames/elements/castbar.lua
SVUI_UnitFrames/elements/essentials.lua
SVUI_UnitFrames/elements/misc.lua
SVUI_UnitFrames/elements/tags.lua
SVUI_UnitFrames/frames.lua
SVUI_UnitFrames/groups.lua
SVUI_UnitFrames/libs/Plugins/oUF_ActionPanel/oUF_ActionPanel.lua
SVUI_UnitFrames/libs/Plugins/oUF_ActionPanel/oUF_ActionPanel.toc
SVUI_UnitFrames/libs/Plugins/oUF_AdvancedAuras/oUF_AdvancedAuras.lua
SVUI_UnitFrames/libs/Plugins/oUF_Afflicted/oUF_Afflicted.lua
SVUI_UnitFrames/libs/Plugins/oUF_Afflicted/oUF_Afflicted.toc
SVUI_UnitFrames/libs/Plugins/oUF_AuraWatch/oUF_AuraWatch.lua
SVUI_UnitFrames/libs/Plugins/oUF_AuraWatch/oUF_AuraWatch.toc
SVUI_UnitFrames/libs/Plugins/oUF_CombatFader/oUF_CombatFader.lua
SVUI_UnitFrames/libs/Plugins/oUF_CombatFader/oUF_CombatFader.toc
SVUI_UnitFrames/libs/Plugins/oUF_Conqueror/oUF_Conqueror.lua
SVUI_UnitFrames/libs/Plugins/oUF_Druidness/oUF_Druidness.lua
SVUI_UnitFrames/libs/Plugins/oUF_Druidness/oUF_Druidness.toc
SVUI_UnitFrames/libs/Plugins/oUF_Experience/oUF_Experience.lua
SVUI_UnitFrames/libs/Plugins/oUF_Experience/oUF_Experience.toc
SVUI_UnitFrames/libs/Plugins/oUF_Friendship/oUF_Friendship.lua
SVUI_UnitFrames/libs/Plugins/oUF_Friendship/oUF_Friendship.toc
SVUI_UnitFrames/libs/Plugins/oUF_Gladiator/oUF_Gladiator.lua
SVUI_UnitFrames/libs/Plugins/oUF_Gladiator/oUF_Gladiator.toc
SVUI_UnitFrames/libs/Plugins/oUF_HunterTraps/oUF_HunterTraps.lua
SVUI_UnitFrames/libs/Plugins/oUF_HyperCombo/oUF_HyperCombo.lua
SVUI_UnitFrames/libs/Plugins/oUF_KungFu/oUF_KungFu.lua
SVUI_UnitFrames/libs/Plugins/oUF_Maelstrom/oUF_Maelstrom.lua
SVUI_UnitFrames/libs/Plugins/oUF_MageMagic/oUF_MageMagic.lua
SVUI_UnitFrames/libs/Plugins/oUF_MageMagic/oUF_MageMagic.toc
SVUI_UnitFrames/libs/Plugins/oUF_Necromancy/oUF_Necromancy.lua
SVUI_UnitFrames/libs/Plugins/oUF_PallyPower/oUF_PallyPower.lua
SVUI_UnitFrames/libs/Plugins/oUF_PriestOrbs/oUF_PriestOrbs.lua
SVUI_UnitFrames/libs/Plugins/oUF_RaidDebuffs/oUF_RaidDebuffs.lua
SVUI_UnitFrames/libs/Plugins/oUF_RaidDebuffs/oUF_RaidDebuffs.toc
SVUI_UnitFrames/libs/Plugins/oUF_Reputation/oUF_Reputation.lua
SVUI_UnitFrames/libs/Plugins/oUF_Reputation/oUF_Reputation.toc
SVUI_UnitFrames/libs/Plugins/oUF_Smooth/oUF_Smooth.lua
SVUI_UnitFrames/libs/Plugins/oUF_TotemBars/oUF_TotemBars.lua
SVUI_UnitFrames/libs/Plugins/oUF_WarlockShards/oUF_WarlockShards.lua
SVUI_UnitFrames/libs/_load.xml
SVUI_UnitFrames/libs/oUF/LICENSE
SVUI_UnitFrames/libs/oUF/blizzard.lua
SVUI_UnitFrames/libs/oUF/colors.lua
SVUI_UnitFrames/libs/oUF/elements/altpowerbar.lua
SVUI_UnitFrames/libs/oUF/elements/assistant.lua
SVUI_UnitFrames/libs/oUF/elements/aura.lua
SVUI_UnitFrames/libs/oUF/elements/castbar.lua
SVUI_UnitFrames/libs/oUF/elements/combat.lua
SVUI_UnitFrames/libs/oUF/elements/healprediction.lua
SVUI_UnitFrames/libs/oUF/elements/health.lua
SVUI_UnitFrames/libs/oUF/elements/leader.lua
SVUI_UnitFrames/libs/oUF/elements/lfdrole.lua
SVUI_UnitFrames/libs/oUF/elements/maintank.lua
SVUI_UnitFrames/libs/oUF/elements/masterlooter.lua
SVUI_UnitFrames/libs/oUF/elements/picon.lua
SVUI_UnitFrames/libs/oUF/elements/portraits.lua
SVUI_UnitFrames/libs/oUF/elements/power.lua
SVUI_UnitFrames/libs/oUF/elements/pvp.lua
SVUI_UnitFrames/libs/oUF/elements/qicon.lua
SVUI_UnitFrames/libs/oUF/elements/range.lua
SVUI_UnitFrames/libs/oUF/elements/readycheck.lua
SVUI_UnitFrames/libs/oUF/elements/resting.lua
SVUI_UnitFrames/libs/oUF/elements/resurrect.lua
SVUI_UnitFrames/libs/oUF/elements/ricons.lua
SVUI_UnitFrames/libs/oUF/elements/tags.lua
SVUI_UnitFrames/libs/oUF/elements/threat.lua
SVUI_UnitFrames/libs/oUF/events.lua
SVUI_UnitFrames/libs/oUF/factory.lua
SVUI_UnitFrames/libs/oUF/finalize.lua
SVUI_UnitFrames/libs/oUF/init.lua
SVUI_UnitFrames/libs/oUF/oUF_core.lua
SVUI_UnitFrames/libs/oUF/ouf.lua
SVUI_UnitFrames/libs/oUF/private.lua
SVUI_UnitFrames/libs/oUF/units.lua
SVUI_UnitFrames/view.lua
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5cc841e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+*.md
+Thumbs.db
+[Dd]ev*/
diff --git a/.pkgmeta b/.pkgmeta
new file mode 100644
index 0000000..0c1189e
--- /dev/null
+++ b/.pkgmeta
@@ -0,0 +1,25 @@
+package-as: SVUI_PKG
+
+move-folders:
+    SVUI_PKG/SVUI_!Core: SVUI_!Core
+    SVUI_PKG/SVUI_!Options: SVUI_!Options
+    SVUI_PKG/SVUI_ActionBars: SVUI_ActionBars
+    SVUI_PKG/SVUI_Auras: SVUI_Auras
+    SVUI_PKG/SVUI_Chat: SVUI_Chat
+    SVUI_PKG/SVUI_CraftOMatic: SVUI_CraftOMatic
+    SVUI_PKG/SVUI_FightOMatic: SVUI_FightOMatic
+    SVUI_PKG/SVUI_Inventory: SVUI_Inventory
+    SVUI_PKG/SVUI_Maps: SVUI_Maps
+    SVUI_PKG/SVUI_NamePlates: SVUI_NamePlates
+    SVUI_PKG/SVUI_QuestTracker: SVUI_QuestTracker
+    SVUI_PKG/SVUI_Skins: SVUI_Skins
+    SVUI_PKG/SVUI_Tooltip: SVUI_Tooltip
+    SVUI_PKG/SVUI_TrackOMatic: SVUI_TrackOMatic
+    SVUI_PKG/SVUI_UnitFrames: SVUI_UnitFrames
+    SVUI_PKG/SVUITheme_Simple: SVUITheme_Simple
+
+manual-changelog:
+    filename: CHANGELOG.md
+    markup-type: markdown
+
+license-output: LICENSE.txt
diff --git a/LICENSE b/LICENSE
index 906a43d..4175642 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
 MIT License

-Copyright (c) 2016 Steven Jackson
+Copyright (c) 2010, Failcoder (Steve Jackson)

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index 7f6ceca..7e34985 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,22 @@
 # supervillain-ui
+
 Custom World of Warcraft User Interface
+
+### Compatibility
+
+SuperVillain UI is designed to work with the latest live expansion of World of Warcraft.
+
+### Notes
+
+* This repo will be used exclusively for development versions
+* All feature requests will be considered but not guranteed
+* Please be thorough when posting issues
+
+## Release Version
+
+If you are looking for the most current release version (non-development) you can find it at [WowInterface](http://www.wowinterface.com/downloads/info23519-SuperVillainUI.html#info) or [Curse](http://www.curse.com/addons/wow/supervillain-ui)
+
+## License
+
+SuperVillain UI is licensed under the The MIT License.
+Copyright (c) 2010, Munglunch (Steve Jackson).
diff --git a/SVUITheme_Simple/LICENSE.txt b/SVUITheme_Simple/LICENSE.txt
new file mode 100644
index 0000000..05ceba8
--- /dev/null
+++ b/SVUITheme_Simple/LICENSE.txt
@@ -0,0 +1,31 @@
+
+The MIT License
+
+Copyright (c) 2010, Failcoder (Steve Jackson)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy
+of this software and associated documentation files (the "Software"), to
+deal
+in the Software without restriction, including without limitation the
+rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/SVUITheme_Simple/ROUND-SIMPLE.blp b/SVUITheme_Simple/ROUND-SIMPLE.blp
new file mode 100644
index 0000000..a4812a6
Binary files /dev/null and b/SVUITheme_Simple/ROUND-SIMPLE.blp differ
diff --git a/SVUITheme_Simple/SVUITheme_Simple.lua b/SVUITheme_Simple/SVUITheme_Simple.lua
new file mode 100644
index 0000000..4ba33ef
--- /dev/null
+++ b/SVUITheme_Simple/SVUITheme_Simple.lua
@@ -0,0 +1,175 @@
+--[[
+##############################################################################
+S U P E R - V I L L A I N - T H E M E   By: Failcoder
+##############################################################################
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local math 		= _G.math;
+--[[ MATH METHODS ]]--
+local random = math.random;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G["SVUI"];
+local LSM = _G.LibStub("LibSharedMedia-3.0");
+
+LSM:Register("background", "SVUI Backdrop", [[Interface\DialogFrame\UI-DialogBox-Background]])
+
+SV.DialogFontDefault = "SVUI Default Font";
+
+if(GetLocale() == "enUS") then
+	SV:AssignMedia("font", "dialog", "SVUI Dialog Font", 10, "OUTLINE")
+end
+
+SV:AssignMedia("font", "number", "SVUI Caps Font", 14, "OUTLINE");
+SV:AssignMedia("font", "number_big", "SVUI Caps Font", 18, "OUTLINE");
+SV:AssignMedia("font", "header", "SVUI Caps Font", 18, "OUTLINE");
+SV:AssignMedia("font", "combat", "SVUI Combat Font", 64, "OUTLINE");
+SV:AssignMedia("font", "alert", "SVUI Default Font", 20, "OUTLINE");
+SV:AssignMedia("font", "zone", "SVUI Default Font", 16, "OUTLINE");
+SV:AssignMedia("font", "aura", "SVUI Caps Font", 14, "OUTLINE");
+SV:AssignMedia("font", "data", "SVUI Caps Font", 14, "OUTLINE");
+SV:AssignMedia("font", "narrator", "SVUI Default Font", 14, "OUTLINE");
+SV:AssignMedia("font", "lootnumber", "SVUI Caps Font", 14, "OUTLINE");
+SV:AssignMedia("font", "rollnumber", "SVUI Caps Font", 14, "OUTLINE");
+SV:AssignMedia("background", "default", "SVUI Backdrop", 0, false);
+SV:AssignMedia("background", "pattern", "SVUI Backdrop", 0, false);
+SV:AssignMedia("background", "premium", "SVUI Backdrop", 0, false);
+SV:AssignMedia("background", "button", "SVUI Default BG", 0, false);
+SV:AssignMedia("background", "unitlarge", "SVUI Backdrop", 0, false);
+SV:AssignMedia("background", "unitsmall", "SVUI Backdrop", 0, false);
+SV:AssignMedia("button", "round", [[Interface\AddOns\SVUITheme_Simple\ROUND-SIMPLE]]);
+SV:AssignMedia("color", "button", 0, 0, 0, 0.5);
+SV:AssignMedia("template", "Default", "SVUITheme_Simple_Default");
+SV:AssignMedia("template", "Button", "SVUITheme_Simple_Default");
+SV:AssignMedia("template", "DockButton", "SVUITheme_Simple_DockButton");
+SV:AssignMedia("template", "Pattern", "SVUITheme_Simple_Default");
+SV:AssignMedia("template", "Premium", "SVUITheme_Simple_Default");
+SV:AssignMedia("template", "Model", "SVUITheme_Simple_Default");
+SV:AssignMedia("template", "Window", "SVUITheme_Simple_Default");
+SV:AssignMedia("template", "Window2", "SVUITheme_Simple_Default");
+SV:AssignMedia("template", "Minimap", "SVUITheme_Simple_Minimap");
+SV:AssignMedia("template", "ActionPanel", "SVUITheme_Simple_ActionPanel");
+SV:AssignMedia("template", "Container", "SVUITheme_Simple_Default");
+
+local _RefreshZoneText = function(self)
+	if(self.InfoTop:IsShown()) then
+		self.InfoTop:Hide();
+	end
+	if(not SV.db.Maps.locationText or SV.db.Maps.locationText == "HIDE") then
+		self.InfoBottom:Hide();
+	else
+		self.InfoBottom:Show();
+		local zone = GetRealZoneText() or UNKNOWN
+		self.InfoBottom.Text:SetText(zone)
+	end
+end
+
+local UpdateBackdrop = function(self)
+	local current = SV.Dock.private.Opacity[self:GetName()];
+	if(SV.db.Dock.backdrop and (not SV.Dock.private.Disabled[self:GetName() .. 'Button'])) then
+		self.backdrop:SetAlpha(1);
+	else
+		self.backdrop:SetAlpha(0);
+	end
+	self:SetAlpha(current or 1);
+end
+
+local _SetThemedBackdrop = function(frame, isBottom)
+	local backdrop = CreateFrame("Frame", nil, frame)
+	backdrop:SetAllPoints(frame)
+	backdrop:SetFrameStrata("BACKGROUND")
+	backdrop:SetBackdrop({
+	    bgFile = [[Interface\DialogFrame\UI-DialogBox-Background]],
+	    tile = false,
+	    tileSize = 0,
+	    edgeFile = [[Interface\BUTTONS\WHITE8X8]],
+	    edgeSize = 1,
+	    insets =
+	    {
+	        left = 0,
+	        right = 0,
+	        top = 0,
+	        bottom = 0,
+	    },
+	});
+	backdrop:SetBackdropColor(0,0,0,0.5);
+	backdrop:SetBackdropBorderColor(0,0,0,0.8);
+
+	frame.backdrop = backdrop
+
+	UpdateBackdrop(frame);
+	frame.UpdateBackdrop = UpdateBackdrop;
+end
+
+local _SetBorderTheme = function(self)
+	self.Border.Top:SetPoint("TOPLEFT", SV.Screen, "TOPLEFT", -1, 1)
+	self.Border.Top:SetPoint("TOPRIGHT", SV.Screen, "TOPRIGHT", 1, 1)
+	self.Border.Top:SetHeight(10)
+	self.Border.Top:SetBackdrop({
+		bgFile = [[Interface\BUTTONS\WHITE8X8]],
+		edgeFile = [[Interface\BUTTONS\WHITE8X8]],
+		tile = false,
+		tileSize = 0,
+		edgeSize = 1,
+		insets = {left = 0, right = 0, top = 0, bottom = 0}
+	})
+	self.Border.Top:SetBackdropColor(0,0,0,0)
+	self.Border.Top:SetBackdropBorderColor(0,0,0,0)
+	self.Border.Top:SetFrameLevel(0)
+	self.Border.Top:SetFrameStrata('BACKGROUND')
+	self.Border.Top:SetScript("OnShow", function(self)
+		self:SetFrameLevel(0)
+		self:SetFrameStrata('BACKGROUND')
+	end)
+
+	self.Border.Bottom:SetPoint("BOTTOMLEFT", SV.Screen, "BOTTOMLEFT", -1, -1)
+	self.Border.Bottom:SetPoint("BOTTOMRIGHT", SV.Screen, "BOTTOMRIGHT", 1, -1)
+	self.Border.Bottom:SetHeight(10)
+	self.Border.Bottom:SetBackdrop({
+		bgFile = [[Interface\BUTTONS\WHITE8X8]],
+		edgeFile = [[Interface\BUTTONS\WHITE8X8]],
+		tile = false,
+		tileSize = 0,
+		edgeSize = 1,
+		insets = {left = 0, right = 0, top = 0, bottom = 0}
+	})
+	self.Border.Bottom:SetBackdropColor(0,0,0,0)
+	self.Border.Bottom:SetBackdropBorderColor(0,0,0,0)
+	self.Border.Bottom:SetFrameLevel(0)
+	self.Border.Bottom:SetFrameStrata('BACKGROUND')
+	self.Border.Bottom:SetScript("OnShow", function(self)
+		self:SetFrameLevel(0)
+		self:SetFrameStrata('BACKGROUND')
+	end)
+end
+
+function SV:LoadTheme()
+	if(self.defaults.UnitFrames) then
+		self:AssignMedia("font", "unitprimary", "SVUI Caps Font", 14, "OUTLINE");
+		self:AssignMedia("font", "unitsecondary", "SVUI Caps Font", 14, "OUTLINE");
+		self:AssignMedia("font", "unitaurabar", "SVUI Default Font", 14, "OUTLINE");
+		self:AssignMedia("font", "unitaura", "SVUI Default Font", 14, "OUTLINE");
+	end
+	if(self.defaults.Maps) then
+		self:AssignMedia("font", "mapinfo", "SVUI Default Font", 14, "OUTLINE");
+		self:AssignMedia("font", "mapcoords", "SVUI Caps Font", 14, "OUTLINE");
+		self.defaults.Maps.locationText = "SIMPLE";
+		self.defaults.Maps.bordersize = 0;
+		self.defaults.Maps.bordercolor = "dark";
+	end
+	if(self.Maps) then
+		self.Maps.RefreshZoneText = _RefreshZoneText
+	end
+
+	self.Dock.SetThemedBackdrop = _SetThemedBackdrop
+	self.Dock.SetBorderTheme = _SetBorderTheme
+end
diff --git a/SVUITheme_Simple/SVUITheme_Simple.toc b/SVUITheme_Simple/SVUITheme_Simple.toc
new file mode 100644
index 0000000..1253db7
--- /dev/null
+++ b/SVUITheme_Simple/SVUITheme_Simple.toc
@@ -0,0 +1,17 @@
+## Interface: 70000
+## Author: Failcoder
+## Version: 1.0.0
+## Title: |cffFF9900SVUI Theme: |r|cff00EFFFSimple|r
+## Notes: Theme for [|cff9911FFSVUI Framework|r].
+## RequiredDeps: SVUI_!Core
+## OptionalDeps: LibSharedMedia-3.0
+## LoadOnDemand: 1
+## DefaultState: disabled
+## X-SVUITheme: Simple
+## X-Email: munglunch@gmail.com
+## X-Website: http://www.supervillainui.com
+## X-Donate: PayPal:munglunch@gmail.com
+## X-License: MIT
+## X-Category: Interface Enhancements
+
+SVUITheme_Simple.xml
diff --git a/SVUITheme_Simple/SVUITheme_Simple.xml b/SVUITheme_Simple/SVUITheme_Simple.xml
new file mode 100644
index 0000000..519b110
--- /dev/null
+++ b/SVUITheme_Simple/SVUITheme_Simple.xml
@@ -0,0 +1,102 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+    <Frame name="SVUITheme_Simple_Default" virtual="true">
+        <Attributes>
+            <Attribute name="panelID" type="string" value="default" />
+            <Attribute name="panelPadding" type="number" value="1" />
+            <Attribute name="panelColor" type="string" value="default" />
+            <Attribute name="panelGradient" type="string" value="default" />
+            <Attribute name="panelTexUpdate" type="boolean" value="false" />
+            <Attribute name="panelSkipUpdate" type="boolean" value="false" />
+            <Attribute name="panelOffset" type="number" value="0" />
+        </Attributes>
+        <Backdrop bgFile="Interface\DialogFrame\UI-DialogBox-Background" edgeFile="Interface\BUTTONS\WHITE8X8" tile="false">
+            <EdgeSize val="2" />
+            <TileSize val="0" />
+            <BackgroundInsets left="0" right="0" top="0" bottom="0" />
+            <Color r="0.2" g="0.2" b="0.2" a="1" />
+            <BorderColor r="0" g="0" b="0" a="1" />
+        </Backdrop>
+    </Frame>
+
+    <Frame name="SVUITheme_Simple_Button" virtual="true">
+        <Attributes>
+            <Attribute name="panelID" type="string" value="button" />
+            <Attribute name="panelPadding" type="number" value="1" />
+            <Attribute name="panelColor" type="string" value="button" />
+            <Attribute name="panelGradient" type="boolean" value="false" />
+            <Attribute name="panelTexUpdate" type="boolean" value="false" />
+            <Attribute name="panelSkipUpdate" type="boolean" value="false" />
+        </Attributes>
+        <Backdrop bgFile="Interface\AddOns\SVUI_!Core\assets\backgrounds\DEFAULT" edgeFile="Interface\BUTTONS\WHITE8X8" tile="false">
+            <EdgeSize val="1" />
+            <TileSize val="0" />
+            <BackgroundInsets left="0" right="0" top="0" bottom="0" />
+            <Color r="0" g="0" b="0" a="0.5" />
+            <BorderColor r="0" g="0" b="0" a="1" />
+        </Backdrop>
+        <Frames>
+            <Frame parentKey="Shadow" inherits="SVUI_ShadowTemplate" />
+        </Frames>
+    </Frame>
+
+    <Frame name="SVUITheme_Simple_DockButton" virtual="true">
+        <Attributes>
+            <Attribute name="panelID" type="string" value="dockbutton" />
+            <Attribute name="panelPadding" type="number" value="1" />
+            <Attribute name="panelColor" type="string" value="dark" />
+            <Attribute name="panelGradient" type="string" value="dark" />
+            <Attribute name="panelTexUpdate" type="boolean" value="true" />
+            <Attribute name="panelSkipUpdate" type="boolean" value="false" />
+            <Attribute name="panelOffset" type="number" value="0" />
+        </Attributes>
+        <Backdrop bgFile="Interface\DialogFrame\UI-DialogBox-Background" edgeFile="Interface\BUTTONS\WHITE8X8" tile="false">
+            <EdgeSize val="1" />
+            <TileSize val="0" />
+            <BackgroundInsets left="0" right="0" top="0" bottom="0" />
+            <Color r="0" g="0" b="0" a="1" />
+            <BorderColor r="0" g="0" b="0" a="1" />
+        </Backdrop>
+        <Frames>
+            <Frame parentKey="Shadow" inherits="SVUI_ShadowTemplate" />
+        </Frames>
+    </Frame>
+
+    <Frame name="SVUITheme_Simple_ActionPanel" virtual="true">
+        <Attributes>
+            <Attribute name="panelID" type="string" value="actionpanel" />
+            <Attribute name="panelKeyOverride" type="string" value="ActionPanel" />
+            <Attribute name="panelPadding" type="number" value="1" />
+            <Attribute name="panelColor" type="string" value="darkest" />
+            <Attribute name="panelGradient" type="boolean" value="false" />
+            <Attribute name="panelTexUpdate" type="boolean" value="false" />
+            <Attribute name="panelSkipUpdate" type="boolean" value="false" />
+        </Attributes>
+        <Backdrop bgFile="Interface\AddOns\SVUI_!Core\assets\textures\EMPTY" edgeFile="Interface\BUTTONS\WHITE8X8" tile="false">
+            <EdgeSize val="2" />
+            <TileSize val="0" />
+            <BackgroundInsets left="0" right="0" top="0" bottom="0" />
+            <Color r="0" g="0" b="0" a="0" />
+            <BorderColor r="0" g="0" b="0" a="1" />
+        </Backdrop>
+    </Frame>
+
+    <Frame name="SVUITheme_Simple_Minimap" virtual="true">
+        <Attributes>
+            <Attribute name="panelID" type="string" value="minimap" />
+            <Attribute name="panelPadding" type="number" value="1" />
+            <Attribute name="panelColor" type="string" value="darkest" />
+            <Attribute name="panelGradient" type="boolean" value="false" />
+            <Attribute name="panelTexUpdate" type="boolean" value="false" />
+            <Attribute name="panelSkipUpdate" type="boolean" value="false" />
+        </Attributes>
+        <Backdrop bgFile="Interface\BUTTONS\WHITE8X8" edgeFile="Interface\BUTTONS\WHITE8X8" tile="false">
+            <EdgeSize val="1" />
+            <TileSize val="0" />
+            <BackgroundInsets left="0" right="0" top="0" bottom="0" />
+            <Color r="0" g="0" b="0" a="1" />
+            <BorderColor r="0" g="0" b="0" a="1" />
+        </Backdrop>
+    </Frame>
+
+    <Script file="SVUITheme_Simple.lua"/>
+</Ui>
\ No newline at end of file
diff --git a/SVUI_!Core/Bindings.xml b/SVUI_!Core/Bindings.xml
new file mode 100644
index 0000000..00cc9fa
--- /dev/null
+++ b/SVUI_!Core/Bindings.xml
@@ -0,0 +1,22 @@
+<Bindings>
+  <Binding name="SVUI_MARKERS" description="Raid Marker" category="ADDONS" header="SVUI" runOnUp="true">
+    RaidMark_HotkeyPressed(keystate)
+  </Binding>
+  <Binding name="SVUI_DOCKS" description="Toggle All Docks" category="ADDONS" runOnUp="false">
+    ToggleSuperDocks()
+  </Binding>
+  <Binding name="SVUI_DOCKS_LEFT" description="Toggle Left Dock" category="ADDONS" runOnUp="false">
+    ToggleSuperDockLeft()
+  </Binding>
+  <Binding name="SVUI_DOCKS_RIGHT" description="Toggle Right Dock" category="ADDONS" runOnUp="false">
+    ToggleSuperDockRight()
+  </Binding>
+  <Binding name="SVUI_RIDE" description="Lets Ride" category="ADDONS" runOnUp="false">
+    SVUILetsRide()
+  </Binding>
+  <Binding name="SVUI_DRAENORZONE" description="Draenor Zone Ability Button" category="ADDONS" runOnUp="false" />
+  <Binding name="SVUI_FRAMEDEBUGGER" description="Frame Stack Analyzer" category="ADDONS" runOnUp="false">
+    DebugThisFrame()
+  </Binding>
+  <ModifiedClick action="VENDORMARKITEM" default="ALT-BUTTON2"/>
+</Bindings>
\ No newline at end of file
diff --git a/SVUI_!Core/License.txt b/SVUI_!Core/License.txt
new file mode 100644
index 0000000..69d4d04
--- /dev/null
+++ b/SVUI_!Core/License.txt
@@ -0,0 +1,31 @@
+
+The MIT License
+
+Copyright (c) 2010, Failcoder (Steve Jackson)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy
+of this software and associated documentation files (the "Software"), to
+deal
+in the Software without restriction, including without limitation the
+rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN
+THE SOFTWARE.
diff --git a/SVUI_!Core/SVUI_!Core.toc b/SVUI_!Core/SVUI_!Core.toc
new file mode 100644
index 0000000..1f37a6a
--- /dev/null
+++ b/SVUI_!Core/SVUI_!Core.toc
@@ -0,0 +1,17 @@
+## Interface: 70000
+## Author: Failcoder
+## Version: 1.3.5
+## Title: |cffFF9900SuperVillain UI: |r|cff00FF00!Core|r
+## Notes: SVUI [|cff9911FFCore Framework|r].
+## SavedVariables: SVUI_Global, SVUI_Errors, SVUI_Filters, SVUI_Media, SVUI_Shared
+## SavedVariablesPerCharacter: SVUI_Private
+## OptionalDeps: LibSharedMedia-3.0
+## X-SVUIName: SVUI
+## X-SVUISchema: Core
+## X-Email: munglunch@gmail.com
+## X-Website: http://www.supervillainui.com
+## X-Donate: PayPal:munglunch@gmail.com
+## X-License: MIT
+## X-Category: Interface Enhancements
+
+SVUI_!Core.xml
diff --git a/SVUI_!Core/SVUI_!Core.xml b/SVUI_!Core/SVUI_!Core.xml
new file mode 100644
index 0000000..4646e09
--- /dev/null
+++ b/SVUI_!Core/SVUI_!Core.xml
@@ -0,0 +1,58 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+    <Include file="libs\_load.xml"/>
+    <Include file="language\_load.xml"/>
+    <Include file="xml\fonts.xml"/>
+    <Include file="xml\templates.xml"/>
+    <Include file="xml\styles.xml"/>
+    <Include file="xml\widgets.xml"/>
+    <Include file="xml\docks.xml"/>
+    <Script file="system\damage_text.lua"/>
+    <Script file="system\core.lua"/>
+	  <Script file="system\media.lua"/>
+    <Script file="system\api.lua"/>
+    <Script file="system\utilities.lua"/>
+    <Script file="system\alerts.lua"/>
+    <Script file="system\dock.lua"/>
+    <Script file="system\reports.lua"/>
+    <Script file="system\layout.lua"/>
+    <Script file="system\dropdown.lua"/>
+    <Script file="system\overrides.lua"/>
+    <Script file="system\errors.lua"/>
+    <Script file="system\debug.lua"/>
+    <Script file="system\profile.lua"/>
+
+    <Include file="setup\_load.xml"/>
+
+    <Script file="system\slash.lua"/>
+
+    <Script file="system\_reports\bags.lua"/>
+    <Script file="system\_reports\cta.lua"/>
+    <Script file="system\_reports\durability.lua"/>
+    <Script file="system\_reports\experience.lua"/>
+    <Script file="system\_reports\friends.lua"/>
+    <Script file="system\_reports\gold.lua"/>
+    <Script file="system\_reports\tokens.lua"/>
+    <Script file="system\_reports\guild.lua"/>
+    <Script file="system\_reports\reputation.lua"/>
+    <Script file="system\_reports\system.lua"/>
+    <Script file="system\_reports\time.lua"/>
+    <Script file="system\_reports\dps.lua"/>
+    <Script file="system\_reports\hps.lua"/>
+
+    <Script file="system\_docklets\profession.lua"/>
+    <Script file="system\_docklets\misc.lua"/>
+    <Script file="system\_docklets\garrison.lua"/>
+    <Script file="system\_docklets\raidleader.lua"/>
+    <Script file="system\_docklets\breakstuff.lua"/>
+
+    <Script file="system\funstuff.lua"/>
+    <Script file="system\misc.lua"/>
+    <Script file="system\mail.lua"/>
+    <Script file="system\henchmen.lua"/>
+    <Script file="system\letsride.lua"/>
+    <Script file="system\automations.lua"/>
+    <Script file="system\gear.lua"/>
+
+    <Script file="system\credits.lua"/>
+    <Include file="filtering\_load.xml"/>
+</Ui>
diff --git a/SVUI_!Core/assets/backgrounds/BUTTON.blp b/SVUI_!Core/assets/backgrounds/BUTTON.blp
new file mode 100644
index 0000000..6e43ee2
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/BUTTON.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/DARK.blp b/SVUI_!Core/assets/backgrounds/DARK.blp
new file mode 100644
index 0000000..856f53a
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/DARK.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/DEFAULT.blp b/SVUI_!Core/assets/backgrounds/DEFAULT.blp
new file mode 100644
index 0000000..0d03ee8
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/DEFAULT.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/MODEL.blp b/SVUI_!Core/assets/backgrounds/MODEL.blp
new file mode 100644
index 0000000..cc16871
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/MODEL.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/TRANSPARENT.blp b/SVUI_!Core/assets/backgrounds/TRANSPARENT.blp
new file mode 100644
index 0000000..ad55bf6
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/TRANSPARENT.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/art/ART1.blp b/SVUI_!Core/assets/backgrounds/art/ART1.blp
new file mode 100644
index 0000000..89f7774
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/art/ART1.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/art/ART2.blp b/SVUI_!Core/assets/backgrounds/art/ART2.blp
new file mode 100644
index 0000000..bd10142
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/art/ART2.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/art/ART3.blp b/SVUI_!Core/assets/backgrounds/art/ART3.blp
new file mode 100644
index 0000000..baebc58
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/art/ART3.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/art/ART4.blp b/SVUI_!Core/assets/backgrounds/art/ART4.blp
new file mode 100644
index 0000000..c5e87a0
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/art/ART4.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/art/ART5.blp b/SVUI_!Core/assets/backgrounds/art/ART5.blp
new file mode 100644
index 0000000..c96a157
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/art/ART5.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/art/ART6.blp b/SVUI_!Core/assets/backgrounds/art/ART6.blp
new file mode 100644
index 0000000..6c71280
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/art/ART6.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/pattern/PATTERN1.blp b/SVUI_!Core/assets/backgrounds/pattern/PATTERN1.blp
new file mode 100644
index 0000000..41359bd
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/pattern/PATTERN1.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/pattern/PATTERN10.blp b/SVUI_!Core/assets/backgrounds/pattern/PATTERN10.blp
new file mode 100644
index 0000000..08dafc9
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/pattern/PATTERN10.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/pattern/PATTERN11.blp b/SVUI_!Core/assets/backgrounds/pattern/PATTERN11.blp
new file mode 100644
index 0000000..be4fc3e
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/pattern/PATTERN11.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/pattern/PATTERN12.blp b/SVUI_!Core/assets/backgrounds/pattern/PATTERN12.blp
new file mode 100644
index 0000000..3c4d83a
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/pattern/PATTERN12.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/pattern/PATTERN13.blp b/SVUI_!Core/assets/backgrounds/pattern/PATTERN13.blp
new file mode 100644
index 0000000..afea146
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/pattern/PATTERN13.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/pattern/PATTERN14.blp b/SVUI_!Core/assets/backgrounds/pattern/PATTERN14.blp
new file mode 100644
index 0000000..422d8c3
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/pattern/PATTERN14.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/pattern/PATTERN2.blp b/SVUI_!Core/assets/backgrounds/pattern/PATTERN2.blp
new file mode 100644
index 0000000..41e5abe
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/pattern/PATTERN2.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/pattern/PATTERN3.blp b/SVUI_!Core/assets/backgrounds/pattern/PATTERN3.blp
new file mode 100644
index 0000000..2b0dafc
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/pattern/PATTERN3.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/pattern/PATTERN4.blp b/SVUI_!Core/assets/backgrounds/pattern/PATTERN4.blp
new file mode 100644
index 0000000..c63ac01
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/pattern/PATTERN4.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/pattern/PATTERN5.blp b/SVUI_!Core/assets/backgrounds/pattern/PATTERN5.blp
new file mode 100644
index 0000000..e60de9b
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/pattern/PATTERN5.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/pattern/PATTERN6.blp b/SVUI_!Core/assets/backgrounds/pattern/PATTERN6.blp
new file mode 100644
index 0000000..4d6b9f1
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/pattern/PATTERN6.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/pattern/PATTERN7.blp b/SVUI_!Core/assets/backgrounds/pattern/PATTERN7.blp
new file mode 100644
index 0000000..1f7f0a1
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/pattern/PATTERN7.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/pattern/PATTERN8.blp b/SVUI_!Core/assets/backgrounds/pattern/PATTERN8.blp
new file mode 100644
index 0000000..2481deb
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/pattern/PATTERN8.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/pattern/PATTERN9.blp b/SVUI_!Core/assets/backgrounds/pattern/PATTERN9.blp
new file mode 100644
index 0000000..aa052c2
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/pattern/PATTERN9.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-BG1.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG1.blp
new file mode 100644
index 0000000..6a546e3
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG1.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-BG10.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG10.blp
new file mode 100644
index 0000000..fe88cce
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG10.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-BG11.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG11.blp
new file mode 100644
index 0000000..fdd2e81
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG11.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-BG12.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG12.blp
new file mode 100644
index 0000000..369aba6
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG12.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-BG13.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG13.blp
new file mode 100644
index 0000000..c23041a
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG13.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-BG14.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG14.blp
new file mode 100644
index 0000000..89a3a00
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG14.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-BG15.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG15.blp
new file mode 100644
index 0000000..8570677
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG15.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-BG16.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG16.blp
new file mode 100644
index 0000000..a91bbf2
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG16.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-BG17.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG17.blp
new file mode 100644
index 0000000..46ae5f5
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG17.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-BG2.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG2.blp
new file mode 100644
index 0000000..e2f3250
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG2.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-BG3.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG3.blp
new file mode 100644
index 0000000..4279ace
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG3.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-BG4.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG4.blp
new file mode 100644
index 0000000..992eb4e
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG4.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-BG5.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG5.blp
new file mode 100644
index 0000000..47ace70
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG5.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-BG6.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG6.blp
new file mode 100644
index 0000000..6120a5d
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG6.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-BG7.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG7.blp
new file mode 100644
index 0000000..ab43ff2
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG7.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-BG8.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG8.blp
new file mode 100644
index 0000000..c9d98b4
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG8.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-BG9.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG9.blp
new file mode 100644
index 0000000..5289c03
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-BG9.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG1.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG1.blp
new file mode 100644
index 0000000..434b72a
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG1.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG10.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG10.blp
new file mode 100644
index 0000000..da8369c
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG10.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG11.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG11.blp
new file mode 100644
index 0000000..573d0a1
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG11.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG12.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG12.blp
new file mode 100644
index 0000000..021606f
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG12.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG13.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG13.blp
new file mode 100644
index 0000000..28dd443
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG13.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG14.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG14.blp
new file mode 100644
index 0000000..920a585
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG14.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG15.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG15.blp
new file mode 100644
index 0000000..42e00b1
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG15.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG16.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG16.blp
new file mode 100644
index 0000000..2b97e37
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG16.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG17.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG17.blp
new file mode 100644
index 0000000..7b8f99b
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG17.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG2.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG2.blp
new file mode 100644
index 0000000..55ac813
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG2.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG3.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG3.blp
new file mode 100644
index 0000000..6ed3593
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG3.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG4.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG4.blp
new file mode 100644
index 0000000..cbee162
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG4.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG5.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG5.blp
new file mode 100644
index 0000000..40fd794
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG5.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG6.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG6.blp
new file mode 100644
index 0000000..e2cb0ff
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG6.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG7.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG7.blp
new file mode 100644
index 0000000..53eb349
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG7.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG8.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG8.blp
new file mode 100644
index 0000000..3ae7d87
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG8.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG9.blp b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG9.blp
new file mode 100644
index 0000000..191bc5c
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/unit/UNIT-SMALL-BG9.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/window/COMPOSITE1-BOTTOMLEFT.blp b/SVUI_!Core/assets/backgrounds/window/COMPOSITE1-BOTTOMLEFT.blp
new file mode 100644
index 0000000..ea598f6
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/window/COMPOSITE1-BOTTOMLEFT.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/window/COMPOSITE1-BOTTOMRIGHT.blp b/SVUI_!Core/assets/backgrounds/window/COMPOSITE1-BOTTOMRIGHT.blp
new file mode 100644
index 0000000..0c7cf9e
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/window/COMPOSITE1-BOTTOMRIGHT.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/window/COMPOSITE1-TOPLEFT.blp b/SVUI_!Core/assets/backgrounds/window/COMPOSITE1-TOPLEFT.blp
new file mode 100644
index 0000000..72a3e0a
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/window/COMPOSITE1-TOPLEFT.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/window/COMPOSITE1-TOPRIGHT.blp b/SVUI_!Core/assets/backgrounds/window/COMPOSITE1-TOPRIGHT.blp
new file mode 100644
index 0000000..24dbf8f
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/window/COMPOSITE1-TOPRIGHT.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/window/COMPOSITE2-BOTTOMLEFT.blp b/SVUI_!Core/assets/backgrounds/window/COMPOSITE2-BOTTOMLEFT.blp
new file mode 100644
index 0000000..309c06e
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/window/COMPOSITE2-BOTTOMLEFT.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/window/COMPOSITE2-BOTTOMRIGHT.blp b/SVUI_!Core/assets/backgrounds/window/COMPOSITE2-BOTTOMRIGHT.blp
new file mode 100644
index 0000000..9d96a5b
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/window/COMPOSITE2-BOTTOMRIGHT.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/window/COMPOSITE2-TOPLEFT.blp b/SVUI_!Core/assets/backgrounds/window/COMPOSITE2-TOPLEFT.blp
new file mode 100644
index 0000000..1b2f541
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/window/COMPOSITE2-TOPLEFT.blp differ
diff --git a/SVUI_!Core/assets/backgrounds/window/COMPOSITE2-TOPRIGHT.blp b/SVUI_!Core/assets/backgrounds/window/COMPOSITE2-TOPRIGHT.blp
new file mode 100644
index 0000000..281198f
Binary files /dev/null and b/SVUI_!Core/assets/backgrounds/window/COMPOSITE2-TOPRIGHT.blp differ
diff --git a/SVUI_!Core/assets/borders/DEFAULT.blp b/SVUI_!Core/assets/borders/DEFAULT.blp
new file mode 100644
index 0000000..e7ae33d
Binary files /dev/null and b/SVUI_!Core/assets/borders/DEFAULT.blp differ
diff --git a/SVUI_!Core/assets/borders/INSET.blp b/SVUI_!Core/assets/borders/INSET.blp
new file mode 100644
index 0000000..9f7e05f
Binary files /dev/null and b/SVUI_!Core/assets/borders/INSET.blp differ
diff --git a/SVUI_!Core/assets/borders/SHADOW.blp b/SVUI_!Core/assets/borders/SHADOW.blp
new file mode 100644
index 0000000..bfb301e
Binary files /dev/null and b/SVUI_!Core/assets/borders/SHADOW.blp differ
diff --git a/SVUI_!Core/assets/borders/TEXTURED.blp b/SVUI_!Core/assets/borders/TEXTURED.blp
new file mode 100644
index 0000000..143c937
Binary files /dev/null and b/SVUI_!Core/assets/borders/TEXTURED.blp differ
diff --git a/SVUI_!Core/assets/buttons/CHECK-BG.blp b/SVUI_!Core/assets/buttons/CHECK-BG.blp
new file mode 100644
index 0000000..f5209ac
Binary files /dev/null and b/SVUI_!Core/assets/buttons/CHECK-BG.blp differ
diff --git a/SVUI_!Core/assets/buttons/CHECK-DISABLED.blp b/SVUI_!Core/assets/buttons/CHECK-DISABLED.blp
new file mode 100644
index 0000000..7134205
Binary files /dev/null and b/SVUI_!Core/assets/buttons/CHECK-DISABLED.blp differ
diff --git a/SVUI_!Core/assets/buttons/CHECK.blp b/SVUI_!Core/assets/buttons/CHECK.blp
new file mode 100644
index 0000000..8227245
Binary files /dev/null and b/SVUI_!Core/assets/buttons/CHECK.blp differ
diff --git a/SVUI_!Core/assets/buttons/RADIO.blp b/SVUI_!Core/assets/buttons/RADIO.blp
new file mode 100644
index 0000000..7b7d04e
Binary files /dev/null and b/SVUI_!Core/assets/buttons/RADIO.blp differ
diff --git a/SVUI_!Core/assets/buttons/ROUND-BG.blp b/SVUI_!Core/assets/buttons/ROUND-BG.blp
new file mode 100644
index 0000000..726b595
Binary files /dev/null and b/SVUI_!Core/assets/buttons/ROUND-BG.blp differ
diff --git a/SVUI_!Core/assets/buttons/ROUND-BORDER.blp b/SVUI_!Core/assets/buttons/ROUND-BORDER.blp
new file mode 100644
index 0000000..c5817be
Binary files /dev/null and b/SVUI_!Core/assets/buttons/ROUND-BORDER.blp differ
diff --git a/SVUI_!Core/assets/buttons/SCROLLBAR-DOWN.blp b/SVUI_!Core/assets/buttons/SCROLLBAR-DOWN.blp
new file mode 100644
index 0000000..7396f4b
Binary files /dev/null and b/SVUI_!Core/assets/buttons/SCROLLBAR-DOWN.blp differ
diff --git a/SVUI_!Core/assets/buttons/SCROLLBAR-KNOB.blp b/SVUI_!Core/assets/buttons/SCROLLBAR-KNOB.blp
new file mode 100644
index 0000000..662fdab
Binary files /dev/null and b/SVUI_!Core/assets/buttons/SCROLLBAR-KNOB.blp differ
diff --git a/SVUI_!Core/assets/buttons/SCROLLBAR-UP.blp b/SVUI_!Core/assets/buttons/SCROLLBAR-UP.blp
new file mode 100644
index 0000000..317d812
Binary files /dev/null and b/SVUI_!Core/assets/buttons/SCROLLBAR-UP.blp differ
diff --git a/SVUI_!Core/assets/buttons/SETUP-ARROW.blp b/SVUI_!Core/assets/buttons/SETUP-ARROW.blp
new file mode 100644
index 0000000..046bd04
Binary files /dev/null and b/SVUI_!Core/assets/buttons/SETUP-ARROW.blp differ
diff --git a/SVUI_!Core/assets/buttons/SETUP-OPTION.blp b/SVUI_!Core/assets/buttons/SETUP-OPTION.blp
new file mode 100644
index 0000000..a88ed4d
Binary files /dev/null and b/SVUI_!Core/assets/buttons/SETUP-OPTION.blp differ
diff --git a/SVUI_!Core/assets/fonts/Alert.ttf b/SVUI_!Core/assets/fonts/Alert.ttf
new file mode 100644
index 0000000..eaed0f6
Binary files /dev/null and b/SVUI_!Core/assets/fonts/Alert.ttf differ
diff --git a/SVUI_!Core/assets/fonts/Boom.ttf b/SVUI_!Core/assets/fonts/Boom.ttf
new file mode 100644
index 0000000..da34fd0
Binary files /dev/null and b/SVUI_!Core/assets/fonts/Boom.ttf differ
diff --git a/SVUI_!Core/assets/fonts/Caps.ttf b/SVUI_!Core/assets/fonts/Caps.ttf
new file mode 100644
index 0000000..42f02d6
Binary files /dev/null and b/SVUI_!Core/assets/fonts/Caps.ttf differ
diff --git a/SVUI_!Core/assets/fonts/Classic.ttf b/SVUI_!Core/assets/fonts/Classic.ttf
new file mode 100644
index 0000000..774c73e
Binary files /dev/null and b/SVUI_!Core/assets/fonts/Classic.ttf differ
diff --git a/SVUI_!Core/assets/fonts/Combat.ttf b/SVUI_!Core/assets/fonts/Combat.ttf
new file mode 100644
index 0000000..fb09813
Binary files /dev/null and b/SVUI_!Core/assets/fonts/Combat.ttf differ
diff --git a/SVUI_!Core/assets/fonts/Combat2.ttf b/SVUI_!Core/assets/fonts/Combat2.ttf
new file mode 100644
index 0000000..4d68705
Binary files /dev/null and b/SVUI_!Core/assets/fonts/Combat2.ttf differ
diff --git a/SVUI_!Core/assets/fonts/Combo.ttf b/SVUI_!Core/assets/fonts/Combo.ttf
new file mode 100644
index 0000000..901c254
Binary files /dev/null and b/SVUI_!Core/assets/fonts/Combo.ttf differ
diff --git a/SVUI_!Core/assets/fonts/DAMAGE_TEXT_FONT.ttf b/SVUI_!Core/assets/fonts/DAMAGE_TEXT_FONT.ttf
new file mode 100644
index 0000000..fb09813
Binary files /dev/null and b/SVUI_!Core/assets/fonts/DAMAGE_TEXT_FONT.ttf differ
diff --git a/SVUI_!Core/assets/fonts/Default.ttf b/SVUI_!Core/assets/fonts/Default.ttf
new file mode 100644
index 0000000..48dd635
Binary files /dev/null and b/SVUI_!Core/assets/fonts/Default.ttf differ
diff --git a/SVUI_!Core/assets/fonts/Dialog.ttf b/SVUI_!Core/assets/fonts/Dialog.ttf
new file mode 100644
index 0000000..2b8c1ef
Binary files /dev/null and b/SVUI_!Core/assets/fonts/Dialog.ttf differ
diff --git a/SVUI_!Core/assets/fonts/Dyslexic.ttf b/SVUI_!Core/assets/fonts/Dyslexic.ttf
new file mode 100644
index 0000000..53a120c
Binary files /dev/null and b/SVUI_!Core/assets/fonts/Dyslexic.ttf differ
diff --git a/SVUI_!Core/assets/fonts/Flash.ttf b/SVUI_!Core/assets/fonts/Flash.ttf
new file mode 100644
index 0000000..1408eb8
Binary files /dev/null and b/SVUI_!Core/assets/fonts/Flash.ttf differ
diff --git a/SVUI_!Core/assets/fonts/Invisible.ttf b/SVUI_!Core/assets/fonts/Invisible.ttf
new file mode 100644
index 0000000..39748bc
Binary files /dev/null and b/SVUI_!Core/assets/fonts/Invisible.ttf differ
diff --git a/SVUI_!Core/assets/fonts/Narrative.ttf b/SVUI_!Core/assets/fonts/Narrative.ttf
new file mode 100644
index 0000000..64ad417
Binary files /dev/null and b/SVUI_!Core/assets/fonts/Narrative.ttf differ
diff --git a/SVUI_!Core/assets/fonts/Numbers.ttf b/SVUI_!Core/assets/fonts/Numbers.ttf
new file mode 100644
index 0000000..3ef95aa
Binary files /dev/null and b/SVUI_!Core/assets/fonts/Numbers.ttf differ
diff --git a/SVUI_!Core/assets/fonts/Pixel.ttf b/SVUI_!Core/assets/fonts/Pixel.ttf
new file mode 100644
index 0000000..cdb4c21
Binary files /dev/null and b/SVUI_!Core/assets/fonts/Pixel.ttf differ
diff --git a/SVUI_!Core/assets/fonts/SFX.ttf b/SVUI_!Core/assets/fonts/SFX.ttf
new file mode 100644
index 0000000..e681424
Binary files /dev/null and b/SVUI_!Core/assets/fonts/SFX.ttf differ
diff --git a/SVUI_!Core/assets/fonts/Zone.ttf b/SVUI_!Core/assets/fonts/Zone.ttf
new file mode 100644
index 0000000..b9a63a7
Binary files /dev/null and b/SVUI_!Core/assets/fonts/Zone.ttf differ
diff --git a/SVUI_!Core/assets/icons/CLOSE.blp b/SVUI_!Core/assets/icons/CLOSE.blp
new file mode 100644
index 0000000..ba31237
Binary files /dev/null and b/SVUI_!Core/assets/icons/CLOSE.blp differ
diff --git a/SVUI_!Core/assets/icons/EXIT.blp b/SVUI_!Core/assets/icons/EXIT.blp
new file mode 100644
index 0000000..f6ff87d
Binary files /dev/null and b/SVUI_!Core/assets/icons/EXIT.blp differ
diff --git a/SVUI_!Core/assets/icons/FAVORITE-STAR.blp b/SVUI_!Core/assets/icons/FAVORITE-STAR.blp
new file mode 100644
index 0000000..8c89657
Binary files /dev/null and b/SVUI_!Core/assets/icons/FAVORITE-STAR.blp differ
diff --git a/SVUI_!Core/assets/icons/MOVE-DOWN.blp b/SVUI_!Core/assets/icons/MOVE-DOWN.blp
new file mode 100644
index 0000000..6ffc37a
Binary files /dev/null and b/SVUI_!Core/assets/icons/MOVE-DOWN.blp differ
diff --git a/SVUI_!Core/assets/icons/MOVE-LEFT.blp b/SVUI_!Core/assets/icons/MOVE-LEFT.blp
new file mode 100644
index 0000000..4b2dd74
Binary files /dev/null and b/SVUI_!Core/assets/icons/MOVE-LEFT.blp differ
diff --git a/SVUI_!Core/assets/icons/MOVE-RIGHT.blp b/SVUI_!Core/assets/icons/MOVE-RIGHT.blp
new file mode 100644
index 0000000..c078623
Binary files /dev/null and b/SVUI_!Core/assets/icons/MOVE-RIGHT.blp differ
diff --git a/SVUI_!Core/assets/icons/MOVE-UP.blp b/SVUI_!Core/assets/icons/MOVE-UP.blp
new file mode 100644
index 0000000..721bb76
Binary files /dev/null and b/SVUI_!Core/assets/icons/MOVE-UP.blp differ
diff --git a/SVUI_!Core/assets/icons/SVUI.blp b/SVUI_!Core/assets/icons/SVUI.blp
new file mode 100644
index 0000000..733c459
Binary files /dev/null and b/SVUI_!Core/assets/icons/SVUI.blp differ
diff --git a/SVUI_!Core/assets/icons/THEME.blp b/SVUI_!Core/assets/icons/THEME.blp
new file mode 100644
index 0000000..56e87d5
Binary files /dev/null and b/SVUI_!Core/assets/icons/THEME.blp differ
diff --git a/SVUI_!Core/assets/icons/VS.blp b/SVUI_!Core/assets/icons/VS.blp
new file mode 100644
index 0000000..512690f
Binary files /dev/null and b/SVUI_!Core/assets/icons/VS.blp differ
diff --git a/SVUI_!Core/assets/sounds/SuperVillain.mp3 b/SVUI_!Core/assets/sounds/SuperVillain.mp3
new file mode 100644
index 0000000..c459858
Binary files /dev/null and b/SVUI_!Core/assets/sounds/SuperVillain.mp3 differ
diff --git a/SVUI_!Core/assets/sounds/beer30.mp3 b/SVUI_!Core/assets/sounds/beer30.mp3
new file mode 100644
index 0000000..e6a018c
Binary files /dev/null and b/SVUI_!Core/assets/sounds/beer30.mp3 differ
diff --git a/SVUI_!Core/assets/sounds/toasty.mp3 b/SVUI_!Core/assets/sounds/toasty.mp3
new file mode 100644
index 0000000..020f086
Binary files /dev/null and b/SVUI_!Core/assets/sounds/toasty.mp3 differ
diff --git a/SVUI_!Core/assets/sounds/whisper.mp3 b/SVUI_!Core/assets/sounds/whisper.mp3
new file mode 100644
index 0000000..01aed6b
Binary files /dev/null and b/SVUI_!Core/assets/sounds/whisper.mp3 differ
diff --git a/SVUI_!Core/assets/statusbars/BUTTON.blp b/SVUI_!Core/assets/statusbars/BUTTON.blp
new file mode 100644
index 0000000..65f5d8e
Binary files /dev/null and b/SVUI_!Core/assets/statusbars/BUTTON.blp differ
diff --git a/SVUI_!Core/assets/statusbars/DEFAULT.blp b/SVUI_!Core/assets/statusbars/DEFAULT.blp
new file mode 100644
index 0000000..d206e27
Binary files /dev/null and b/SVUI_!Core/assets/statusbars/DEFAULT.blp differ
diff --git a/SVUI_!Core/assets/statusbars/FLAT.blp b/SVUI_!Core/assets/statusbars/FLAT.blp
new file mode 100644
index 0000000..1187efc
Binary files /dev/null and b/SVUI_!Core/assets/statusbars/FLAT.blp differ
diff --git a/SVUI_!Core/assets/statusbars/GLOSS.blp b/SVUI_!Core/assets/statusbars/GLOSS.blp
new file mode 100644
index 0000000..8476a8e
Binary files /dev/null and b/SVUI_!Core/assets/statusbars/GLOSS.blp differ
diff --git a/SVUI_!Core/assets/statusbars/GLOWING.blp b/SVUI_!Core/assets/statusbars/GLOWING.blp
new file mode 100644
index 0000000..5680cc8
Binary files /dev/null and b/SVUI_!Core/assets/statusbars/GLOWING.blp differ
diff --git a/SVUI_!Core/assets/statusbars/GRADIENT.blp b/SVUI_!Core/assets/statusbars/GRADIENT.blp
new file mode 100644
index 0000000..4c1aaef
Binary files /dev/null and b/SVUI_!Core/assets/statusbars/GRADIENT.blp differ
diff --git a/SVUI_!Core/assets/statusbars/HALFTONE.blp b/SVUI_!Core/assets/statusbars/HALFTONE.blp
new file mode 100644
index 0000000..4942d56
Binary files /dev/null and b/SVUI_!Core/assets/statusbars/HALFTONE.blp differ
diff --git a/SVUI_!Core/assets/statusbars/LAZER.blp b/SVUI_!Core/assets/statusbars/LAZER.blp
new file mode 100644
index 0000000..043f07a
Binary files /dev/null and b/SVUI_!Core/assets/statusbars/LAZER.blp differ
diff --git a/SVUI_!Core/assets/statusbars/SMOOTH.blp b/SVUI_!Core/assets/statusbars/SMOOTH.blp
new file mode 100644
index 0000000..b540fe0
Binary files /dev/null and b/SVUI_!Core/assets/statusbars/SMOOTH.blp differ
diff --git a/SVUI_!Core/assets/statusbars/TEXTURED.blp b/SVUI_!Core/assets/statusbars/TEXTURED.blp
new file mode 100644
index 0000000..621625a
Binary files /dev/null and b/SVUI_!Core/assets/statusbars/TEXTURED.blp differ
diff --git a/SVUI_!Core/assets/textures/Affected/AFFECTED1.blp b/SVUI_!Core/assets/textures/Affected/AFFECTED1.blp
new file mode 100644
index 0000000..7ed332b
Binary files /dev/null and b/SVUI_!Core/assets/textures/Affected/AFFECTED1.blp differ
diff --git a/SVUI_!Core/assets/textures/Affected/AFFECTED2.blp b/SVUI_!Core/assets/textures/Affected/AFFECTED2.blp
new file mode 100644
index 0000000..c1e0e27
Binary files /dev/null and b/SVUI_!Core/assets/textures/Affected/AFFECTED2.blp differ
diff --git a/SVUI_!Core/assets/textures/Affected/AFFECTED3.blp b/SVUI_!Core/assets/textures/Affected/AFFECTED3.blp
new file mode 100644
index 0000000..5827696
Binary files /dev/null and b/SVUI_!Core/assets/textures/Affected/AFFECTED3.blp differ
diff --git a/SVUI_!Core/assets/textures/Affected/AFFECTED4.blp b/SVUI_!Core/assets/textures/Affected/AFFECTED4.blp
new file mode 100644
index 0000000..8563d3f
Binary files /dev/null and b/SVUI_!Core/assets/textures/Affected/AFFECTED4.blp differ
diff --git a/SVUI_!Core/assets/textures/Affected/AFFECTED5.blp b/SVUI_!Core/assets/textures/Affected/AFFECTED5.blp
new file mode 100644
index 0000000..bd92196
Binary files /dev/null and b/SVUI_!Core/assets/textures/Affected/AFFECTED5.blp differ
diff --git a/SVUI_!Core/assets/textures/Alert/ALERT-BG-2.blp b/SVUI_!Core/assets/textures/Alert/ALERT-BG-2.blp
new file mode 100644
index 0000000..9bf1b37
Binary files /dev/null and b/SVUI_!Core/assets/textures/Alert/ALERT-BG-2.blp differ
diff --git a/SVUI_!Core/assets/textures/Alert/ALERT-BG.blp b/SVUI_!Core/assets/textures/Alert/ALERT-BG.blp
new file mode 100644
index 0000000..1ec2399
Binary files /dev/null and b/SVUI_!Core/assets/textures/Alert/ALERT-BG.blp differ
diff --git a/SVUI_!Core/assets/textures/Alert/ALERT-BOTTOM.blp b/SVUI_!Core/assets/textures/Alert/ALERT-BOTTOM.blp
new file mode 100644
index 0000000..634bac9
Binary files /dev/null and b/SVUI_!Core/assets/textures/Alert/ALERT-BOTTOM.blp differ
diff --git a/SVUI_!Core/assets/textures/Alert/ALERT-BURST.blp b/SVUI_!Core/assets/textures/Alert/ALERT-BURST.blp
new file mode 100644
index 0000000..bfe1059
Binary files /dev/null and b/SVUI_!Core/assets/textures/Alert/ALERT-BURST.blp differ
diff --git a/SVUI_!Core/assets/textures/Alert/ALERT-FULL.blp b/SVUI_!Core/assets/textures/Alert/ALERT-FULL.blp
new file mode 100644
index 0000000..c4cca50
Binary files /dev/null and b/SVUI_!Core/assets/textures/Alert/ALERT-FULL.blp differ
diff --git a/SVUI_!Core/assets/textures/Alert/ALERT-ICON-BORDER.blp b/SVUI_!Core/assets/textures/Alert/ALERT-ICON-BORDER.blp
new file mode 100644
index 0000000..f3458ac
Binary files /dev/null and b/SVUI_!Core/assets/textures/Alert/ALERT-ICON-BORDER.blp differ
diff --git a/SVUI_!Core/assets/textures/Alert/ALERT-LEFT-2.blp b/SVUI_!Core/assets/textures/Alert/ALERT-LEFT-2.blp
new file mode 100644
index 0000000..c4457f5
Binary files /dev/null and b/SVUI_!Core/assets/textures/Alert/ALERT-LEFT-2.blp differ
diff --git a/SVUI_!Core/assets/textures/Alert/ALERT-LEFT.blp b/SVUI_!Core/assets/textures/Alert/ALERT-LEFT.blp
new file mode 100644
index 0000000..40f2080
Binary files /dev/null and b/SVUI_!Core/assets/textures/Alert/ALERT-LEFT.blp differ
diff --git a/SVUI_!Core/assets/textures/Alert/ALERT-RIGHT-2.blp b/SVUI_!Core/assets/textures/Alert/ALERT-RIGHT-2.blp
new file mode 100644
index 0000000..838eaed
Binary files /dev/null and b/SVUI_!Core/assets/textures/Alert/ALERT-RIGHT-2.blp differ
diff --git a/SVUI_!Core/assets/textures/Alert/ALERT-RIGHT.blp b/SVUI_!Core/assets/textures/Alert/ALERT-RIGHT.blp
new file mode 100644
index 0000000..b04bc6d
Binary files /dev/null and b/SVUI_!Core/assets/textures/Alert/ALERT-RIGHT.blp differ
diff --git a/SVUI_!Core/assets/textures/Alert/ALERT-TOP.blp b/SVUI_!Core/assets/textures/Alert/ALERT-TOP.blp
new file mode 100644
index 0000000..64796cd
Binary files /dev/null and b/SVUI_!Core/assets/textures/Alert/ALERT-TOP.blp differ
diff --git a/SVUI_!Core/assets/textures/Alert/SAVED-BG.blp b/SVUI_!Core/assets/textures/Alert/SAVED-BG.blp
new file mode 100644
index 0000000..cfd7d8c
Binary files /dev/null and b/SVUI_!Core/assets/textures/Alert/SAVED-BG.blp differ
diff --git a/SVUI_!Core/assets/textures/Alert/SAVED-FG.blp b/SVUI_!Core/assets/textures/Alert/SAVED-FG.blp
new file mode 100644
index 0000000..d2107fa
Binary files /dev/null and b/SVUI_!Core/assets/textures/Alert/SAVED-FG.blp differ
diff --git a/SVUI_!Core/assets/textures/CHATBUBBLE-BACKDROP.blp b/SVUI_!Core/assets/textures/CHATBUBBLE-BACKDROP.blp
new file mode 100644
index 0000000..a000ecc
Binary files /dev/null and b/SVUI_!Core/assets/textures/CHATBUBBLE-BACKDROP.blp differ
diff --git a/SVUI_!Core/assets/textures/CHATBUBBLE-BG.blp b/SVUI_!Core/assets/textures/CHATBUBBLE-BG.blp
new file mode 100644
index 0000000..9b7cc4b
Binary files /dev/null and b/SVUI_!Core/assets/textures/CHATBUBBLE-BG.blp differ
diff --git a/SVUI_!Core/assets/textures/CHATBUBBLE-TAIL-DOWN.blp b/SVUI_!Core/assets/textures/CHATBUBBLE-TAIL-DOWN.blp
new file mode 100644
index 0000000..ce84495
Binary files /dev/null and b/SVUI_!Core/assets/textures/CHATBUBBLE-TAIL-DOWN.blp differ
diff --git a/SVUI_!Core/assets/textures/CHATBUBBLE-TAIL-LEFT.blp b/SVUI_!Core/assets/textures/CHATBUBBLE-TAIL-LEFT.blp
new file mode 100644
index 0000000..61b47d4
Binary files /dev/null and b/SVUI_!Core/assets/textures/CHATBUBBLE-TAIL-LEFT.blp differ
diff --git a/SVUI_!Core/assets/textures/CHATBUBBLE-TAIL-RIGHT.blp b/SVUI_!Core/assets/textures/CHATBUBBLE-TAIL-RIGHT.blp
new file mode 100644
index 0000000..12ddd0f
Binary files /dev/null and b/SVUI_!Core/assets/textures/CHATBUBBLE-TAIL-RIGHT.blp differ
diff --git a/SVUI_!Core/assets/textures/CHATBUBBLE-TAIL-UP.blp b/SVUI_!Core/assets/textures/CHATBUBBLE-TAIL-UP.blp
new file mode 100644
index 0000000..722e039
Binary files /dev/null and b/SVUI_!Core/assets/textures/CHATBUBBLE-TAIL-UP.blp differ
diff --git a/SVUI_!Core/assets/textures/CHATBUBBLE-TAIL.blp b/SVUI_!Core/assets/textures/CHATBUBBLE-TAIL.blp
new file mode 100644
index 0000000..17e10a6
Binary files /dev/null and b/SVUI_!Core/assets/textures/CHATBUBBLE-TAIL.blp differ
diff --git a/SVUI_!Core/assets/textures/DIALOGBOX-HEADER.blp b/SVUI_!Core/assets/textures/DIALOGBOX-HEADER.blp
new file mode 100644
index 0000000..05cf36f
Binary files /dev/null and b/SVUI_!Core/assets/textures/DIALOGBOX-HEADER.blp differ
diff --git a/SVUI_!Core/assets/textures/DROPDOWN-DIVIDER.blp b/SVUI_!Core/assets/textures/DROPDOWN-DIVIDER.blp
new file mode 100644
index 0000000..4776934
Binary files /dev/null and b/SVUI_!Core/assets/textures/DROPDOWN-DIVIDER.blp differ
diff --git a/SVUI_!Core/assets/textures/Dock/DOCK-ICON-ADDON.blp b/SVUI_!Core/assets/textures/Dock/DOCK-ICON-ADDON.blp
new file mode 100644
index 0000000..c38f93a
Binary files /dev/null and b/SVUI_!Core/assets/textures/Dock/DOCK-ICON-ADDON.blp differ
diff --git a/SVUI_!Core/assets/textures/Dock/DOCK-ICON-BREAKSTUFF.blp b/SVUI_!Core/assets/textures/Dock/DOCK-ICON-BREAKSTUFF.blp
new file mode 100644
index 0000000..b778e24
Binary files /dev/null and b/SVUI_!Core/assets/textures/Dock/DOCK-ICON-BREAKSTUFF.blp differ
diff --git a/SVUI_!Core/assets/textures/Dock/DOCK-ICON-CHAT.blp b/SVUI_!Core/assets/textures/Dock/DOCK-ICON-CHAT.blp
new file mode 100644
index 0000000..c61c5fa
Binary files /dev/null and b/SVUI_!Core/assets/textures/Dock/DOCK-ICON-CHAT.blp differ
diff --git a/SVUI_!Core/assets/textures/Dock/DOCK-ICON-GARRISON.blp b/SVUI_!Core/assets/textures/Dock/DOCK-ICON-GARRISON.blp
new file mode 100644
index 0000000..cbbe2ac
Binary files /dev/null and b/SVUI_!Core/assets/textures/Dock/DOCK-ICON-GARRISON.blp differ
diff --git a/SVUI_!Core/assets/textures/Dock/DOCK-ICON-HEARTH.blp b/SVUI_!Core/assets/textures/Dock/DOCK-ICON-HEARTH.blp
new file mode 100644
index 0000000..74776c0
Binary files /dev/null and b/SVUI_!Core/assets/textures/Dock/DOCK-ICON-HEARTH.blp differ
diff --git a/SVUI_!Core/assets/textures/Dock/DOCK-ICON-HENCHMAN.blp b/SVUI_!Core/assets/textures/Dock/DOCK-ICON-HENCHMAN.blp
new file mode 100644
index 0000000..835d005
Binary files /dev/null and b/SVUI_!Core/assets/textures/Dock/DOCK-ICON-HENCHMAN.blp differ
diff --git a/SVUI_!Core/assets/textures/Dock/DOCK-ICON-OPTIONS.blp b/SVUI_!Core/assets/textures/Dock/DOCK-ICON-OPTIONS.blp
new file mode 100644
index 0000000..7001882
Binary files /dev/null and b/SVUI_!Core/assets/textures/Dock/DOCK-ICON-OPTIONS.blp differ
diff --git a/SVUI_!Core/assets/textures/Dock/DOCK-ICON-POWER.blp b/SVUI_!Core/assets/textures/Dock/DOCK-ICON-POWER.blp
new file mode 100644
index 0000000..dc9996a
Binary files /dev/null and b/SVUI_!Core/assets/textures/Dock/DOCK-ICON-POWER.blp differ
diff --git a/SVUI_!Core/assets/textures/Dock/DOCK-ICON-QUESTS.blp b/SVUI_!Core/assets/textures/Dock/DOCK-ICON-QUESTS.blp
new file mode 100644
index 0000000..0b7ee68
Binary files /dev/null and b/SVUI_!Core/assets/textures/Dock/DOCK-ICON-QUESTS.blp differ
diff --git a/SVUI_!Core/assets/textures/Dock/DOCK-ICON-RAIDTOOL.blp b/SVUI_!Core/assets/textures/Dock/DOCK-ICON-RAIDTOOL.blp
new file mode 100644
index 0000000..7d2a6a4
Binary files /dev/null and b/SVUI_!Core/assets/textures/Dock/DOCK-ICON-RAIDTOOL.blp differ
diff --git a/SVUI_!Core/assets/textures/Dock/DOCK-ICON-SIZE.blp b/SVUI_!Core/assets/textures/Dock/DOCK-ICON-SIZE.blp
new file mode 100644
index 0000000..ebc44f8
Binary files /dev/null and b/SVUI_!Core/assets/textures/Dock/DOCK-ICON-SIZE.blp differ
diff --git a/SVUI_!Core/assets/textures/Dock/DOCK-ICON-SNACK.blp b/SVUI_!Core/assets/textures/Dock/DOCK-ICON-SNACK.blp
new file mode 100644
index 0000000..27e176d
Binary files /dev/null and b/SVUI_!Core/assets/textures/Dock/DOCK-ICON-SNACK.blp differ
diff --git a/SVUI_!Core/assets/textures/Dock/DOCK-ICON-SPECSWAP.blp b/SVUI_!Core/assets/textures/Dock/DOCK-ICON-SPECSWAP.blp
new file mode 100644
index 0000000..6fd0249
Binary files /dev/null and b/SVUI_!Core/assets/textures/Dock/DOCK-ICON-SPECSWAP.blp differ
diff --git a/SVUI_!Core/assets/textures/Dock/DOCK-SPARKS-1.blp b/SVUI_!Core/assets/textures/Dock/DOCK-SPARKS-1.blp
new file mode 100644
index 0000000..03281c6
Binary files /dev/null and b/SVUI_!Core/assets/textures/Dock/DOCK-SPARKS-1.blp differ
diff --git a/SVUI_!Core/assets/textures/Dock/DOCK-SPARKS-2.blp b/SVUI_!Core/assets/textures/Dock/DOCK-SPARKS-2.blp
new file mode 100644
index 0000000..9a4b442
Binary files /dev/null and b/SVUI_!Core/assets/textures/Dock/DOCK-SPARKS-2.blp differ
diff --git a/SVUI_!Core/assets/textures/Dock/DOCK-SPARKS-3.blp b/SVUI_!Core/assets/textures/Dock/DOCK-SPARKS-3.blp
new file mode 100644
index 0000000..6f07c90
Binary files /dev/null and b/SVUI_!Core/assets/textures/Dock/DOCK-SPARKS-3.blp differ
diff --git a/SVUI_!Core/assets/textures/Dock/LABEL-DUR.blp b/SVUI_!Core/assets/textures/Dock/LABEL-DUR.blp
new file mode 100644
index 0000000..0021afa
Binary files /dev/null and b/SVUI_!Core/assets/textures/Dock/LABEL-DUR.blp differ
diff --git a/SVUI_!Core/assets/textures/Dock/LABEL-REP.blp b/SVUI_!Core/assets/textures/Dock/LABEL-REP.blp
new file mode 100644
index 0000000..a455cf9
Binary files /dev/null and b/SVUI_!Core/assets/textures/Dock/LABEL-REP.blp differ
diff --git a/SVUI_!Core/assets/textures/Dock/LABEL-XP.blp b/SVUI_!Core/assets/textures/Dock/LABEL-XP.blp
new file mode 100644
index 0000000..d1033e1
Binary files /dev/null and b/SVUI_!Core/assets/textures/Dock/LABEL-XP.blp differ
diff --git a/SVUI_!Core/assets/textures/Dock/PROFESSIONS.blp b/SVUI_!Core/assets/textures/Dock/PROFESSIONS.blp
new file mode 100644
index 0000000..c1f8518
Binary files /dev/null and b/SVUI_!Core/assets/textures/Dock/PROFESSIONS.blp differ
diff --git a/SVUI_!Core/assets/textures/Doodads/AFK-BG.blp b/SVUI_!Core/assets/textures/Doodads/AFK-BG.blp
new file mode 100644
index 0000000..56a8990
Binary files /dev/null and b/SVUI_!Core/assets/textures/Doodads/AFK-BG.blp differ
diff --git a/SVUI_!Core/assets/textures/Doodads/AFK-NARRATIVE.blp b/SVUI_!Core/assets/textures/Doodads/AFK-NARRATIVE.blp
new file mode 100644
index 0000000..7a2ca02
Binary files /dev/null and b/SVUI_!Core/assets/textures/Doodads/AFK-NARRATIVE.blp differ
diff --git a/SVUI_!Core/assets/textures/Doodads/COMICS-TYPE1.blp b/SVUI_!Core/assets/textures/Doodads/COMICS-TYPE1.blp
new file mode 100644
index 0000000..b155a11
Binary files /dev/null and b/SVUI_!Core/assets/textures/Doodads/COMICS-TYPE1.blp differ
diff --git a/SVUI_!Core/assets/textures/Doodads/COMICS-TYPE2.blp b/SVUI_!Core/assets/textures/Doodads/COMICS-TYPE2.blp
new file mode 100644
index 0000000..149053b
Binary files /dev/null and b/SVUI_!Core/assets/textures/Doodads/COMICS-TYPE2.blp differ
diff --git a/SVUI_!Core/assets/textures/Doodads/COMICS-TYPE3-BG.blp b/SVUI_!Core/assets/textures/Doodads/COMICS-TYPE3-BG.blp
new file mode 100644
index 0000000..7f77f66
Binary files /dev/null and b/SVUI_!Core/assets/textures/Doodads/COMICS-TYPE3-BG.blp differ
diff --git a/SVUI_!Core/assets/textures/Doodads/COMICS-TYPE3.blp b/SVUI_!Core/assets/textures/Doodads/COMICS-TYPE3.blp
new file mode 100644
index 0000000..fa4e920
Binary files /dev/null and b/SVUI_!Core/assets/textures/Doodads/COMICS-TYPE3.blp differ
diff --git a/SVUI_!Core/assets/textures/Doodads/DRUNK-PARTYTIME.blp b/SVUI_!Core/assets/textures/Doodads/DRUNK-PARTYTIME.blp
new file mode 100644
index 0000000..8d670cb
Binary files /dev/null and b/SVUI_!Core/assets/textures/Doodads/DRUNK-PARTYTIME.blp differ
diff --git a/SVUI_!Core/assets/textures/Doodads/HENCHMEN-CALLOUT.blp b/SVUI_!Core/assets/textures/Doodads/HENCHMEN-CALLOUT.blp
new file mode 100644
index 0000000..e603724
Binary files /dev/null and b/SVUI_!Core/assets/textures/Doodads/HENCHMEN-CALLOUT.blp differ
diff --git a/SVUI_!Core/assets/textures/Doodads/HENCHMEN-MINION-SWITCH.blp b/SVUI_!Core/assets/textures/Doodads/HENCHMEN-MINION-SWITCH.blp
new file mode 100644
index 0000000..e7aa27b
Binary files /dev/null and b/SVUI_!Core/assets/textures/Doodads/HENCHMEN-MINION-SWITCH.blp differ
diff --git a/SVUI_!Core/assets/textures/Doodads/HENCHMEN-OPTION-LEFT.blp b/SVUI_!Core/assets/textures/Doodads/HENCHMEN-OPTION-LEFT.blp
new file mode 100644
index 0000000..4d24d93
Binary files /dev/null and b/SVUI_!Core/assets/textures/Doodads/HENCHMEN-OPTION-LEFT.blp differ
diff --git a/SVUI_!Core/assets/textures/Doodads/HENCHMEN-OPTION-RIGHT.blp b/SVUI_!Core/assets/textures/Doodads/HENCHMEN-OPTION-RIGHT.blp
new file mode 100644
index 0000000..c2a0da3
Binary files /dev/null and b/SVUI_!Core/assets/textures/Doodads/HENCHMEN-OPTION-RIGHT.blp differ
diff --git a/SVUI_!Core/assets/textures/Doodads/HENCHMEN-SPEECH.blp b/SVUI_!Core/assets/textures/Doodads/HENCHMEN-SPEECH.blp
new file mode 100644
index 0000000..5cc33a7
Binary files /dev/null and b/SVUI_!Core/assets/textures/Doodads/HENCHMEN-SPEECH.blp differ
diff --git a/SVUI_!Core/assets/textures/Doodads/HENCHMEN-SRSLY.blp b/SVUI_!Core/assets/textures/Doodads/HENCHMEN-SRSLY.blp
new file mode 100644
index 0000000..9df5027
Binary files /dev/null and b/SVUI_!Core/assets/textures/Doodads/HENCHMEN-SRSLY.blp differ
diff --git a/SVUI_!Core/assets/textures/Doodads/HENCHMEN-SUBOPTION.blp b/SVUI_!Core/assets/textures/Doodads/HENCHMEN-SUBOPTION.blp
new file mode 100644
index 0000000..f3ddf05
Binary files /dev/null and b/SVUI_!Core/assets/textures/Doodads/HENCHMEN-SUBOPTION.blp differ
diff --git a/SVUI_!Core/assets/textures/Doodads/HENCHMEN-WTF.blp b/SVUI_!Core/assets/textures/Doodads/HENCHMEN-WTF.blp
new file mode 100644
index 0000000..11b4789
Binary files /dev/null and b/SVUI_!Core/assets/textures/Doodads/HENCHMEN-WTF.blp differ
diff --git a/SVUI_!Core/assets/textures/Doodads/MENTALO-BUTTON1.blp b/SVUI_!Core/assets/textures/Doodads/MENTALO-BUTTON1.blp
new file mode 100644
index 0000000..b6d0b7d
Binary files /dev/null and b/SVUI_!Core/assets/textures/Doodads/MENTALO-BUTTON1.blp differ
diff --git a/SVUI_!Core/assets/textures/Doodads/MENTALO-BUTTON2.blp b/SVUI_!Core/assets/textures/Doodads/MENTALO-BUTTON2.blp
new file mode 100644
index 0000000..07f54d3
Binary files /dev/null and b/SVUI_!Core/assets/textures/Doodads/MENTALO-BUTTON2.blp differ
diff --git a/SVUI_!Core/assets/textures/Doodads/MENTALO-ENERGY.blp b/SVUI_!Core/assets/textures/Doodads/MENTALO-ENERGY.blp
new file mode 100644
index 0000000..8f95e14
Binary files /dev/null and b/SVUI_!Core/assets/textures/Doodads/MENTALO-ENERGY.blp differ
diff --git a/SVUI_!Core/assets/textures/Doodads/MENTALO-HAND-OFF.blp b/SVUI_!Core/assets/textures/Doodads/MENTALO-HAND-OFF.blp
new file mode 100644
index 0000000..83bf001
Binary files /dev/null and b/SVUI_!Core/assets/textures/Doodads/MENTALO-HAND-OFF.blp differ
diff --git a/SVUI_!Core/assets/textures/Doodads/MENTALO-HAND-ON.blp b/SVUI_!Core/assets/textures/Doodads/MENTALO-HAND-ON.blp
new file mode 100644
index 0000000..582bc0b
Binary files /dev/null and b/SVUI_!Core/assets/textures/Doodads/MENTALO-HAND-ON.blp differ
diff --git a/SVUI_!Core/assets/textures/Doodads/MENTALO-OFF.blp b/SVUI_!Core/assets/textures/Doodads/MENTALO-OFF.blp
new file mode 100644
index 0000000..fbaa90c
Binary files /dev/null and b/SVUI_!Core/assets/textures/Doodads/MENTALO-OFF.blp differ
diff --git a/SVUI_!Core/assets/textures/Doodads/MENTALO-ON.blp b/SVUI_!Core/assets/textures/Doodads/MENTALO-ON.blp
new file mode 100644
index 0000000..c7fca5e
Binary files /dev/null and b/SVUI_!Core/assets/textures/Doodads/MENTALO-ON.blp differ
diff --git a/SVUI_!Core/assets/textures/Doodads/PLAYER-AFK.blp b/SVUI_!Core/assets/textures/Doodads/PLAYER-AFK.blp
new file mode 100644
index 0000000..a4abb33
Binary files /dev/null and b/SVUI_!Core/assets/textures/Doodads/PLAYER-AFK.blp differ
diff --git a/SVUI_!Core/assets/textures/Doodads/QUESTION.blp b/SVUI_!Core/assets/textures/Doodads/QUESTION.blp
new file mode 100644
index 0000000..627cb48
Binary files /dev/null and b/SVUI_!Core/assets/textures/Doodads/QUESTION.blp differ
diff --git a/SVUI_!Core/assets/textures/Doodads/RESPONSE.blp b/SVUI_!Core/assets/textures/Doodads/RESPONSE.blp
new file mode 100644
index 0000000..689a3ee
Binary files /dev/null and b/SVUI_!Core/assets/textures/Doodads/RESPONSE.blp differ
diff --git a/SVUI_!Core/assets/textures/Doodads/THREAT-BAR-ELEMENTS.blp b/SVUI_!Core/assets/textures/Doodads/THREAT-BAR-ELEMENTS.blp
new file mode 100644
index 0000000..0557091
Binary files /dev/null and b/SVUI_!Core/assets/textures/Doodads/THREAT-BAR-ELEMENTS.blp differ
diff --git a/SVUI_!Core/assets/textures/Doodads/THREAT-BAR.blp b/SVUI_!Core/assets/textures/Doodads/THREAT-BAR.blp
new file mode 100644
index 0000000..64c81a5
Binary files /dev/null and b/SVUI_!Core/assets/textures/Doodads/THREAT-BAR.blp differ
diff --git a/SVUI_!Core/assets/textures/Doodads/TOASTY.blp b/SVUI_!Core/assets/textures/Doodads/TOASTY.blp
new file mode 100644
index 0000000..a9c9d96
Binary files /dev/null and b/SVUI_!Core/assets/textures/Doodads/TOASTY.blp differ
diff --git a/SVUI_!Core/assets/textures/Doodads/UNIT-XRAY-CLOSE.blp b/SVUI_!Core/assets/textures/Doodads/UNIT-XRAY-CLOSE.blp
new file mode 100644
index 0000000..309a501
Binary files /dev/null and b/SVUI_!Core/assets/textures/Doodads/UNIT-XRAY-CLOSE.blp differ
diff --git a/SVUI_!Core/assets/textures/Doodads/UNIT-XRAY.blp b/SVUI_!Core/assets/textures/Doodads/UNIT-XRAY.blp
new file mode 100644
index 0000000..7ae156f
Binary files /dev/null and b/SVUI_!Core/assets/textures/Doodads/UNIT-XRAY.blp differ
diff --git a/SVUI_!Core/assets/textures/EMPTY.blp b/SVUI_!Core/assets/textures/EMPTY.blp
new file mode 100644
index 0000000..9717eeb
Binary files /dev/null and b/SVUI_!Core/assets/textures/EMPTY.blp differ
diff --git a/SVUI_!Core/assets/textures/NPC-NAMETAG.blp b/SVUI_!Core/assets/textures/NPC-NAMETAG.blp
new file mode 100644
index 0000000..b6c4077
Binary files /dev/null and b/SVUI_!Core/assets/textures/NPC-NAMETAG.blp differ
diff --git a/SVUI_!Core/assets/textures/Numbers/TYPE1/NUM0.blp b/SVUI_!Core/assets/textures/Numbers/TYPE1/NUM0.blp
new file mode 100644
index 0000000..2b91673
Binary files /dev/null and b/SVUI_!Core/assets/textures/Numbers/TYPE1/NUM0.blp differ
diff --git a/SVUI_!Core/assets/textures/Numbers/TYPE1/NUM1.blp b/SVUI_!Core/assets/textures/Numbers/TYPE1/NUM1.blp
new file mode 100644
index 0000000..1a1e852
Binary files /dev/null and b/SVUI_!Core/assets/textures/Numbers/TYPE1/NUM1.blp differ
diff --git a/SVUI_!Core/assets/textures/Numbers/TYPE1/NUM2.blp b/SVUI_!Core/assets/textures/Numbers/TYPE1/NUM2.blp
new file mode 100644
index 0000000..d20cb32
Binary files /dev/null and b/SVUI_!Core/assets/textures/Numbers/TYPE1/NUM2.blp differ
diff --git a/SVUI_!Core/assets/textures/Numbers/TYPE1/NUM3.blp b/SVUI_!Core/assets/textures/Numbers/TYPE1/NUM3.blp
new file mode 100644
index 0000000..be13782
Binary files /dev/null and b/SVUI_!Core/assets/textures/Numbers/TYPE1/NUM3.blp differ
diff --git a/SVUI_!Core/assets/textures/Numbers/TYPE1/NUM4.blp b/SVUI_!Core/assets/textures/Numbers/TYPE1/NUM4.blp
new file mode 100644
index 0000000..7eca69c
Binary files /dev/null and b/SVUI_!Core/assets/textures/Numbers/TYPE1/NUM4.blp differ
diff --git a/SVUI_!Core/assets/textures/Numbers/TYPE1/NUM5.blp b/SVUI_!Core/assets/textures/Numbers/TYPE1/NUM5.blp
new file mode 100644
index 0000000..eb3b98a
Binary files /dev/null and b/SVUI_!Core/assets/textures/Numbers/TYPE1/NUM5.blp differ
diff --git a/SVUI_!Core/assets/textures/Numbers/TYPE1/NUM6.blp b/SVUI_!Core/assets/textures/Numbers/TYPE1/NUM6.blp
new file mode 100644
index 0000000..10547de
Binary files /dev/null and b/SVUI_!Core/assets/textures/Numbers/TYPE1/NUM6.blp differ
diff --git a/SVUI_!Core/assets/textures/Numbers/TYPE1/NUM7.blp b/SVUI_!Core/assets/textures/Numbers/TYPE1/NUM7.blp
new file mode 100644
index 0000000..c54fe0c
Binary files /dev/null and b/SVUI_!Core/assets/textures/Numbers/TYPE1/NUM7.blp differ
diff --git a/SVUI_!Core/assets/textures/Numbers/TYPE1/NUM8.blp b/SVUI_!Core/assets/textures/Numbers/TYPE1/NUM8.blp
new file mode 100644
index 0000000..09a73cc
Binary files /dev/null and b/SVUI_!Core/assets/textures/Numbers/TYPE1/NUM8.blp differ
diff --git a/SVUI_!Core/assets/textures/Numbers/TYPE1/NUM9.blp b/SVUI_!Core/assets/textures/Numbers/TYPE1/NUM9.blp
new file mode 100644
index 0000000..d8416e1
Binary files /dev/null and b/SVUI_!Core/assets/textures/Numbers/TYPE1/NUM9.blp differ
diff --git a/SVUI_!Core/assets/textures/Numbers/TYPE2/NUM1.blp b/SVUI_!Core/assets/textures/Numbers/TYPE2/NUM1.blp
new file mode 100644
index 0000000..c0ebd6f
Binary files /dev/null and b/SVUI_!Core/assets/textures/Numbers/TYPE2/NUM1.blp differ
diff --git a/SVUI_!Core/assets/textures/Numbers/TYPE2/NUM2.blp b/SVUI_!Core/assets/textures/Numbers/TYPE2/NUM2.blp
new file mode 100644
index 0000000..1111dff
Binary files /dev/null and b/SVUI_!Core/assets/textures/Numbers/TYPE2/NUM2.blp differ
diff --git a/SVUI_!Core/assets/textures/Numbers/TYPE2/NUM3.blp b/SVUI_!Core/assets/textures/Numbers/TYPE2/NUM3.blp
new file mode 100644
index 0000000..04b5d3e
Binary files /dev/null and b/SVUI_!Core/assets/textures/Numbers/TYPE2/NUM3.blp differ
diff --git a/SVUI_!Core/assets/textures/Numbers/TYPE2/NUM4.blp b/SVUI_!Core/assets/textures/Numbers/TYPE2/NUM4.blp
new file mode 100644
index 0000000..957ee6c
Binary files /dev/null and b/SVUI_!Core/assets/textures/Numbers/TYPE2/NUM4.blp differ
diff --git a/SVUI_!Core/assets/textures/Numbers/TYPE2/NUM5.blp b/SVUI_!Core/assets/textures/Numbers/TYPE2/NUM5.blp
new file mode 100644
index 0000000..4d5323c
Binary files /dev/null and b/SVUI_!Core/assets/textures/Numbers/TYPE2/NUM5.blp differ
diff --git a/SVUI_!Core/assets/textures/SPLASH.blp b/SVUI_!Core/assets/textures/SPLASH.blp
new file mode 100644
index 0000000..e58d74f
Binary files /dev/null and b/SVUI_!Core/assets/textures/SPLASH.blp differ
diff --git a/SVUI_!Core/assets/textures/TITLE-HIGHLIGHT.blp b/SVUI_!Core/assets/textures/TITLE-HIGHLIGHT.blp
new file mode 100644
index 0000000..6c515fa
Binary files /dev/null and b/SVUI_!Core/assets/textures/TITLE-HIGHLIGHT.blp differ
diff --git a/SVUI_!Core/assets/textures/WorldState-CaptureBar.blp b/SVUI_!Core/assets/textures/WorldState-CaptureBar.blp
new file mode 100644
index 0000000..08c5650
Binary files /dev/null and b/SVUI_!Core/assets/textures/WorldState-CaptureBar.blp differ
diff --git a/SVUI_!Core/filtering/_load.xml b/SVUI_!Core/filtering/_load.xml
new file mode 100644
index 0000000..c55eb24
--- /dev/null
+++ b/SVUI_!Core/filtering/_load.xml
@@ -0,0 +1,15 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+    <Script file="defaults.lua"/>
+    <Script file="class_filters\pets.lua"/>
+    <Script file="class_filters\deathknight.lua"/>
+    <Script file="class_filters\druid.lua"/>
+    <Script file="class_filters\hunter.lua"/>
+    <Script file="class_filters\mage.lua"/>
+    <Script file="class_filters\monk.lua"/>
+    <Script file="class_filters\paladin.lua"/>
+    <Script file="class_filters\priest.lua"/>
+    <Script file="class_filters\rogue.lua"/>
+    <Script file="class_filters\shaman.lua"/>
+    <Script file="class_filters\warlock.lua"/>
+    <Script file="class_filters\warrior.lua"/>
+</Ui>
\ No newline at end of file
diff --git a/SVUI_!Core/filtering/class_filters/deathknight.lua b/SVUI_!Core/filtering/class_filters/deathknight.lua
new file mode 100644
index 0000000..e3ff4d5
--- /dev/null
+++ b/SVUI_!Core/filtering/class_filters/deathknight.lua
@@ -0,0 +1,31 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+if(select(2, UnitClass("player")) ~= 'DEATHKNIGHT') then return end;
+
+local SV = select(2, ...)
+
+--[[ PRIEST FILTERS ]]--
+
+SV.defaults.Filters["BuffWatch"] = {
+    ["49016"] = {-- Unholy Frenzy
+        ["enable"] = true,
+        ["id"] = 49016,
+        ["point"] = "TOPRIGHT",
+        ["color"] = {["r"] = 0.89, ["g"] = 0.09, ["b"] = 0.05},
+        ["anyUnit"] = false,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+};
\ No newline at end of file
diff --git a/SVUI_!Core/filtering/class_filters/druid.lua b/SVUI_!Core/filtering/class_filters/druid.lua
new file mode 100644
index 0000000..47b262e
--- /dev/null
+++ b/SVUI_!Core/filtering/class_filters/druid.lua
@@ -0,0 +1,73 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+if(select(2, UnitClass("player")) ~= 'DRUID') then return end;
+
+local SV = select(2, ...)
+
+--[[ DRUID FILTERS ]]--
+
+SV.defaults.Filters["BuffWatch"] = {
+    ["774"] = {-- Rejuvenation
+        ["enable"] = true,
+        ["id"] = 774,
+        ["point"] = "TOPRIGHT",
+        ["color"] = {["r"] = 0.8, ["g"] = 0.4, ["b"] = 0.8},
+        ["anyUnit"] = false,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+    ["8936"] = {-- Regrowth
+        ["enable"] = true,
+        ["id"] = 8936,
+        ["point"] = "BOTTOMLEFT",
+        ["color"] = {["r"] = 0.2, ["g"] = 0.8, ["b"] = 0.2},
+        ["anyUnit"] = false,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+    ["33763"] = {-- Lifebloom
+        ["enable"] = true,
+        ["id"] = 33763,
+        ["point"] = "TOPLEFT",
+        ["color"] = {["r"] = 0.4, ["g"] = 0.8, ["b"] = 0.2},
+        ["anyUnit"] = false,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+    ["48438"] = {-- Wild Growth
+        ["enable"] = true,
+        ["id"] = 48438,
+        ["point"] = "BOTTOMRIGHT",
+        ["color"] = {["r"] = 0.8, ["g"] = 0.4, ["b"] = 0},
+        ["anyUnit"] = false,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+};
\ No newline at end of file
diff --git a/SVUI_!Core/filtering/class_filters/hunter.lua b/SVUI_!Core/filtering/class_filters/hunter.lua
new file mode 100644
index 0000000..48a1332
--- /dev/null
+++ b/SVUI_!Core/filtering/class_filters/hunter.lua
@@ -0,0 +1,16 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+if(select(2, UnitClass("player")) ~= 'HUNTER') then return end;
+
+local SV = select(2, ...)
+
+--[[ HUNTER FILTERS ]]--
+
+SV.defaults.Filters["BuffWatch"] = {};
\ No newline at end of file
diff --git a/SVUI_!Core/filtering/class_filters/mage.lua b/SVUI_!Core/filtering/class_filters/mage.lua
new file mode 100644
index 0000000..7ec8a01
--- /dev/null
+++ b/SVUI_!Core/filtering/class_filters/mage.lua
@@ -0,0 +1,31 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+if(select(2, UnitClass("player")) ~= 'MAGE') then return end;
+
+local SV = select(2, ...)
+
+--[[ MAGE FILTERS ]]--
+
+SV.defaults.Filters["BuffWatch"] = {
+    ["111264"] = {-- Ice Ward
+        ["enable"] = true,
+        ["id"] = 111264,
+        ["point"] = "TOPLEFT",
+        ["color"] = {["r"] = 0.2, ["g"] = 0.2, ["b"] = 1},
+        ["anyUnit"] = false,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+};
\ No newline at end of file
diff --git a/SVUI_!Core/filtering/class_filters/monk.lua b/SVUI_!Core/filtering/class_filters/monk.lua
new file mode 100644
index 0000000..e043d63
--- /dev/null
+++ b/SVUI_!Core/filtering/class_filters/monk.lua
@@ -0,0 +1,73 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+if(select(2, UnitClass("player")) ~= 'MONK') then return end;
+
+local SV = select(2, ...)
+
+--[[ MONK FILTERS ]]--
+
+SV.defaults.Filters["BuffWatch"] = {
+    ["119611"] = {--Renewing Mist
+        ["enable"] = true,
+        ["id"] = 119611,
+        ["point"] = "TOPLEFT",
+        ["color"] = {["r"] = 0.8, ["g"] = 0.4, ["b"] = 0.8},
+        ["anyUnit"] = false,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+    ["116849"] = {-- Life Cocoon
+        ["enable"] = true,
+        ["id"] = 116849,
+        ["point"] = "TOPRIGHT",
+        ["color"] = {["r"] = 0.2, ["g"] = 0.8, ["b"] = 0.2},
+        ["anyUnit"] = false,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+    ["132120"] = {-- Enveloping Mist
+        ["enable"] = true,
+        ["id"] = 132120,
+        ["point"] = "BOTTOMLEFT",
+        ["color"] = {["r"] = 0.4, ["g"] = 0.8, ["b"] = 0.2},
+        ["anyUnit"] = false,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+    ["124081"] = {-- Zen Sphere
+        ["enable"] = true,
+        ["id"] = 124081,
+        ["point"] = "BOTTOMRIGHT",
+        ["color"] = {["r"] = 0.7, ["g"] = 0.4, ["b"] = 0},
+        ["anyUnit"] = false,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+};
\ No newline at end of file
diff --git a/SVUI_!Core/filtering/class_filters/paladin.lua b/SVUI_!Core/filtering/class_filters/paladin.lua
new file mode 100644
index 0000000..c9739c2
--- /dev/null
+++ b/SVUI_!Core/filtering/class_filters/paladin.lua
@@ -0,0 +1,129 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+if(select(2, UnitClass("player")) ~= 'PALADIN') then return end;
+
+local SV = select(2, ...)
+
+--[[ PALADIN FILTERS ]]--
+
+SV.defaults.Filters["BuffWatch"] = {
+    ["53563"] = {-- Beacon of Light
+        ["enable"] = true,
+        ["id"] = 53563,
+        ["point"] = "TOPRIGHT",
+        ["color"] = {["r"] = 0.7, ["g"] = 0.3, ["b"] = 0.7},
+        ["anyUnit"] = false,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+    ["1022"] = {-- Hand of Protection
+        ["enable"] = true,
+        ["id"] = 1022,
+        ["point"] = "BOTTOMRIGHT",
+        ["color"] = {["r"] = 0.2, ["g"] = 0.2, ["b"] = 1},
+        ["anyUnit"] = true,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+    ["1044"] = {-- Hand of Freedom
+        ["enable"] = true,
+        ["id"] = 1044,
+        ["point"] = "BOTTOMRIGHT",
+        ["color"] = {["r"] = 0.89, ["g"] = 0.45, ["b"] = 0},
+        ["anyUnit"] = true,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+    ["1038"] = {-- Hand of Salvation
+        ["enable"] = true,
+        ["id"] = 1038,
+        ["point"] = "BOTTOMRIGHT",
+        ["color"] = {["r"] = 0.93, ["g"] = 0.75, ["b"] = 0},
+        ["anyUnit"] = true,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+    ["6940"] = {-- Hand of Sacrifice
+        ["enable"] = true,
+        ["id"] = 6940,
+        ["point"] = "BOTTOMRIGHT",
+        ["color"] = {["r"] = 0.89, ["g"] = 0.1, ["b"] = 0.1},
+        ["anyUnit"] = true,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+    ["114039"] = {-- Hand of Purity
+        ["enable"] = true,
+        ["id"] = 114039,
+        ["point"] = "BOTTOMRIGHT",
+        ["color"] = {["r"] = 0.64, ["g"] = 0.41, ["b"] = 0.72},
+        ["anyUnit"] = false,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+    ["20925"] = {-- Sacred Shield
+        ["enable"] = true,
+        ["id"] = 20925,
+        ["point"] = "TOPLEFT",
+        ["color"] = {["r"] = 0.93, ["g"] = 0.75, ["b"] = 0},
+        ["anyUnit"] = false,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+    ["114163"] = {-- Eternal Flame
+        ["enable"] = true,
+        ["id"] = 114163,
+        ["point"] = "BOTTOMLEFT",
+        ["color"] = {["r"] = 0.87, ["g"] = 0.7, ["b"] = 0.03},
+        ["anyUnit"] = false,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+};
\ No newline at end of file
diff --git a/SVUI_!Core/filtering/class_filters/pets.lua b/SVUI_!Core/filtering/class_filters/pets.lua
new file mode 100644
index 0000000..c2a7266
--- /dev/null
+++ b/SVUI_!Core/filtering/class_filters/pets.lua
@@ -0,0 +1,43 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...)
+
+--[[ PET FILTERS ]]--
+
+SV.defaults.Filters["PetBuffWatch"] = {
+    ["19615"] = {-- Frenzy
+        ["enable"] = true,
+        ["id"] = 19615,
+        ["point"] = "TOPLEFT",
+        ["color"] = {["r"] = 0.89, ["g"] = 0.09, ["b"] = 0.05},
+        ["anyUnit"] = true,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+    ["136"] = {-- Mend Pet
+        ["enable"] = true,
+        ["id"] = 136,
+        ["point"] = "TOPRIGHT",
+        ["color"] = {["r"] = 0.2, ["g"] = 0.8, ["b"] = 0.2},
+        ["anyUnit"] = true,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+};
\ No newline at end of file
diff --git a/SVUI_!Core/filtering/class_filters/priest.lua b/SVUI_!Core/filtering/class_filters/priest.lua
new file mode 100644
index 0000000..14da8be
--- /dev/null
+++ b/SVUI_!Core/filtering/class_filters/priest.lua
@@ -0,0 +1,129 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+if(select(2, UnitClass("player")) ~= 'PRIEST') then return end;
+
+local SV = select(2, ...)
+
+--[[ PRIEST FILTERS ]]--
+
+SV.defaults.Filters["BuffWatch"] = {
+    ["6788"] = {-- Weakened Soul
+        ["enable"] = true,
+        ["id"] = 6788,
+        ["point"] = "TOPRIGHT",
+        ["color"] = {["r"] = 1, ["g"] = 0, ["b"] = 0},
+        ["anyUnit"] = true,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+    ["41635"] = {-- Prayer of Mending
+        ["enable"] = true,
+        ["id"] = 41635,
+        ["point"] = "BOTTOMRIGHT",
+        ["color"] = {["r"] = 0.2, ["g"] = 0.7, ["b"] = 0.2},
+        ["anyUnit"] = false,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+    ["139"] = {-- Renew
+        ["enable"] = true,
+        ["id"] = 139,
+        ["point"] = "BOTTOMLEFT",
+        ["color"] = {["r"] = 0.4, ["g"] = 0.7, ["b"] = 0.2},
+        ["anyUnit"] = false,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+    ["17"] = {-- Power Word: Shield
+        ["enable"] = true,
+        ["id"] = 17,
+        ["point"] = "TOPLEFT",
+        ["color"] = {["r"] = 0.81, ["g"] = 0.85, ["b"] = 0.1},
+        ["anyUnit"] = true,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+    ["123258"] = {-- Power Word: Shield Power Insight
+        ["enable"] = true,
+        ["id"] = 123258,
+        ["point"] = "TOPLEFT",
+        ["color"] = {["r"] = 0.81, ["g"] = 0.85, ["b"] = 0.1},
+        ["anyUnit"] = true,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+    ["10060"] = {-- Power Infusion
+        ["enable"] = true,
+        ["id"] = 10060,
+        ["point"] = "RIGHT",
+        ["color"] = {["r"] = 0.89, ["g"] = 0.09, ["b"] = 0.05},
+        ["anyUnit"] = false,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+    ["47788"] = {-- Guardian Spirit
+        ["enable"] = true,
+        ["id"] = 47788,
+        ["point"] = "LEFT",
+        ["color"] = {["r"] = 0.86, ["g"] = 0.44, ["b"] = 0},
+        ["anyUnit"] = true,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+    ["33206"] = {-- Pain Suppression
+        ["enable"] = true,
+        ["id"] = 33206,
+        ["point"] = "LEFT",
+        ["color"] = {["r"] = 0.89, ["g"] = 0.09, ["b"] = 0.05},
+        ["anyUnit"] = true,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+};
diff --git a/SVUI_!Core/filtering/class_filters/race.lua b/SVUI_!Core/filtering/class_filters/race.lua
new file mode 100644
index 0000000..407b7f7
--- /dev/null
+++ b/SVUI_!Core/filtering/class_filters/race.lua
@@ -0,0 +1,28 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...)
+
+--[[ PET FILTERS ]]--
+
+SV.defaults.Filters["Racial"] = {
+  ["Dwarf"] = {65116},
+  ["Draenei"] = {59545,59543,59548,59542,59544,59547,28880,121093},
+  ["Gnome"] = {20589},
+  ["Human"] = {59752},
+  ["NightElf"] = {58984},
+  ["Worgen"] = {68992,87840},
+  ["BloodElf"] = {28730,50613,80483,25046,69179,129597,155145},
+  ["Goblin"] = {69046,69070,69041},
+  ["Orc"] = {20542,33702,33697},
+  ["Tauren"] = {20549},
+  ["Troll"] = {26297},
+  ["Scourge"] = {20578,7744},
+  ["Pandaren"] = {107079},
+};
diff --git a/SVUI_!Core/filtering/class_filters/rogue.lua b/SVUI_!Core/filtering/class_filters/rogue.lua
new file mode 100644
index 0000000..ab46e33
--- /dev/null
+++ b/SVUI_!Core/filtering/class_filters/rogue.lua
@@ -0,0 +1,31 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+if(select(2, UnitClass("player")) ~= 'ROGUE') then return end;
+
+local SV = select(2, ...)
+
+--[[ ROGUE FILTERS ]]--
+
+SV.defaults.Filters["BuffWatch"] = {
+    ["57934"] = {-- Tricks of the Trade
+        ["enable"] = true,
+        ["id"] = 57934,
+        ["point"] = "TOPRIGHT",
+        ["color"] = {["r"] = 0.89, ["g"] = 0.09, ["b"] = 0.05},
+        ["anyUnit"] = false,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+};
\ No newline at end of file
diff --git a/SVUI_!Core/filtering/class_filters/shaman.lua b/SVUI_!Core/filtering/class_filters/shaman.lua
new file mode 100644
index 0000000..ad6faf2
--- /dev/null
+++ b/SVUI_!Core/filtering/class_filters/shaman.lua
@@ -0,0 +1,59 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+if(select(2, UnitClass("player")) ~= 'SHAMAN') then return end;
+
+local SV = select(2, ...)
+
+--[[ SHAMAN FILTERS ]]--
+
+SV.defaults.Filters["BuffWatch"] = {
+    ["61295"] = {-- Riptide
+        ["enable"] = true,
+        ["id"] = 61295,
+        ["point"] = "TOPRIGHT",
+        ["color"] = {["r"] = 0.7, ["g"] = 0.3, ["b"] = 0.7},
+        ["anyUnit"] = false,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+    ["974"] = {-- Earth Shield
+        ["enable"] = true,
+        ["id"] = 974,
+        ["point"] = "BOTTOMLEFT",
+        ["color"] = {["r"] = 0.2, ["g"] = 0.7, ["b"] = 0.2},
+        ["anyUnit"] = true,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+    ["51945"] = {-- Earthliving
+        ["enable"] = true,
+        ["id"] = 51945,
+        ["point"] = "BOTTOMRIGHT",
+        ["color"] = {["r"] = 0.7, ["g"] = 0.4, ["b"] = 0.4},
+        ["anyUnit"] = false,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+};
\ No newline at end of file
diff --git a/SVUI_!Core/filtering/class_filters/warlock.lua b/SVUI_!Core/filtering/class_filters/warlock.lua
new file mode 100644
index 0000000..f0ae203
--- /dev/null
+++ b/SVUI_!Core/filtering/class_filters/warlock.lua
@@ -0,0 +1,16 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+if(select(2, UnitClass("player")) ~= 'WARLOCK') then return end;
+
+local SV = select(2, ...)
+
+--[[ WARLOCK FILTERS ]]--
+
+SV.defaults.Filters["BuffWatch"] = {};
\ No newline at end of file
diff --git a/SVUI_!Core/filtering/class_filters/warrior.lua b/SVUI_!Core/filtering/class_filters/warrior.lua
new file mode 100644
index 0000000..0fef543
--- /dev/null
+++ b/SVUI_!Core/filtering/class_filters/warrior.lua
@@ -0,0 +1,59 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+if(select(2, UnitClass("player")) ~= 'WARRIOR') then return end;
+
+local SV = select(2, ...)
+
+--[[ WARRIOR FILTERS ]]--
+
+SV.defaults.Filters["BuffWatch"] = {
+    ["114030"] = {-- Vigilance
+        ["enable"] = true,
+        ["id"] = 114030,
+        ["point"] = "TOPLEFT",
+        ["color"] = {["r"] = 0.2, ["g"] = 0.2, ["b"] = 1},
+        ["anyUnit"] = false,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+    ["3411"] = {-- Intervene
+        ["enable"] = true,
+        ["id"] = 3411,
+        ["point"] = "TOPRIGHT",
+        ["color"] = {["r"] = 0.89, ["g"] = 0.09, ["b"] = 0.05},
+        ["anyUnit"] = false,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+    ["114029"] = {-- Safe Guard
+        ["enable"] = true,
+        ["id"] = 114029,
+        ["point"] = "TOPRIGHT",
+        ["color"] = {["r"] = 0.89, ["g"] = 0.09, ["b"] = 0.05},
+        ["anyUnit"] = false,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+};
\ No newline at end of file
diff --git a/SVUI_!Core/filtering/defaults.lua b/SVUI_!Core/filtering/defaults.lua
new file mode 100644
index 0000000..49ae94b
--- /dev/null
+++ b/SVUI_!Core/filtering/defaults.lua
@@ -0,0 +1,113 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local _G = _G;
+local select            = _G.select;
+local assert            = _G.assert;
+local type              = _G.type;
+local error             = _G.error;
+local print             = _G.print;
+local ipairs            = _G.ipairs;
+local pairs             = _G.pairs;
+local tostring          = _G.tostring;
+local tonumber          = _G.tonumber;
+local GetSpellInfo      = _G.GetSpellInfo;
+local SV = select(2, ...)
+
+local playerClass = select(2, UnitClass("player"));
+local filterClass = playerClass or "NONE";
+
+local function safename(id)
+    local n = GetSpellInfo(id)
+    if not n then
+        return false
+    end
+    return n
+end
+
+--[[ FILTER DATA ]]--
+local FilterIDs = {
+    ["BlackList"] = [[36900,36901,36893,114216,97821,36032,8733,57724,25771,57723,36032,58539,26013,6788,71041,41425,55711,8326,23445,24755,25163,80354,95223,124275,124274,124273,117870,123981,15007,113942,89140]],
+
+    ["WhiteList"] = [[31821,2825,32182,80353,90355,47788,33206,116849,22812,123059,136431,137332,137375,144351,142863,142864,142865,143198]],
+
+    ["CC"] = [[47476,91800,91807,91797,108194,115001,33786,339,78675,22570,5211,102359,99,127797,45334,114238,3355,24394,64803,19386,117405,128405,31661,118,122,82691,44572,33395,102051,20066,10326,853,105593,31935,105421,605,64044,8122,9484,15487,114404,88625,87194,2094,1776,6770,1833,1330,408,88611,51514,64695,63685,118905,118345,710,6789,118699,5484,6358,30283,115268,89766,137143,7922,105771,107566,132168,107570,118895,18498,116706,115078,119392,119381,120086,140023,25046,20549,107079]],
+
+    ["Defense"] = [[17,45438,115610,48797,48792,49039,87256,55233,50461,33206,47788,62618,47585,104773,110913,108359,22812,102342,61336,19263,53480,1966,31224,74001,5277,45182,98007,30823,108271,1022,6940,114039,31821,498,642,86659,31850,118038,55694,97463,12975,114029,871,114030,120954,122783,122278,116849,20594]],
+
+    ["Player"] = [[45438,115610,110909,12051,12472,80353,12042,32612,110960,108839,111264,108843,48797,48792,49039,87256,49222,55233,50461,51271,96268,33206,47788,62618,47585,6346,10060,114239,119032,27827,104773,110913,108359,113860,113861,113858,88448,22812,102342,61336,117679,102543,102558,102560,132158,106898,1850,106951,52610,69369,112071,124974,19263,53480,51755,54216,3045,3584,131894,90355,90361,31224,74001,5277,45182,51713,114018,2983,11327,108212,57933,79140,13750,98007,30823,108271,16188,2825,79206,8178,58875,108281,108271,16166,114896,1044,1022,1038,6940,114039,31821,498,642,86659,20925,31850,31884,53563,31842,105809,85499,118038,55694,97463,12975,114029,871,114030,18499,1719,23920,114028,46924,3411,107574,120954,122783,122278,116849,125174,116841,20594,59545,20572,26297,68992]],
+
+    ["Raid"] = [[175601,175599,172069,172066,166779,56037,175654,166185,166175,174404,173763,174500,174939,172115,166200,174473,158986,159113,159178,159213,159410,160521,159386,159188,162497,159202,156152,156151,156143,163046,159220,163242,163590,163241,160179,159972,162346,162892,162475,155569,158241,158026,167200,159709,167179,163374,158200,163472,172895,162185,162184,161242,161358,156803,164004,164005,164006,158619,164176,164178,164191,157349,164232,164235,164240,158553,165102,157801,156096,156743,156047,156401,156404,158054,156888,157000,156999,155365,155061,155030,155236,159044,162276,155657,155222,155399,154989,155499,155318,155277,154952,155074,163284,162293,155493,163633,155921,165195,155701,156310,164380,155240,155242,176133,156934,175104,176121,158702,155225,157139,161570,157853,155080,143962,155078,36240,155326,165300,157060,156766,161839,156844,156309,156203,173471,164271,158315,156601,170395,170405,158692,158702,158686,158683,159585,156112,184369,180079,179897,185978,182373,182280,182074,182001,187819,181345,184360,184449,185065,184450,185066,184676,184652,181488,188929,180389,179867,181295,179977,179864,179909,179908,181957,182200,182178,182325,185239,185510,182600,179219,181753,182038,188666,189627,180415,185237,185238,185241,180526,181508,181653,179428,182008,179407,188208,186073,186407,186500,186063,186333,181275,181099,181597,182006,181841,182088,184964,186123,185014,186952,186961,189891,183634,189895,190049]]
+};
+
+local InitAuraBars = [[2825,32182,80353,90355,86659]]
+
+SV.defaults.Filters["BlackList"] = {};
+SV.defaults.Filters["WhiteList"] = {};
+SV.defaults.Filters["Defense"] = {};
+SV.defaults.Filters["Player"] = {};
+SV.defaults.Filters["AuraBars"] = {};
+SV.defaults.Filters["CC"] = {};
+SV.defaults.Filters["Raid"] = {};
+SV.defaults.Filters["Custom"] = {};
+
+for k, x in pairs(FilterIDs) do
+    local src = {};
+    for id in x:gmatch("([^,]+)") do
+        if(id) then
+            local spellID = tonumber(id);
+            local n = safename(spellID);
+            if(n) then
+                src[id] = {['enable'] = true, ['id'] = spellID, ['priority'] = 0, ['isDefault'] = true}
+            end
+        end
+    end
+    SV.defaults.Filters[k] = src
+end
+
+for id in InitAuraBars:gmatch("([^,]+)") do
+    if(id) then
+        local spellID = tonumber(id);
+        if(safename(spellID)) then
+            SV.defaults.Filters["AuraBars"][id] = {0.98, 0.57, 0.11}
+        end
+    end
+end
+
+local function SanitizeFilters()
+    for filterType, filterData in pairs(SV.db.Filters) do
+        if(filterType == 'AuraBars') then
+          for id, params in pairs(SV.db.Filters[filterType]) do
+            if(type(id) ~= 'string') then
+                SV.db.Filters.AuraBars[id] = nil;
+                local newID = tostring(id);
+                if(newID) then
+                    SV.db.Filters.AuraBars[newID] = {0.98, 0.57, 0.11}
+                end
+            end
+          end
+        elseif(filterType == 'Custom') then
+          for customType, customData in pairs(SV.db.Filters.Custom) do
+            for id, params in pairs(customData) do
+                if((not params.id) or (tonumber(id) ~= params.id)) then
+                    SV.db.Filters.Custom[customType][id] = nil;
+                end
+            end
+          end
+        else
+          for id, params in pairs(SV.db.Filters[filterType]) do
+              if((not params.id) or (tonumber(id) ~= params.id)) then
+                  SV.db.Filters[filterType][id] = nil;
+              end
+          end
+        end
+    end
+end
+
+SV:NewScript(SanitizeFilters);
diff --git a/SVUI_!Core/guide/_template/config.ld b/SVUI_!Core/guide/_template/config.ld
new file mode 100644
index 0000000..1bf3a1e
--- /dev/null
+++ b/SVUI_!Core/guide/_template/config.ld
@@ -0,0 +1,33 @@
+project='SuperVillain UI'
+title='SVUI Guide'
+description='Docs'
+full_description='Usage documentation and code references for the SVUI addon'
+format='discount'
+backtick_references=false
+file = {
+  '../../system/core.lua',
+  '../../libs/_Librarian/Librarian.lua',
+  '../../libs/_SVUI_Lib/LUA.lua',
+  '../../libs/_SVUI_Lib/Registry.lua',
+  '../../libs/_SVUI_Lib/Linguist.lua',
+  '../../libs/_SVUI_Lib/Events.lua',
+  '../../libs/_SVUI_Lib/Timers.lua',
+  '../../libs/_SVUI_Lib/Animate.lua',
+  '../../libs/_SVUI_Lib/SpecialFX.lua',
+  '../../libs/_SVUI_Lib/Sounds.lua',
+  '../../libs/AceVillain-1.0/AceVillain-1.0.lua',
+  '../../system/media.lua'
+}
+dir='../docs'
+readme='doc.md'
+style=true
+template=true
+not_luadoc=true
+all=true
+kind_names={topic='Manual',module='Addons',file='Libraries',classmod='Packages'}
+custom_tags={
+  {'media',title='Media'},
+  {'plugin',title='Plugins'},
+  {'lang',title='Localization'},
+  {'userdata',title='User Data'}
+}
diff --git a/SVUI_!Core/guide/_template/images.css b/SVUI_!Core/guide/_template/images.css
new file mode 100644
index 0000000..0a0b793
--- /dev/null
+++ b/SVUI_!Core/guide/_template/images.css
@@ -0,0 +1,34 @@
+/***
+* BASE64 IMAGES
+*/
+.menu-icon {
+  display: inline-block;
+  width: 32px;
+  height: 32px;
+  background-image: url('data:image/png;base64,
+iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAA20SURBVHhe7ZoNVFRlGscV0/zY0nXTzpqZ9kG6YhtBCDknYjbrZFnJirrsup4sE53CsQmTSIqyb3MPNasrspEuak1iHjpoYri2BVmEYuzaKT8S3JzyizqyseTC3f//5X0u74yDgtk3D+d3Lg6Xuff/e5/73vcyduqojuqojuqojuqojjptdUYQx1fnINpXJ3//77haTq6zQpdjlOMMEh0V3dXEcRVe1+hdw/Q2dLW8f/MxTlXkaajQB5fgYNDgQd108O6asxC6twmCnw16COHDw7vFJcQxHkWQwGO0vH8YGTN2TBe8KvueWN5pKvtgSUlJ5sF5kmHJv0vuooI7ENiBcKMcPwf9wQBwAUJfaILQQ8BAzbkI3wf0AkpGfHy8KUOF5jHw3mfwOBBwJomMiuwGuhr7fjMVGR3ZNYDLA4mLjutpMMKZ4BxmcD2k/cYEr90IuF8zDmcU6CsMGzqsG0lMSlTbYPA7PzOJuyquB05Tuqalc75ujYwa2RX0DBaQcF1CX9AL4RUSXMBJXZ/1UNYbmr0+n2+XSdaDWdXY53EwA9yI0ElagiJmZMzFoN+1113bj1sJnhCfMBBE4XcuM6CAvpRgiPha3aAMSnjQD6HDhcyHMlPiRsX90uACCZ42O21D4ZrCXZv/vtkirdYxy9pcgn2aqZ4ze85usFGLSEJoJxARF+vgwtySt0uaXHe7FokEBL8InCcinKOdcgm1uxvUNa6D9wHnARV8YvJEH8IfXrFyxWGEHgHCNdH4upXBgVV7sFanPEFBgMmenXsUvpU+izIw8m4EH6dxctQ9d3tWcku8Od4mSgA7IWAcQl8NIgBF9I24LKInkLmhfRJiYmN6xMXCZDNRpLS01A8sjR+vXSlk3J9Rk/dCXl19fb0lUEIARwNpreqO1ikRldsrGz1pnsPgX+CTkuISy5vtJfMQ2AEera3Fe2nQeXvBHRiI0SA8/ur4wZkPZMrE2DYJDK6xg4P7CgsL9elZSkDiuMQX8Po4gvClJa+X2MHLy8styLAK1xaSYzbrArC2vLNFv2PrBQk2FKAliIBfFRUV2QIoGd23F+GVBAoIkkABrUoIM8ODi3X4JXIAqaeffpoCknX4GoZnmeHZDQi9PW1O2os26WmrDLZnP5e9jxLaKkKP/l91+IEUkJGRsdcUoCWwG5YjPL9sCRHDI7ohZ0gJnXFf7mqGB/EcdfvNtQCOPgT4tYBUCc8ywu9By74a54ibAEYYDDdJnpycAApERKiS0V/2t2WNGP1NrhmuP+jwSgBouQzkUtMg9A4tQYnAvr1DSsAihMvRHtjhHHAlKS4utmq/CLxO64/WW8Ubiq3MBzO3YYadmJGeUVmxrcKqP4bWB2xH8Cl+Pw1MwTjdAIbbBK4LhmGhE6NJLNlUUhM8RxStK7IW/mmhsNo92z0Ni6CBoA+BxEHg6vWvrVfdZ1ZDQ4NV9EqRlTE3g7fam8CvIyIizkdcc06wiwLOwk5KQOa8TPsNKUEQAQj/OAXk5+cfNgVwFNCSFLAApCH0dC2hmQSn00TCaxZseReXg2bZsmUiYEtKSspqkIzQQ08kwO4Ewd+MSKAAkTD/sfnNAmT0QX/spEaeb6be0AgfJGCW7oDjBBB2AkRYrumufyD4o9gqUu9KXWmSmZn5IkH4WQTvVwa+BPvBDoRm+GycVzKIP1UB7ARQjfCxQV0QIGAwRn53sAD/Qf+JBPhDCRDQ1gGUvVkWQPDPMfJfYuRtMPr7EJwCeEmxA64B0VrCwLYKEAkY9c3HCWDFXBPzi8TbEp8o24YTMzBlyAE4ujiZWWAi5oLHKcUG+1TXVCv4/UlLL4Aa6huawXVrFo+3ft16q+r9qv/l5uT6cUwum/n80Lzyc8SRG7kPj2/OH5XvV1pFxRh5gwJfwSEwBZGPvxNQgnexd+zUKVPdwAt2UkBARwQJQBdMQkf4TQEmwbNy7aEgZKQM6urqbIJ/pidZHl89OzB8KAG8e3mf9arQC7MXbkiZkeIhntmeKeByxD1eACtyKB4rmxlGeBAIqLYD6ZPA9b1NSRjtzEMX+CmBl4aMvGzrvkCINgjgyk8RInQo9DmsCCWA4TUHEJrPCfK02QsRJfhJBSgJ+CW2GiUEC2A7zmJowtsiRcB4Y/nWcvsyoABWw3/R3qD+PxBpIK0fHLAt8DwQfgYJIaAOHbBOB1fhCSK2KkBeCMNjbTfQE/TFCIeD0VlZWepaLSvH3ABy83Jrx9wwJrvwlULLv89vcYt/vzX/4fl7wOflW8q/AlbFuxUBBE96q15eFUDRerS4wY6qHQFsr9xu0uS5x7MXi7E/+/1+i2wt36rIez5vJ847CXJiwfnjJ4zvQpjPyNpqiQRbwOZNeKQ1BBAEfsEUwC1DQwD5ijJwlzhgcDBjns0BxcMZnwkQ8BlCH8l4IOMItxSQvzy/VQEbN2y0ClYXWIiYH0JAIxZNfwkh4ITBpZQABKQAO3wrAo4yuBBwvQO2ZRs6oAk0EIS3KADt+hSBgA/AQRFhCiAUAGqDBUgXnLIAhGMH9KcACU8REh6XgOW518PLoEBGXzpAEAEmJyuZxeUSwIz9JkTcyy0lMKSMPmhieEpoRUDjgqcWPHEqArogfA+E6w9ulpPnY2jFVoykpmBNQZPb494G/Fu34aAh2LENrWtw3D5VgXAClUmUk27Z22VWztKcKgxESqo7tWrH+3gfUFQIQcC3yldXWVHZyPPD1n5fdlfu87kNuAy9ePjpj0xh+F6u/5NWF3aAFnAh3rypFQFW3rI89VxAEfw+IBzgY6nQHgEiQQv4TAt4kechEjDLH0OoBgYX5H1Xr1lNAR9OmjBpZpCANhU7QM0BFPBI1iMhBdAyD0YBYBYk5Lnd7k/y8vA4DPgzUwDhrSuAoJWaKYBQAKCAeRCwiefBkUf4RvAFQ/O1UALABoTnlxKgaVtpAb1NAcQUsOfjPaoDdBeoZwNcrzdAwjzBdbfrMc1iUJ67NPdjsBfUYET2zX+qhdzlubUI3WSKMDuAIqT9Eb4BW9X6oQSw/YHvlAXwExfQKzIicljaPWluoCYpUwCR29Pc9Lnbsf9tmHBuAVEChIzU/JaMGT3m95p7CF7jkrqF0c7709PTD61ds9Yivpd8X3rSPKV4KNrNh6fSd0o5AdfhtQP8nhNv1fYqG3Zl9rPZ3BZPmz5tvCPeMQD0Sp6c3KUT/z7cjuqsPnGJwHqgWYJV/FqxGvVgAatW4lYGsP9CLcCWgFB2eODGc3kl8Av5K/I/Jx6PRwEBz1ACwn8IDiF4BdgPEerpEaEZvhrbJt4tzPD887sIAMU4/hUI3xecifDtF8CPmgwBXgqQ4DwQkQ4QCVjcvIED36Ul3ILQLyFgzY4PsB+gQBN5XZDbKbsAIl5F8CMMTyDiCMJvlfDsAPncQdCjvwujPwfH7xMw+u0UwOqsBdgS8OZNFMA7AJHghoBjOPAT3GLfY2Y4iLBWv4zJycD8GZHWFxEcdQSX8BVofxWecC0i58Hw3DI8JKjwZNCQQS2jfyoCUu5I6Rp9RXRP0A9cgollA1C3LG75JysT+Qvvvn/vU1tZOOU8n6OgwCDsbiJqAbMUdxC9mFmyeIm1pXTLp64Zrn/ie3vSK3+7XE2G+i5h5SzO4XZ3bk7u0uio6AjAia8TP9xRSb5OIbgtIS46bsTMGTNtCfkr8wMEyIgwPLYNCL0fbBWys7M3m2A2Jx8jPLGDUwJBaIb/NFR4bhlcwqdOT73PDK+rTQufk5ZIgAD14SckLKIE2mdwGQkd3JaQOjt1P67l+eAuMB4r89GaS4nT4bwEXEtc013LEPo9we1yv4fwi9kFZniBEnT4jQzvjHX2DQp/eosStACR4PEu8paBxtYEsP0hgeuEEwkQKGIsuFNTKMFxGSgkOGgCNRCwBOGTGJ7oU/3GqrP+zwlngrPBANwpwqfeOTXVm+P9SH1QGXRNi5iFzyzkg82HuCvwfp8IYhQOZ6TBzbdPu/12sNPr9X4l4UvfLFXgNWuFb0WTZh3EznKOcl4KzgV9QHd9zbd9wdPuap5N+b9AKIF/YQmjBFuE1/t6KAHE5/OpJTJWiDW2CITWuNLnpL/F4AxrBg8SwODPjYwdOZRI8CHnD+mOc+H1fnqu+VZLbieQwG7Ad7LEVCIQaqRrpiudJxssgMhSlSgRDueTCF69di1ufyDUqOvv9+L75Qh/kw7flTA8jv0tBJdqEdCMIYBAAD9c6Q8Jk8DrGPW61gSwGyQ4P3sgZnDAblDBcVnwS426hCc45rcYPnTJCYRhBpbbZW8wAFySMi3FvXjR4vUigE+UJrJOENg1DI/tLmwXocv+6BjlGKr/k9VZeLDpCfjhpkj/TsObpSTohZMtAneLoZqbIOKEArgSlPDoolvBCAku4DX23fcqeMjSEnjbFJQIb7a32hRQ9BrWEDo8aGR4XDoqPOglwfXbsqTjfhhlCFASECoKEt4SAVgF2uEho1IHN/+O/4OvzslJyV1AN0eso3d0bHQ4yfXlfgRkUUPWT54w2Y155CJwDujJOQW///1v9zaUaltKwDZMJKTMTvnIDM9PooLC/6hKrl01e2sBYxDe++T8J8cyPD+O+7GGl7IFMDwI059B2qTcmfKjDR9QCBqLZ/fBvKcTTHg/jNvb6SoI6A4BXMaqjgByifzk6icZuqM6qqM66ntQnTr9HxzJ0mIqNkzFAAAAAElFTkSuQmCC');
+background-size: cover;
+background-repeat: no-repeat;
+background-position: center; }
+.comic {
+  background-image: url('data:image/png;base64,
+/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAICAgICAgICAgIDAgICAwQDAgIDBAUEBAQEBAUGBQUFBQUFBgYHBwgHBwYJCQoKCQkMDAwMDAwMDAwMDAwMDAz/2wBDAQMDAwUEBQkGBgkNCwkLDQ8ODg4ODw8MDAwMDA8PDAwMDAwMDwwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wgARCACGAMgDAREAAhEBAxEB/8QAGgABAQEBAQEBAAAAAAAAAAAAAQACAwQFCP/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAfwwBAQAIEREIGwAjIEZET3mTBgyAEBEBEQkZACAhE+sYORk5gZMkQEREAERkBAhPsGDBgyYMmTICRGSECMkQCRH1DIGQMgYMkAERAZIgAiEj6BkCIjIGTJEZIDJEQGSISPYACRGjJABkAAyQAAgQkeowAkJo0IAZMgZICAAIQA7mQA0Jo2JERgDIEAgQAAGyMkJojoaESIDIGRICMgAEQARsTRo6GyNABkAAyZMARo5kREaI0Js6HQ2AnMyYMmTIERGCEiASNGzodDZEYMHMyBEAmzkIEQEImzRo2IGTBgyRohNCcBICICETRo2RGTIEImyNEeQhIgAiE0aNEIAQmjRoRMniECEAMkJo0JoiIhNGzZER//EABwQAQACAgMBAAAAAAAAAAAAABEAUBBAATBBcP/aAAgBAQABBQIhsEIfBC2ND3D0GuWbcllxGOP/xAAUEQEAAAAAAAAAAAAAAAAAAACA/9oACAEDAQE/AVT/AP/EABQRAQAAAAAAAAAAAAAAAAAAAID/2gAIAQIBAT8BVP8A/8QAIRAAAQMDBAMAAAAAAAAAAAAAEQCB8BAhYDAxUHFhcJH/2gAIAQEABj8Cy+/pib4XIebkNJBrOKMV0nFD4KcfU4TFdXThf//EACcQAAECBAUFAQEBAAAAAAAAAAABESExUWFBcYGR8BChscHR8eEg/9oACAEBAAE/IXy5+9Dfo2E2Gv2Mp9dOk8OmnR6nYcdsR80HIDjmSDi82+XF454FZ5FGtuQk3TfpDraX+Xc8kciJxyFej2FhSCPGWMZyogqVwg2OsZ0FS1oT/aipiLkdukvhxB/E+kTsa6j1UzOQ6Ls4y9XXW/Vc1SlXjFmnYlpBMYQtK4vKcuR9ux5GWgy6nYivSOA1+nEMp0QZby5gK7xga9MzLcYyj1fB7Qm+86qfsJaWHSevLDfL/pOUchucwGqK3cVunmpmGI5GxroSx0G45jOJIaN6DE+lR8MKLSkpXH3eOd7jrlHOJzSmRnI1/RapgNmNQzmYzIoJdejvI0dTFITFhiqUJwMYFGh4MKlYEU16PjhO34PHLDmI/JcUdE5AfHDkzz7+m6qmJ4mMWOcQb9MnuR2GqQG1JQWA1iVrngdxEoVgR/g6zi6eRx0k246/R2i5xh+SI8r9GxQakjimEJ9y4oqPLo2OxSEsTNW6QJRWAvYjoWHHtDAWEZWQcdrjrgh6mJxFE3NpPp8M8J6ycVF9a/RU1XAXcWpMbcnlkNpiMMv8GpAUiqxXJBlrOf8AD2KqYyHX6Rex2IBHEVpFWEuKd6/0fOuv2wjOnbWbexoaNp8uNvj/AH0NzmIzLlLWhdlyw3PozVeev0ZNpEJTeHLExe+/VHX3n0ewq7lXHwgt+j/g4iz7uOvK/biZzl7b2STR5YVysZ64zk8dqGp5bJZ3Gk0sGtP+jd0eNPlhm9+niR190zuZStIjp2b4Ouor7+SbDapNRt6XInHJjEKGUHJYiLmOzdv4J2ZuWH1f1X0Iv3X7Y4mtIbjI2Em0+XF49qw2qb1u+07C0pKkaexdJNODfLiq/PJd4zv+ji8c5y56KbQ5Lp46MaxOOZqcQQRs/nwRa6+hJStrTO4iyvJrTaML1HRrM+lWeVhfKOsnjtQe0ZJm0s7ir9h6FXx2rlYfeng82qXwPA0e2tBlvZMSeMGd2wrlYQ99NurdMySJ75MTvh/PY+Ums3wf+vavofy+tfgdLYs3dvYssGZrN8FXi2r6HvflziDc5gc5c46T/RvkJfg2TXlrahvVXm/2nTsd6f7/AD+Cb0wEXw72rlYdp6+n9E/E8aZ3HWDYy5buLmjM72rlYV8YVI/y9M7l53ETJmdcq/wZZY450zUdSKwbF6Z3G+ouDVysN9VbYQ9DLRaNi8ITnc5y5zljik+cj/nI256H4o/OYj/xvXs2k2nw4r+/Rq0e/wBKN29ezakZfhyPu9BNa3/aiaUhLS1RktJoyaM7UPrxm8Jw0IYwrhPGUJ1MMGZoSaFtSjsmj7lbKxPdthI6o4sIjZdHHEX4ez45WzSuJPg/wRXZsXbSY8ODfRVZVuRNxJtj3E9CK7LVFXYeFCI0L7uSVUohWbG0sKdURJqpFHR3xlYYyLFlWirI153FY6xZCKaiu2tVFgqpiiLXWzysf//aAAwDAQACAAMAAAAQEAAgkAAgkEgkgAAEEEkAAkgEAAAAEgAgggEgkEkggEggkEkEkgAEEAgggAkgggAgEgggEAkgkkAggEEEggkAkEkAEgEAAgAAgEgkEEgEkgAkAAAkkAgEEkEAEkggEgAgAkAAEgAEAEAgAEAEgkkkAEkkEkgAAgEkgkAAAEEAkAAEggAkEgAEkEgkAggAkAAEkkgEAEkAgEEgAgggkgkAH//EABQRAQAAAAAAAAAAAAAAAAAAAID/2gAIAQMBAT8QVP8A/8QAFBEBAAAAAAAAAAAAAAAAAAAAgP/aAAgBAgEBPxBU/wD/xAAlEAEBAAIDAAEEAgMBAAAAAAABEQAhMUFRYXGBkbGhwdHh8PH/2gAIAQEAAT8Q3UKqkOWdG/uchibHZONcpejvEbsALWydP08x5VsnNnxNbwQPL/nOQqU8rLv64m6yvVJPsZQ/t615hQu3c+v0Lgzc4eLv70zUV1dHK/a5IGic3f8AOEvDXK9XBR9TnbrAK9uzX8/1g+L6hy/X35zo03Zr9eHp3kDVDu9T6eeGR3Dx2/d98xeza/H+fcq3ddeT6TvGlkfrrKUH45q/+4edm00/Mf3ny152Q/GsVEQRARUIsLNDrti7WqoqiKkinSddsAeTSc15Z2vZ1+omhQ0FU+z2fObV0X+H5/rEW0PRreR3tDv/ANH8ZHmI7UnHbjyDdcF98PnKoJs4sS/Gn85e+b/Me9f+4q6vOx7dc/X4ywEEfxvrNui8bHj/AL5yaER/7fOb7Fps5/O8qcRXSd/kzZNqeJzilkDp79KOJwSknPX0P6xF3s5ZOfjNFJHiG/vN4Cfmj/eNsi/E5MeygO2c/bADaAEwgdEdv1DGrCKEk2ZBGy7HGbIbV2FJaFeHbvO0jq0Jo8vB6YABoO+JHj89Yw6U9T95LF2fO3+sTbro2f1gxDfKRr8V/OVC65Csn36+MtXUObz38v43rIB1p0FHc473854gJdTRz1vXziHCBlUEOqb4xHPIzf6/xjFDk9UvHH1y9lm9wfGr/OWhUh7GfKUwcEhb5fOd/jEOTXAD35TvGxTVda6PrqYfUvZ/5myX5eMFsvNZf+1lSVPig/vEiIwagoRQ5F30x4QgICgWwPJPPTNyIRIiogsFmg67Yitq8khpIpNJ0d4m4Cqxl28/f06xKQXggsPL584iq300+mRCL9fF++cnfuyw/OHddG3fDOfrkiqnUv3ie95BSGnMQ44Xs+cd1dpst99nXV5xYVZ39U54d/GsRsBtDcfT5/rEibaUmnXErR7kRFLWk/PkweAVtXlL2B3kSt+kUo9bwJyFdQ4fizj5xEarWo5ZOobMKVXZORv49yIxQdyn0ub4qC6T/ebbtR4b/WNMKqmghaHA/MyjESJHBBNi69HeIciBS8Rspd+DrIiLsgFGmQVfsesQ4LFLFpyDYPq8408CxdcTtn8jEygIXZNfO9/HmISoWHtr1oxAKu3h9PcbA3OzR+x3k2ha4i93kgfOIAIb0HP4GaxGixVlW/e/7zXoDwCb16JvNShEqh0fJv65IVAJqlp67NfGG2015T48e8RwFOwG2aOecDgDshCe9/nJFkHdjDnmajksKvXS9fPeIbFthrnkn+5mlTc4Jb17+s3dj3DZ+85BJzERv2xoV0BSE2VGnXbFqqqqSRiRE0OjvAFaoTrarUO17OsocEok5BShl25esXS9AO4IcCzg6e8qqqXmJvwx4fDvAOzaYgu3mHb75kHEWFNk+E6+XEyrYR611kv4Ihbz85B0q9QPzmgKAROOf7xsBNaqcfjFCemuSbwUIDe42+ccYgvNOG/G2d4hK3pufgdvznQ2kZUnZvr5xiiaZZEL8aEwqitcb3sTgO/MbpA4H5TjnzH0w8uvePxm3ag64n8ayUvK6N8cvmCvI36d/wCcRwQjZ2hspfsOssVeUUii8C3a6esrgocGxU5j/J7wkSRKJ0nk49LvN3wi3idRqnh1lbui1wLp6z6HjJTjQeqPBvT695SamihJo5Q5l6lx5aKJe4PFLd9eZWgBNIy3yjz8423leFJrn/rglObKxB/cPrvJKAJ1Xv4jiKuk8C6/GPLYV7YccRwBsFe2cH1MU2aHeh58ZMNHpd874vXeeRCTb/28V5Ca0N/zveLGa9S7+nH4xSCKBDW/pnBG3/vpzgTSEiu1+7h660hu/md5yJCUm2rde+nBioACbE5J2FOPXrHoQ0LoIPHwfvBARgO7ap3AzcCo3ir7DK60BEBxOxPPnDVNVlHTXG+jz3KqxW1ALob3+BjsB7qlrzNb+fM0CLEpwH36+ceVdQg0a6vnx7i6Iiaicu9e/GAohPibPn/eUHMHbJs9uJQmcqDfd5/PnI/oN4W3bA6R78usenycQvvO8V58CyP03c5YTW7N/oz4Chxzv7+YQaB8HAfP3wRqp45f6y132rz88YUAHUTkT79fOVIl3qc0N75vrf8AYmcI2APnW9HxiEJXxya4wbNcvK/zgq2Btmj+PnOFSLzwff4wZGw4Xh+368ynldwOQeea7+cZQE2QmqjuefPudO4Ej9p+mKCqhEO58jm9ed51Ha6UunFP5YSEKLRo079nz7g7eOSxdWU26vWIjrHgdp5048JSpF3e9zIoJBsNL7J/NyA6HZ3r3g18Yot6ghBV4Gd+Nx4g7QDG9/f1w0J4XiCdz4wcC8Ax8eNfrJ5BnYfHIXFFCNtEKn1c+3EXhsXjUv69M0BVBxuHXfGUkbXbf4mVLSLpYb36uOnQoeOH+J/GGzV9CP8ArHCkC8zv6YHZ8pPuh+9Zw0NKR6/p64NUiGArNcVNfHuCipTzhYPMAIQBdYpV2G/0xIIBs96AVKn91x2Ztd9aHWhrX3ZfPFapzU8l+jIAPUzXrhU98/jFGo0VWa+vP1ZatKO9m6ccCPnuO4vola899GBSR2I2R6EGnr1iKaICKydb/g9/q7OxfQN9UmnzBdlKohQvMN79MgNocyUD6a4+ca1dDBqg/fcPnvFwEeag9NnvhlHTt4sOOvtgpG/Gv+82T+EQ6xZVKeR8mAeFN1t84JjBL3oVS4RKgOgKOv5wAKT210e8OvjHdjiPJpdXi/HmFAGVi7HTgcEqSl6Clj6an5fzgiGpycCel7YiXYBAOxX1FwRsCj8Oza/f9mfUJeoRcN6nrnERnpQpdjF7fZjSqiQC1F+4U4eseWqlANOra6/kxdBdVGqDlAujs7/nEBqQWu9HM/gdft3jQMRa14F1tOHrFQWKmpfRfTt7/atDWrqghyzz47zktEBWJH30ejHYoiQfC2Hl8esWZH2H5+N+5oKB9Xf3scEqNDgt57w02rTet+5eH3GifHeAwoHT/wAxTgFOW6305o27cXe/Z7kIJE5Quzf+WCTZHB0ef5YCx0hbo2pU1+2Q5orKcscyf1d4IRgxQBYLdcr+GCxIL7hpZZ/dclY9peFUTSDBQsNHcLQahp88IKIFQTRbqbPXWI44IXgsHX2cnF2jyLedcQEHw7x6ocCHJNs/kZBr7QaTuPnr1iFW64uhDiocePeNYwFaqA09n4HeAiO9qTbXmEa+nWEoJojpHnr7nrCESW8HN8+uDJrhTrjufGJaro2XfPDsxJaGmQLPl53gpoVMvWufc7olnyvz1ivrDhZby5uh9lrT8T95pY8ugZZ4P84O10tn5T9JiTaAj8K8i7vXmXBQ3k717Xr/AM4xVjdPMWvsGHNpy2M1f+n7kFo6ENUUbOS4K0CQwu91q/f24wdIqNGwIO4ug7O8BOgaqUrhHrrCqrQIKqi8F2K9PWa8aYCL6PqdveUTRULZpA2ngdneBuroVUoDww5Ho6yjY3RC7rhPa9PX6ESFVCYk5BXSdvf7CL2OATLp07XOC9nm3XPp144nKaqpI/F+fPc/91z9j30yFAERAq99PZ7hUTnrevzA157jp455rP8AnINzZsgd/NyFAB1JZ+PjCLKnCL+/69w5Crz036c/Zk6REKxNXnbl/hhpKE+AeL+/vebWtVFacqcNT8so2qJHW9J0n9H5xJE0GCEBfHY/hkKJQMZo64Ppfc5LaxURvCJpPyxVYraTbft+RkOOAoB1HkPT16yHTEQGuofP8HvJekVtSN6v6HeB4tFTZTbCb9HWHGSAi+DzGP1vWBREoA8ILKmvTvJd8rqQCApH6XeETUCDXeumefHWP5DEax6F7Xp6x3BKqA1XwfTt7z6bJSEEO/gOzIzaznZdPD8j0dYyw02Itb59fnNKUvgTnudE7e8o1EKXuT36fGF4oBNPQ/u9eYLeKCfK/K8/OdNNcDlHcbqdveaKMNDNadL/AMcYUXSJtuK+m7+GK9FbQbadxMuZttpQY7h16wmXsCNCOn/hiiDRAO0WQW7Xp6ycAash2j1477ZFgg3AaQ5Qug7O8CViSIJVkePXTAlhAhW0UibvoesKAJRA0gNDdDvtgUEREQCISguh32yxroAQKCtNbHrpkqINElQiG8n11zRxRG6218v5GH8yANI+fs9ZstB1K0Q6XzxxTQ20ahRO39MNWbjabb8XV9xAIF1CbJ9usfmHT59/jzKW1d3em+/X4wVkSV0VL5/eCcIGR315/lgDo3Lws4vk69wY6Vjfm+8fjeMIjQliIXnhu/hlEljsYfC/v7i8/KdKx1w0/wAs72k0Tbpt4+88zREas5ALuuz11k6kBppHln2uAu21aoipJAa8O8DRBIoQELahPtdYOAgBArDKKb9uspbohGsNBTR7d5Kq1UJAS0RwH3MBA0IkSNOyOT69ZJAAMCGxQPL7gcUz0D5Th9/XDpBguivGvPjvLQAFUdXlrs8OsQBjEF8Gb+fHNDvAHncf799yq8Jo12/HR8ZV95d87OecQTXyP0f385taccz58weK6dNS/wCPjBsnoKdnvvGvMG63rX8cQffnB3Wnm03wnnz7iVBzTvGl4/TNoklp2x8t7+PMRtuB5RrQX+TkCyoITe5PD33FYzZuUhvX8DrIAUAbtj3Xt1p6yB7UAKOyA3Xrti1GssIbEF167Yi4KsLyROXjpghXZJXlheWmumEWYMSNRDdfkZSaUkEiIn5HbP/Z');
+  background-color: #000;
+  background-size: cover;
+  background-repeat: no-repeat;
+  background-position: center;
+  background-attachment: scroll;
+  border: #333 solid 1px;
+  box-shadow: 5px 7px 20px #000;
+  padding: 16px;
+  margin-bottom: 16px; }
+.card-header {
+  color: #ffffff;
+  background-image: url('data:image/png;base64,
+/9j/4AAQSkZJRgABAQEASABIAAD//gATQ3JlYXRlZCB3aXRoIEdJTVD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wgARCABGAZADAREAAhEBAxEB/8QAHAAAAgMBAQEBAAAAAAAAAAAAAAECAwQFBgcI/8QAGQEBAQEBAQEAAAAAAAAAAAAAAAECAwQF/9oADAMBAAIQAxAAAAH8qAM3y5LJylhATlsSS1kRUhJGkdTN5llNAAAAAAAAAAAAAAAEhEhEisAPRZvEssKKCyNONvWLChWQFQgsE70vIswUCAAAAAYABYdLluNM3Y3KXL0xPOqrmJn3msjYoq1KwA9Xm8CyNRJw6UrgIVogqpEQqB6zNwp5zRgIkXxoLzVLoM5cnXlZWc/O7eXbfz6YOmNeNVWQri9uG7HTDrGHpzFzXEaQAeuzeJZRRDlmSK7CK6QyIzcWR6GXRLgsuLAJGcy1QU1TZmKbAhLWdTO/X+L6GbWPO9/N2efasz6wly6xnucu8VpXZVYgA9fm85d0nLavyNS9La1Zal1FkSKayplrPZnrOZ7KKFkBYiGIRWsUmMmX46e5535z0jJx1eeoVj3zkuTU1GUx2XRoNkvoI1yxq+KjIZ6qjYTPJ9MRoJkgBK1itiAArRolCI6plBlqMrPpXDp8065pltXq89X516qTNqcHUoueNqY9To5t8uqWnUtlvw3Z6cbpjKTXXG+46B5LrgIE0YBQIJYEFhDsZEsJ0hRYMQCPccd+R3OVUpeljV0uHebBpzdSqxm3GtMuqa0RozbZqjU4nTmpoSNlzPTPO9MgpWkqAQXPLEYhgSRKE0azRDJ0DOpjUZXjea5jVNZrmFMgjIU4ZIkrCFVaCiAFhTQAAAAIAAAGAAIYwAAJQDUABJEjQAH/xAAoEAABBAICAgICAgMBAAAAAAABAAIDBBESBRMQIRQgIjIVIyQwMUD/2gAIAQEAAQUC86egsLXwPa0TY8rpRZharCwseCmR5bKNZP8A0YPjVYWv0jbln/HZ8tOD2pp8OOD6Cysr2sFOaQKo2gvN1m/3CNzlUpdstiiYZJOOkiNWgx8dihE2GOr/AGsqN3cIy5keCQdsez+zvQ2P0qDaGQYmWqx9XFZYi72ZCt34y5FcV+VbmI9XfQNJQrSlDj53IcVOU3hnpvCq1Siqqlxn4iCpEvlVYkeVrtT7gt2AySS/eYX1rr/i154C+vBCYYv1rVo8yY9yODEz83Ywic/Xjvde03W15awuXW5Y8ORcUJEXIRlyFKVwbxdkrjqr6rblL5jRwkSbxMAX8dCxf48aN+s1O5WsEeZjCPLvKPKWCjetFOlnctCV1BPaGpvs1z12JdYhUe58PIOdJavSSRwlx/joX7wRxCnDBM0tEu7WlrDn8n/XiDmHkABcpy0GPmliMzLD1DFaDm0Ljj/C2ChwBQ4CFDhqrUKtOFfJpRKTlagR5yunc2Mu5iXL+VskfPtPBlmKLNj1haAJo+uUZAF3BZEgazXw61KrFJr1vkl+VF+zsFz6bSvgzODqMjAa7sx1zGrH/UIHFCo4pnHZVOsK4kqwzObDVjXyqbE7mKrUedjCfzjkeXtOVG7ObXNyPZG7L11NXWFgfRwymtDCfY+5WowIxktDkW4Z4k/SpJ2Vp2ddhRnWTP8Aa6XLYbLXxyESL45zM4BTHPgSuTXSla2CA2w9NqPehxuQ3jImGcNZJ7e3X2D6jwL3OY+GFlF2PvlbtRlauwoSrtXat8howiV+yxhYWPB9jh5A6hyrCy/vlBb5Y5zcSPxI+w96ktSNa6Qv8h6bKhOmzoWcL5aks7GZ20ucLfK3Xb+V6fsrB3o+1khbrZbLZbIu95WVlYWVlZKGWrsKDgtlssrZbrZcdY647020xkDkWRk66o7J5ytlt4Jz4ytl2FdpXcV3OXc5bEnYrYrYrYoykjKysrPjKz/uysrKyspry1OeXLsK7CuwrsK3Wfr/AP/EACURAAICAQIGAgMAAAAAAAAAAAABAhEhEBIDIDAxQFATIkJDcf/aAAgBAwEBPwHo17K/LhHcyUadDg0RhayOCoirFEx2EivR1zQ74Nrc8k19Sf1Q42qIx2rJ+NkVkoeBefZZfPB/ZDxk4b3ROJmVHEbij9dkXcaEtiyRkXeGdtH0LVFl6UUUVyXpfhOcnhibXY/o9XEoorrZ0fn3yvWjbpRtPjXKx+Uh9Wyyyxu/UX0LLL0v0F9L/8QAJBEAAwABBAIBBQEAAAAAAAAAAAERAhASICEwQDEiMkFCUHH/2gAIAQIBAT8B8N/pT288tq6Mctyos1kZZx9GObpk4PM7+RsvsMXgpS6XSEMvgsw6MPuMPqdE5lTJ7mftDJ9aLv1qUelKXSEIQhCcc1cRV9GajMOlTBJs/cajo3ufQ0SfHgejv4IbdOkbjcbisrOyMhDaQhPPtSP91em4pS8qPXsjIQiIYk9l6s/BOK4VFKPI3Plj7T+RfHFEJxhNIQSnJe09e/JCEJ/ChCE5/wD/xAA0EAACAQIDBQYEBgMBAAAAAAAAAQIRIQMSMRAgIlFxMDIzQWGBBBORoUBCUFJiciOCweH/2gAIAQEABj8C/BpjX6Ch7um5qWvt89kTqu3tFsy4qlC1USUeJKjI5mqN0qiTle9mOStRDWWsdLknThWhkUatE63JRjstvRJr17Lhjb1NEj/w1+5qdJGHLdsqlsOf0PDPJdWcWJFdC+I/ZEVTEnKWnIk8eNOVzTD9zvRXRHm+iMNYSdaPUj8xUSjmJKOrap9TLHSmVDhHX1ON1lq2Z/45ivoSHYY95E9yyqabnIvRlanDCT9hZfh8T1qeGl1ZNTpe6oRWbLR6l5TZo31Z4a9y/wAqP0PFXsfmfRHDhyfU4cGnUtGKO/T2L4sn7l5M8zQ0MJ/yJYr8kca402pV51MjehHK6TbM1avLqfKk1GSVL8hubuTcnR5q0KT8/Mkqj5Ft1r1L6UP88XJehL5cXkrYllwaqXoVjgv3NFE4pxRfG+xec2d2vVl44a/sWnhL+p4leiZ3cR+xw4DfucGDGPV1PyR6I8b6Ivjzf+xdt7NDRdnHNNyhVVTJYkHKE+cXqSzXdRXdtLlPsNPiVdBZeFlsNv1OK2yrFt1LyHR1qZsRVZ3YGsEWv0RbDkzhwfqy2HFCw8al45jCcJOKrehxTlLq9+nZURQ57KbmHLnFGLHlLZF+pF+TLCuq0Gnu2iWid5I77HmlL6jLkormcxVWpc+DnzhT/gqfu7PXZ5FzQ0LbeS3WYfNWJtJ8V1tgxU0E06WFxsST9y/Yq9kSLGuz4aX7XT7kl+G13Jx9amFPkcSUv7XNKdC0q9Tn+Dp+jf/EACkQAQACAQMDAwUBAAMAAAAAAAEAESExQVEQYXEggZGhscHR8OEwQPH/2gAIAQEAAT8h6Gsz9sOvWoJSLcQBO2X69HadDjSph7U/7SV2zKgn1duraaXvNM3hhgC01EJhwK1g95Yy82fiIvYniS1ofBL9svaXFMS564qbDVD0r/hv0fT5LlzxaVeTmPDSya5aCYgC4Fwic0G1g3JYK77u7haKtuDRL2slF+sci1CYqUqlENJWKjHtAgHaHRFKfSewOnCprlJUrqlwqG89rmVe9i4DFw4MxxNoSloVsw3nIfaBuCJ/fPWumongTX175pT90JrJMf8AQCw9XHFEO0MZBbzUF1WoNPLCyx8xfrDRf2No9hkFyEdl6P4laBSDORa+q/E0Dp8qxNK/k+IvxcAfKUIUU0HSfsq4OuauvdiPA0/BLEvzEpZqCM/TomtyqPWli9Mu0u3xphwyoF0lEyU7ygQI5uZwBdKrSfThtKFDuxvxZNZ7kI/bsWbh51swuGMt2o/EGy/ufiGfh933jvm9kwD7BZor/LvGPlQfuaYeS59qP9sHyfATRY4vFdqZdqqci8sxykI0DA+cfmMp52BjAxs2IYAmJWhc03ZxxTGBNd7d/wDYFvC+XIgjVZU+gQUiKzjEJazZsSVMo6McYz2Snh6eyUK3BQRoN53RAZo02mHcVVGxsrCX8b3YNu+8x1fT/wBwpnPJCMvvWDe5I/ME5Pw/Eypfx+lNj4B/cVg3ekdb+ScTDzuf6TtHsfqN4rymUc5WHHKW6cgePTu7Tunidh6KXesSypgTDUM03E0eXhirc0l2tZKu8ShU0HAiE5ZfBgDDIsXirmni7ukPbBGIQA+UNQphDq9ZsU1wE/VYHJ3JVABWsyaPmAWqnBNZKgX8liK2WBHyBNm/K7ln0j4c7Oofv0Q4J2YcR8ehjTBuzVGWDQ9B6FbufaWcENbRHkMJuSyEGsdDamStVftFrdY+su524Epd2fiqhBg8eIEFAKEFFLM2gmusMiN9N4TRw8wVfGJsFCrJ2i6ZeLZuSlY5mCWlmtIuSoNrhlNq7k3jMfc19h/CFWLov0YhCUurlgw1zBHrfSy5QI8SAMNy/QjNRp7RW3zljWa8iUe+8PmiF/ZbwAolGYdBS5IcXlX8v+QfAohvjMFqB8kdvEoBqWMA9imj5itypkg9gTciFENeUOpX0Klcple8Igwd0bSMmusFnLcBWFU3HM8rlyxrfc/MC64ZjRGqcy/MPb6fuuYZnrmIvBG+xCxjWCHOsekuWVHcJqLzPOpltfdllz7DpOjsz/X4ikOqrJ9GFb51hTR7/wB3K41bvCo+NDhlI5IU3i3eXDBiul4MgED6spvG49FWIOG4+WjLS0tLS2Wlpa+u5bLZfS5eXl5eXijW8FB9Pha15jbb0//aAAwDAQACAAMAAAAQkEoif8aCcCckkkkkkkkkkkgAgkj7E79X8UeoEkkkgAgeZohYpYkg4iE2mJ4lcAk1qOpu30fRus8kk86+rfvR53JN9UItWByNsurUkhWf7rx5HTOZAyy6FpypO4roA5XUExe3A2T8X+bWREDUxcaU9ce4FV7DyW/ZNzCptE2Sf5a7JIgZBdJNTpIYBCkkjE+bYkgjIevY/wDAr8/nJIJBJJIABAJJNpAG5JP/xAAiEQADAAIDAAICAwAAAAAAAAAAAREQISAxQTBRQFBhcbH/2gAIAQMBAT8Qz5iZSK4wnF/o7lOMg6LweWIf4CIM0QU1iqBakfSE1vwaqERqY9oiDX0OJcn8dLlD5whMGoJGhtFKchIH4RZkv4/06aHxGgHX9Apjs8GzZIN3ih4WGobKUpSlxCC0MiIiJGiouSisvGTiVb+DENjurwUY9jfY/BFr2JY2ENNsSoCjNUuyLrihRvYpdnQgp6Q2ZWyskERoqRBVhSlZed5LQlpUdiha2GuqL6InpnohsbDEg8QhBEIjRUUr+sNrsYrKUvBZ7y8XN4PCEdPCLujRrEHwLZRQk/RUJ2QVbFISok7x4yhPgXBIhBixc6x0KpSiekNrwb2PY6NvNE8IEosQn4aXRW+yjGTMJmfLMzCZeipjSOuhtjdKMXNKUuFFFKKyv86ispSl4//EACERAAMAAgIDAQADAAAAAAAAAAABERAhIDEwQVFAUGFx/9oACAECAQE/EONy3hS5pS8F/BzLVRricFhiGLr8DKDeBxEOgG4ZNpjIl7E0VMrGhaVlohOvi+xZvPRome3NUVEEYp0fwbZRYqTtjVi9mPEbE3hdBtEd/wCgwXSEYeliTi+xdYeKLbiGpiEIQqIIGonCyijZRWWScITNBCsSiXwVRex7q0JLRIdGMUg9NJDtQ60iaFyLrQrL6Km2O42yL2J7Box/0K+ZiMfYsv6ISQQQnhp3lPVIe9JSRKEOgm1tCfpiQjCixSrBqVlZMrH0gNGtCfSETk/HCcWJGJ1YSpnshDaYmJiy6G0eoj0OBykYmezZ0X4Q9M7c4MeKilKUvjnTExI2JMTUZKEgklmDDEY2GVBkpJhLsSMuaUpcXw0pS4pSiUS7RGuhMW9igiEx1iEIQQQQQiIiEJ+uEEEEEJx//8QAKRABAAICAQMEAgMBAAMAAAAAAQARITFBUWFxgZGhsRDBINHw4TBA8f/aAAgBAQABPxD8aIJkN2l9K0wa6lDaR5hAwF28RLNql8vMbMZE3LNtY8xJ5ngE8gmFoPS4gVWWIpFqX4mOKp/9ELjh/lUNBvSX7Qayk7MvdWXLfk2StrXNtBpko6VFtRELkg6EQCO8y2D5nQv6xhOb5ZvEuhr7luB4FM/ESLj7N/3NiyuRf1LVobW2JceJq7HMQEwWnRSWrwBXk/UCPREr/wAFAlkxKLnzHf0jl8vc0Dh3lVVRoZdTlsrHxLdLFVGgLwYtj6sZBYmzlHfaCGuroqXk71xW4zD4tFuk67UnVM29bPUGw8Md6FZNeTdRRoAqMlWfcxsO3GFtebgo1T2lVALMpx3n0Y7yzk9vyRl7ukuw0vxBlAtEpMeYUdZbd3mCKt+YdxaggCdYZVoC+gzFg8zQ6s5jUxsA2PTNXMpfnQ53zMwHQyr61LCpo/ZfuAYpf6In2hKes8vw3T3cYCIjyVe9TXH/AGZZvC6f0DAb/wAI5qYqlwV7q/UGGg7mlPJrFQV+zqKUwNVdVni9JDKj/wDpix2qv1/ZKkac4PlIPxwkswmNbzCUSQQTfWxF7QxHCEYAzxUC71fbBb6wr5YaNLujoPEeOTJRVu7e1QQIsvE2rfdWOcgb+VufZlJKUfJZ+4zQVtBhYO2GrenaIRsdpaH0P4G5cIsIibEtyqlMMgFJi/10bxBlDuXXTLFdD0HErKjqKZoiyxCZAwhvWsJKFgLHMepXtOTPV1vYlJGvU6VQK53d41Aasf8AeKw8cYSmEbsO0YWBRmERKs7PpNNTlZe1pT9OW8PsiLjFpaPkwLYJwC/tNOJ0D0oYoh/Wj7EoBX+GoqLzqo+Anuul09yKAR6F+CBIsS0hvGJY2uVV+5a+UgZSvpgqau84vEO6CUKos2DvDuMoWh5ta8ymAQlUK/QVFJOMatDl5wnvKM7+0yEd60QczlyLWUvmkyGIbNFHVoT2jQrtsIcjf/Zap0GRAPOq9I2QFWxY09GFWrd/eH3im4sOVQFLW86/gQKDP64nqQr6QVvIsumCo1+2ymeoFEYldDs1iXELdcNes3ELIldZndGW0/UCS54/dB95hQH1KusHXvZCHmn2h9mLgx1uD2k3kvnD5lItD/WzLIGqk37AyvGrTL4hxh82lPdEFRz8jfcDKck2NPtcNO86YHk+Vlkh7Ku/eLlzOAalTTKuJiAUG9o3V3OIEckRoC0EUcQhBsZa4hsrrs1DBuRqgZNW65l2l9QVCy1ozV94UwvI2dqOJohJBHsN16Q4VAaKINlhh1DH2kQUAl9j5lxplWK3xx7+kqGSxcgLB249IbNXTdQ4w1DpPsfitoHljsbogeiWtxbB2qxdSDU06xZywdrX6mCPRRVN4QQs3arTftM9922fuPEq65dBoxtcPmYi1rGT1lHhev8AaAMp8rFSse4wDgvAlTTK7y+gm36hwElWXc3wzSJ5iVKxBYIlTcItt1r0TIh6s5Ynsg4ExAYNgMeIXIeercqFMBBueAgwlrWnQ1v5uXFBVGaClwGjc3vkY8xN1qCmxIPmUYG9OA3/AFGDFCLFB16wmgpi4oopvB3l6Cd4HjLh/DkteYl6koYAhfJOK3bHpMsUyMK5uC7oC3d3lgumcG2Y59CUfM+ACaDF9IlMUVOWrPYuUpFkXkrat3zOAbesYSAvoX9I3WK7pgiFey43KL6QiKLYzUIERlks6ynWKJU0rFPiOWQIbbeMxUo+gM+rluGLoBG5dy11VQz8XZlM5LFdGAl5WV3lJvqXlehBivojb+ocAAiDcYVUDrIEbhL1dOL4YTC1t47Fd7mDp8uB9Uz8wwaUN7sguEEAcCpXv8QxcAYG7XG0+xabMfqJhpQ1X5gOY6qv6l5dG8y8ZlneWBvU6iMK+0C0SopCGGsbGyBSFSjguy1ahL8C+Su1QFKAquF7r4l7FxZiSbL4X9JylOAvkSMHeiL2Mmkww1K+m3vKGm13l3mX6y/WPfGZnqEyWb9VlZRR23LuQOxAvVRSBhzMvV7S7ABxmYUT3leqetcw4K2uTXiXC0Hq5Zd2JnLR7SktAzoljm5kzA9oN3QzPRCEejcamrOfFzNgJVinq/aMAmQy/wDTxiN4eA/Yv9QoCAPN/wBi2RyHiMK+UJynEC7gACnSG9wCctNMwbDF+Z3Pwi8XOIsbgHMWKWLXsUfOP6iMWFMAKGd6d6KbzAtNTvTvRJli3/AU0xVljWJ3p3mWeYtwYwAq/wCFXfiK+6PDgbJ3J3J353YDgLtcv5B4l9Mfw//Z');
+background-size: cover;
+background-repeat: no-repeat;
+background-position: center; }
+.skinned-page {
+  background-image: url('data:image/png;base64,
+iVBORw0KGgoAAAANSUhEUgAAAQAAAAC4CAYAAAAMnDLKAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAB3RJTUUH3wgZDwkyIJT6egAAIABJREFUeNrsvXeTLNmR5XdvRKQWpZ9+ryW60Q05wGCwuyR3zcgPxs+2Ri5nhzuDgWy0wtOydGVV6oy4+0cff/UrR9RrkEajGTkZZrCHyr4ZGXHD/bj7cRExhPC/hvWxPtbHv8kjW2/B+lgfawBYH+tjfawBYH2sj/WxBoD1sT7WxxoA1sf6WB9rAFgf62N9rAFgfayP9bEGgPWxPtbHGgDWx/pYH2sAWB/rY32sAWB9rI/1sQaA9bE+1scaANbH+lgfawBYH+tjfawBYH2sj/WxBoD1sT7WxxoA1sf6WB9rAFgf62N9rAFgfayP9bEGgPWxPtbHGgDWx/pYH2sAWB/rY32sAWB9rI/1sQaA9bE+1scaANbH+lgfawBYH+tjfawBYH2sj/WxBoD1sT7WxxoA1sf6WB9rAFgf62N9rAFgfayP9bEGgPWxPtbHGgDWx/pYH2sAWB/rY32sAWB9rI/1sQaA9bE+1scaANbH+lgDwPpYH+tjDQDrY32sjzUArI/1sT7WALA+1sf6+LcMAGm9Netjffz//yjeoewJ/8b/j9xPdPcT33F/dWuvA8Drzhv/H1r7t1z3u9b65xZr/r7u8/XxbxwAKnkCXriSPqfwVBCa6z7/PiW4bm2CV3LdtYSaz/x5uba6Zm3Cf/tb1ianbBV+87r7CO663rU21exR3V6mGmBI71hbBwKp5trqwCa4telvBM3/qyDztwJRugbw/u8Yhnet+VsA/P+NtX/L/vwta9+5vwUWeeX2wpu5kyacnBdeYm38nrVeae066sCgqgGDyikkryF+z9pwzXljzTmza9bav6X7/czdR3jHWgoAr82fI70DSDN3bXWCkb5nrX8G1629DsT4e9XfoPD8vb9FeP3+f58sVfg3XgPK/hquWxuuMUrX7cffujbUgHDdnqZ3eHPV96y9zhiEEELIQwj/k1NwKlBVwxMkxyFUTvGvEwRudOmE14NK7pQ5vGPtdQqTueug0ER8lmrOW9UouF9bB5yZO69/0O9SWr9PdUoba/a0esfa5K67qvmMClRdo5hVjWEIbp+uA5S6/Yg1zy/W7Eedx1anbO/ygN7lWYV3eJ91BscrXHLPq7rmHH/L2rr9SDX7HGv2+vu89OCe39t7yUMI/wkflm7jeBOlU0yvsOGaC85qPudFlPhuDoGp3AVHp4iFAxReM5W2umatnYPCX+FeolPa3AEH7zEPIaycYvmHHQG65TUP0IcihVvrBbdubZ2VrbvvygFTVgM+fCa2p9yPUAOkHlA8cFc1FrgOYKM7f8C1hBr5SDXGoqpRxOA8TRqcUAN2qcYrSk4W6u4xfc9aD5rXgY/3iryHXV3jvaQaz/ivDLB5AKUT3CiBDlCgiE2mq2trTUGLa246Ohd4hY3PncBEtyErp2yVeyhU2pUT9OTOneMhLLFhXgjq7rHCfvCBVFhLRalqFKis2Y9Us9Zb5KxGgcI1+/EuQKmuseqhBmCra6xNcNfXcF4jBT1ec97rPLbrALbOOCUHYFzrQSJBfrOaeyy/xzgRYEsnG8HJWOH2g3sRvwdg3+XtZs6zCjXebnL7+04DnIcQ/gcn0EsnXB7Vcvz3JW7oXdaUysbPg3so0T3A0l1b5R5qXvMA+bAoYAW+66+7qgGJVAMoDexF6byf6LyAphPm5O5x5RTI7zO9mVWNN0OgCTV7x/Atd2tDzd5Fp8zVNbxB6fajvMbaB1x3dCBROmufub1ruN/j3tXtR+XANNZwMdd5d9ftXR3A2nXkNdbUe2z0lFKNh53X7Gnu9i7UeLvXATd1yxvgurCzCiHk5gGYMufO2vDEDVzEEhuRXyMYdizw8Aq3EV6gV26DvMtd4L95QKHVW+G6CicwuUPilRP+CvceXbqU19fAPftzJF2fX0tACdinpQPYBNBM13gzyQEeAaVwrqsX6JWzQHSNV/i7UeOhhBr5CE74yxoFWtYAh/cOGgDXqga460Ciusaart4RAtaBcbpGgaoa8GFITMXyMkP5yGr2vwI40jhlDsDCNYCyuub3qndwaQTNkIcQ/gN+zB7QAl+m27iqiYcX+G7jHWvtvBGAUjlAYWy5dGtLPIDo1nJDuXbpAIVeRIl78x5D7ly1FSxME8pWOquScC9VCKHlQofMPUQqRcspUHBrGZI13X4QJEKNopRO8IID48oJvweU3FlTeltN7HPlAKVyMWvDgV3mPC4KdMudN9bsB72t0hmiOuD2IcjS7VOoMTgejKsa41S6e1k6Q/R9+8FzZDWhJQ0Zz8vsVB3oUo9iTZYnGAm4wuKixtWygxu9hBDZxZXO5UsOUKJzue2m6V14QCmdFSugHHMIZrNGgQoXgkQoceniLsbwK5ynAWFYOeHN3drCgUR5jQKt8JBs7eoaF5PhigeU6GLR6wAlOdc/XAMosSYUymq8iwouc4nPs2usqZePokaBcqcUfu9SDUh4MM5cCFK3d3UKG2CcfPhWun3OagxOclwY9650slQXEhcuTCudbi2ct5vjnGWNt0sPpagJtd+uNQ7Au4Klc7kLh1SFI8f8A7SHssLaHIKeOUCpHPjYjdAz4EOZO0BZ1bjnFR5s7rwOupgNbOzcWbbKudENh/KVs0DR3bedf4FztLBfpbtHWkgCSRP7Ed1aKhC9jiWAzXtxmQNCxur0aOoAparxlDLdY3L3SFnKIAe87pYLB1ZYWzgFb0Iul1C4rEbuGjUAG3DeEl5Ygee4cmFC7gxZ5q6lvIYUXDiD4wGd+zGHLjVr9j/iuhd4jk3c08KtJaDQE8nJL+QhhP/RucaVU4oZhCJ3VoKoVmhtxOcZLnaJC27opnkOcglLfRadAi2x1jZsgWto6e8SG0RmngrUwgYvHNhVeIABSpUBJAgedDGp4HMoS8vtMb0LWr3gBMaupQlXdYnfbF4DKAHueeksfYH9pIX0IF9dAz70tlaQiVbNfjRdfGsg0b4GULx82NrKWT1vIUt3DZkzOJnbZyqmN065A5+V2/+yBny8Iatw73XGKXMGpwH5Lx1HlAEk7LzRhYYF7nOOczXw3BY4X2Yk4C/hxhQ1lpOpuplzISoofu5QhnFQCwAydXEN0ZyoVmgtY1Yq3ALnNZBYQvALt7YB4V3A0hYu/pvBIrQdoBTOnSdItHHOlfNQknPjOlAouv6eFCwBPjmEN2KfVri+NvbQ7wfTYEsIbUdrCSgEHwp02ylm4bIMBJ8Wrs17iJ4Parv4NuAclXOXW3BlF/BQ2lhLMEgAlBLnJWdTOuM0c+cgM7+EAtI4rfB7ZnAW13gXq+8xOHxec7fPoYZQtd+cOv2M2H8Cx9u1xgF4kqNwzOQUClTH9vq1+TWueHRgM62xCAY0FSx4oY2wB9DGOebwVgp9Z45N7cDKzoHyTWch5xAMrrX7aODvKdC9DeHye5ccynedAkVnIed48F0IeIl7oMtdubUMyQpYhQUEoQOlXkJpDdy4tg13eonf8NzACoDSBqBUuIbKKUWJ6y6h1MzSzCHoHezPqqamYw5Z6sFdX0A+GpBF7keJc3BtBvlYYW2BZ57huZRY23JyR0+QpOAca5sA4qV73gmGtnRrF84DiPDG6YUFGPG3HsCvIRA5FNNO0nLEUZ1LRZDInEVIcLlX8AIKBxKlQ2jb6ImzFAkbVAEt7borPCyuXQEBm1i7lCAmuElLbKitLQE+EcIxxz23tGfpGrd9ge/6EKSBe1y6vaOFpNXrOovHUCOvUYqVC0N8DFm680Y888LFofabXVw/ASVzYEwPpYX94NrShXornH/pYvjKxeX0rFY1BHMG4S+1H8sa4xQhSwF7Vzo3muHlDDLcgSFbOBDMXTjbcRmJEvfH9PXceTOl4ylIuM9qdIteKZ/5JA8h/EfcyNSlsFiBtdADzFz8ssRaWr0mNmqG77RcwQMtZBsPdIp4P8ODSrAIdlMTKFYTAr2CkFZYa2jYwT1UEDjb6AmEoOu4BAMDA6wpBK9bY/XMsnVwDSvnllXYj6jzzFzcSy9sDne9hzhx6fiLCoIX4InksLIBXhgJTu4z3eius3glvt90HlTHZY/oAredy912efiFC8nmAHUfly/gPdArImncwHkT7mXpdCDCEJFU7cBjm+D3OtiPZY3cMZxtu1x+CVniM1m5EKR0MlPguggSuQNBz9u89WDzEMK/x003oXAzp+AZ3F+ykiQd5tqICK8gYOMbENIZLthAgmkRphxnQLkOUHjhYvjoztODJZ3jOgo87AoWocQ9BiBm7ryLHjyhGQSijbUreBdGxkzxENrO5aZAmyexwt+FE7AGrPUMYNdwNQ+MLXtO2TJX5s0QpI99WDrCK+C+UwhhgP1dOK8vOTDuwzuaw7K24d6XLkPQwtoEZamwzy1Y4JmLe7OauhWGThW8mMKBcQRILCAfDVjqqmbvlgCJDDJd4R4rACzBJ6upOi0d+Mwc0Uoif4lQI3OAQnI+WQjQxgZdAHEbLlYJAIMYQhgDfVtwTedOyDOtzeD6cC0Ft4GNmONhM94PcKMJKG1cy8IV67RcuFIAUEqXJSCSToC+fTw8uo28R3toQ+fCJQiMhTb2uwNYoDmuuQFPpC4OXYCNbrh4k0phlnOJ58qUI4m+rlubuxhyDsDow9KTnCSgBIAEwS4g7IwAlAqAktfE8NFlkPoARA8oWY3LvYLBIUjQXZ4BjL3X0biGNA5u7VzruB8z5zHQeufOk+Y+t51xygFAyXFF9KCm4GwarkhsGUJomQcQJLxNCHTpynvptpw7gi65WJQKfoEfJ8qvsNaQ6hxZh7ZLC64APoXOG50rXjkSzH5zAsHpQLB9zNqG0M6ArG1kEwKs6dI9lAogMXehRuWAsARI0LWmKzjGHgxqXO4GrMUEe9t3aboVhKDpQhC6qUuAYAOhTQlAqQCwcyhyG1Zp7jyUOTyD3HlxM1gkU/w5LB2Z9QmUwgNKctmmsQPuJfaDBodk9AL7UbjrIMcT4MEyzGVvB9OqU1jktuMMCshXpXtsYC3BJ3eyPoG318azI6BEJ6NMVcc8hPAr50avEMOTEadStMB6+rSZ3cgY6biGu+ASGx0AEgWEbOoImwogUUBhg7MIXTzgC3g2HceS0z1va21AHMoahjnAq1NDCrIKawrhH0DZ5s7FL13apo/7mGPPLNyYOBdzgRAkAHxKCDRJqQY8lARAIWlGgZ4ARPqOTGLtRVfnXeH3kiNJzUPqOW+mDYVZORe4h7CLnJKBB8PLHhRlBkHv4RoSvk/uKEdY5wGWxNsY4VAXBm7p0tctyNJca5nVWCHs6uBZzcAdFQjrAvRiDt1qI2yfOVKwg+9eOPJ7ydJ0IwHniKlJMEzC1TZLVo5N4eIXQH+7wQ4E5sIp0BwkVoGbqUIII+R0yXLPYMHsms4BPoz3JwCeBjbChLLvMhLRcSA+3rf4fOwIM5KNc2x8V9ewcKFQCQVtwd2dwlUl0UqLUIUQNrQPC8RzAS76GN8bwNIwP9/GeYMLQZg+MkAJAB9yJTkE2oAquBCkg3ua4B57jtRiTUfPAUrPgfEM920Au4RikiSdwBMcAHwWznuqnIX0pGDTecEzhHr0oC5cRoLE6QqecRNrDQhZsbiEHLSw1mSshfsgsd52gNKCsV64attWCGFuHADdSVOWHJasCfdrCYE2HoBNPy0IxlQPsHDkmBUNUcHP8bDN1ZrDpesCuUZ42B2gvCFxF+7YCFa6B+VZAqjs+keIhfsuhi+wmU2tTXDlFwDCEg+lpb0zQd9EfcIUFqvpyL8Z3Ny+/p5if5oOHI2kMpCYwdtgldkU97iBfa5cFoUgsdJ1z10FYQGDQZDYcEQteZhCMmMAu4HYeop9bAN0be+G8PLG4GG62DuThR7c/zE8pQ4Ac6nf7ACYps4DKJyn2oHiz5yHkju9KJx3EZ2L33CeGVPShXSiAS+kCX5mAY+hobXsSG1jL+Zurf3e214A5vgjkCoLIZy5irsc1ruCy9dwCtQG2kzgHkagWsLFNUBczAEyhmr2sLrO65ghJOhBCMb6O0I4xvhuD8J57hR2CS8ggxdg+5HDbV8CVAIedgOuYJLwknRbam3CfqygbAvEoTMQtR0I/wrgY8LB9GkPFnKB0MHCjQn2g/n2OQRoA+clGK9gOQ2MNhHvVy5MYwZpFULYwu8tIUsGQucAuC1XhLWAfLW01kB9yxWUmYVsY5+XAMsSIL3EOZsA46l7VlOAYBOciPFjXVcktkS83wKvMIJX3YUbP8M+BOhW5uQmwutrwmhPEB724FGeu6raVh5C+KkjRJa4uI4jEsYuZ29u6AkUqMCPrxwCNkMIp84NyQAoC8SbbSkbXa0CXMQULmrHCUHfVX0RDMzFLHGOJty1c1xXHw9wDG+mgc9sbzbgJY3B9jNmTVg7B7FlhycFaSGb8CTsHHQZ5+AAzELOAT4l9mMGXmWAtfb3CoAygZUfAKCXAIIeADbD2hmebRvhxgL3nRCCBAhvJUApa/gI89jOwWlswC1ewPobmXYCD3IL/3+KsM08mjOkBocA/AlCGzMWY2QDevCMZvAMGgCJ5OSxgMGJjhQMzoNlTcfKpU9z6VYDhHkObzKDEcl1jwULgRaIFdoOqc500w2knyKEg/nJcygqc5wXLt7PEGqsoPj2YDNsHtNmcwlMBUtROrdxAeHdAHKPatxGs0LnOm8EKUhAYZHMCK7aABbZhKMNr+ocYLSp77L0uAGloRu3Dc5hBnKoBXfUOIUduJZTF95kENwV3P6Oc6N7AEGzkAP8e4HUVNfF8FOEYptYW+IaLN4dI+7eci5+21X6XSC7sgWXm260ycI5jMUmWHNavT4M2RLnpSGzax1AH2bwhkxJT13KN+K5zvQZ5S5BljhRa6LPMngX0YXPERxPA5mUGe6RBjjWVIFaUdApyd48hPDzcLV3uAFChIrPwp4A12cO17iHC5y4yqUOGOETIFcX1mAKl9uU+gS1BgMAyhgsdAByJzwsIyRHsIwWVowgTJtI/VxAIJrwLkwgN5EKG4GNb+NeTNAHALcLxKEtuOdkas1aj2HFGM+RaDLF59roSpUvIAR7yEgsXbVnDpKuDCHsQtimiNGbSLGVCFemCNVmAKqGi8sHUA7uR9M1y0wRkmy6ayOnkRB2rgSaNBQ5MlFB8mEhyC54kguAYAF5NpDbhNydIRSzkPYCxmHLufgBIVbuZH0Dz/jcedes8htLhhK8juAIxBLeRRse9sL1r7Dd+MJGghUu3p+7E69cPFGgFmDiiJUVYtYCimJxzMCRUjOgag+CdwoeoBGudnoxD2xA1QQgJNfwMQQYnCJtNsB1LBCCpBpXcANWzNb2gMZnIIS2XeEMeyr62ocVlCK5GN72eAghIlnlU2GFrm8Mi18AUOZQ/qjPZk4gg4R3DkKV7rkx1+Y677j8Oes/GJcbUM1gURc1nMbqHZxGAU5jitz6wDU4zRAz9/Gb59i7ITxEA9UhAPQUgDHEdRlfsoFQ7gSk3wD3O8H3c3jRAdfAEMTClRwgH+AxsA7C9pnG2rzxAVz8qSsoa8HbM54iWBbgHPFPFq5O25njB5NuhCkUFkxMHUicIpRo46EmuD4RFjkDu9lyNQUtuJ/nsEQtV5fAKr8BFOoC1qOFawhgxOfwGAqXJZgBKEjSnTqiL3N8xCb4D2YOtrDPZK4tpTmCVdlwfQhThBlDPZMVQpDM7YcJoQ9BqLBLl+bcgltNorULD8dAbgchHnmRTVyvAcomrNEFzrGJe1gCDJZ45qycZN/JAunNPjw2hosZQKKAm38By9mFK76AhxBdFuQEBo6FTuYlbMB6n8AL6Tui1cA44LwNRzBXjp8xWTsNV7sqkyPnu5CDC3hjXTyfeR5C+AcIk+XW2+Fqb3hEPNZ1efimS0lUUGbGuCOAxQAXcYbww9afAfE2gOpn4Wr/Pav8zoGWHlCacCmTS+cM4AJaoVMbrvMIxMoGrC45jQLWgy7m1NUgcP8YruxAIC6QgekhPWmexxaq8s4haAMg/xIeykr/7RyWeuBKZ+ldbGjtHHn4AgI2hoXcxnmXjomusK9BIcjIAUoObuUCSr0LkL+AVesBuEu4/QSUBAViLLyA9e+BG1hBHpPbD8vqXDhXvAlAGbvw7QK60Q1X287HAOMNpLlPwR014HEEeBf2nI+hJ22n9CVAIoCcj+6abe/6eQjh7yF4bSgsO+9iuNpeewrWlJNT5rjgCFSj61qBOCL5FEIIR3Bvh444yvGbDa1tIJZKeEgBqNuGGz0B4lJgItzGC6wdwCLTWjWQRqzgYpYg72bgEvpg4U/Baezqd+Yg7tg/cYo9uIEioDmuo4O1Bii7rkdiif2z8KpEaLOoyTIMnNcyA1FrWYYplIRdjhPsh5GCE4BzGx7BBTyyXQDKArxKcvF+EmieI+SkAYlu77ZgKCbYu4bLoS/g9vPzgHNPcY99/LcRipU6kGMDty726hxhTBuFUUvIUtT5JwC9FgjDJQjmiIxVhJfeg376Kty3Od2/c27xFBbGFGUKl7uN+G0Bq8minCTF76OYwiNgH4h/gNCh41A+QcFjCOENLAFZ3RVcKlPoN+AmhgC2GZDfCLwDWIwh2OcJ3FBz+Y4Ql2+6Yqkx0kQbEgy79w24thMQP7mE9MIVOtHCnYPcGyKeO0Na0kDiAoDTx7M+g6UgoCydYDBttgKgBLi7phBdKdsS3swSNfYTeFUDrTWl3UCcO4an1NJ/O3OEaoI3M0H4OEBIMkIefttlJBrhaifnCcKfTbj8U4Cx6cAJQtgh+Kexawpj+prGqQni2TJcfXx25uTxDF55E+XOpa5lgJBs5BrA+jDKR/q7QJbBwvWGzQScufLNBjaIgxg5rGLqapfP4Fa2sHkLXWCvxpqam9RB59cp3C+Ws57Aglkp5JlLKZm7dwTPoofvRxBYRoIdOIIuwrU2BbTqx324ihsoFZ3DmprSHYMU2nLdYwYGJqSnAN4tMPRT7Z2B8a7ueeEsch9714A1vQD6t3E/cxdObbkcNbMMSzwv1iW0ACiWZVgCXBcQ0o72fwnwYRnwFCTYpp6feQG7CIkmKKNu6LqP8Ls7YL/HyK60dN5TlKZvgDSeIbTJQJJmeo4915cxBzHHUvEjeD4DeGRzyL55wkeQnyEI9zHqEnLsXUT9QBte+wr600PoZFm5LjiwJUK0TtBAkF8iBjfrfARLnzlyZ4kCIR+T5DUo08ePnoar/c59CMBID4lE3xwE4gCM7AEU0FJvMxBbAzyg1/h7AxbPSJ8+XO43iJk2HZHTAQDZwzYh3oNVPEEz0gDFTyYIt8CZnMJ9HWLvTCBv6DtbWnsBwoxDQc5BmBlIjOGCc2z4GbyLW9r3KbycDMTWCGBwE+k4TvKx8OYUMfSeK4pKAJrKkZa7rkjMLOsOXGsr/LoBDuMIRUPb2LuJ9mkXHuEhwpMdEMyUOyMFj10dRBPe7ilIxQE8uDNwMA2Q5S0QtZYJOoKhYWk0y8oTDE4bgNBE7YB5sBYSH+K+WgidLlCsVbhivEkeQvh3IEOmQAdzVfYRdxRwjUdwiY2kOcJFdhGvjWCpcqQEmQ/N8PkKfEQXN3EG4bc03RQuZh+lokc6r3kuY8R/TShMqXscurhrCqUewqV6Aw9lG+vGcOUDvIsABZqCIAoglAxQTCnuwEMZgTht6bdPAXi34CKfo7y04+oPpsiT72rdCJ5PF0BwDsLTQOICeegOYtYLsOZ39PcUcXQLSnSMQrI7CPPGUAgLBY/AU9xBPvsMRmFD3zl0+2FFYod4hptI11pa9AZCniPUnmwgpDMPdgcG7thlJDgXkiDRg6c1geGsnGFJ4WpH4whZs+CKlFaOpzgIV7tuWetvnFeBPSUp2M5DCD8CmddEfHQAwQggggJcEytBfAUBzYGYJAWtX+A1vtt1BR1msQLQsoG4q4G1SxB6XSD3VEpYIDQZAaH7iAvPtLaJmJWbT1b3COBj2YczANo2BP8YsbdVsJ2jEcrccHuAllW5iZBihopAa1k+hODdwe/NUGBjluwE//0WuJoJMiYZvAvjOvaQY79ACNLQ/Z87QJkhG3CO/RggNLpAXv6GfmuEppcBiL4TEGg3AK6Wot1E3cg+lOIWUnHnaEpq63yvALA3EP4cw/K2AShGau/CwB2jsMtYe4YVuzBkJygF7sJTNZDYBN8xDldHsHWRZj5wcj5H/QwtfUP70YUHwUwbK0Mto9awQqDoLE4HREoJpWggVs/xsPqwdGfhanuixR372IgMjRMJ+eEllKIAH8HRWQsU2pjlZF63gJs6EXInoHwC0DQRqpy5EOQUXtEmOI2Z1vZB9J0hrNhy9RGnsIA3wC+MUEBlodAJUjhmeaNLlW7h+0aS3oIlPkVRyw1Y6SViauMPzgA0e4hvZ7hvK2w6BiO9hyKTKRTcXOwTKD85jRlkKcETWSHFxmKgU8jKHkJLWs4teIcl1s4hdxbi7cLjsJDgBojYV8hIbaGnxVzuHTyH10jZ7SD9e4GwzQzJATiMHZQ6j1E704R7bmHFECz/DMVs5uFNHUhEEJULGJwuvJs3yDo08hDCT5BvbCCOMJdtAC6APfUt1PqT9W/ClW+AgOJQiUOkCvtwzUcuhk9wWxLKZ3O4k2S5TwEWRmw1tDaHC1ZA2SYgu1oAiSZQ3kKQkYRo5YgtyzJ0XLiyDYb5BMC0gdJo8xiGIMiOwY304LZVALwqhHAbVomhUIHnZ9+7AzJp6kpUMwCeeRcWSozB6vdhJMzDu4E+ihEKyDbxW3YvuwDJU3A8m+AabJ8tBNlzHAqzPBXCzpU8qAt4AT2QgLbWUmG3kDI+gPU39/0UxPgewPYNPMYh5LbEWlPUVzAGG8gMzHFvCRmrRk2dxgqkce7i/Qnko3K8m2UTzmHxe+AlViGEqb0cNANCNVzdcEQs1MVFnAOxekD1i3B1BHEbFYGHetgtVMxxjHcf3MK+c7nH4Wr76SZKXg8AUj1U/42bDjVvAAAgAElEQVRdFVcDgLKCNQ2whEPHaRRgmFdgyldQCEsNWtrwFsi9CVxBIzMPUSC0h36Jc5SvdsBcW9gzRP39CJxCB/yHEVBtEHIjuJ9txJsNuIerEMJdKPEC91aXRryPa5uGq+28LQeO95CxucB1dCBDyXEaBry8jq4rtLHMz4ZL97URgiTE5QuAEJuYNqDgB5DPLed1NAXqNjjk0BVFGU90DD7I4vhDZK+2IUvHWrMBfTtDY9aGq5PJsW+sVRhLLlhDwklAbZfpGdhD/RWqmfhiAb6ss4uLOHVthQ3XAzBwSNVx5b0LIOAAPQBvUBc+hADPUL1lZZbHIAGHiFEnEOyoB3AGj6Efrg7e4NuLtpEKOoIw+8GX7CDLQMIkgMQFioS20MSyj/LqG0iD+W6zAQjEqSwbB1bO3H4cwqXcxu9NcU8NXd8RlLaP+HcGYraltaeucpKdhyNkO1gKfOY8lDGMQoaqxyYEOmk/xq6mfxuE8DHk8QYyABOw5Pa86N1tw7ujfGTgNIyQ2wRZzY7BBsq/V/BgWTy2Ak+xA+9hH0T5hiuWaiLUWIFwD/CYS8jwBrI/h+Fqi3WA5xKR+4/wxqdo2AshhDOrBGwiNl6Ev36HXA5XguTCHEU+7EI7QBqxQClw7sgqS9M1kS9u4KEQ1XKBRBvFIx1YlAs9bCNL9mG9hwhXFq5seIi46xyWJiGut/h/Q4JiIUQP6DrDPSbE8EY0taGwJYSUrmuhB5tBASoQZgsU8BgbnUCCVdiPKfoQhsitW+qNI7XPIXg7YM8XWFuAEbcw6gbWzuA9tcF/WMx8B6A2gsJugIOx1O1tsOcnqI7cAoNv8f4NeKMMj3ZQYblEjYWBxSHAeAthsHk/HRCJxwh9tsLVyTpTcF4DpF+P4O1apyRDr014bK9BovMdEysAlWUOXqJuoI3n5EOvoPP2wtXhIiWyBANrB+ZYbY40YlagAzdpEq5Or12is6xwXXbHUDae4wQpNvMu9qGobHw4AOfQhHfRABudIZ5rIp1p7HlEvG9C+gYA1UEqbYWHbdVnb3BPPTQaLUEgBhBmnCXQg/U6RkHJbaT0ZgCUDtKTTZezX6FfI8c+HSDXfwd8zRm8uV0AkrHcN1G8dYaKv13wKitkV1Yo1pmCt+AQmAvwOLvIwy+1P5yyfIr9uSuhnaNApoNGFta230Tq7sIx8wtwRBFhUMQ5mijMOcfz2URhzyGMYy/89VyKDaT7DlA1O8Bzm8LltrqEYxScDQCcE5QNs7DHvNIu0noThMO56xd4o7970E9OEH47UYiFQM1w9b0AHAM2RcEC85MTgEAA8meOQIxAO0sdMrf+UsKVh6utnQvER1YN9gx/9xC/j0C2mMv7DF1V2yAIj0HiWEjwHJu1jVhqH1WJVmZ5gPTUHu59H+5mD0UoSwn6TRQkHeHh9tGEYzUMu0hZncId79UURZlXdFdKfIH89wCe2RtY8veg8DOXgjL23IitB3Bdrc+hg1DtDVzg24itz+Dq7ujc3LtbIFAP4UHt6jNLZZ5in3f1exMQiBsA44Nw2Wm5p/uwa9t0ZbL7qFbcQoHMKaroTA4OUeOyhbTqATwiA5ZjeMjbKJ577crmOyBJR04H9iGPbSg4a1ya4FsKhGpDeJcncPsbqHA8CSF08xjjr2OMyxDCIsaYxxjbUUcIYT/G2I8xhhhjpv9WhhBmMcYqxtjV53kI4STG2AkhTLSuF2M0QJnqPHmMsRVjPIsxNkIIRzHGjRBCO8ZoefjzGGMvhJDFGAcxxkmMMYUQXsUYt0IIzRhjC2mzIoQQYoy7McaprvtZjHFT52ApsD34myGEpOt+bFY0xrip75+hBPkW3NgnxrjGGHfhMp6iZt5Q/ike2J1w2Yt/gtjUSKUXUIp7qOY6Q5VZU2BwgFy+hQNm4Y7Ah9wAqXiOVONtPZMTALyVRpcgbA0kRqjcCwizMleX8B6s0gyZGKu9eAmr/wCE1BnSkl0p6XO4zPdhZI4h5Bs6/ytwErdgGA6QVepp7aGu4UgyEFG2PUcV5BAE8mu4/T2EWDMArBmqV8jhszT9Ah6HGYvXqCfZdMVjDVeVeQxvbAMe7j4K9BroCzAA3whXu08L1F70QwiLPMb4CymKuUshpbQvBe7iYb+d9xZjNLcjpJRexhiH+ixKOacppYWAYqjP8pTSa62rpPR9xFxnUtqWwOEkxpillKa6lmEIoYwxzlNKx1rb0DWe6fPzGOOGQCXGGJcppRf6OxOAjAVir6Xw/RhjEWPMU0qvdK1ZjHEnxriMMWYhhCcxxi0BXldr3+h6yhjjvRjjQt99FmNsxBibAiUrChkLZB+EEOa6n2cWPsUYb+k6rPFnGmO8q9/YlgJdhBCWMcb3Bcrm/p5amWyM8ZYe/pl+744+t8lGx8bsxxjvSRmsWnBXa61ZycKsqLVnKFPuhhBWMcbbWmvkYtJ1T0GuRa29j7TnTJ/d1b8D3WOFaytQ3TiPMd6REdkSGC/0+QM09Ryh2rGjZ/8sXA46uSMZs+zAOISwrec1QM7evI42MiAjKOAQ3My+fq+N9N05itE20CT2DJxDB1zTEkSfpTlfhMvhIW2EhsfwoiO8iz66KHvIKKwQDjQASId5jPFXFmunlC5kod/GCFK2Log4W3ymteZuxJTSYYyxLSHoSPiDlLArhbdChuOUUpDHsBVCKARCL6WAbT2odghhklKqQginUsw2CLNKlnygBzhLKc3lvezpvF0J4kxKM5BglCGEZUrpuQAl1zXOYoxT3WNP1xdDCKuU0lP9Togx7qWUZjHGRUrpCEDV0n5YWLGSkNrvH0rZ+wKsIqX0yoQ0xvihPKGW3N2lrnkrxthNKZkXMNHasX73AKz/rRhjK6VkfQHnVj0opT0A+bmrPZ1rrVWqzWKM72mfz3QfO9pTE/RDa4iJMb4v4RzDqre0/xXy4osY4we6xxKeXFNgl0sOFlr7nn47Tym9tBy3rqWpPRrb9QqUuwKJpc57U/doHs1IwJ1rn55K5qsY47a+P9H/TgXQ5n2aKz/R2h7y9UeW/pMsWdPPqWSsp3su0fhmcmfFXC/1PJuS7aTnlmkfNvVvI4TwQmsLM2RIXa4kk7k+f63fqbS2k8cYf2zMpKxzktK+gReQwEIvZXnbWGuhQgtlrWVKaSJraGRJnlJ6FmMcppSihRBWpGHors8KWeR2SmkupYvyCg5gqQo9QCNWRrK8LdQ/r2QBO3pYp/JQjgQSLd37iZSp0NqhubQCsV0pfj/GeA6l6EoY57pvhiA7EvSRBLSt3ywFEs+0l0sJ+gReQC7Ay7UPz8xiQIESWkc3JDRDWY+pAOUHEkADQuvOHAA4zAt4T+fd1lqr7OwKCM9AVt0MIVwIUI7B+g8VvpnVPbH0oSz7qZGtEsj+d5FXWEmZuxL499BbcK5ntCFFbKSUnljlm9bOY4xJ8tjQ2n6MsaO9C3oGD/QcM4D0UGDcTilZWvVcHlXDrW3ivFZ5eRZjvKH/1hCANfQ7wxhjL6Vk8xtPJAMNyallJGaSpYEMi+nAhhS4oT1s2vOEQpuxHsg7bEo2spTSiYXluO/zGGMzjzH+GrX7mbyAphazvLEJxnElZT4USPThylh+tgGrwhvpSzFWUqxKPIIV5WQppSda24G7Zkx5JQW31JS53MYZpBBCpc2exBhv6jttIWAhq7KnB5VijBNtyK4sS1v3FrQfN7S2gGcwSCk1dN2n8iQOZWlyAchED6Wl8xqhVykc2tb1bNhaS7nFGO/GGC/kmb1GaHJba61zzlzusa7xtdWVyyJPdJ6ZwombApAevItVjPEjCTzrGLZMgME9LHReA8pzdCNG7eG+pet0bRMB+AUINrP2xp+can8WAk8j/zJ5mrsKB6Nkqa/r3kPn4lRyYM88SPE7uo8bAogL3WuUZc/lXTw28lvPJqaUlvA0b0iRMnkihX5zV3tRaZ8qhZddKbF1mZ7rek059/WcelrbSimNwI9tmvctJc50bU3zjKUvb2Q4Wbhnk7pMD0uEBD2dK89jjD8Jl6O8cp3EQoKxCS9OXODEPRSonKLU0BjJXDfUtRgeJExPgm6xaUNudB8u9xztq1FIutB5X2rjBkj9nKWUcoubY4zW3/BCIUkHddEXKaUo1N0CoLySwEUppqVElwKDXT28ppQtmWssxZ+LAzmV9V/FGLckBEspjnEDWQhhDE4jSHjfxBgrPfQdPZOGwMdY/0qW7EBKeyJPKxcQLvWbGcBgX/dzyrZn/dYBgMPOywKcKAJxibbdt9WDer6HAKU7uvcp6ulvy2PYEfiU4BHmujZT5m09x52Ukt3jhUCignE5EbimGOMd7aV5AZsChA1xRKfa40prDVCeWSim7yxSSiPdRxKoV9KJR5LDXN+pUkoTydFSgGJc2kMr6NHaLKU0FSCuZISMH3uq57eQXLdCCAsZpkr/rZDn80oexZmut4N05tJ1745CCC3JEsuGJyGESA4gwrIbF1Cg2iohZ547j4GzAzgplUhlhTybGGBwhJxmX6g+AmG4jfTFsW7EAMUm6ARtyDaY/CN5Hcda+7b0Umu7eribMcbjEEIzpXSkDbbcf2YejtVtxxgntlYC0JNFKCRwliq9J6vbUrxvqD3QwzqU+3+kONTyxAcCl5XF+1YurbU3JSDbsjRz+1vXOZFAHlq7s4i3faSbBkbE6rcsc2Bhxb5Adqbn0RSoWIFXru9+JKBK8D6aOn8QoJRS4o91b02Qgg2BW9D1JnAOJ/rtA7NUWmuua5TwG6Bs6VmvdB87suhVjLE0gJXS7Yp/quS2D80rFcifIrtl5F2Uld2w2Nw8Pkuf67wLPatnOseu9GiVUjK9WAjEVjrvUxmnofbE6mxiSmkJTiTB6LUQaozFTZnn1EQtgFUTNiV3K2RoBiGEzLIAC9Q0WwowQ7VYC7nkGcp/jVzIwA9Y5ZFZ9I5rHkqoKbda+r5ibOtQ20AGwmKsrn5vaGSjHuyO1lqsE0Cs7GpNJgXdlhD27HMDNp1nLsGwh51p7YXOO9P+7IhDSFo7lPDtyXIYmVfEGLeTCA+BT1Ocxl258jMpUJQ3kyu2fGkFWVo7QyooCVA62o831i8gpnwqQDjDnIIhXPlKa/cAKJZyjAKqDe2Rka9D3ZNlDk6l3BbfTiQLb1tSRVC+5RckvBaCmBttCvQBPIix7m9HIYCtbWmf76CR51Qh4MAySNqPQoB4SyDRkzwGhW6dGGNfz6sKIZgsZSGErryOTErY1h5ZyfZxCGELIHEqIzDReXfMkApQN/R8N+TFJRmGroAjDyHM9ZuWKuyKLDTZbRlRLZ7pDK79AF7HvvShC2M9gudug0VSSumlAUABZU/IF+Zo+5ygsymifzkLV1+PnAlFjVgzJatQH23FF4z3rTqvIddsjqKLQp8/lXAuFMd0tHEW/1k/dhuZh/MQwo42di5lnplLFUIYam1bQrCNuOtUa21I4zbIxtdw5buyTBOkAG8I9aPCih0p9xZSW0kgcVv3YOHKQF6ADc2wbrhKCmTvbXhu5axy26fIw1v6MCG3XsHKWn3F2LrN9Ly2RGAZiN0VSFgt/Yn4jXaM8aYUs5KS7el3jRc5AmF2W17BVPHttvbDuh9PtB/9GONd7XOpvTOX+6Y+N3KzKQWfgVAdIh1qbdAzfX9X+9qUNW3pPAaEhZ55AlfVEXBEGZg9S++ZwQE/ZDMPzWPYA6Cfar+DZMQajUrJnxmyhmQ0SQ8aUvwKa+1ZWSbGuCoj3C2GP5bsFtDbZLxUjHEjjzH+DMpcuF79NspIm2hOWFLhUQgxdhmCZbg6IbaBFt1D5GkDBhe0hfJDAMoTCYHdTCa0NJfKkDtTjNbXQ2lLOY/khk31UII+fySrZNOJ+3qoBhS7VmChtW1Z1y097LlCkjMUBu2IeDKl2LXCJim9gUweY7wlBXrLIoNzGcua9qQY91HIcmj7BtfTetlL5OwzVJRVApQFmoeWWmslpfuIy99HEdEc1rSKMW7quqdIcZaYI3Cm3HqU4j+23LjAx9KIZwKJoQTynvZuqv24bdkbKf6RAb9ieONV3mif27KGZ0p/ZgLYWwgXn8MTtOacsaWTBdQLGJyh5KMv72gh2SiNt5F8vBCJN4OsWphRIgXeEzhYq655ZhYSJpNzyc2FwOYNa1xQNVoIZHog0a02p432fTPAGdL84W0hULj6AlBOCY5oyUyuHoAv7EgoxrCGj74rG87RKvy2dlnx/lZNueJIIGEddVZTYKlCe4XYQoAwQIxWpJQeS8FLCaSRm/ZgbeBCW5vWVFXkrsClSCn9xWJ9gMTLGONMVv+BtSxrbTKOQu75ERT/ga5hU0oxM+JPWQUbrvFG3ECUhXyBQqI7shTW8PPShFZutOXEx0YQIf57Yc1bMcZPwuUoLXtxRBtC/dzKSZFGDGjzbSsGDwIf4w0+EFj0U0qv7bnrfvqqdxjrfPfNq0kp/cXKe7V2IBd6JC7gnizcTZFrU/3ebVjTC4VZewLr3ZTSC7j4u0aUqrbkLXsuUDuFd7AtkG8I6I/lzRQ6x1yc1CPtc1N7koUQzmVszAsrBWKPUEPSQem81TtsQHYtZ7/Q7w5A3o3d7I1TEn2ozbG5FB2EA0uU6vcMACrU+zedRearwiOagf7qPWMAgAa8hxPUSfPVz4Vi+Q3bFJRkch7gWGvtofTRrPT2fXGI0UJK6VsJgZWhzhUzzbR2F97Fl2aRrVRTKL6vjb9tzUMppa8EHPMQwm25dAs9rEznHcgifCnLcR5j/BAx2nNVDe7pXJsppUfa/5Hi5kpu43MpU0/XuC3LO5Yb/ZEEx+rjzeXelqdzLIb6QEAyRVxuXkDP+A/tpw2inMUYf6h1xvq3dO4MIJEJUH6ICr+xuINN5MsfmUcYY/wUMmT1Cn3tyZYU3KpDP9S5+gLNhRRtD/txIa/ofV3bpgBlZmGGQPJUWZfn4lVaOu8T82xlROylpfa8bggk+jI0Hf27KcC0ephnUPBtyO5zWO+AdG0LTU9BBLMRiB3XdZi7ASAFCG0jVeteh9aGMW1CP3shhMoKgXL0CAfEUvQCpgCCBkDiBA1CCSizQC1zJhfHqpYqXPAcTSnWKWZluR252D2kEcdCOhsW0lVM0xBI7FlGQOzogb6b6/ORruWRHuzb15BZWCE238ZpRSm+uec9Xd+BlKaQJZvpWv4kq5JUjZfJHT2WRfhQ+9RPKf1Zn8UY4wcS3qn4BSMKmyGErZTSt1bbH2P8TGGStVOfyhK2FVY8tUYaKeZUwneg/3VFMj2w70tp71jJrcDEyLSG1p6iUtCq/z6U4u/bdBvxBlaU89LStMoGTEBOmrUPIh2/tU67GONHIuwW8ojmFhIINL8GSPxACmPe3UzpuD4AZaK1H5iLLYA9BxjbsBZLM9/SZxZyllJeC11PZBieyIvrSYlHAq2l9vntDEgZp5swinzZTluyanr0At2yOUL0E+hPRHs6R39xuEgDfxccVpPHGP8ecf5UJ/6ruBw9+8l93kHdwAjFCPQO3gjhB663IKG9tAXF7MvltjTiFGWqW2D9n0kgSlkyCytm8i529MBaSvdZY8YOSoEX8C7sDTcjpXMsc2BucSkBM97gBmoEniFN1NH1PZVnERX7Gln1EDUMe/rspZR7JaU1F/NbgVJTwtuQa30mjsHAYANudBZj/Fi/baWvZ1LWpRT0uT5fmrKFy5HdxzbUQi79S5sqJLBLegZjpJvepvvgzdyyrAl4iras4AcWVgjsB0b0iXCztuBVjPFDZU662o+2zntHcbdVLFppdA6Pzaos77t+iJk+a2OfzSU399+MwkQela19qSzUieRjQzJwprVddFbuK+5/KXncwDSoKepmzN0vJEtbqOe31nIzxm8VHWXsDTfIx4ClDT08x99vC4F+iricln3sXHnLEMzQhmiafwClDSAczjAPMCEPP0ALckDe0vL7OXrc+yhuaMAtayFmsi4qq0vYtkIbrbUMQxdtqlHXfUOCYW6ZbaLlh8cCiRdY2wmXQzLnWmu1BnNZhD0B060Y44lizhMJ+g6aqf6iz0pTCgHNS6w1QHkoz2IZY/yRFCjTtWWyYjdRJjuTUnwuS9dBvN5WTGyx+oW8gB8qD39T+3EmL8cIORsnbvzHhf59Aybf1s7g0dzS+c3rsBj+JrJFJYTf+ASbpXiEcLGl+34qb21pWRB9/ghu9Ibi+jfySOwakhToW+TWNzBYJEOtQUNewTfW1SqD1oEM2J5ZN+bTcPnSEfMubLTeGdqjTXaN8OvA253D7WdNjrUhmxGxArsJivYi9PoMw0YShv/keYzxlxjImGEQSBMnKUEiFPj7Ak0PAaOzIgZyrLSZr+BmRQyTsOmtm1j7WArVQZrRUlZmUawB6QkKOYZSEJu1lvRQmrDIb9s1BQzsfd+Ga7YfLoeE3pSgNRRXW5FMX678gSzZazWj8PVO9lLVjuLwMyn+E5Q02zvxznXuttzwmTyRxxL+oFbakxijue0dCan1FvxFwryU4lv78THapq1/wroRFwoFT0SCnmEaTkPu+XMQfZ9pbQtxfw/1A9bYdCGeYoLGGBPyTa09UPHSsaU99XxPQJIOZeUmCFF35HXcEOs/s3y/rHWFDJJlUvbEA1X63YaeSQ5jYaO/rA7EiGcjo9s0WCL7rAAn6ll1MKrOBos05CHvgg97Ea6+sdrGtkc0ZLXC1XHpCfyYcWAj/F4IV9/V0MQ5Sjf4J+QSkgyTfxpwIThxJEC5Zy6GKeEZNMLVd9SPwWIG5KrbuLiJNsjSF1vIHIwxcqmD3oJnJkQYWmIEiL140zIHD61gJVzOp+frvm/CIj8WAmeYGFOhkm7HSoFNuCRUN60SDVNg9pD6eS6BOgsh3JEy26i1MxtyovTWK1WwvZE1rURsncQYT6V4RYzxfYHOEux3VNXimfLuVjT0oYhN6y0Yoq5/hNLcQhbySKBno9XmIu9G4XLsd9Ra6414YcZEa0+1N+dom15J8R/rWmcKHUYou55a+KZMygt5NSPxIksBzinApyHW38D4jWL4SmB/gpZ2U/wxwHjHpWDfvgJM3ksJg2P1Jh09c8t6BQDKSnJnstxHFupQsmCVrjnGd9kr99owZBkK7PimbXtVmKUcbWReCzM7jUCcAmSsdL9pWYCINGBkfhE1+Rlih8JlBFrORcmAVE0UAp2Eqy8Q2cc8PXN9lqjx3kRG4ADuex/FEda3voGhkKdC5+cCCRvSaM05GyiQsTn1T3XebWyuZUGsV34m8HmCTskeqsPsJZ3WHdfDWptpl1CTPpZFvwghDHS9hZTijgpTRlKoYxF8Y+XWn0oozwUSTVm2qVj/HSntB0aMKW15R6FJSzntV5b9UPz8TM/fQqloNeqyWNbh9omKlpK8gYG5/9onq2SMMcYfSiEtfOsqRLNqSGugWYm7ONPePZQ3lLR2hsk/Y/UhTMR/PNXaiUqxSyjxOFwObN1Bzv7IGP5wOSF5gkI16/nPkH7eROHNCsZxw7IOAJShDMW5itcy3afJYwRIcJz7EgNT7Fps9sYAHnaBdHCFwSUBHkPAwJAKg0561gvwM8QKFQDAXmFdwSvIMLjAPIYW5qlVjm2cA30amI46wuQWc5dtVtsIs+CiYtZmuPoCz0PMSdvC3LhncNEa2uiRlO6FhL8NF7+NQqVdK2zRRlvo0BNi27W19N9KNf28Qvx/U8RhpfiRjU0W129I0K1xpUQTlPWAG8HZjDGOZelPpTSWqcitW0xKbEUn76kPYUNlqKUUc9vKYdF9d1cAclPW40Jgc1tEnL1uax99CO8LCI4VZtzEjL8S05hKhRWPbWKPlG3XWniV1hsKUD5VYc9YKb0tnHshTsOmTFmhU+WawvoYsmlgfEv30AWBm8vFbyukSwIOe2NQVx6KjV7rAgSthmEXsyStQWuka9zFeL0RalyMhLTQsotwdorZjBFj3goUzQ1QhTtBuX4Him+l2PQCFuDmWqjpOc5jjD/Hl5eODMxQCrxyRUAlQKNCL0GG9uEAtyUDSLTx2QHYzgJs5hhWOg9X3y7EufLm+thctwYeoE383UII8ixcjt62CSwHmMO2B07htSyYAYwNw0xS0HvG+AoIllYaLLfxSIr/WOCTqZzY0loreR23rOFKFuGW3MVbajiZYKzaTVSqPVRYM1OxziGqCiOGd/SkbJV4g0/D5ajpUytCkWXeRF78QpZ+pD2xkl2rYd/EOLNjDO64JQ/gQEC8qyo/m+X33PZDIcRTawtWGHPPQEN7d0su/l3t3UyAuCXewAa7PES9/C0Bd8KEKxsIa913bCm2eRUvkHYuMHqrcKPcCvALLeTWz9Hxuoe1Vnq8wigxvs16C5k2i+HnyBCQWO/g2kxnT0C4B/TRsI8nIDXYCiF0rB14BVchAJEKpB4ylPcGoEgEVzAHu5+QusgBEiU6ATuw2CuEGlW4OnX4Faa+EtX4+m2Ly79k+g/exQRTcK36708SZL5MYhou3/Br4UAHwnWqSkFjal9LqW7p97ZTSl+rG+1AqaYhiNCRBLERQrgtITLv4IGuu6fvHksYexL+fZU0P5P1jqilf2XTj2KMD8QXRACh5eFPQLAlS0+KKbeBIwsRfWc2ngxViEGZg8cWrmntBYq5rKy5o3DloQD9WDl7q994qc5NG8bxQPu8UKjwoay09TJcWPGO0pHH8sIeIs23I47jTPc3VFhinuA3mA40tNFp4hfarkjsL9aQhJFaNqXaGoQsJDZvxjJWpnjP5DUaoHTgfZ5jyGvAQJUGiuamaK9vQwfOnNHtWt1KuBzdTt0KqAK0z5N5ADk4gHMgWgBBGNEvEOH2F7gQU3DzEJpAngu4inxfGcc6F1BuY0+7cO2YWsyBgA2lfrZRBGQDHbvwDkqBxJ9kaTZxnjeIv3bRc/BHndcIlAFSgGMNrTSv44+yVG2RhZu63n0p5Efa26GuYanY8D1Un52ovBNIwrQAACAASURBVPdDXcNeSulLq8uXUnTRVfkMRUDvqeJuImX7wABFz/UJOiV/KOs9E+HXs5JdrX2KUuDPBdgR7nUQoKyknAsQhVMRfd9YBke1BoWKog7kRn9s+fyU0p8kuAtdt5XbvpFCP9Cz3NWzLmXh74O3sbU31RNwQ9dmTTT3tNbmHLyW0g7RwNRJKX0hr2MTYe8Fulo54epbgUYfBnMB8nob3bFfIQQyEr3E/MA2vF2Ojy+gtHMMFs0cwTdxir90Xjjf8zEKIbStDiBcUwo8dQ1Cvl8gx1pa79wpfhOAYhds/3aQTThwLksX8Yu9e7DtKpwu0C9gSPdI7pflWc06Heph3wCofSuFbyKksHNsINaznLG9/OGmgaMVnMhaDAUGX4nVvgghfIzegj8pft/WOYay0hcCiR+iwvGPKhvuKbbfkJUeKbf+mRjxG/I6LqSYD7Qfh6qcfIYioI91bwfWDISKsnNUn5WSjRdSjKniW5tSs5TVs1Lgn2NAijW7WHlvS5V7K3kbnyvdZwU4SRb1rlj/Z9q3oxjjp/rv2yml32s4hlVZbllYIo/hI8vna+8ytejekZt/ISL4qYCup/3/FinNLcmHyflLzLCwF9HYde+C41mAC7A3Ak9lcL7R2k0YmRH0h+X2z8LluPoALi1DQ52R9vuYNBzB8CfweBFEfuG5u1zumy8COgX7HmB952D27TiCexRBUoyRdrALPES8n4GZtFcX9cPVOew95C0tLXKOTSuA5h0rwNEDs/fpjVEEsYkJKX+Wa7iFhzLGTAN73Xc7pfQHWdkhNtmyD0250ZXW/tamyoiltuaQp1L89+x+JNAtKfFHAoyFXFqbxDuUkP5R03VGMcafGwMt9/pUIcieZhV8ba6+FHMhJX9KEFRY8QzNSp9YuawE8Q2Ght6JMY6UwdgXwFq/wKtw+f6DoeLyscKgv1gRjBTfBnccyD23wa1bAse27ueHIvyCLH4hy97Vs/lWw18PBRKFnuuXIll3BOBbAiYr5vrAOvOkxAXCAXtpRyHguxEu3zPxIly+7KOt8y7E5Ft5bx9TeN6+XBfzIqNA8yas/Qrp4Db6AiycGrhmvQzxfs/14nRcyJ7VpPJppMs8xvh3KB9k9Z8p/hxuf4G1M8Q0CWtzxC8JzKS9aIFrLVzo4qafAwEzhCCVG28chc72ogdjSe3VX/YW2h6mzBpYbGLyzwghiAHNqRT0mdz/HdzzMXKtu2Cjv7b6cwtv5I7amOuPzKOS4tvMwxsSoteaXZCkVElu429tXpyBhJj8fYUQP5LwD3XelazkL5QBGEtBxwofWuqo+zOGoP5SgGV5Z5ub3xQYPLR6BTH7M1kz6xcYyjv4QM9vJgV/T/ezo3SfvQG3ofTkgcKChyoiylQjsRIBOBNR+IFVL8o937DqP5tLaAVF8nQyFWgZoMx0Xhug8VJhyn08S7O89iZeM1QH4fJFshYam9E7RPhga/lm6R6acJ5KXjZRkl6BmW8iRrfz91CrEjF/ow1P9RRDPip4thV0tnJNfHaURgKWTmljDRdQXRP3B1QPNhD/s0Owj3PwvA1c6EugcAxX33IbnCdhis8SyVO0Em8CQL4GoPRQoWebt4f05HOtWYjpHgCoDtCs1IR1PAsh3AApOJW1vyXhtCGZ9gakG/aCE1h7m3X4IYaGfivwGep3l7KmDYUFn+uBlgKfgeL4e5ZNkJAv5DGcSYG+VVxfyMratJ2RwOAzDPewFF5pawUa5/JEfqDv3A8h/EVyUIroi5gfeChlrbT2ofbqRKGNycLEjXe7a2XfAuObAkID2CP9XYojOJdX9LVCDyu2sVeDV3q29vKVt3wQQs7c1Q/sgpt6Gi7f7diCR2Dp0i2Exo8lh2ZcBpB/e4luA9bf5mmwv2YO3iGDK28xPAuGZi4NH6HXE1yvFe4lqwP4KdwCVvk1wSAmNhDUeAxN1y9gLkYLVv4cBEVEyaMRfkNc2L5j/RfgExrh8tVgNmt+AGJkiZRhK1y+t65ENmEK1z9HgcsmHvYhPIZtXMsTbKY1fBxi5uEDGyslhbdjU9c5Em/wRASWvcjyTbh8ocS2uIe58uUPFVYkFQ4dCDysvPqWrn8l4e9K8X+qa7tQ+myAApVKYBBlTX+l6TulrHchXuOGMgQPMRjkF5jx91ozENis9Fjpt5FCkDOkIpPOa+24+1LmffETM3lcj8PlCPQ9TBW2Oo1dgYy9HShHavAtH4TZklbxeaRn99I4CniZb1CS3kfM/UyGYQPGaYbM1wDx+htY/wJKa6Xsm1DSl26AZxMDd+aob0nQtRW8dLP4C4TEbO1fwbD7iV+ZAcCPcVMRlr2CIkfEyYxbWgCJCgwmC4amLqxYoie5QL8zXasBFJ7Vhx3clL0AcYCSxwTWlG9U/VZAYC/fnAHscim4xVhPpZCenLFuwht4sH9BPvftK7wlzPbSTJt5+EgWehRCuK9WYms8sVc8WxrrpUDktTIElpl4g2EpfaQGFwIUK5N9H805leLQ+0h5PbRSWBWCvdT/bMbfDXQuPsLLUv5e607C5Svg7qIz7SvMEvg7hSmWZWiKR9kAGdrTc/uhCnFKEYi5PLOhCMeHSOe+pxoJe/GHucR8x4E12NwWSAxQUJbA8dhrvff1/FqoOu1DLrfRcLMv0KkgS3ZtDcTw5nUMUaxj1bHHWBtR9m5z+1qQsZOadt45PIQWQOIEhT4ZDHsF4MgJKBYCBFj1AAUPzqWvHCGRQAzmiJP5xmC6HVNccIRFX4IEDNd0QZ2D9W9hoxnDN9Cp1wZI7KDoaArOYYDw5RVCkAydW+ZKbaIy6wsJqFWf2dtwSutxt0yHsgFbEto9rbsAaN61enYRWEMQiOfhchy5vddvKtb/K3PJxX4bYXmsundLP70nr2ApL+ADxPBnmLlncfljAcq+YnibE3Aqq9xVfv9DNP08l3IncR1Hsppm7T+XJxJEZpr1tvZhayhqKKyYKYz5oyz0Knz3whKbmGRvNHrPeCGtNe/uHp6dvbjUqvyGApSefvcOyDQbnzZESGCZqUPJwBDFO00olNWQGHBvgug7dbF4H4bMXtVWoPmuQClwF6HvGMqewziPUKsQoRdN1N0UyOyZVxCtGSi5wp7K9f4zDZjw3yIuonQeRIHPFuHqG4dH4BEydC5FtDS2wYSy16ADRLMXUhjR90QPogTrb+9wP1BZqKUdn2ImXBuun72Vx2oE2sjJHunh3cS1vZRiWrz/TOTdY7nPN1HdZSmlICF9DZbbiossxWYvmrSZ/keKWR9iKs+uXO03WmevFTtV2uyh1i1ByI1ZJ6B4/65z8T9Gp+ZMlvyezQ7Q3AF7ucZHyuW3lCF4Kg8iizH+RPd2Zrl8KXRfJbiP8V6HH0hZF+I/7uk85vq/hhzYG4MWIgVv6DwWNr2CfN5D/ccf8DqxPuJu85T2kPJlI4+FqHPwR0Mo1gv0ArQgS0eukacJtv4UIWSCVecLPEsw+Y1rwnLf83/hunlzeC8BxjeEEI7zLMt+ig/mNXn/yrn/ES4OBxDw/y9xjuD6CBKAgKhWgWMwYiRD7J1h7RIpwEwPvIWGoDaAY6KHZSnGRyjFLPQAzM06Qc43oqe7heaQcxB6d8FVPLTJQsoy3NX1nkuYPtC6TZBg5yIF7xrpJOG3N+Le1jVYOeuelCIh87ClTrsfKM1VYoCkvaOuUFFOLuv/Y8XubRUdJZTKGjha4dFP5cJvqehoYhOCrFMP9fufy2N4T+SrVePdF09xHkI4FCh8JHD6UKHUmWL4e1ZSHEI4kqdzV8/0lpQtiRy8o/+Wi3z9Fvdwx9qaUf3HvoVHkJ89KN3XKuIaIvQ8RUw9gLW2jFUX9fvnIBG3UNX3DN5DjiYyxvtZTWVtgRi+grecwfDmjo8LqMSNAILgPO+37wacK93SkDAENaHY35n+FzVuyf62tSvluEu3dqnPM5zH1kzt5SM6x8Kds6l/c5FIbazN9O9U/w70e0UI4bEIs0LrWjqnEVvb+rcZQrCBjkZi9fT/X8uCbWNE2CMrBbb5bkpXGat+Q/u1LSHqqlvufdXwNyWgS8tPSyCfy5L9JcuyTxTbd8X4T5Uj35Wgm4X8ykaIqYruiSbRlCGEG1mW3bXhHAor7sQYl1mW/dCNC+thnHhDIFGEEJZZlv1CXMRc91zqGppq/f0qXM7w/4WeUaF7tknNmwofvtaUpv0Y4+e6zl1dm4Vku/IyXgo0v1V+v6sQ7ht0ve3ovCORpH9WNmEoI/Ac3ad7ANiZuIc7IPUsHn+ssGkPg24euqEzAUVim+CqMvSpZK4H30qE2cV3CkNGdv44XL40JyCrxZA6d0pc4bwVem5ygMQSnkBkfU8eY/wxXw1e425EdAVmrhR4AjQKCA3Kmt6ChXNr7ILLcPXlI0bONSyOEVucUPuf4/wruWw26XcD17DEtQyQW/+TFHYDIc0SKZY+XlD6Fd9IjBedHGlM1X2BSSel9Dt78DYqSkM590MIZ1mWfSig2Ugp/VYP+0j5+Y2U0kphzLHWDtTj/mdxAa+zLPvMYnYp8wvF39sqbPpGa59kWfa5rnkzpfRK1roXY9zKsuwH+q2QUnqcZdmdEELIsuyjlNJre5lmjLGZZdlnEs4cLbpVlmU/UqvroVm+LMs+l5HYtboEFSL90ARRgDXPsuwDgeaeVfmllI4FhBbWPRS43MOwjyeSnccCwi09l0fyRHbQOHUg+f5Ca62x6EAEpb1TclfXnYcQ3lb5CWQX4mDGmPgcxGPYvMiuPgu6Z3th7qaMUwyXr5lv6aNcmR2b/9/Bec+1LjdDKB5pagYMxnCmVGqF85phznSPQf8mewVbjLHINVoqQPiptJWrJaYy++rB0nEGHiTogjBdSAAZI3YxbqCOxQzIbdpUIsvPrlRSO0RKz/oQnqO81wDlDPnfBlI/T+TKW/lmUN7Z0i82oaeoqupf5GIObR67JugslS//UILVqqrqvxlhqe9sau0FKuD6IYR2VVX/ZPsjT2JTvfOvQwivsyz7ib2ZuKqq/9Py0SoOGqaULlJK+1K4D2OMrSzL3k8p/Vbx+ijLsk/4ZiXF5Te/w4Lsp6oqnKHuvqFpvBfiDZohhJhl2c8EGladuJllWQejw5+qsGeZZdmPxEFsV1X1W+1lkgfQQq2BTRTKY4zDqqr+RcBg5b1DXdsLne99kZTDlNIXVlOvfbZMz0FVVc8VkvR17/sqvbY+/i0YIqu6a2NmYI4ZkDvQCQtbm3hvpg2V3YXBsaKcIIB+W2CHF+423fgum61QwEMZYfZ/wFxH6q19biBR6jxvJwJ9WqP4I2eRE5hx3wMwRtFNrGkJJkhcOAWPINM6zuuY0MLjN6euEKkBj+EwXL5WLCG2r9DIc66S0YeyJl2XZz0Hn2BcxlPl5vvI61aK67YQlzeqqvpXvMDyptj3UhZoW4LbVF78jzZHXu7uSoDyWwzI3FNI8EdjtVXll0IIuRQoZFm2Kws3VPPQaUrpTZZl/yALvJlS+oOBWJZlP5YiP0spHaeUXsqiz7Mse5BS+hqDOj7IsmwvxniYUpqllJ5mWfZBSmmaZdlnKaVvNMN/EmN8kGXZpu67kpt/Q2HFZ4rhbTzbTSlchbAil6X9RIA4FHm3rWfb09pXlg4WaEZ5Yf+q599G/cChDIOFZD1lTP6IAi5rAbZ39tnLV4yhPw+Xo7mt6jQh7UvW/wJ9/H2ARGnVg9CZFQrK2nhpB2sNMse7jeEZBxQ4tZwnHuHRF85Y5xYC/CRcnQpcoLooQQmiO8kE1XxMH0Y0JiQHKC1cQIlwoIu1p4iDSDguw9VpwwHsfAXG3soscxRHRBQX2UShDfQhJDDMTVzvSwGBIfcpQqG2YsYzMcxf4aUdXZW+jhU7F7JOFyGEUFXV7zE484ZafM+RL/8UgPIvEq6ViLMqpTRFb8En9hp1eRdNKdCvbCiFQoV5lmUfyRJtV1X1G5uQlGXZf0Lt/hN5LdsxxttZlt1TCHKeUjrKsuzv5YYaAXgqV/e+uIdvpeDPZOmtLv8FQHZT592PMeZVVX0l6x9sSAksaldey7nGxH9plZFyvW1K02vt3T1kJb5Rj8G5uf7hcm5iE0Nf3r6+XinXjiyw9dlHV7eyYEcd3mM5gbG0lLT1C7wRwPQgo5mTXXsDsbU9N1xIXTrPO4Wrk4WrmpR9w+lyAYBYWQjAuDy44SCF+3FWFxFRMljpyqFPXW9BgQq9TJapi+Kb0vUWEHxO0J0VXClk5fKhT1F9ZQq+wHCSPkDiADnaJv7/Qucfgjl+or9fobx3KUWxF03G8N1M/1cSSKv+s4KkU1kle431fSPvqqr6kwBlQ5ZvZt12spg/tJSUvI5dhRUf6tVmr6SoZYzxp/ZadSn+QCnDf9C9PVVIsMyy7Cey5DsppT/ovy+zLPt35hLrLTkjxeoNvQfxX8U9jLMs+7mKiqY2HyCE8AEyDX+UMh4p5Whu8Asp/R7e+/dUax8p89BU2HOSUrJX0dlr1g7lLX0pzqBtYExeSCBjA2i/FZDksqoV8vClZCC6Gv0VZDiH4rfx2TmyUGbZLawoXcHODANHaNnnyBpkrjV/7qpwl64JyGflcteunFkI8LkrBV66mH9Vk87zDUEZThzD1QGjqUbx6S0sw+X7ygI67ZjLnMO1aqE4YoX43jiDJfqpOyjfXCGeW6DoiG2VbQCHsaxzV6jxFC6c1RScIe97z+J91OjPxHIPtHaptXcFEpazt5ec3OCseRXr2Biy+zaFR+BxS6FMUy3F9k76eYzxx7LSM8tr24s6Bc5fm7BLwV/JG7EhIlEGYiqlSlr7a5FthT7vSol/pDTko3A5r/DnytZ0BVRDgdjHuvcjFR6dyZtpxRibVVX9QXswg2d1IY9movvOZOG/1nn3sXeliNozzODbgBI/EdBsh6tz9TpQUHPBbbJOB/F+hAy2YcmPsI68F9N90TH5CQbU1q4g//TOWUWbEI42XTqfxjp3pfomy9EGQ+QuDx9gWTPX5htdRiDARclxjtKVBDeAgDwna5Ynruxxik3JXG/BBQqGLC7K4eb0gPpv9PBb4a9nFeZI5yQ0WTDjEVFXsIGNfogehm3Ej1+hRr+pa/wmXM6Ne2AgpLU2Wt1Ck+f6bRvqkavH/Wu4pjbs1N6y8yKE8L4Y4Y/EkM/l2t/AK6vPUkpfZVl2zzoBxZ5zko+VMC9SSn/IsuyWvIn/oLX7WmsKtBdjnEjBt8U5/EKAe4YJznfFpZTyLqzE+BN7/bnCIxvsYi/xfBQuR2bbG5Sa4ko2ZTE3BQKvED480N7ZG5vsGXWUWrQiMWv6ydBu23XDa1YOJIIjmOcunF2B5F657tZxuPr2HvbXlI7zmoerA3pZqr+CZ5tgkIPTZbsW1vjMQghvswAJzGGAgodw9eWgZbg6QZhrs5q1mbvgpSMMF1BIbsgCE4WiA5IlYqYANrWJ0uMZ8q1d1FyfYCMaKNwx978H8nPq9mWAe36mIg8rArLioAu5pO/bfaid93a4HDxqcwIPZO3es/BKwm/DSe8rdrXZ9jleUtERgdXTPX0qq9iQV1BJ2Btyjb+RlX2tCb1HipWfBbxgIsZ4Xx7DSETfp2KaP9Hal/Ia91QK/BJ5+A+lzD8TMB6Gy/HeH9uMiKqq/hnx/g80EuxE+9FTKXAMIZTiP2xe330pToW3R9lshUoVgVt69lZIZc1RG3hpR8capsLl6PaWYu9vMTEohqvv5VtIPhooBWapesP1mHShQ8fh8s0/EYaMSluFqzM4ZzW828IZ6+iMX8PpbHQkekIpcMNCgB+4kt4Ai1zVuDK+QjC6foEM36kcSBSO4c+gvBXiFSLe2HETBRB2AeaVrjzJRauVXkqJLTPxAo08DcR69tLRLjbKhige6fMNNCRNkLPe0ZqWmOu7KjppQdkGignvGRhUVfUbxe67Ov8xGPi2BP3IiD6d1yoFRyjsaQl8xuIefmNvzsUg0InmEi5RCnxfFnKRUhophj+TZT1S1eD7IvQ+U4rtRKTgT3Sdu7K+L8XudxRePlTK8BtlOjZUl/9YLntH+/GZfutclv0jlPceCHySwMr6AmJVVf/F6ii0t7Nw+faiLgC2mVL6R4QTNrdvLIKuayXMaILahm6Y0tqYuR4s7WG4HNzJyj0LHXpoBDLvYu6yZFMXThc1vBu9c8b4zZpq3txl25YAtbdeALsBQ038H4FUlasFWDk+ICLe92XCyREYhSMbmbYILlTwswnJnBqgnIXLMUwBsVKGuMs8jxd6WF1kFZa4pxY29MgROz24Xq9UbtqRwtvkmwO5rlZ9dibG/mP97qaY8j7m1L2v8x5I8N6XQN4WcNgbjz8QoCQrGxZB2MZM/7yqqj8j9z1QSu6RAD+LMf7Upt9KMbvhu8GVH4IUtFd3/VLFNDZ2zKoTP7XpN3q12IEyShP1C/zeypsV79/SPr9RSPAD/e7dEMJX8pbeSJnv69yvtHd35MXdFshbo9B97XNL+/4Evfd71kCWUvpv2ue7IPgOreNT+2Ty942e3wYIuAvI/wBy+toAPVx9MS6H5djaIwzuCKg5Wbl5FwEcmDeqqxo9WcFjyB0RH1xtjm/jfxsCzFzcQQX3hUBLh0YRil2Gq/MAF65ykK8gWzgvINW0JUfEKw1343xhCXsLRqjdD/iNI51jULOW92gxYNP1IfjXK5sg/FlWycKHHXOV5Qq/Z9NjlaM2BN6UxTkQ2fe1LORmuBxM2dLDuoMpuCO53J9J8W+LR7BR2e/LuzgNISyqqvqdPIYYY/xE351J2fakXFWMMYh4G6ii79ci+OzVWNY7by+f+MLIM5GCL0XIfaHf2tL/dkMIj1Un8FJE4SJ8N7b7X7Qfefhuxp+9Im0kIPxU3MiGKgXNJbfy3pkyKV/LmxkKYB/J4ttI8QcmRxjMOQiXMycz9SPsiMthtqldUwr8Gp2gAQN0Csd3WdnwtmvYmcIy+4G8bRfHl9CPvKZfgPpSuXkc0YXaf0XO5xhCGRw6+EGgq5qKQP9Z5sKBvMbSV474WNZ0HK5cF1Rew1MkFw8dwdInl9WIYHdzdG+1XBu0H5sckU1ouyrHY51rD9zD7/X3Quc37uFrdORZCPHncPlGog/tFeayhiNYve0QwpcqXPlSCrSj3PXXMcZz/X1b3/n2u8xg9acY49+JRNuTt/AKqcIPtA+rqqq+0N9BIeEjWciF6hU+sRbrqqp+l2WZvZfvFyIbbaBHF/H+pkKbTBWAn4uUtAIceydAgXucKwvyESb/fKXruAkPyjoDv9He2VDXr1Ffv4V3MUaFZPcFYjbr3zJO/XA5Wt44nk08cyuFt5n8nL2/j87CCCU8QfMXXwHO2pSEmoCmq52ZOxI61lTspnB18k+4JizP4YVX9BwMAEjeNWvmAESn+FMHEgk3njmXfu68i+i+4y194YopUrj68hE/kpxMbYWQhWg5dwNHhuHqaKQM92ggYSPJOw6oEoaFGAv7heLaTXgcY9Qb3LOiKcWht3SOnXA5stvezGOhQlsWsmM97lYQpPj5SMq6pXDin1SC/FL9HVu670eK4T+wl26klP5rjHFWVdVLzQO0zMtLnXtH1vtzeS3zqqqeQDG3tZdPzIUWufhIJbv/KmUr5AEdqz7iXF7Lp7qnnq5lL6W0EjBZJ51NGL6PPv7fqhXb5j120Y47U4hgo+K+1XU+V52GvZH5Zbh8/VcfHXztcDkReQjjsYSL3oYCvdb3ObJ+gVifAzqfhss3WKWazj7qHL2A9I40uhnrFvStcrpM/Sxdy//bNODHNQTD3LkmyeXjC1fYwy4lliAW1wwWyRyZMUI6I7o6geBAZeaUm23GU9QEJKQVEzIHJRj7jjtvA98hoJw7VneMFmDrILPGo+cCAnu77lgu/W/lim8g0/BN+G6Y5yl68Bsppf8isqqv87ekyDbXwKo3Wyml/02Vhl2lAYcoqHkRQviVrrWXUvrfVeiyjDH+e33nsbiHVwKDKsb4nvoQRuIB/p3WnoYQTqqqepxl2cdqOPmsqqr/qmGlrxSa2Bt2V+JG7hohJ0tsE4A/1j021CH4DO26HxlpKnB7EC5f8W7WdKn7vG/lvCmlf9bvZajTsCayA3EONpvioRRzjjy/GYEJKlJzyLPJRw/WdwTLnsGTZC1Kgix1oHMr52nyhbsc7f2uUXwl2P7g9MvX6iTO9GAaMNak7pIDALoSF+Hq6KKVY/wb+N6FS/9Vzs1p1xAgmas58DXNEQhYIlRg5qABkDD3y0CiBdDgdxu4rhm4gIS+B+MWtsLlNJa/iBS0ysI3SCN1FMOf6vtfqhbA8tc2Fv2NGPGPDNSkMDd0nT8wq6RYtq+1G7r+3+laRwKJUuf4rbUOyyL3Qgi/kYK+iTH+LyL3rHbf3r77E5XH/rO8gNcxxv+oyrphVVVfCCB68g5uCNRKKf5P8FLUL9CVdlsEp70e+yspfFNeESf2bEj5rXT2sSz9ShkCy8M/DN+NELsJpbABLDa3r9T+PNXfW5BRI4CnLv08g+x77muC1t8A4rqqkespvAiW2JfwYEO4OtaucKF26TivClkzZsd8/U2AMSMYVBYCrMJfj/rybGNylrnliheyGqX1rxFnpxKJi+BCkORi/uh6n8euDyFhM7hBbDRquIKmGe7DNysFV0E1R8bAzmEDRs8hTGW4fFnGNsqJX+r/P1E4sAHXcIGhI3vh8sWnX8ui2zSaY5Q7F1L8cynxbwQwMXw3LedcLvqpVejZ3lVV9X9YajCE8GtNCDoQEDTknndjjBtKsXUFUP+z/rXy5SgLvhtjHOi8VhPx96oatHkJmaz0lu7l93omrwRqVvf+pf61F6xswSt4EkL4AO75I2RyGuHyjcyFwPgBFM7cdVPQ3XA5aPYAzy5H1yknXCXIaNNxXxnCBMrYEmXCNEYTl55jut1zapXzlDNX+s6KwKXzwLOa8IEVgZEAEJ0y19UEQKkC5QAAIABJREFU1J04uJvxa4saVGO5Y1ET21Q1ww/8VKKmO28Or6N0DH/X9RZkUPwq/PUI9IjzBlfFxT6EJvLD53qwKwmiZQ9+E76bYrOQJepqnb1a7B7cyT9qzaG+Y3nl/XD1TUR7UqqewOYBwoo3IqpsKu4nAplSxNt7mMJzoPM0lQX4me5trIKkPVnrnwpIvrXnKvLvQjUM/6zqwWUI4Zda+1wAs9L3cxFx/1kWei6uo9Be7Gvtx+gd+Sftw4X+tQk69nLXe2gw+1qAa8M9dyydGS6HetorsV+Hy7mRQ+zzETiFyrHmc5cJ4MxM5uzJuHN0Xo4wpOXKg1nc5lPvZPJXjsRr1GTlokuX++ahufNishzvoPNu/soxigwRShdnlDVrK/dv7mL46PKhvmmBBUNVjcfgiyPm4eorzts1sZQB0BzVXbnzZiYudIioImw7t+4Uoc4Q638vK3MLv/ksXE6BuYNqxH8UaNgoMhsnPtX1PTA+Qa64CbNZ04mE1whEm0b8p3D5kpP3BBKWwnopazoLIfxMlnckL+Ajxfs3tPaPUrZZCOHXUqqTqqoei7TbDJcDTH+vew4676FSb7/DO/zsTcjfgEj9zCyVSNL7yKK0ZNGNu3kAg/Gfw3cTkNuo+DxC1+YDKO5v9ds2aHOg67BxXyzxPgHXwOE1U2dJmYevrmmIy5GWq8JfT/fxMbsfvLtw4BBdZqKupia4LNzSpcTfhiDWDEQlTq76r640OLqUR1aDVMldcOXyntw87zHMXeVghrUrh3h1pKBH4+Ka3oJGTZll0zVFLVHUEZDi6aKSa+yKjO7iHF+Gy5HTQ7ihX0npPwQw/KssfNQ5zBL8QcUp98H6fhEu58Z9JADoStBt7PUQnoKRYD/V2l3VBJjLayDxQl7EwxDCL2Qpf6z8/hvtwQPF+3NZ3d9LiechhM+l3GdSrvso7BmHEP5F99wREL7SnvxF3MD9cPlevd/pPhpaazXttk8PID9foDrvBuT3H/XdmwgPX0FGN2EAvwXpGkB8r1wImOAxsEmObeu5y241nW6xzZf6svzvrX1pkxRXluV194jIPRMyWcUmQAhJpS5Nd5u1lY11z7f5OH94umxa3VUqNZJKKwghAaLETookM8k1Fvf5oHN5J07c55E9NjLDBBEe7s/d393OPfde8j4KyQaU4qWb7NUo0zYScH0sK1chltT8fiNCG1l2C/KTSvqpBURs8xgYe4haiVnw8GpBPhkUVIVSU+jA01jUhToUBcgaWxleryhm9Hy2x3jfYeM5T+AXS/0HlonGW5rZXyDEp3DudRz7nJSEj0P/dxzrjS9/tTQefI2UwaqZfYzr1/jce+PfR+HRJdzvebjcHQjuH3DsgrcJB7loEZ7Dl5ZGjv0Trvc2vI59WNNFeCRP8P1NKIlZrOlHAqZO4B438Ky/ADbgodBDHLeB5/E2eYE3oAiOEd/+kIg9b5Nx+Iqe8QxZ9p+x5tUAYC4lm7VBnpof+yuxRFkGnhNNXIHDxuLOWaUwXysReGbWRlm1vhjV1jZ9jgGoJmHhbkToSwEDGznxSLSVBbEOgxyN3JwFoYMCkeqJMNDSCO1xbBKKpXFjPbmfRkslJUNgkvHoEwGki7jXm0wuYfM6nfgFQLA5uO5eh/A9Pr9EAr9uqeHkSUvtwf8TMf0FS3MMfN6hC9ATCivewefetOShpZ4GHzgS3jTNZ0gdzuEc29jQm0jP/SPW/xaEzZ/9f8NzHwGg20PmoYZC+cLSKKxrWEcHVvYVrlXhvD/gvHdx7Fnc40M8v5NY9xox7j7Hc7tAvI1NouueIW/rBjyqM8RC3aGM0HHaV8+l6Mf3tO/duYApOG/jLfXdaC1Ifn9GBLCxuL2egvI66qsI6PGaoh8JZhByc6qyLK+jMKSkbruGfLBJF943jQbps4KObagjsPepr+hYb0rY4JpdOtYbGo6K9J9fcyRr0DV2ZX0V/bvBuXaRL5+hzsPetbiRY705ZEfOw2vx+3oOcos3cJxHsU2JYpeTqEariqJwl3aA1NkZrGsHFusq3PC5oijuYCM/gkBcwGZ5Bet5BQKxBm9jEYL0LgRjgBj+NgRyAd/dwqb50X4bW34a19kkdL4Hy/4TMge3kTk4AWEc4jvffP+Eda5CUflQ1gvE0nSc4gNcY8nMPoFgDyGgJyC0L6DgLhOx5ybu9QWu8xaBvb9AuB1ofUpkoFO4/4LO7cU8PEruIXkuJmm9SoyUG5E5EdrGJtvrPafCIz62Ds67I5mmgjJnWoV7IEqjssnGIGbxaHC/5qgqy/J6QALqBC56RAWuZbGFaJ9OACAqQNEP6MS18J2LltChCVw2C67HacQ9G5/qUkvutAItlnkJjGV0KMuwQC/Ay499hPQseQcdS51uZikX/Qgsv1Uone98xj2UyWpRFL/gd7fAj19Gtd3XUFYzUCZvodttXRTF5+gduILjv8Xn2+gQdKEoimf4/RdFUXxEA0P9vOtFUVxD9949KEBH/Q3EoR9xfW9VfhFKeB7X9G65V4ui2IHi+xz3dQbfzxZF8QDrcyrwPO75S/x9Cf9fKIpiEwrVuf7LOPY+nktD3XuHuP49KONF3OcOzrGF3yyRst/AZx0xcN4qf4aOZSNXkKHYoVbzJr8vYSD82NdI9/aw5wxZFU6t+37sCxXYMh66YgORZ1xWaOtU2GQLMI3fIxdCAb7I3RgFFYZ8/k4L4tmVcKMM0pNDQfK5OUkhaZt94VyrAuMMB/coaKQ4qpB88FPhjnvfg9eE2BsVCHkT0QUKXXwMNQN93+HYbVi4ZWIQ7iOu93DhJpTPz7D0yzjvHSjHUwDCzuBYg8fwB1rHbVjIFbjil8hjuA23vweLegcKr8A536O02+ew3j3czzPiTpxCXL6L636OYzpYnyvcB/j+HCnre/j9AVnwHkKqgrgX3pBzydL4cq+12CZ8qEvp4MomW80N6X12pPhmW1z6RjArre7rkhfQQKDHJmZBwHe96Qt5uQWIWl3ybhuZu8EerHrpDXnG7FkXVVmWV8Ut0Nbe3BW4H1CB9fhGmHu5ar/Iu4ji/Zzgl3Jd7UrEL64R1F9bI5kALqWwsEyyF47qvrI0zNTpxc4zd+qxU45vwW1dJhfugNKSXkQ0C1f8HMWXA3w3gPt5jXCN/4Dg9Ild+BIC8NLMPsSxSwAFZ7B5PyLA8TmE8yMI/1kz+yMxGv+HpXFWj4E1XMVx58zsz3gO95A58ClMz7EGB+jOU/bjMygqd/HXLY2MW4BScTzlc1zPJ+k6DuAU8DVLDWTu4Dlzm6wOPb9F8kC3qUisJL5HI3n4KpABzghws01ORW8K3lQH9F71vJXl16V0OZPb5iXej/Z/Qwq1E5GLKrRqrjOWfWSTcwA1/6kpvahp6GEQDlRB0UIUgtQZT4LjoFpekj94TcVUNt5yiUGYQphZBb2sktbGHIF5YufxCLIGwnCCgCYvYvG5f+eI9PKUwoEVCMo+HevU11VLLctukVV3BPohrv8K6T4Pr74g3oCDbz9gnc/N7J/JO/qUcIC/x9+/tzQ++19wrWWK4Udm9jus/S6OfQSFsoA13bDUhussBPxXXPchPAafr3gT3/8NivEcjtuHAjxDXP9nuO4T3KMr0j0iYA3wnH2WxJawQ7mWfpjJ2Zuk/BSUY+arfz4rYB8D1aMMZZcLdzriqfr/50mYtTfGUDzYGQHnx2TWMQALmHsaT+S6kyhvoAyEtpuhNnaCsKIr57Ug1RE9NPYu5oI0YiWex4F8zp8pTjG0yR6Bu5RGnCVX8jE2/THKO7+wNOlo1dLo8psEmDkF9iW+e4aN75r+vqVOMrP4bo/otlfpHL8SSr0M4fKN/i0Rdz7C9V5b6p583tKQzE/w2YaZ/XdLk41/wFrexrEu4MfJuyiIFLUMq+wg3V3cwwsKV5w56c+DyUiedz9LIN1dHOvh33ES+i381sPCp1ASXjPi053cys6LN1oFe8CC/W1S29LJZLNKMnSH4l1rD44qyLRpyp2VRNUSPhdSKKQkpYErgMImJwOra9zIgpsgl6lNQ8uWsEK9C1UShYQgUbFSLSFFEXgzldQLNDY+t6AICoIswBOMKrF6UhwytNQ09Bgd70JVUO54QOm7c+R2fkNewhp+1wdaP0cbegWf+aSji2Sxf8I9eghyHpvf4Bpfs9Sb0PPzPiD1PSiMA+TLr+Lvfw8hfEYhyu+onuITeBX7OMdrKAEnylyj93WDUp6nyTL+BKG/TDn6b7BOxy8W8ezuWOqT0CG8wLsGe6/GEbywY8TS9PZuHhJw/4gt8hpZGUT0+EMR9jLI0bM8VWSB28JOTu2pvCgdnsFuDVFHYrQ7Nl7N+4aFyyCgZZD8MkDymykkIKZG5qiNUaGRHjvIaONIoQwzCoU7pJQC9NUBI9AkHNDnodOL/Jglela3YRmXaN1bBAat0TU+h6CuElC0ZWlo5QXyjD6mvLcz/baJZvw2gY5/xebfgqLx9TkB5wKe2RV8tgOL/AHxFR5AyXg67wO45esAG9+HsJ1BePAA6yoh+Nt43zcIsFykdJxTti8ToepjrMkZeU7a8rZvb1G87UpzjjIye1C8C1Ac/k7ukXLmvn0blNLT+ZgW0M074iUOMlRdtuaN7Lcm4LiwsasCQ2nCMBwFdPVIXgqhAnOoXXEIoG60EmQi5l5tkz3+RpKvVAGqghSetdCG1ZXKKZ9opLk+6EMb75xaBu6XrncQACtcglmRi+Wb6RSdw/POM1R44kzB0xBO3xyPaDMfp3v+Ahv/Iq3/HinbK/T3f4ervELu9ANL03beh7CfRLzvWZHLWOcWhPkVUP8+hPcrEo4PoXx8TPozM7uOtZ8jYs9TKI+zhNY/gcKYgYX/Fd99TfforvIzQuW9GUqPBP8U7Yl1AstO0Lv8mjgCvld36B3O22Tfvq7s3QOLm3H0RAAtoOXyvmuCY6uAJVtlMK9CvAyL0tc22XSnCgxw5SDglcDS1xnXp84syCQFGAm4xvCd4DwR4aGfObaxuMFoJ9CqB5K9YPeoscnuqRqjKaZR2WSxkrLEvFPsIqWYnGo7D6Hwc34BQfGuxbtY109CZGmAnp/Hhj5uqQT2G5zzHbqvTyEMHSiJLXzuRTsXKHX2GWVv/gGYw1l4KD2Kv9cQf3tV4z9AuZzFOTxzcRLHruN+HiFEcBzgOzyvXSirS3hPuzi/ey1e5Thnqf3WWXpvD8izmCFh/QnXP0Pv/BnVcLDwOllnPkjdqeV0Rh97ggeSMfA9qqlCZdtWwXkLEewykLWh/LaScKAIZCBSEkPPAqjro23AGG1UIK4fWM6cRVfLXgcLbqakBovggeQ0oLVwDcpAoWgsxai/or8jemEVZSTcMszT5ji01ChknlBoxwjcC9ig83jc770P/gQrfY54A7vYZKcgzK/x3R8hbBdwXUfbn8PKvkshxv+BNZ2FFX+MZ+QZid/T+j8hsPP35Frewe+v4TmegOVdwb1eoXTYt7hXBziPIYTxpipvWyrc+RuBvXPwOjxb8TMUoIOte2RtZyH8brBYSXARmzPvFgM2Xlfiem3GoSGBsvQ6cqziTEWGI8BFbEUQVpQBlsYDcaLW/mrI3pzHQ4BhEAvXAnKUGWGrhF1UtcTwyucvA4seued1gIIWmYxEVDhRiOuj17MpYGOT0aqek5618QGqfg4HzfzFbxAC3aMN2cd3a5Se8iYWD2GlmfP+DELmffOdNPMtBOgS1uH1Aj7g9AL+XcBaf2ip1t5j+B4UyocQsnI0Gn1WluVlCNFFeDNPLbW3+jts8DnwEs5CuN0V37HURPVtS12WbhAWsYo1elx+SIrJ+xV6RmKBXPpd/PHjfGT8LPH6j5FQDOjd9khJaM6e+SLqikckoDrIplmQ3fL9HM3jZIDZAgNXtmAPyqytAiqwhvd9VwBlIDA5em+VKVoogsVVQVxeZzIHFrj/wynHMrVxKFhAHaRhNCd71OxFNAlpIAxEnnzEIU/H0nyBGTp/nzwGxwi8W22PNtgi8bvvW+oo5LGwW1mPib3I5Ra8gEVYzlv4zSNY6nM4dtdSpd4yBPRbS511/tFHg+HP97jWEsKNH/B3J/a8ZWk60y8kbBfw2RxCk/NQEF2KvytSBmap2cdJEgymdO9YKshiDKZPSsb/c6+rI4Qet9azInClgHicLWJGH2NQbEReB0oid94DYQ+yQikzhCE1crWEpxYQ91TGq6osy2tCYsgJRTEFKCxEGzWiDAqx/FHFU470Uwe8hDq4ZqQ0uGxySJuosbi6KgcK1nIPFbmSfXIb3bWcsfF+b54GekVsQGcBzuPzijIHnppawsbz2HWWqK9vxl2Rx/AAQuyI903cl6PiK3CtC7juH1rqfvwNva9LUBL3cexNgIIOsn1vqSbiMq75hHL/l3GtNSgdH8h5Al7EgFJ1pyxNZ/IGrM/Jw/ENvkkcCn/+XXhFczY+eJPJPz0idGnn6YiLUk1JVVtgwdV7nBE8oWeTlXq78nnEW1FvV7tsVdZS7Rd4HGOp9aosy3cyZJ1CYt4qEOYoO9BkEPgmUALqnreVP7Zd0wKlZJINKAUsyaX5NKyoA74Dr5uHM+6TV8DsMKedLhBrz5uKuLJcoOfwBIJT2vhU5H1L9fMuBLcsVQq6YulBgPoQZPcuvoY1fQEvwC31fWwaJ/YswD2fwVo+Ik/He++fwRrPIkNwHArlA0vTcu6QIK7ieB+r/rWlisYOvAUHVH12wgHu52dcb5YULAN0C4RTbeC3HVHOg4BoNgiyQkVgcMziOpgiQ1jLkdtqSWHPtHgMWodQBkqikzHWrCQOJKwY0b7sMhXYLD9RRNt6Rej8KAMKajeTtjRdE6Q46ozHoB2Mohi+yOAPZQsoWJLGVPxjT/LDPKK5sfGW5DsEmHGb8W38nluIeZy+TTn4ASye4TvnsfukY88QHCMswuPwLSgF7xL0Vwj3An7bh8vt/RE+pI3yCZTAIT73VOYO1vN7ClH+hDVsWird3cKf10Q8WqZU5ivKEDhzcg/exgx5MSuWmpycwPtftzQjwPeNz99zz8GrMzcIPPT04CF5Xdzn8TDI2bPX2JE9VmX2mZLpuhnSHBexcQs7Bpg7tMdGFtfi1DbZDlyVTy8gDLmRMKUCl5k8vC6Yb069gk6Qy2yL93MMRD2vuued4BwKlqiimoZpjCRFo0qiK8BKZZMjmrmhhANCe+SyLVKo4Ei794n3ibUOVh0nK/ETucM9WERm3TlZZ9FSqfFL/N+Btm0I3EUI/EWKve8iLj9FSuI2/u25fx+y+h0s/ymy4N6o1HsT+r1/CuH2+1yyVB24Z+N05y+J2NPFb/bw5wD370r1GYGoTO/1ZqTLZLC2xCvr2njfy24m1V0GxqkTUIP7QSZA91Qu1R1xAHQMn7UYyo7ISxSa1DZJMS6NagGKgGFnLQtmkKINbawyD6GYArwVGSQ/d15GX9tSjjn3rg5Az2IK8FnJb3YojvXf/0q55S4BWI8gCGzJnpK18uajTGf1kGCOYu3XlC83uOI+Ydhbbz3Ge/EGG+4y36J1eqWesxVvA0AcIoT4G+XoT8KbGODYby31NfQCn8ZS16OrtEHv4vcjSyOzKuAJxy01US0h4D6JZ4G8q3uU0iuJ2OP7YYGs3jP6N7fwdvxHC706AY/FLB7PFbWpi7AqLpIrMgDzyGKafCQDOhqcW4mxl36UeoE3IGCEwg8ylN0oQ6CMwCJIIyogooChuviRgLfRlHOWPgIbG4tHnEdlyG1EJ8YHegEBZJ42iFsn70Dr57lpqU+du3f7RE5Zo/V/QbGwj7j2DrtOpjFy+33qjRfiDAD0LcL6u5L43lLBjbfmXoKS8LHn3gfgF5zzPuL9Ls59B+/Aq//OwT0fwmO4aom/v2XjA2PeIk/qa7rHDinNdcrvGxF45ikedqv3iEhY/n7XCSRkfvwrGx/IySGBWmgXto4IeNmCKVVB2DkKzp9LgefYsi7k3WAtJqSkvngLb0LqqizL92TBo8D1GQZIfo7KWE9REt1AO2pfwIisk2MVRrxqyyifnJKI0p+5uge9RyZbaAlmI3nZHr38R/AATpEycQbgDHkHRvHzWbrmr9i8i/jO7/WPsMgnLNGK18mivotrzJnZvxEC723DtmCpa+T3DYJ7A8f1LXX1LS3NALiG8x+zVNzzGOc9J/G+sw+XiBtxB8roDBFnRvS8FknZeuOOBRsvlnEFy89uncDXQvCcjqQKefpUZAy7QTqunJKz5/MqUK01NCzEw4xCsUBh5JruNAE3Z4xkxA1BSgESzPK9zuvATR8FFjz3eRNYU8ucdxgQI6KH13ZsxEvINSgZBO59nfEY+gLSdFo2k444W6ZjXxIXgM/nfQLeouf2wNJo62OWRk1/Cg/gCj1XZ+M59djX8DHCgUuW6hNuUaz4d7DOK1AoZ2F5zxEouIXn7S3lnAR0moTQ+xdsUuZgCd//QLyFRfx9QKHGEj0/B/jWKWXJz7mSuJeJPQuyDwqJ+3UwDO+lOnDFXxGfwAKjFVWOdsVrjBqBviT2KHsTe0HeX/ddGWTwLGPQxgylZwEiYdU0YI7nH40zyllrFdpoBFlOkyoppzPlWM3ZWwseYcGxkcBbQK9UkJTztV7Uwi4gNzDxzTRPx/Ik5EW6lzuE+lfYMAYlcRJAn6PC/4l/nyHB8fkCF6EkfFLNn2Cl3W13oO9rnOO6JUr0DRLAK5Zaq38Ggb9maWil04N3bLzs+balQiVXHBv4/iWUhiPiz8Ryz9t44dW8jTf16JDQzdKz0wYxundnMnuJ9/tBi8eg+2bPJqf+DgO2KF9vPsDSTABKV1S67wqbLPoZCCYW9el4kwXoTxGgaUh+KWkzRc+1cKcO3PA276LJcAEioC/Xo2B0BJZfTkm08R0i7IKvzR2EvCON/2aWXiJnE3gw6TbFvr45nD04D0HyZqQ+i8BLiB/j2A5Z8Kf49ycA+rxs+RHWt43w4X2EGRWO9dbePovALfuapaGlXrNwwVId/pAAuVlL3Xy8NPm0paGds7TRmSpdkRfgAjNL7DxWuD2ykC4ws5IKi8bYawv4xibb3mu2SbkzEe13R1KOjRCSovoaJRcx6zRSPlGquhJ8rAoA94F2BdY8PC94mHHxixbhqOS4JiD25IC+JhN/W5AyNNqARQbTKAPaZJlRPmUmfxuhsRFbUdfQt/FxznXAQCyI9NOz8VZPJTHhmPr6AhbyNT5foc31kCz7PNDzZYQQFyHIB7C6D+Hme0ut7yy14n4fn3UIS1iCMjhPac9PLQ3zmIF3s0F5++OkAL+EklgjQ9GneHWO3sWGpYrKKIxkBctdpLUnBE/IYY9t3yYHzY5sska/zCgJ3jOdINTryXm5dbhOz1ZD1gQhSKQkzOLeFso01F4Fb7IAFmx0zuUr717LhKO8f5MBLLQLStmS7svRcMvg/J3ghWgIotdsK1bSIpCINszPg1NKmm7hCa61ZAycMBR1Ifac/yGdvwuh7dn4QFNn3Pm0W+92c4+4BwvkljdI712jWPkrsrIuoE8tzQF4B+c6hmOXLPU3PA8BP4SSuQDB93Fji1AexwlL2IMSW7NUNOVj3F8SeOdg6lDy+UMinzEzjrvvjDLWUEPJqNxbDUM3gytFNPaINlzZ+NDOCDRWTr/WC1TBsVEvS/YYRpLif+OVcy1AkUl3lZYvrNEYuWyxkDkBikhAOUUQ4RRtvQSUcVgKizAHCmpLtFxKkPOsjQBBhaRDhzbeFJJBQt8wA1Igc3TeHbKKzuv3eH8TQnWAF+6puHUcu0aWyQdobFpqTT4H4Z6FV+A1B3ctNdt8l9hqNylNeAJC/hjf/QRw8bilcd8uwIsEWjoJ6hR5LU8p7z9L4KS3WztGz+5QhLtL73Vg43X1apxyAsRGIKKm1xb3j8jNwuSwohTLy1a8kfR4KYbyIAgr1BNRhRIVvlWyZ/cNVOD3MmkwC/KKZQtHIHfsMBDYWqiNbfhCrhfaUKxw2ZLfZw1vFnf+iWoLzCb7r0XMrGEA7uwR4McNRTctNaQoxAVUJeE01zmyVlvkBbilb4gZ5xtslWLpu5ZaaXmZ7KylLsWXSCl+DSF2kpGz8Lyf/lVSBt7ObMfSQM4SimaIa3oM/jOE2EefHcd5HuM3y+TV+DPaw2+XiKfAz46nRe8Lkr8rgsPtvvvihfXFc2WsaiSA81CsfhWEGSN5542kujuBUe1lwvCuTXan6kl+nydtRziFH8tyFVKBlfBQZph7nSl5/zp4QIW4xrkH0UZqYCt9lJSeZTISUbyfCwks0OSFxUVTFmjsipD9mvLnnPrpkIs5sjSSap6O9ZSgexhLBAiapanCXvK7AiF2rsEhrud1Aj5G/AnW9CME3i3tHuL403guly315fsGbMBVS5N8N8lLOUd8hi+hCBZIAbn7PyCSUUlKoqRjvbd9Y6mvYUN7tBEkf5/+XYpnxvMhmoziHmYAs4idp30vywAfa1pYhDlmIFc05qjAtfAVdP4mtwlvbLzC8E3GyhWACtC0QYW5z3M856i7T1szxdLaS3+LKSwpa8ER2pRElQlBui3sRP1crQVnSkpBhuclzVSSEPtadGadI+J+Pa4t8LZgiwS+bUBw++TidyGYq3gP3g58Axb6pSV67wJSd+59rELAvVjpBWUdlkmpPaBjHf/YoPBljphs9y01LSnIO/T3xlVy3IyDM1AjsoKlpM3UA+1bvna+DPZNYzEd3AJAWw2NgtGdAOTWfpfa+acRWWgblKMKiu9pVzgJldYCtJF1GExQbbcnCLzeYJkBRMzay3kHAVMqp3z2Je/aVnzRtKTtihaOgGXYVrruqGGkl2Zqfphz1Jya8jbVK3S9JyTwju4OLNGJz9Im+B6/9aKaBTx7b8Zxlth43sRzC/G+u9J/oRTkMXgZj3DNB+AIeAx/E9dw6+sknxppw1XyaDzF6RvyOO2rFxTKMMD1CudybCd7AAAL3UlEQVSdkXfOvfhK+rwjxw7o2TJGo114OFTUkHhXUnoFyUTkCXYzBLsotV5mPNWRxQVIkaEcZnCKQ5ssZqsdBLw+BXhTbnx5RAupVjaiTtZTlE81xZXnB93JHFscwXpbyxqa4NjG2huZ9CQ1aPSctAfCrJxnJJ+z+79k441OvcfAaVqPd8xds/FKsR8hrO+Qkvg3eAVLdPwhKY/rluoObhCI53n+Gp7EvKXagjlkFxbhTZwkQpMXR1WkKHxfbAtzT9lus/TuOXXHQqojsk1SbEUA9EVknTID5vVk31XB8bkWYDmAuQwMZARcK4mutPHmvZqSLm1yaI9iGMZU4KO40VH+v81jMJvsZGItnIJptQUWfN45wnqj2gLtHXhUpqC1cBj0RVYB8Bm1dDoI2GdscZbE2yoIHPR7/gYI/xl6Pi/wrJcgiH7svwLMO29pRPYveE6LBPSVZva/EQ4sWuLwvyBA7h1C3T+GcvDwxnGKV/j+mE32QNgn5p7z+U3y+5zuy02EUjbeDgGGfOwoMC4HFvP6o/Rf1Ai0sMmZAWapzkELfTaF0cehjYYrB4FS89BGsYfDYJ9ranAMc2AqcM7aKeBlUwS0yVhrLioqgxjZLN9v0DJAyTTmXq7hSK6dWY43kKtvKKcAkW3NT4rAOmmfumgaLbe2KimuPkUb3PvoLWMDvsZ5v4KAXiH39yYEc9VSn/7Kfhv4+TYE3GfL/0gMxLfI+3L23yXych6SUK3Q87qD6yzQ89in+16gZ86t1dj75Bp8Bpg7JOA92i/cLp7z8FG//wNR3EoC6mSwgE6Qs58TxVGR8vZ1v5bQxveXZo9YUc1kPNauZKF6krqvNYz3ECDXtCBKDeaqkpqW3HwkiJZJAUbuTGPxqLDI62haFFUbvdeCNGKZueeyxesopijLKmCxabOJjuZrycoOhPU1TxvcZxGcJKXhG3UBcf8ufvsZLP0J/OYRrrmB464QYegvltp3LSPl6JWAq1ASvmm/g2fhyqdPMfw8ra221N2IuRMlpS9n6Hn3JSVWZdxoFvChjRfoKHg3jd7LgFw38Bgq2VuDwForMUjb681kzsvZhVyD0QhEPwzSn0Mxsv4MtrUrcBtgNq0RqE2xnEVL+GAB6HKU2YNttOGjpgZtSuagCZDVKONRH+F5VBkvpq24illezDhk6qvHzz2ybE4PdjfYPYXHEOTTOPYFjl2xRNl9aKnN+GVLcwkfW5onuIrPvc7+BjyGs1jbS0pBudfg4Nq6pYYovmm5vp2n6nrL746854hJOhChLlpCBBXEMgMAVoHH0BXUvwk8FAUM6wDf0jqErnjGjH804hV1RPnkvJlOkN16c14FAadZtiYj0AMb729WthzbBKm9KARpawRatlj24f8DppFTEkdpX14Hz07ZYVHIkxvBru2gNHXaIcHXTVDB9ePmIi/x76Gl4iMvNnoGV9476vrI8V0IuKfsdiC0ns8/BqBwDUrhtKVpPV4D4L+ftdS19wWBme6mDmlDd8gF74u7eyheI6fWFFcZZTI2uVl7EQs0OrZLOXhNsQ0oK8O8BK094etE7cB5DezFqMcwkBRzlxTVXqBQTNbxBgN4d4qwtYF/UVybQzxH/x8Fs2ghXEyLy83ah4LUNr0LcXNEVLcIWGLFFNJRTeGAMi9LiW/7OK+Wks4QvjBH59izNFDUx2UvILZfhPX3uHEbx65batg5Z2mkubc/WyCM4RlASE9VejbAc/lLtJZNS/MNHI/okKvPA1YGFne2ZWIPp+Si+RBRyXgEBBcZdN6CFF6RCUEaScvpbMqBEJIifKyNwswzMBj/2BXgk5uGah3Cvpl1S4tHelngtlgmNWiZz9T1icYu10F+PwdATluDgoIRPtF2jxaAlk3mHpuAP2BBRsKCVOlQABt+Tvqy9wgR59SP99SfJffQh2N6vt8be/ZhlVcIkd4kwfKx3v7v72Hh3TINcI7HEPT3CMj6mVz7GVh973Z0AK+gstQstCFBdyzglXgni2Q1D8SaDiQkq2Sjc/y9J57ZjI133eWuzn163yaeVT8AhqN33lhcG2N0/h69+754hS60+2JgeqLEClKarPAaKGxWKCWFIbuyr+fdA7geuNVRMUTkvuaOzaH1UV89y+Qrcx5D3eIV5FKRudChaPEEpvVHzJ1jGnOSv3stiG4lqZ9uQLZqbLwAyQky3Iz0FVl+T8l5J13vIVBD0B/js5+B5DNHv6Z/n6HY/SsAiI7Y75ELOgSw6MLxzFIL9JKEdBfnnaNn8iutlS37vgCF/Dy1QG1kk51+h+IxRL3yCkkT5mZJVIGlr6cQe6qWDJKShJjbsCeZIK09iTyRqHEun3csrFAqcFszjjIjzFVGqIopoOC0eL9swQbahG0awNeGS+QAuSogakxTbm3kpVrSQeqJREVFiur62ri2wAlDs/Ru+vYbw8+be/q6b5EV5kGkT7CWC5Sfvw1lsWVpmGkf1+vjPG5lN7CGJxD8hWAPcEk0K5C5jPfXDVJh2rVqGOzTXEhW2+Qk39x5DwPlo3x+9WAjmVAXnz1jNWAK6NUiH5WQlHoZ46ThipKJOkehArdhAdMEPNJ2B2LZ2vL+uTx8bXmKcXGE8x6VClxae3ekaThFbt3FFKUZIcNODKpssuT4LtzvJfr9OiHW87SZfLz4miXG4UNLPfDOEcHoT5YGinjDz3VLbcPOEf7gswJG2JDLpKj6JNzuynYtUXa7AYFKPTdNsbFLrBt9i0IKE+HMMVRzHa2jPLweq63imcSlXkA0laoO0pMmAq+EslzfgejZ+QBbzYKUR6ECt6XNck09LBDQiBFo1j7SqzwCKBhRjHPKZ5pCaeslYEcAENsmxUwLFSxwYXXdPYvHUK/SZ88JnGPg6L6lLj6+7m8sdQ9eIcLPX/E5D/i4AwVTW2pj7nl/HxHmIcdzeAMDS8VHZqmPH5evDm18FHvZQubS51xlANzZzB4thDikOXttCGuWZ/mxx8G/8bAumjKs3Jc9m6Qza0//qP5l2mDcQSZzwOctzazhuQC5WXvWQgIqp2QJpllrO4JQ5PCESKFou+5piuoo1rstO5KjAkd8inoKealNaWrJqIJY3PhyUUDFA3x+nKyHNw09TaQjr+zzUeS+/n+FF7BM4ca+pRl/50g4fXLwDKH2NVmgOcEp5m1yws1u4NLqeLiyJYzMTYlSy8kKRQW8Ea+jCrCYSo49DIg9vF7OEuxJ+o8r9RpRWDs22eNvKNeuyCCwd8gDbAcWdK2KNpe1IPw57rxaU0ZUIzdMqblNgKKPghfr2i1CXy0jKFFMFgnbIBD4uiXksQArsUy8bxmQVO9xKC9Y+eoFWWT3FJztd4zWsUkWdgGbs4TQNmb2B4o1f8FnawD2trHmP+M3/5M8g3uW5g1eJxT6zzjf72gNrwlkW6F79m7Gx228MMoZjgsS8mhDDc7Da36fn11X0mZcCTiQY2cCS60eiqP28/TueNjnjBB7NJvAbd7mbXwoqGdv1EMxS6XdRu9V60YOLJVYF5JBMkk5DihrUxRVVf2vwK0diYZsCwWaAPlXkk6u2cdRwLpp3XurKa68EiwsiLssUGKlbL5cOHDU8/Kx/9Xnqp5PRz6vKdWzYJMlqQckWP7sH1qaJ+jFOSfx/4sU2/btt9Lf92jj+dDOe5QW9PTkY/utJsD3j7cq89He7E2ObJwOzQNme/IshpIS4xBwRp6HPyN9jyMbb/ZhAviqi98lXoKJd8Hrjo7l9fXovTsfZJ/A2iZyz+m8O/ReG8vT40s61gJDpkZvu8wgh1VgrepM/rxoya2XGSGoWrgGbS56nVlnlHphj0Hd8zrjguu6h5kMgcaAZpPzEExebGExLdRkE9QZhRd5SUPhN8ySe8cu35ylUdveqddddx/y4TX458hK38dmeh/neoQN5oDSdSidEdKIXUuDSTbJqrvF93vfEgDrkKyT2Tgzrm+TLDwLrLeR1awCIdR9Pch4c0MBgLt0zb54F4fC9+jS+faFf7Bn4+Pk5mgvHth4Z6K+jXfzYW7Evo03GB2Q19FICMj3zQbdORIr/xeYr0jEb5FX2QAAAABJRU5ErkJggg=='); }
diff --git a/SVUI_!Core/guide/_template/ldoc.css b/SVUI_!Core/guide/_template/ldoc.css
new file mode 100644
index 0000000..2a8d337
--- /dev/null
+++ b/SVUI_!Core/guide/_template/ldoc.css
@@ -0,0 +1,9 @@
+@charset "UTF-8";body,html{width:100%}hr,main{display:block}.button,.checkbox,audio,canvas,img,svg,table td,video{vertical-align:middle}body,fieldset{margin:0}fieldset,hr{border:0;padding:0}blockquote,h1{line-height:1.35}.button,.fab,.icon,.ripple{overflow:hidden}.badge,.typography--text-nowrap{white-space:nowrap}.bigfoot-link-list a,.button,.layout-tab,.link-list a,.menu-item,.navigation-link,.tabs__tab,a{text-decoration:none}.card-section>.section-dialog>ul>li,.link-list,.menu{list-style:none}table,table.function_list,table.module_list{border-collapse:collapse}html{color:rgba(0,0,0,.87);height:100%;-ms-touch-action:manipulation;touch-action:manipulation}body{min-height:100%}hr{height:1px;border-top:1px solid #ccc;margin:1em 0}.fab,.fab .button-ripple,.icon,.icon .button-ripple,.ripple{border-radius:50%}textarea{resize:vertical}.browsehappy{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.accordion,.button,.card,.checkbox,.dropdown-menu,.icon,.item,.radio,.slider,.switch,.tabs__tab,a{-webkit-tap-highlight-color:transparent;-webkit-tap-highlight-color:rgba(255,255,255,0)}[hidden]{display:none!important}::-moz-selection{background:#b3d4fc;text-shadow:none}::selection{background:#b3d4fc;text-shadow:none}body,html{font-family:Helvetica,Arial,sans-serif;font-size:14px;font-weight:400;line-height:20px}h1,h2,h3,h4,h5,h6,p{margin:0;padding:0}h1,h2,h3,h4,h5,h6{margin-top:24px}h4,h5,h6,p{margin-bottom:16px}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-family:Roboto,Helvetica,Arial,sans-serif;font-weight:400;line-height:1.35;letter-spacing:-.02em;opacity:.54;font-size:.6em}blockquote,h4{font-family:Roboto,Helvetica,Arial,sans-serif;font-size:24px}ol,p,ul{font-size:14px}address,ol,p,ul{letter-spacing:0}address,h5{line-height:1}h6,ol,p,ul{font-weight:400;line-height:24px}a,h5{font-weight:500}h1{font-family:Roboto,Helvetica,Arial,sans-serif;font-size:56px;font-weight:400;letter-spacing:-.02em;margin-bottom:24px}h2{font-family:Roboto,Helvetica,Arial,sans-serif;font-size:45px;font-weight:400;line-height:48px;margin-bottom:24px}h3{font-family:Roboto,Helvetica,Arial,sans-serif;font-size:34px;font-weight:400;line-height:40px;margin-bottom:24px}h4{font-weight:400;line-height:32px;-moz-osx-font-smoothing:grayscale}h5{font-family:Roboto,Helvetica,Arial,sans-serif;font-size:20px;letter-spacing:.02em}h6{font-family:Roboto,Helvetica,Arial,sans-serif;font-size:16px;letter-spacing:.04em}p.preface{border-bottom:1px solid rgba(0,0,0,.12)}p.preface:last-child{margin-bottom:0}a{color:#ff4081}blockquote{position:relative;font-weight:300;font-style:italic;letter-spacing:.08em}blockquote:before{position:absolute;left:-.5em;content:'“'}blockquote:after{content:'”';margin-left:-.05em}mark{background-color:#f4ff81}dt{font-weight:700}address{font-size:12px;font-weight:400;font-style:normal}.typography--display-4,.typography--display-4-color-contrast{font-family:Roboto,Helvetica,Arial,sans-serif;font-size:112px;font-weight:300;line-height:1;letter-spacing:-.04em}.typography--display-4-color-contrast{opacity:.54}.typography--display-3,.typography--display-3-color-contrast{font-size:56px;font-weight:400;line-height:1.35;letter-spacing:-.02em}.typography--display-3{font-family:Roboto,Helvetica,Arial,sans-serif}.typography--display-3-color-contrast{font-family:Roboto,Helvetica,Arial,sans-serif;opacity:.54}.typography--display-2,.typography--display-2-color-contrast{font-family:Roboto,Helvetica,Arial,sans-serif;font-weight:400;font-size:45px;line-height:48px}.typography--display-2-color-contrast{opacity:.54}.typography--display-1{font-family:Roboto,Helvetica,Arial,sans-serif;font-size:34px;font-weight:400;line-height:40px}.typography--display-1-color-contrast{font-family:Roboto,Helvetica,Arial,sans-serif;font-size:34px;font-weight:400;line-height:40px;opacity:.54}.typography--headline,.typography--headline-color-contrast{font-family:Roboto,Helvetica,Arial,sans-serif;font-weight:400;line-height:32px;-moz-osx-font-smoothing:grayscale}.typography--headline{font-size:24px}.typography--headline-color-contrast{font-size:24px;opacity:.87}.typography--title,.typography--title-color-contrast{font-size:20px;font-weight:500;line-height:1;letter-spacing:.02em}.typography--title{font-family:Roboto,Helvetica,Arial,sans-serif}.typography--title-color-contrast{font-family:Roboto,Helvetica,Arial,sans-serif;opacity:.87}.typography--subhead,.typography--subhead-color-contrast{font-family:Roboto,Helvetica,Arial,sans-serif;line-height:24px;font-size:16px;font-weight:400;letter-spacing:.04em}.typography--subhead-color-contrast{opacity:.87}.typography--body-2{font-size:14px;font-weight:700;line-height:24px;letter-spacing:0}.typography--body-2-color-contrast{font-size:14px;font-weight:700;line-height:24px;letter-spacing:0;opacity:.87}.typography--body-1,.typography--body-1-color-contrast{line-height:24px;letter-spacing:0;font-size:14px;font-weight:400}.typography--body-1-color-contrast{opacity:.87}.typography--body-2-force-preferred-font{font-family:Roboto,Helvetica,Arial,sans-serif;font-size:14px;font-weight:500;line-height:24px;letter-spacing:0}.typography--body-2-force-preferred-font-color-contrast{font-family:Roboto,Helvetica,Arial,sans-serif;font-size:14px;font-weight:500;line-height:24px;letter-spacing:0;opacity:.87}.typography--body-1-force-preferred-font,.typography--body-1-force-preferred-font-color-contrast{font-family:Roboto,Helvetica,Arial,sans-serif;font-size:14px;font-weight:400;line-height:24px;letter-spacing:0}.typography--body-1-force-preferred-font-color-contrast{opacity:.87}.typography--caption,.typography--caption-color-contrast,.typography--caption-force-preferred-font,.typography--caption-force-preferred-font-color-contrast{font-size:12px;font-weight:400;line-height:1;letter-spacing:0}.typography--caption-force-preferred-font{font-family:Roboto,Helvetica,Arial,sans-serif}.typography--caption-color-contrast{opacity:.54}.typography--caption-force-preferred-font-color-contrast{font-family:Roboto,Helvetica,Arial,sans-serif;opacity:.54}.typography--button,.typography--button-color-contrast,.typography--menu,.typography--menu-color-contrast{letter-spacing:0;font-family:Roboto,Helvetica,Arial,sans-serif;font-size:14px;font-weight:500;line-height:1}.typography--menu-color-contrast{opacity:.87}.typography--button{text-transform:uppercase}.typography--button-color-contrast{text-transform:uppercase;opacity:.87}.typography--text-left{text-align:left}.typography--text-right{text-align:right}.typography--text-center{text-align:center}.typography--text-justify{text-align:justify}.typography--text-lowercase{text-transform:lowercase}.button,.layout-tab,.tabs__tab,.typography--text-uppercase{text-transform:uppercase}.typography--text-capitalize{text-transform:capitalize}.typography--font-thin{font-weight:200!important}.typography--font-light{font-weight:300!important}.typography--font-regular{font-weight:400!important}.typography--font-medium{font-weight:500!important}.typography--font-bold{font-weight:700!important}.typography--font-black{font-weight:900!important}.color-text--red{color:#f44336!important}.color--red{background-color:#f44336!important}.color-text--red-50{color:#ffebee!important}.color--red-50{background-color:#ffebee!important}.color-text--red-100{color:#ffcdd2!important}.color--red-100{background-color:#ffcdd2!important}.color-text--red-200{color:#ef9a9a!important}.color--red-200{background-color:#ef9a9a!important}.color-text--red-300{color:#e57373!important}.color--red-300{background-color:#e57373!important}.color-text--red-400{color:#ef5350!important}.color--red-400{background-color:#ef5350!important}.color-text--red-500{color:#f44336!important}.color--red-500{background-color:#f44336!important}.color-text--red-600{color:#e53935!important}.color--red-600{background-color:#e53935!important}.color-text--red-700{color:#d32f2f!important}.color--red-700{background-color:#d32f2f!important}.color-text--red-800{color:#c62828!important}.color--red-800{background-color:#c62828!important}.color-text--red-900{color:#b71c1c!important}.color--red-900{background-color:#b71c1c!important}.color-text--red-A100{color:#ff8a80!important}.color--red-A100{background-color:#ff8a80!important}.color-text--red-A200{color:#ff5252!important}.color--red-A200{background-color:#ff5252!important}.color-text--red-A400{color:#ff1744!important}.color--red-A400{background-color:#ff1744!important}.color-text--red-A700{color:#d50000!important}.color--red-A700{background-color:#d50000!important}.color-text--pink{color:#e91e63!important}.color--pink{background-color:#e91e63!important}.color-text--pink-50{color:#fce4ec!important}.color--pink-50{background-color:#fce4ec!important}.color-text--pink-100{color:#f8bbd0!important}.color--pink-100{background-color:#f8bbd0!important}.color-text--pink-200{color:#f48fb1!important}.color--pink-200{background-color:#f48fb1!important}.color-text--pink-300{color:#f06292!important}.color--pink-300{background-color:#f06292!important}.color-text--pink-400{color:#ec407a!important}.color--pink-400{background-color:#ec407a!important}.color-text--pink-500{color:#e91e63!important}.color--pink-500{background-color:#e91e63!important}.color-text--pink-600{color:#d81b60!important}.color--pink-600{background-color:#d81b60!important}.color-text--pink-700{color:#c2185b!important}.color--pink-700{background-color:#c2185b!important}.color-text--pink-800{color:#ad1457!important}.color--pink-800{background-color:#ad1457!important}.color-text--pink-900{color:#880e4f!important}.color--pink-900{background-color:#880e4f!important}.color-text--pink-A100{color:#ff80ab!important}.color--pink-A100{background-color:#ff80ab!important}.color-text--pink-A200{color:#ff4081!important}.color--pink-A200{background-color:#ff4081!important}.color-text--pink-A400{color:#f50057!important}.color--pink-A400{background-color:#f50057!important}.color-text--pink-A700{color:#c51162!important}.color--pink-A700{background-color:#c51162!important}.color-text--purple{color:#9c27b0!important}.color--purple{background-color:#9c27b0!important}.color-text--purple-50{color:#f3e5f5!important}.color--purple-50{background-color:#f3e5f5!important}.color-text--purple-100{color:#e1bee7!important}.color--purple-100{background-color:#e1bee7!important}.color-text--purple-200{color:#ce93d8!important}.color--purple-200{background-color:#ce93d8!important}.color-text--purple-300{color:#ba68c8!important}.color--purple-300{background-color:#ba68c8!important}.color-text--purple-400{color:#ab47bc!important}.color--purple-400{background-color:#ab47bc!important}.color-text--purple-500{color:#9c27b0!important}.color--purple-500{background-color:#9c27b0!important}.color-text--purple-600{color:#8e24aa!important}.color--purple-600{background-color:#8e24aa!important}.color-text--purple-700{color:#7b1fa2!important}.color--purple-700{background-color:#7b1fa2!important}.color-text--purple-800{color:#6a1b9a!important}.color--purple-800{background-color:#6a1b9a!important}.color-text--purple-900{color:#4a148c!important}.color--purple-900{background-color:#4a148c!important}.color-text--purple-A100{color:#ea80fc!important}.color--purple-A100{background-color:#ea80fc!important}.color-text--purple-A200{color:#e040fb!important}.color--purple-A200{background-color:#e040fb!important}.color-text--purple-A400{color:#d500f9!important}.color--purple-A400{background-color:#d500f9!important}.color-text--purple-A700{color:#a0f!important}.color--purple-A700{background-color:#a0f!important}.color-text--deep-purple{color:#673ab7!important}.color--deep-purple{background-color:#673ab7!important}.color-text--deep-purple-50{color:#ede7f6!important}.color--deep-purple-50{background-color:#ede7f6!important}.color-text--deep-purple-100{color:#d1c4e9!important}.color--deep-purple-100{background-color:#d1c4e9!important}.color-text--deep-purple-200{color:#b39ddb!important}.color--deep-purple-200{background-color:#b39ddb!important}.color-text--deep-purple-300{color:#9575cd!important}.color--deep-purple-300{background-color:#9575cd!important}.color-text--deep-purple-400{color:#7e57c2!important}.color--deep-purple-400{background-color:#7e57c2!important}.color-text--deep-purple-500{color:#673ab7!important}.color--deep-purple-500{background-color:#673ab7!important}.color-text--deep-purple-600{color:#5e35b1!important}.color--deep-purple-600{background-color:#5e35b1!important}.color-text--deep-purple-700{color:#512da8!important}.color--deep-purple-700{background-color:#512da8!important}.color-text--deep-purple-800{color:#4527a0!important}.color--deep-purple-800{background-color:#4527a0!important}.color-text--deep-purple-900{color:#311b92!important}.color--deep-purple-900{background-color:#311b92!important}.color-text--deep-purple-A100{color:#b388ff!important}.color--deep-purple-A100{background-color:#b388ff!important}.color-text--deep-purple-A200{color:#7c4dff!important}.color--deep-purple-A200{background-color:#7c4dff!important}.color-text--deep-purple-A400{color:#651fff!important}.color--deep-purple-A400{background-color:#651fff!important}.color-text--deep-purple-A700{color:#6200ea!important}.color--deep-purple-A700{background-color:#6200ea!important}.color-text--indigo{color:#3f51b5!important}.color--indigo{background-color:#3f51b5!important}.color-text--indigo-50{color:#e8eaf6!important}.color--indigo-50{background-color:#e8eaf6!important}.color-text--indigo-100{color:#c5cae9!important}.color--indigo-100{background-color:#c5cae9!important}.color-text--indigo-200{color:#9fa8da!important}.color--indigo-200{background-color:#9fa8da!important}.color-text--indigo-300{color:#7986cb!important}.color--indigo-300{background-color:#7986cb!important}.color-text--indigo-400{color:#5c6bc0!important}.color--indigo-400{background-color:#5c6bc0!important}.color-text--indigo-500{color:#3f51b5!important}.color--indigo-500{background-color:#3f51b5!important}.color-text--indigo-600{color:#3949ab!important}.color--indigo-600{background-color:#3949ab!important}.color-text--indigo-700{color:#303f9f!important}.color--indigo-700{background-color:#303f9f!important}.color-text--indigo-800{color:#283593!important}.color--indigo-800{background-color:#283593!important}.color-text--indigo-900{color:#1a237e!important}.color--indigo-900{background-color:#1a237e!important}.color-text--indigo-A100{color:#8c9eff!important}.color--indigo-A100{background-color:#8c9eff!important}.color-text--indigo-A200{color:#536dfe!important}.color--indigo-A200{background-color:#536dfe!important}.color-text--indigo-A400{color:#3d5afe!important}.color--indigo-A400{background-color:#3d5afe!important}.color-text--indigo-A700{color:#304ffe!important}.color--indigo-A700{background-color:#304ffe!important}.color-text--blue{color:#2196f3!important}.color--blue{background-color:#2196f3!important}.color-text--blue-50{color:#e3f2fd!important}.color--blue-50{background-color:#e3f2fd!important}.color-text--blue-100{color:#bbdefb!important}.color--blue-100{background-color:#bbdefb!important}.color-text--blue-200{color:#90caf9!important}.color--blue-200{background-color:#90caf9!important}.color-text--blue-300{color:#64b5f6!important}.color--blue-300{background-color:#64b5f6!important}.color-text--blue-400{color:#42a5f5!important}.color--blue-400{background-color:#42a5f5!important}.color-text--blue-500{color:#2196f3!important}.color--blue-500{background-color:#2196f3!important}.color-text--blue-600{color:#1e88e5!important}.color--blue-600{background-color:#1e88e5!important}.color-text--blue-700{color:#1976d2!important}.color--blue-700{background-color:#1976d2!important}.color-text--blue-800{color:#1565c0!important}.color--blue-800{background-color:#1565c0!important}.color-text--blue-900{color:#0d47a1!important}.color--blue-900{background-color:#0d47a1!important}.color-text--blue-A100{color:#82b1ff!important}.color--blue-A100{background-color:#82b1ff!important}.color-text--blue-A200{color:#448aff!important}.color--blue-A200{background-color:#448aff!important}.color-text--blue-A400{color:#2979ff!important}.color--blue-A400{background-color:#2979ff!important}.color-text--blue-A700{color:#2962ff!important}.color--blue-A700{background-color:#2962ff!important}.color-text--light-blue{color:#03a9f4!important}.color--light-blue{background-color:#03a9f4!important}.color-text--light-blue-50{color:#e1f5fe!important}.color--light-blue-50{background-color:#e1f5fe!important}.color-text--light-blue-100{color:#b3e5fc!important}.color--light-blue-100{background-color:#b3e5fc!important}.color-text--light-blue-200{color:#81d4fa!important}.color--light-blue-200{background-color:#81d4fa!important}.color-text--light-blue-300{color:#4fc3f7!important}.color--light-blue-300{background-color:#4fc3f7!important}.color-text--light-blue-400{color:#29b6f6!important}.color--light-blue-400{background-color:#29b6f6!important}.color-text--light-blue-500{color:#03a9f4!important}.color--light-blue-500{background-color:#03a9f4!important}.color-text--light-blue-600{color:#039be5!important}.color--light-blue-600{background-color:#039be5!important}.color-text--light-blue-700{color:#0288d1!important}.color--light-blue-700{background-color:#0288d1!important}.color-text--light-blue-800{color:#0277bd!important}.color--light-blue-800{background-color:#0277bd!important}.color-text--light-blue-900{color:#01579b!important}.color--light-blue-900{background-color:#01579b!important}.color-text--light-blue-A100{color:#80d8ff!important}.color--light-blue-A100{background-color:#80d8ff!important}.color-text--light-blue-A200{color:#40c4ff!important}.color--light-blue-A200{background-color:#40c4ff!important}.color-text--light-blue-A400{color:#00b0ff!important}.color--light-blue-A400{background-color:#00b0ff!important}.color-text--light-blue-A700{color:#0091ea!important}.color--light-blue-A700{background-color:#0091ea!important}.color-text--cyan{color:#00bcd4!important}.color--cyan{background-color:#00bcd4!important}.color-text--cyan-50{color:#e0f7fa!important}.color--cyan-50{background-color:#e0f7fa!important}.color-text--cyan-100{color:#b2ebf2!important}.color--cyan-100{background-color:#b2ebf2!important}.color-text--cyan-200{color:#80deea!important}.color--cyan-200{background-color:#80deea!important}.color-text--cyan-300{color:#4dd0e1!important}.color--cyan-300{background-color:#4dd0e1!important}.color-text--cyan-400{color:#26c6da!important}.color--cyan-400{background-color:#26c6da!important}.color-text--cyan-500{color:#00bcd4!important}.color--cyan-500{background-color:#00bcd4!important}.color-text--cyan-600{color:#00acc1!important}.color--cyan-600{background-color:#00acc1!important}.color-text--cyan-700{color:#0097a7!important}.color--cyan-700{background-color:#0097a7!important}.color-text--cyan-800{color:#00838f!important}.color--cyan-800{background-color:#00838f!important}.color-text--cyan-900{color:#006064!important}.color--cyan-900{background-color:#006064!important}.color-text--cyan-A100{color:#84ffff!important}.color--cyan-A100{background-color:#84ffff!important}.color-text--cyan-A200{color:#18ffff!important}.color--cyan-A200{background-color:#18ffff!important}.color-text--cyan-A400{color:#00e5ff!important}.color--cyan-A400{background-color:#00e5ff!important}.color-text--cyan-A700{color:#00b8d4!important}.color--cyan-A700{background-color:#00b8d4!important}.color-text--teal{color:#009688!important}.color--teal{background-color:#009688!important}.color-text--teal-50{color:#e0f2f1!important}.color--teal-50{background-color:#e0f2f1!important}.color-text--teal-100{color:#b2dfdb!important}.color--teal-100{background-color:#b2dfdb!important}.color-text--teal-200{color:#80cbc4!important}.color--teal-200{background-color:#80cbc4!important}.color-text--teal-300{color:#4db6ac!important}.color--teal-300{background-color:#4db6ac!important}.color-text--teal-400{color:#26a69a!important}.color--teal-400{background-color:#26a69a!important}.color-text--teal-500{color:#009688!important}.color--teal-500{background-color:#009688!important}.color-text--teal-600{color:#00897b!important}.color--teal-600{background-color:#00897b!important}.color-text--teal-700{color:#00796b!important}.color--teal-700{background-color:#00796b!important}.color-text--teal-800{color:#00695c!important}.color--teal-800{background-color:#00695c!important}.color-text--teal-900{color:#004d40!important}.color--teal-900{background-color:#004d40!important}.color-text--teal-A100{color:#a7ffeb!important}.color--teal-A100{background-color:#a7ffeb!important}.color-text--teal-A200{color:#64ffda!important}.color--teal-A200{background-color:#64ffda!important}.color-text--teal-A400{color:#1de9b6!important}.color--teal-A400{background-color:#1de9b6!important}.color-text--teal-A700{color:#00bfa5!important}.color--teal-A700{background-color:#00bfa5!important}.color-text--green{color:#4caf50!important}.color--green{background-color:#4caf50!important}.color-text--green-50{color:#e8f5e9!important}.color--green-50{background-color:#e8f5e9!important}.color-text--green-100{color:#c8e6c9!important}.color--green-100{background-color:#c8e6c9!important}.color-text--green-200{color:#a5d6a7!important}.color--green-200{background-color:#a5d6a7!important}.color-text--green-300{color:#81c784!important}.color--green-300{background-color:#81c784!important}.color-text--green-400{color:#66bb6a!important}.color--green-400{background-color:#66bb6a!important}.color-text--green-500{color:#4caf50!important}.color--green-500{background-color:#4caf50!important}.color-text--green-600{color:#43a047!important}.color--green-600{background-color:#43a047!important}.color-text--green-700{color:#388e3c!important}.color--green-700{background-color:#388e3c!important}.color-text--green-800{color:#2e7d32!important}.color--green-800{background-color:#2e7d32!important}.color-text--green-900{color:#1b5e20!important}.color--green-900{background-color:#1b5e20!important}.color-text--green-A100{color:#b9f6ca!important}.color--green-A100{background-color:#b9f6ca!important}.color-text--green-A200{color:#69f0ae!important}.color--green-A200{background-color:#69f0ae!important}.color-text--green-A400{color:#00e676!important}.color--green-A400{background-color:#00e676!important}.color-text--green-A700{color:#00c853!important}.color--green-A700{background-color:#00c853!important}.color-text--light-green{color:#8bc34a!important}.color--light-green{background-color:#8bc34a!important}.color-text--light-green-50{color:#f1f8e9!important}.color--light-green-50{background-color:#f1f8e9!important}.color-text--light-green-100{color:#dcedc8!important}.color--light-green-100{background-color:#dcedc8!important}.color-text--light-green-200{color:#c5e1a5!important}.color--light-green-200{background-color:#c5e1a5!important}.color-text--light-green-300{color:#aed581!important}.color--light-green-300{background-color:#aed581!important}.color-text--light-green-400{color:#9ccc65!important}.color--light-green-400{background-color:#9ccc65!important}.color-text--light-green-500{color:#8bc34a!important}.color--light-green-500{background-color:#8bc34a!important}.color-text--light-green-600{color:#7cb342!important}.color--light-green-600{background-color:#7cb342!important}.color-text--light-green-700{color:#689f38!important}.color--light-green-700{background-color:#689f38!important}.color-text--light-green-800{color:#558b2f!important}.color--light-green-800{background-color:#558b2f!important}.color-text--light-green-900{color:#33691e!important}.color--light-green-900{background-color:#33691e!important}.color-text--light-green-A100{color:#ccff90!important}.color--light-green-A100{background-color:#ccff90!important}.color-text--light-green-A200{color:#b2ff59!important}.color--light-green-A200{background-color:#b2ff59!important}.color-text--light-green-A400{color:#76ff03!important}.color--light-green-A400{background-color:#76ff03!important}.color-text--light-green-A700{color:#64dd17!important}.color--light-green-A700{background-color:#64dd17!important}.color-text--lime{color:#cddc39!important}.color--lime{background-color:#cddc39!important}.color-text--lime-50{color:#f9fbe7!important}.color--lime-50{background-color:#f9fbe7!important}.color-text--lime-100{color:#f0f4c3!important}.color--lime-100{background-color:#f0f4c3!important}.color-text--lime-200{color:#e6ee9c!important}.color--lime-200{background-color:#e6ee9c!important}.color-text--lime-300{color:#dce775!important}.color--lime-300{background-color:#dce775!important}.color-text--lime-400{color:#d4e157!important}.color--lime-400{background-color:#d4e157!important}.color-text--lime-500{color:#cddc39!important}.color--lime-500{background-color:#cddc39!important}.color-text--lime-600{color:#c0ca33!important}.color--lime-600{background-color:#c0ca33!important}.color-text--lime-700{color:#afb42b!important}.color--lime-700{background-color:#afb42b!important}.color-text--lime-800{color:#9e9d24!important}.color--lime-800{background-color:#9e9d24!important}.color-text--lime-900{color:#827717!important}.color--lime-900{background-color:#827717!important}.color-text--lime-A100{color:#f4ff81!important}.color--lime-A100{background-color:#f4ff81!important}.color-text--lime-A200{color:#eeff41!important}.color--lime-A200{background-color:#eeff41!important}.color-text--lime-A400{color:#c6ff00!important}.color--lime-A400{background-color:#c6ff00!important}.color-text--lime-A700{color:#aeea00!important}.color--lime-A700{background-color:#aeea00!important}.color-text--yellow{color:#ffeb3b!important}.color--yellow{background-color:#ffeb3b!important}.color-text--yellow-50{color:#fffde7!important}.color--yellow-50{background-color:#fffde7!important}.color-text--yellow-100{color:#fff9c4!important}.color--yellow-100{background-color:#fff9c4!important}.color-text--yellow-200{color:#fff59d!important}.color--yellow-200{background-color:#fff59d!important}.color-text--yellow-300{color:#fff176!important}.color--yellow-300{background-color:#fff176!important}.color-text--yellow-400{color:#ffee58!important}.color--yellow-400{background-color:#ffee58!important}.color-text--yellow-500{color:#ffeb3b!important}.color--yellow-500{background-color:#ffeb3b!important}.color-text--yellow-600{color:#fdd835!important}.color--yellow-600{background-color:#fdd835!important}.color-text--yellow-700{color:#fbc02d!important}.color--yellow-700{background-color:#fbc02d!important}.color-text--yellow-800{color:#f9a825!important}.color--yellow-800{background-color:#f9a825!important}.color-text--yellow-900{color:#f57f17!important}.color--yellow-900{background-color:#f57f17!important}.color-text--yellow-A100{color:#ffff8d!important}.color--yellow-A100{background-color:#ffff8d!important}.color-text--yellow-A200{color:#ff0!important}.color--yellow-A200{background-color:#ff0!important}.color-text--yellow-A400{color:#ffea00!important}.color--yellow-A400{background-color:#ffea00!important}.color-text--yellow-A700{color:#ffd600!important}.color--yellow-A700{background-color:#ffd600!important}.color-text--amber{color:#ffc107!important}.color--amber{background-color:#ffc107!important}.color-text--amber-50{color:#fff8e1!important}.color--amber-50{background-color:#fff8e1!important}.color-text--amber-100{color:#ffecb3!important}.color--amber-100{background-color:#ffecb3!important}.color-text--amber-200{color:#ffe082!important}.color--amber-200{background-color:#ffe082!important}.color-text--amber-300{color:#ffd54f!important}.color--amber-300{background-color:#ffd54f!important}.color-text--amber-400{color:#ffca28!important}.color--amber-400{background-color:#ffca28!important}.color-text--amber-500{color:#ffc107!important}.color--amber-500{background-color:#ffc107!important}.color-text--amber-600{color:#ffb300!important}.color--amber-600{background-color:#ffb300!important}.color-text--amber-700{color:#ffa000!important}.color--amber-700{background-color:#ffa000!important}.color-text--amber-800{color:#ff8f00!important}.color--amber-800{background-color:#ff8f00!important}.color-text--amber-900{color:#ff6f00!important}.color--amber-900{background-color:#ff6f00!important}.color-text--amber-A100{color:#ffe57f!important}.color--amber-A100{background-color:#ffe57f!important}.color-text--amber-A200{color:#ffd740!important}.color--amber-A200{background-color:#ffd740!important}.color-text--amber-A400{color:#ffc400!important}.color--amber-A400{background-color:#ffc400!important}.color-text--amber-A700{color:#ffab00!important}.color--amber-A700{background-color:#ffab00!important}.color-text--orange{color:#ff9800!important}.color--orange{background-color:#ff9800!important}.color-text--orange-50{color:#fff3e0!important}.color--orange-50{background-color:#fff3e0!important}.color-text--orange-100{color:#ffe0b2!important}.color--orange-100{background-color:#ffe0b2!important}.color-text--orange-200{color:#ffcc80!important}.color--orange-200{background-color:#ffcc80!important}.color-text--orange-300{color:#ffb74d!important}.color--orange-300{background-color:#ffb74d!important}.color-text--orange-400{color:#ffa726!important}.color--orange-400{background-color:#ffa726!important}.color-text--orange-500{color:#ff9800!important}.color--orange-500{background-color:#ff9800!important}.color-text--orange-600{color:#fb8c00!important}.color--orange-600{background-color:#fb8c00!important}.color-text--orange-700{color:#f57c00!important}.color--orange-700{background-color:#f57c00!important}.color-text--orange-800{color:#ef6c00!important}.color--orange-800{background-color:#ef6c00!important}.color-text--orange-900{color:#e65100!important}.color--orange-900{background-color:#e65100!important}.color-text--orange-A100{color:#ffd180!important}.color--orange-A100{background-color:#ffd180!important}.color-text--orange-A200{color:#ffab40!important}.color--orange-A200{background-color:#ffab40!important}.color-text--orange-A400{color:#ff9100!important}.color--orange-A400{background-color:#ff9100!important}.color-text--orange-A700{color:#ff6d00!important}.color--orange-A700{background-color:#ff6d00!important}.color-text--deep-orange{color:#ff5722!important}.color--deep-orange{background-color:#ff5722!important}.color-text--deep-orange-50{color:#fbe9e7!important}.color--deep-orange-50{background-color:#fbe9e7!important}.color-text--deep-orange-100{color:#ffccbc!important}.color--deep-orange-100{background-color:#ffccbc!important}.color-text--deep-orange-200{color:#ffab91!important}.color--deep-orange-200{background-color:#ffab91!important}.color-text--deep-orange-300{color:#ff8a65!important}.color--deep-orange-300{background-color:#ff8a65!important}.color-text--deep-orange-400{color:#ff7043!important}.color--deep-orange-400{background-color:#ff7043!important}.color-text--deep-orange-500{color:#ff5722!important}.color--deep-orange-500{background-color:#ff5722!important}.color-text--deep-orange-600{color:#f4511e!important}.color--deep-orange-600{background-color:#f4511e!important}.color-text--deep-orange-700{color:#e64a19!important}.color--deep-orange-700{background-color:#e64a19!important}.color-text--deep-orange-800{color:#d84315!important}.color--deep-orange-800{background-color:#d84315!important}.color-text--deep-orange-900{color:#bf360c!important}.color--deep-orange-900{background-color:#bf360c!important}.color-text--deep-orange-A100{color:#ff9e80!important}.color--deep-orange-A100{background-color:#ff9e80!important}.color-text--deep-orange-A200{color:#ff6e40!important}.color--deep-orange-A200{background-color:#ff6e40!important}.color-text--deep-orange-A400{color:#ff3d00!important}.color--deep-orange-A400{background-color:#ff3d00!important}.color-text--deep-orange-A700{color:#dd2c00!important}.color--deep-orange-A700{background-color:#dd2c00!important}.color-text--brown{color:#795548!important}.color--brown{background-color:#795548!important}.color-text--brown-50{color:#efebe9!important}.color--brown-50{background-color:#efebe9!important}.color-text--brown-100{color:#d7ccc8!important}.color--brown-100{background-color:#d7ccc8!important}.color-text--brown-200{color:#bcaaa4!important}.color--brown-200{background-color:#bcaaa4!important}.color-text--brown-300{color:#a1887f!important}.color--brown-300{background-color:#a1887f!important}.color-text--brown-400{color:#8d6e63!important}.color--brown-400{background-color:#8d6e63!important}.color-text--brown-500{color:#795548!important}.color--brown-500{background-color:#795548!important}.color-text--brown-600{color:#6d4c41!important}.color--brown-600{background-color:#6d4c41!important}.color-text--brown-700{color:#5d4037!important}.color--brown-700{background-color:#5d4037!important}.color-text--brown-800{color:#4e342e!important}.color--brown-800{background-color:#4e342e!important}.color-text--brown-900{color:#3e2723!important}.color--brown-900{background-color:#3e2723!important}.color-text--grey{color:#9e9e9e!important}.color--grey{background-color:#9e9e9e!important}.color-text--grey-50{color:#fafafa!important}.color--grey-50{background-color:#fafafa!important}.color-text--grey-100{color:#f5f5f5!important}.color--grey-100{background-color:#f5f5f5!important}.color-text--grey-200{color:#eee!important}.color--grey-200{background-color:#eee!important}.color-text--grey-300{color:#e0e0e0!important}.color--grey-300{background-color:#e0e0e0!important}.color-text--grey-400{color:#bdbdbd!important}.color--grey-400{background-color:#bdbdbd!important}.color-text--grey-500{color:#9e9e9e!important}.color--grey-500{background-color:#9e9e9e!important}.color-text--grey-600{color:#757575!important}.color--grey-600{background-color:#757575!important}.color-text--grey-700{color:#616161!important}.color--grey-700{background-color:#616161!important}.color-text--grey-800{color:#424242!important}.color--grey-800{background-color:#424242!important}.color-text--grey-900{color:#212121!important}.color--grey-900{background-color:#212121!important}.color-text--blue-grey{color:#607d8b!important}.color--blue-grey{background-color:#607d8b!important}.color-text--blue-grey-50{color:#eceff1!important}.color--blue-grey-50{background-color:#eceff1!important}.color-text--blue-grey-100{color:#cfd8dc!important}.color--blue-grey-100{background-color:#cfd8dc!important}.color-text--blue-grey-200{color:#b0bec5!important}.color--blue-grey-200{background-color:#b0bec5!important}.color-text--blue-grey-300{color:#90a4ae!important}.color--blue-grey-300{background-color:#90a4ae!important}.color-text--blue-grey-400{color:#78909c!important}.color--blue-grey-400{background-color:#78909c!important}.color-text--blue-grey-500{color:#607d8b!important}.color--blue-grey-500{background-color:#607d8b!important}.color-text--blue-grey-600{color:#546e7a!important}.color--blue-grey-600{background-color:#546e7a!important}.color-text--blue-grey-700{color:#455a64!important}.color--blue-grey-700{background-color:#455a64!important}.color-text--blue-grey-800{color:#37474f!important}.color--blue-grey-800{background-color:#37474f!important}.color-text--blue-grey-900{color:#263238!important}.color--blue-grey-900{background-color:#263238!important}.color--black{background-color:#000!important}.color-text--black{color:#000!important}.color--white{background-color:#fff!important}.color-text--white{color:#fff!important}.color--primary{background-color:#3f51b5!important}.color--primary-contrast{background-color:#fff!important}.color--primary-dark{background-color:#303f9f!important}.color--accent{background-color:#ff4081!important}.color--accent-contrast{background-color:#fff!important}.color-text--primary{color:#3f51b5!important}.color-text--primary-contrast{color:#fff!important}.color-text--primary-dark{color:#303f9f!important}.color-text--accent{color:#ff4081!important}.color-text--accent-contrast{color:#fff!important}.ripple{background:#000;height:50px;left:0;opacity:0;pointer-events:none;position:absolute;top:0;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);width:50px}.ripple.is-animating{-webkit-transition:-webkit-transform .3s cubic-bezier(0,0,.2,1),width .3s cubic-bezier(0,0,.2,1),height .3s cubic-bezier(0,0,.2,1),opacity .6s cubic-bezier(0,0,.2,1);transition:transform .3s cubic-bezier(0,0,.2,1),width .3s cubic-bezier(0,0,.2,1),height .3s cubic-bezier(0,0,.2,1),opacity .6s cubic-bezier(0,0,.2,1)}.ripple.is-visible{opacity:.3}.animate-default,.animate-fast-out-slow-in{-webkit-transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(.4,0,.2,1)}.animate-linear-out-slow-in{-webkit-transition-timing-function:cubic-bezier(0,0,.2,1);transition-timing-function:cubic-bezier(0,0,.2,1)}.animate-fast-out-linear-in{-webkit-transition-timing-function:cubic-bezier(.4,0,1,1);transition-timing-function:cubic-bezier(.4,0,1,1)}.badge{position:relative;margin-right:24px}.badge:not([data-badge]){margin-right:auto}.badge[data-badge]:after{content:attr(data-badge);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-align-content:center;-ms-flex-line-pack:center;align-content:center;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;position:absolute;top:-11px;right:-24px;font-family:Roboto,Helvetica,Arial,sans-serif;font-weight:600;font-size:12px;width:22px;height:22px;border-radius:50%;background:#ff7700;color:#fff}.button,.fab{position:relative}.card,.layout{-webkit-box-direction:normal;-webkit-box-orient:vertical}.button .badge[data-badge]:after{top:-10px;right:-5px}.badge.no-background[data-badge]:after{color:#ff4081;background:rgba(255,255,255,.2);box-shadow:0 0 1px gray}.button{background:0 0;border:none;border-radius:2px;color:#000;height:36px;min-width:64px;padding:0 8px;display:inline-block;font-family:Roboto,Helvetica,Arial,sans-serif;font-size:14px;font-weight:500;letter-spacing:0;will-change:box-shadow,transform;-webkit-transition:box-shadow .2s cubic-bezier(.4,0,1,1),background-color .2s cubic-bezier(.4,0,.2,1),color .2s cubic-bezier(.4,0,.2,1);transition:box-shadow .2s cubic-bezier(.4,0,1,1),background-color .2s cubic-bezier(.4,0,.2,1),color .2s cubic-bezier(.4,0,.2,1);outline:0;cursor:pointer;text-align:center;line-height:36px}.button::-moz-focus-inner{border:0}.button:hover{background-color:rgba(158,158,158,.2)}.button:focus:not(:active){background-color:rgba(0,0,0,.12)}.button:active{background-color:rgba(158,158,158,.4)}.button.colored{color:#3f51b5}.button.colored:focus:not(:active){background-color:rgba(0,0,0,.12)}input.button[type=submit]{-webkit-appearance:none}.raised{background:rgba(158,158,158,.2);box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)}.raised:active{box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.2);background-color:rgba(158,158,158,.4)}.raised:focus:not(:active){box-shadow:0 0 8px rgba(0,0,0,.18),0 8px 16px rgba(0,0,0,.36);background-color:rgba(158,158,158,.4)}.raised.colored{background:#3f51b5;color:#fff}.raised.colored:active,.raised.colored:focus:not(:active),.raised.colored:hover{background-color:#3f51b5}.raised.colored .ripple{background:#fff}.fab{font-size:24px;height:56px;margin:auto;min-width:56px;width:56px;padding:0;background:rgba(158,158,158,.2);box-shadow:0 1px 1.5px 0 rgba(0,0,0,.12),0 1px 1px 0 rgba(0,0,0,.24);line-height:normal}.fab:active,.fab:focus:not(:active){background-color:rgba(158,158,158,.4)}.fab .material-icons{transform:translate(-12px,-12px);line-height:24px;width:24px}.fab .material-icons,.icon .material-icons{position:absolute;top:50%;left:50%;-webkit-transform:translate(-12px,-12px);-ms-transform:translate(-12px,-12px)}.fab.mini-fab{height:40px;min-width:40px;width:40px}.fab .button-ripple{-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000)}.fab:active{box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.2)}.fab:focus:not(:active){box-shadow:0 0 8px rgba(0,0,0,.18),0 8px 16px rgba(0,0,0,.36)}.fab.colored{background:#ff4081;color:#fff}.fab.colored:active,.fab.colored:focus:not(:active),.fab.colored:hover{background-color:#ff4081}.fab.colored .ripple{background:#fff}.icon{font-size:24px;margin-left:0;margin-right:0;min-width:32px;width:32px;color:inherit;line-height:normal}.icon .material-icons{transform:translate(-12px,-12px);line-height:24px;width:24px}.icon.mini-icon{height:24px;min-width:24px;width:24px}.button-ripple,.card{overflow:hidden;width:100%;height:100%}.icon.mini-icon .material-icons{top:0;left:0}.icon .button-ripple{-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000)}.button-ripple{display:block;left:0;position:absolute;top:0;z-index:0}.button[disabled] .button-ripple .ripple{background-color:transparent}.primary.primary{color:#3f51b5}.primary.primary .ripple{background:#fff}.primary.primary.fab,.primary.primary.raised{color:#fff;background-color:#3f51b5}.accent.accent{color:#ff4081}.accent.accent .ripple{background:#fff}.accent.accent.fab,.accent.accent.raised{color:#fff;background-color:#ff4081}.button[disabled][disabled]{color:rgba(0,0,0,.26);cursor:auto;background-color:transparent}.button--fab[disabled][disabled],.button--raised[disabled][disabled]{background-color:rgba(0,0,0,.12);color:rgba(0,0,0,.26);box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)}.button--colored[disabled][disabled]{color:rgba(0,0,0,.26)}.card{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;font-size:16px;letter-spacing:0;font-weight:400;z-index:1;position:relative;background:#fff;border-radius:2px;box-sizing:border-box}.card-media{background-color:#ff4081;background-repeat:repeat;background-position:50% 50%;background-size:cover;background-origin:padding-box;background-attachment:scroll;box-sizing:border-box}.card-header{color:#000;display:block;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-align-content:stretch;-ms-flex-line-pack:stretch;align-content:stretch;line-height:normal;padding:60px 0 0;-webkit-perspective-origin:165px 56px;perspective-origin:165px 56px;-webkit-transform-origin:165px 56px;-ms-transform-origin:165px 56px;transform-origin:165px 56px;box-sizing:border-box}.card-section{color:#000;background-color:#fff;font-size:13px;line-height:18px}.card-section>.section-dialog{overflow:hidden;width:96%;background-color:transparent;padding:.5% 2%;margin:0;text-align:left}.card-actions,.card-section>.section-actions,.checkbox{box-sizing:border-box;width:100%}.card-section>.section-dialog>ul{padding-top:4px}.card-section>.section-actions{color:rgba(0,0,0,.54);font-size:16px;background-color:transparent;padding:8px}.card-actions{font-size:16px;background-color:rgba(0,255,255,.1)}.card-menu{position:absolute;right:16px;top:16px}.card-header-title{-webkit-align-self:flex-end;-ms-flex-item-align:end;align-self:flex-end;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;font-size:24px;font-weight:300;letter-spacing:1px;background-color:rgba(0,0,0,.5);transform-origin:149px 48px;margin:0;padding:12px 0}.card-header-subtitle,.card-header-title{overflow:hidden;display:block;line-height:normal;-webkit-transform-origin:149px 48px;-ms-transform-origin:149px 48px}.card-header-subtitle{-webkit-align-self:flex-end;-ms-flex-item-align:end;align-self:flex-end;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;background-color:transparent;transform-origin:149px 48px;margin:0;padding:8px 0}.checkbox-input,.checkbox-label{line-height:24px}.checkbox{position:relative;z-index:1;display:inline-block;height:24px;margin:0;padding:0}.checkbox.is-upgraded{padding-left:24px}.checkbox.is-upgraded .checkbox-input{position:absolute;width:0;height:0;margin:0;padding:0;opacity:0;-ms-appearance:none;-moz-appearance:none;-webkit-appearance:none;appearance:none;border:none}.checkbox-box-outline,.checkbox-focus-helper{position:absolute;left:0;top:3px;display:inline-block;box-sizing:border-box;width:16px;height:16px}.checkbox-box-outline{margin:0;cursor:pointer;overflow:hidden;border:2px solid rgba(0,0,0,.54);border-radius:2px;z-index:2}.checkbox.is-checked .checkbox-box-outline{border:2px solid #3f51b5}.checkbox.is-disabled .checkbox-box-outline{border:2px solid rgba(0,0,0,.26);cursor:auto}.checkbox-focus-helper{border-radius:50%;background-color:transparent}.checkbox.is-focused .checkbox-focus-helper{box-shadow:0 0 0 8px rgba(0,0,0,.1);background-color:rgba(0,0,0,.1)}.checkbox.is-focused.is-checked .checkbox-focus-helper{box-shadow:0 0 0 8px rgba(63,81,181,.26);background-color:rgba(63,81,181,.26)}.checkbox-tick-outline{position:absolute;top:0;left:0;height:100%;width:100%;-webkit-mask:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnDQogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iDQogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIg0KICAgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIg0KICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyINCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyINCiAgIHZlcnNpb249IjEuMSINCiAgIHZpZXdCb3g9IjAgMCAxIDEiDQogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4NCiAgPGRlZnM+DQogICAgPGNsaXBQYXRoIGlkPSJjbGlwIj4NCiAgICAgIDxwYXRoDQogICAgICAgICBkPSJNIDAsMCAwLDEgMSwxIDEsMCAwLDAgeiBNIDAuODUzNDM3NSwwLjE2NzE4NzUgMC45NTk2ODc1LDAuMjczMTI1IDAuNDI5Mzc1LDAuODAzNDM3NSAwLjMyMzEyNSwwLjkwOTY4NzUgMC4yMTcxODc1LDAuODAzNDM3NSAwLjA0MDMxMjUsMC42MjY4NzUgMC4xNDY1NjI1LDAuNTIwNjI1IDAuMzIzMTI1LDAuNjk3NSAwLjg1MzQzNzUsMC4xNjcxODc1IHoiDQogICAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lIiAvPg0KICAgIDwvY2xpcFBhdGg+DQogICAgPG1hc2sgaWQ9Im1hc2siIG1hc2tVbml0cz0ib2JqZWN0Qm91bmRpbmdCb3giIG1hc2tDb250ZW50VW5pdHM9Im9iamVjdEJvdW5kaW5nQm94Ij4NCiAgICAgIDxwYXRoDQogICAgICAgICBkPSJNIDAsMCAwLDEgMSwxIDEsMCAwLDAgeiBNIDAuODUzNDM3NSwwLjE2NzE4NzUgMC45NTk2ODc1LDAuMjczMTI1IDAuNDI5Mzc1LDAuODAzNDM3NSAwLjMyMzEyNSwwLjkwOTY4NzUgMC4yMTcxODc1LDAuODAzNDM3NSAwLjA0MDMxMjUsMC42MjY4NzUgMC4xNDY1NjI1LDAuNTIwNjI1IDAuMzIzMTI1LDAuNjk3NSAwLjg1MzQzNzUsMC4xNjcxODc1IHoiDQogICAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lIiAvPg0KICAgIDwvbWFzaz4NCiAgPC9kZWZzPg0KICA8cmVjdA0KICAgICB3aWR0aD0iMSINCiAgICAgaGVpZ2h0PSIxIg0KICAgICB4PSIwIg0KICAgICB5PSIwIg0KICAgICBjbGlwLXBhdGg9InVybCgjY2xpcCkiDQogICAgIHN0eWxlPSJmaWxsOiMwMDAwMDA7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmUiIC8+DQo8L3N2Zz4NCg==);mask:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnDQogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iDQogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIg0KICAgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIg0KICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyINCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyINCiAgIHZlcnNpb249IjEuMSINCiAgIHZpZXdCb3g9IjAgMCAxIDEiDQogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4NCiAgPGRlZnM+DQogICAgPGNsaXBQYXRoIGlkPSJjbGlwIj4NCiAgICAgIDxwYXRoDQogICAgICAgICBkPSJNIDAsMCAwLDEgMSwxIDEsMCAwLDAgeiBNIDAuODUzNDM3NSwwLjE2NzE4NzUgMC45NTk2ODc1LDAuMjczMTI1IDAuNDI5Mzc1LDAuODAzNDM3NSAwLjMyMzEyNSwwLjkwOTY4NzUgMC4yMTcxODc1LDAuODAzNDM3NSAwLjA0MDMxMjUsMC42MjY4NzUgMC4xNDY1NjI1LDAuNTIwNjI1IDAuMzIzMTI1LDAuNjk3NSAwLjg1MzQzNzUsMC4xNjcxODc1IHoiDQogICAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lIiAvPg0KICAgIDwvY2xpcFBhdGg+DQogICAgPG1hc2sgaWQ9Im1hc2siIG1hc2tVbml0cz0ib2JqZWN0Qm91bmRpbmdCb3giIG1hc2tDb250ZW50VW5pdHM9Im9iamVjdEJvdW5kaW5nQm94Ij4NCiAgICAgIDxwYXRoDQogICAgICAgICBkPSJNIDAsMCAwLDEgMSwxIDEsMCAwLDAgeiBNIDAuODUzNDM3NSwwLjE2NzE4NzUgMC45NTk2ODc1LDAuMjczMTI1IDAuNDI5Mzc1LDAuODAzNDM3NSAwLjMyMzEyNSwwLjkwOTY4NzUgMC4yMTcxODc1LDAuODAzNDM3NSAwLjA0MDMxMjUsMC42MjY4NzUgMC4xNDY1NjI1LDAuNTIwNjI1IDAuMzIzMTI1LDAuNjk3NSAwLjg1MzQzNzUsMC4xNjcxODc1IHoiDQogICAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lIiAvPg0KICAgIDwvbWFzaz4NCiAgPC9kZWZzPg0KICA8cmVjdA0KICAgICB3aWR0aD0iMSINCiAgICAgaGVpZ2h0PSIxIg0KICAgICB4PSIwIg0KICAgICB5PSIwIg0KICAgICBjbGlwLXBhdGg9InVybCgjY2xpcCkiDQogICAgIHN0eWxlPSJmaWxsOiMwMDAwMDA7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmUiIC8+DQo8L3N2Zz4NCg==);background:0 0;-webkit-transition-duration:.28s;transition-duration:.28s;transition-timing-function:cubic-bezier(.4,0,.2,1);-webkit-transition-property:background;transition-property:background}.checkbox-tick-outline,table tbody tr{-webkit-transition-timing-function:cubic-bezier(.4,0,.2,1)}.checkbox-ripple,.icon-ripple{box-sizing:border-box;overflow:hidden;-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000)}.checkbox.is-checked .checkbox-tick-outline{background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnDQogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iDQogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIg0KICAgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIg0KICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyINCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyINCiAgIHZlcnNpb249IjEuMSINCiAgIHZpZXdCb3g9IjAgMCAxIDEiDQogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4NCiAgPHBhdGgNCiAgICAgZD0iTSAwLjA0MDM4MDU5LDAuNjI2Nzc2NyAwLjE0NjQ0NjYxLDAuNTIwNzEwNjggMC40MjkyODkzMiwwLjgwMzU1MzM5IDAuMzIzMjIzMywwLjkwOTYxOTQxIHogTSAwLjIxNzE1NzI5LDAuODAzNTUzMzkgMC44NTM1NTMzOSwwLjE2NzE1NzI5IDAuOTU5NjE5NDEsMC4yNzMyMjMzIDAuMzIzMjIzMywwLjkwOTYxOTQxIHoiDQogICAgIGlkPSJyZWN0Mzc4MCINCiAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZSIgLz4NCjwvc3ZnPg0K) #3f51b5}.checkbox.is-checked.is-disabled .checkbox-tick-outline{background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnDQogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iDQogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIg0KICAgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIg0KICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyINCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyINCiAgIHZlcnNpb249IjEuMSINCiAgIHZpZXdCb3g9IjAgMCAxIDEiDQogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4NCiAgPHBhdGgNCiAgICAgZD0iTSAwLjA0MDM4MDU5LDAuNjI2Nzc2NyAwLjE0NjQ0NjYxLDAuNTIwNzEwNjggMC40MjkyODkzMiwwLjgwMzU1MzM5IDAuMzIzMjIzMywwLjkwOTYxOTQxIHogTSAwLjIxNzE1NzI5LDAuODAzNTUzMzkgMC44NTM1NTMzOSwwLjE2NzE1NzI5IDAuOTU5NjE5NDEsMC4yNzMyMjMzIDAuMzIzMjIzMywwLjkwOTYxOTQxIHoiDQogICAgIGlkPSJyZWN0Mzc4MCINCiAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZSIgLz4NCjwvc3ZnPg0K) rgba(0,0,0,.26)}.checkbox-label{position:relative;cursor:pointer;font-size:16px;margin:0}.checkbox.is-disabled .checkbox-label{color:rgba(0,0,0,.26);cursor:auto}.checkbox-ripple{position:absolute;z-index:2;top:-6px;left:-10px;width:36px;height:36px;border-radius:50%;cursor:pointer}.datatable,table,table td,table th{border:1px solid rgba(0,0,0,.12)}.datatable td,table,table tbody tr,table td,table th{position:relative}.checkbox-ripple .ripple{background:#3f51b5}.checkbox.is-disabled .checkbox-ripple{cursor:auto}.checkbox.is-disabled .checkbox-ripple .ripple{background:0 0}table{width:100%;max-width:100%;white-space:wrap;font-size:12px;line-height:16px;background-color:#fff;color:#000;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}.bigfoot-heading,.datatable,.link-list a,.menu-item,.textfield__label,ul.nowrap{white-space:nowrap}table thead{padding-bottom:3px}table tbody tr{height:48px;-webkit-transition-duration:.28s;transition-duration:.28s;transition-timing-function:cubic-bezier(.4,0,.2,1);-webkit-transition-property:background-color;transition-property:background-color}table tbody tr:hover{background-color:#eee}table td,table th{padding:6px;margin:0;height:32px;box-sizing:border-box}table td{text-align:left}table th{vertical-align:bottom;text-align:center;text-overflow:ellipsis;font-size:14px;line-height:24px;letter-spacing:0;font-weight:700;color:rgba(0,0,0,.54)}.datatable td,.icon,.layout-title.floating-title,.switch{vertical-align:middle}@media (min-width:40em){table{font-size:13px}th{font-size:15px}}.datatable thead .datatable-select{margin-top:0}.datatable tbody tr.is-selected{background-color:#e0e0e0}.datatable td,.datatable th{padding:0 18px;text-align:right}.datatable td:first-of-type,.datatable th:first-of-type{padding-left:24px}.datatable td:last-of-type,.datatable th:last-of-type{padding-right:24px}.datatable td{height:48px;border-top:1px solid rgba(0,0,0,.12);border-bottom:1px solid rgba(0,0,0,.12);padding-top:12px;box-sizing:border-box}.datatable td .datatable-select{vertical-align:middle;position:absolute;left:24px}.datatable th .datatable-select{position:relative}.datatable-select{width:16px}.datatable-cell.non-numeric{text-align:left}.datatable-cell.justified,.icon-label{text-align:center}footer{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:row wrap;-ms-flex-flow:row wrap;flex-flow:row wrap;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;padding:4px 2px;color:#9e9e9e;background-color:#424242}footer:after{content:'';display:block}footer>.left-section{display:inline-block;-webkit-box-ordinal-group:1;-webkit-order:0;-ms-flex-order:0;order:0}footer>.right-section{display:inline-block;-webkit-box-ordinal-group:2;-webkit-order:1;-ms-flex-order:1;order:1}footer>.social-btn{width:9px;height:9px;padding:0;margin:0;background-color:#9e9e9e;border:none}.link-list{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:row nowrap;-ms-flex-flow:row nowrap;flex-flow:row nowrap;margin:0;padding:0}.link-list li{margin-bottom:0;margin-right:16px}.link-list a{color:inherit}.bigfoot{padding:16px 40px;color:#9e9e9e;background-color:#424242}.bigfoot-bottom-section:after,.bigfoot-middle-section:after,.bigfoot-top-section:after{content:'';display:block;clear:both}.bigfoot-left-section,.bigfoot-right-section{margin-bottom:16px}.bigfoot-right-section a{display:block;margin-bottom:16px;color:inherit;text-decoration:none}@media screen and (min-width:760px){.link-list li{line-height:9px}.bigfoot-left-section{float:left}.bigfoot-right-section{float:right}.bigfoot-right-section a{display:inline-block;margin-left:16px;line-height:36px;vertical-align:middle}}.bigfoot-social-btn{width:36px;height:36px;padding:0;margin:0;background-color:#9e9e9e;border:none}.bigfoot-drop-down-section{display:block;position:relative}@media screen and (min-width:760px){.bigfoot-drop-down-section{width:33%}.bigfoot-drop-down-section:nth-child(1),.bigfoot-drop-down-section:nth-child(2){float:left}.bigfoot-drop-down-section:nth-child(3){float:right}.bigfoot-drop-down-section:nth-child(3):after{clear:right}.bigfoot-drop-down-section:nth-child(4){clear:right;float:right}.bigfoot-middle-section:after{content:'';display:block;clear:both}.bigfoot-bottom-section{padding-top:0}}#about,.bigfoot-link-list:after,.container:after{clear:both}@media screen and (min-width:1024px){.bigfoot-drop-down-section,.bigfoot-drop-down-section:nth-child(3),.bigfoot-drop-down-section:nth-child(4){width:24%;float:left}}.bigfoot-heading-checkbox{position:absolute;width:100%;height:68px;padding:32px;margin:-16px 0 0;cursor:pointer;z-index:1;opacity:0}.bigfoot-heading-checkbox~.bigfoot-heading:after{font-family:'ff Icons';content:'\E5CE'}.bigfoot-heading-checkbox:checked~ul{display:none}.bigfoot-heading-checkbox:checked~.bigfoot-heading:after{font-family:'ff Icons';content:'\E5CF'}.bigfoot-heading:after,.bigfoot-link-list:after{display:block;content:''}.bigfoot-heading{position:relative;width:100%;padding-right:52px;margin-bottom:16px;box-sizing:border-box;font-size:24px;line-height:36px;font-weight:500;text-overflow:ellipsis;overflow:hidden;color:#e0e0e0}.bigfoot-link-list li,.menu-item{font-weight:400;letter-spacing:0}.bigfoot-heading:after{position:absolute;top:0;right:0;width:36px;height:36px;background-size:cover}.bigfoot-link-list{list-style:none;margin:0 0 32px;padding:0}.bigfoot-link-list li{font-size:14px;line-height:20px}.bigfoot-link-list a{color:inherit;white-space:nowrap}@media screen and (min-width:760px){.bigfoot-heading-checkbox{display:none}.bigfoot-heading-checkbox~.bigfoot-heading:after{background-image:none}.bigfoot-heading-checkbox:checked~ul{display:block}.bigfoot-heading-checkbox:checked~.bigfoot-heading:after{content:''}}.icon,.icon-label{display:inline-block}.bigfoot-bottom-section{padding-top:16px;margin-bottom:16px}.logo{margin-bottom:16px;color:#fff}.bigfoot-bottom-section .bigfoot-link-list li{float:left;margin-bottom:0;margin-right:16px}@media screen and (min-width:760px){.logo{float:left;margin-bottom:0;margin-right:16px}}.icon{position:relative;z-index:1;height:32px;margin:0;padding:0}.icon-input{line-height:32px}.icon.is-upgraded .icon-input{position:absolute;width:0;height:0;margin:0;padding:0;opacity:0;-ms-appearance:none;-moz-appearance:none;-webkit-appearance:none;appearance:none;border:none}.icon-label{position:relative;cursor:pointer;height:32px;width:32px;min-width:32px;color:#616161;border-radius:50%;padding:0;margin-left:0;margin-right:0;background-color:transparent;will-change:background-color;-webkit-transition:background-color .2s cubic-bezier(.4,0,.2,1),color .2s cubic-bezier(.4,0,.2,1);transition:background-color .2s cubic-bezier(.4,0,.2,1),color .2s cubic-bezier(.4,0,.2,1)}.layout-drawer,.menu-outline,.tooltip{will-change:transform}.icon-label.material-icons{line-height:32px;font-size:24px}.icon.is-checked .icon-label{color:#3f51b5}.icon.is-disabled .icon-label{color:rgba(0,0,0,.26);cursor:auto;-webkit-transition:none;transition:none}.icon.is-focused .icon-label{background-color:rgba(0,0,0,.12)}.icon.is-focused.is-checked .icon-label{background-color:rgba(63,81,181,.26)}.icon-ripple{position:absolute;z-index:2;top:-2px;left:-2px;width:36px;height:36px;border-radius:50%;cursor:pointer}.menu,.menu-outline{position:absolute;top:0;left:0}.icon-ripple .ripple{background:#616161}.icon.is-disabled .icon-ripple{cursor:auto}.icon.is-disabled .icon-ripple .ripple{background:0 0}.menu-container{display:block;margin:0;padding:0;border:none;position:absolute;overflow:visible;height:0;width:0;z-index:-1}.menu-container.is-visible{z-index:999}.menu-outline{background:#fff;padding:0;border-radius:2px;overflow:hidden;opacity:0;-webkit-transform:scale(0);-ms-transform:scale(0);transform:scale(0);-webkit-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);-webkit-transition:-webkit-transform .3s cubic-bezier(.4,0,.2,1),opacity .2s cubic-bezier(.4,0,.2,1);transition:transform .3s cubic-bezier(.4,0,.2,1),opacity .2s cubic-bezier(.4,0,.2,1);z-index:-1}.menu-item,.menu-outline{margin:0;display:block;border:none}.menu-item,.menu-item[disabled],.menu-item[disabled]:focus,.menu-item[disabled]:hover{background-color:transparent}.menu-container.is-visible .menu-outline{opacity:1;-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);z-index:999}.menu-outline.menu--bottom-right{-webkit-transform-origin:100% 0;-ms-transform-origin:100% 0;transform-origin:100% 0}.menu-outline.menu--top-left{-webkit-transform-origin:0 100%;-ms-transform-origin:0 100%;transform-origin:0 100%}.menu-outline.menu--top-right{-webkit-transform-origin:100% 100%;-ms-transform-origin:100% 100%;transform-origin:100% 100%}.menu{height:auto;width:auto;min-width:124px;padding:8px 0;margin:0;opacity:0;clip:rect(0 0 0 0);z-index:-1}.menu-container.is-visible .menu{opacity:1;z-index:999}.menu.is-animating{-webkit-transition:opacity .2s cubic-bezier(.4,0,.2,1),clip .3s cubic-bezier(.4,0,.2,1);transition:opacity .2s cubic-bezier(.4,0,.2,1),clip .3s cubic-bezier(.4,0,.2,1)}.menu.menu--bottom-right{left:auto;right:0}.menu.menu--top-left{top:auto;bottom:0}.menu.menu--top-right{top:auto;left:auto;bottom:0;right:0}.menu.menu--unaligned{top:auto;left:auto}.menu-item{color:rgba(0,0,0,.87);text-align:left;padding:0 16px;outline-color:#bdbdbd;position:relative;overflow:hidden;font-size:14px;cursor:pointer;height:48px;line-height:48px;opacity:0;-webkit-transition:opacity .2s cubic-bezier(.4,0,.2,1);transition:opacity .2s cubic-bezier(.4,0,.2,1);user-select:none}.layout-tab-bar-button,.menu-item{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.menu-item:focus,.textfield.is-focused .textfield__input{outline:0}.menu-container.is-visible .menu-item{opacity:1}.menu-item::-moz-focus-inner{border:0}.menu-item[disabled]{color:#bdbdbd;cursor:auto}.menu-item[disabled] .ripple{background:0 0}.menu-item:focus,.menu-item:hover{background-color:#eee}.menu-item:active{background-color:#e0e0e0}.menu-item-ripple-container{display:block;height:100%;left:0;position:absolute;top:0;width:100%;z-index:0;overflow:hidden}.progress{display:block;position:relative;height:4px;width:500px}.progress>.bar{display:block;position:absolute;top:0;bottom:0;width:0;-webkit-transition:width .2s cubic-bezier(.4,0,.2,1);transition:width .2s cubic-bezier(.4,0,.2,1)}.layout,.navigation{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox}.progress>.progressbar{background-color:#3f51b5;z-index:1;left:0}.progress>.bufferbar{background-image:-webkit-linear-gradient(left,rgba(255,255,255,.7),rgba(255,255,255,.7)),-webkit-linear-gradient(left,#3f51b5,#3f51b5);background-image:linear-gradient(to right,rgba(255,255,255,.7),rgba(255,255,255,.7)),linear-gradient(to right,#3f51b5,#3f51b5);z-index:0;left:0}.progress>.auxbar{right:0}@supports (-webkit-appearance:none){.progress:not(.progress-indeterminate):not(.progress-indeterminate)>.auxbar{background-image:-webkit-linear-gradient(left,rgba(255,255,255,.7),rgba(255,255,255,.7)),-webkit-linear-gradient(left,#3f51b5,#3f51b5);background-image:linear-gradient(to right,rgba(255,255,255,.7),rgba(255,255,255,.7)),linear-gradient(to right,#3f51b5,#3f51b5);-webkit-mask:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8c3ZnIHdpZHRoPSIxMiIgaGVpZ2h0PSI0IiB2aWV3UG9ydD0iMCAwIDEyIDQiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCiAgPGVsbGlwc2UgY3g9IjIiIGN5PSIyIiByeD0iMiIgcnk9IjIiPg0KICAgIDxhbmltYXRlIGF0dHJpYnV0ZU5hbWU9ImN4IiBmcm9tPSIyIiB0bz0iLTEwIiBkdXI9IjAuNnMiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPg0KICA8L2VsbGlwc2U+DQogIDxlbGxpcHNlIGN4PSIxNCIgY3k9IjIiIHJ4PSIyIiByeT0iMiIgY2xhc3M9ImxvYWRlciI+DQogICAgPGFuaW1hdGUgYXR0cmlidXRlTmFtZT0iY3giIGZyb209IjE0IiB0bz0iMiIgZHVyPSIwLjZzIiByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4NCiAgPC9lbGxpcHNlPg0KPC9zdmc+DQo=);mask:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8c3ZnIHdpZHRoPSIxMiIgaGVpZ2h0PSI0IiB2aWV3UG9ydD0iMCAwIDEyIDQiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCiAgPGVsbGlwc2UgY3g9IjIiIGN5PSIyIiByeD0iMiIgcnk9IjIiPg0KICAgIDxhbmltYXRlIGF0dHJpYnV0ZU5hbWU9ImN4IiBmcm9tPSIyIiB0bz0iLTEwIiBkdXI9IjAuNnMiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPg0KICA8L2VsbGlwc2U+DQogIDxlbGxpcHNlIGN4PSIxNCIgY3k9IjIiIHJ4PSIyIiByeT0iMiIgY2xhc3M9ImxvYWRlciI+DQogICAgPGFuaW1hdGUgYXR0cmlidXRlTmFtZT0iY3giIGZyb209IjE0IiB0bz0iMiIgZHVyPSIwLjZzIiByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4NCiAgPC9lbGxpcHNlPg0KPC9zdmc+DQo=)}}.progress:not(.progress-indeterminate)>.auxbar{background-image:-webkit-linear-gradient(left,rgba(255,255,255,.9),rgba(255,255,255,.9)),-webkit-linear-gradient(left,#3f51b5,#3f51b5);background-image:linear-gradient(to right,rgba(255,255,255,.9),rgba(255,255,255,.9)),linear-gradient(to right,#3f51b5,#3f51b5)}.progress.progress-indeterminate>.bar1{background-color:#3f51b5;-webkit-animation-name:indeterminate1;animation-name:indeterminate1;animation-duration:2s;animation-iteration-count:infinite;animation-timing-function:linear}.progress.progress-indeterminate>.bar1,.progress.progress-indeterminate>.bar3{-webkit-animation-duration:2s;-webkit-animation-iteration-count:infinite;-webkit-animation-timing-function:linear}.progress.progress-indeterminate>.bar3{background-image:none;background-color:#3f51b5;-webkit-animation-name:indeterminate2;animation-name:indeterminate2;animation-duration:2s;animation-iteration-count:infinite;animation-timing-function:linear}@-webkit-keyframes indeterminate1{0%{left:0;width:0}50%{left:25%;width:75%}75%{left:100%;width:0}}@keyframes indeterminate1{0%{left:0;width:0}50%{left:25%;width:75%}75%{left:100%;width:0}}@-webkit-keyframes indeterminate2{0%,50%{left:0;width:0}75%{left:0;width:25%}100%{left:100%;width:0}}@keyframes indeterminate2{0%,50%{left:0;width:0}75%{left:0;width:25%}100%{left:100%;width:0}}.navigation{display:flex;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;box-sizing:border-box}.navigation-link{color:#424242;font-weight:500;font-size:13px;margin:0}.layout{width:100%;height:100%;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;overflow-y:auto;overflow-x:hidden;position:relative;-webkit-overflow-scrolling:touch}.layout-transparent>.layout-header,.layout-transparent>.littlefoot{color:#fff;background-color:rgba(0,0,0,.35);box-shadow:none}.layout-transparent>.layout-drawer{color:#fff;text-shadow:0 1px 3px rgba(0,0,0,.5);background-color:rgba(0,0,0,.35);border-right:1px solid #000}.layout-transparent>.layout-drawer-button{color:#fff;background-color:transparent;box-shadow:none}.layout-shadow{box-shadow:inset 0 0 100px rgba(0,0,0,.5)}.layout-drawer,.layout-header{box-sizing:border-box;-webkit-box-orient:vertical;box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)}.layout.is-small-screen .layout-large-screen-only,.layout:not(.is-small-screen) .layout-small-screen-only{display:none}.layout-container{position:absolute;width:100%;height:100%}.layout-title{display:block;position:relative;font-family:Roboto,Helvetica,Arial,sans-serif;font-size:20px;line-height:1;letter-spacing:.02em;font-weight:400;box-sizing:border-box}.layout-tab,.tabs__tab,.tooltip{text-align:center;font-weight:500}.layout-title.floating-title{position:absolute;top:0;left:52px;height:48px;line-height:44px;z-index:2}.layout-spacer{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.layout-drawer{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;width:240px;height:100%;max-height:100%;position:absolute;top:0;left:0;border-right:1px solid #e0e0e0;background:#fafafa;-webkit-transform:translateX(-250px);-ms-transform:translateX(-250px);transform:translateX(-250px);-webkit-transform-style:preserve-3d;transform-style:preserve-3d;-webkit-transition-duration:.2s;transition-duration:.2s;-webkit-transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(.4,0,.2,1);-webkit-transition-property:-webkit-transform;transition-property:transform;color:#424242;overflow:visible;overflow-y:auto;z-index:5}.layout-drawer.is-visible{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}.layout-drawer>*{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0}.layout-drawer>.layout-title{line-height:64px;padding-left:40px}@media screen and (max-width:1024px){.layout-drawer>.layout-title{line-height:56px;padding-left:16px}}.layout-drawer .navigation{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:stretch;-webkit-align-items:stretch;-ms-flex-align:stretch;align-items:stretch;padding-top:16px}.layout-drawer .navigation .navigation-link{display:block;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;padding:16px 40px;margin:0;color:#757575}.layout-drawer .navigation .navigation-link:hover{background-color:#e0e0e0}.layout-drawer .navigation .navigation-link--current{background-color:#000;color:#3f51b5}.layout-drawer-button{display:block;position:absolute;height:48px;width:48px;border:0;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;overflow:hidden;text-align:center;cursor:pointer;font-size:26px;line-height:50px;font-family:Helvetica,Arial,sans-serif;margin:10px 12px;top:0;left:0;color:#fff;z-index:4}.layout-header .layout-drawer-button{position:absolute;color:#fff;background-color:inherit}@media screen and (max-width:1024px){.layout-drawer .navigation .navigation-link{padding:16px}.layout-header .layout-drawer-button{margin:4px}.layout-drawer-button{margin:4px;color:rgba(0,0,0,.5)}}@media screen and (min-width:1025px){.layout-fixed-drawer>.layout-drawer{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}.layout-fixed-drawer>.layout-drawer-button{display:none}}.layout-header{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-pack:start;-webkit-justify-content:flex-start;-ms-flex-pack:start;justify-content:flex-start;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;width:100%;margin:0;padding:0;border:none;min-height:64px;max-height:1000px;z-index:3;background-color:#3f51b5;color:#fff;-webkit-transition-duration:.2s;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1);-webkit-transition-property:max-height,box-shadow;transition-property:max-height,box-shadow}.layout-header,.layout-obfuscator{-webkit-transition-timing-function:cubic-bezier(.4,0,.2,1)}.layout-fixed-drawer:not(.is-small-screen)>.layout-header{margin-left:240px;width:calc(100% - 240px)}.layout-header-row,.layout-header-row .navigation{-webkit-box-orient:horizontal;-webkit-box-direction:normal;margin:0}.layout-fixed-drawer>.layout-header .layout-header-row{padding-left:40px}.layout-header>.layout-icon{position:absolute;left:40px;top:16px;height:32px;width:32px;overflow:hidden;z-index:3;display:block}.layout.has-drawer .layout-header>.layout-icon{display:none}.layout-header.is-compact{max-height:64px}.layout-header.is-compact.has-tabs{height:112px}@media screen and (max-width:1024px){.layout-header{min-height:56px;display:none}.layout-header>.layout-icon{left:16px;top:12px}.layout-header.is-compact{max-height:56px}.layout-header.is-compact.has-tabs{min-height:104px}.layout-fixed-header>.layout-header{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}}.layout-header--transparent.layout-header--transparent{background-color:transparent;box-shadow:none}.layout-header--scroll,.layout-header--seamed{box-shadow:none}.layout-header--waterfall{box-shadow:none;overflow:hidden}.layout-header--waterfall.is-casting-shadow,.switch__thumb{box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)}.layout-header-row{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;box-sizing:border-box;-webkit-align-self:stretch;-ms-flex-item-align:stretch;align-self:stretch;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;height:64px;padding:0 40px 0 80px}@media screen and (max-width:1024px){.layout-header-row{height:56px;padding:0 16px 0 72px}}.layout-header-row>*{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0}.layout-header--scroll .layout-header-row{width:100%}.layout-header-row .navigation{padding:0;height:64px;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.layout-header-row .navigation-link{display:block;color:#fff;line-height:64px;padding:0 24px}@media screen and (max-width:1024px){.layout-header-row .navigation{height:56px}.layout-header-row .navigation-link{line-height:56px;padding:0 16px}}.layout-tab,.layout-tab-bar-button .material-icons{line-height:48px}.layout-obfuscator{background-color:transparent;position:absolute;top:0;left:0;height:100%;width:100%;z-index:4;visibility:hidden;-webkit-transition-property:background-color;transition-property:background-color;-webkit-transition-duration:.2s;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.layout-drawer.is-visible~.layout-obfuscator{background-color:rgba(0,0,0,.5);visibility:visible}.layout-content{-ms-flex:0 1 auto;display:inline-block;overflow-y:auto;overflow-x:hidden;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;z-index:1;-webkit-overflow-scrolling:touch}.layout-fixed-drawer>.layout-content{margin-left:240px}.layout-container.has-scrolling-header .layout-content{overflow:visible}@media screen and (max-width:1024px){.layout-fixed-drawer>.layout-content{margin-left:0}.layout-container.has-scrolling-header .layout-content{overflow-y:auto;overflow-x:hidden}}.layout-tab-bar{height:96px;margin:0;width:calc(100% - 112px);padding:0 0 0 56px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;background-color:#3f51b5;overflow-y:hidden;overflow-x:scroll}.layout-tab-bar::-webkit-scrollbar{display:none}@media screen and (max-width:1024px){.layout-tab-bar{width:calc(100% - 60px);padding:0 0 0 60px}}.layout-fixed-tabs .layout-tab-bar{padding:0;overflow:hidden;width:100%}.layout-tab-bar-container{position:relative;height:48px;width:100%;border:none;margin:0;z-index:2;-webkit-box-flex:0;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;overflow:hidden}.layout-container>.layout-tab-bar-container{position:absolute;top:0;left:0}.layout-tab-bar-button{display:inline-block;position:absolute;top:0;height:48px;width:56px;z-index:4;text-align:center;background-color:#3f51b5;color:transparent;cursor:pointer;user-select:none}@media screen and (max-width:1024px){.layout-tab-bar-button{display:none;width:60px}}.layout-fixed-tabs .layout-tab-bar-button{display:none}.layout-tab-bar-button.is-active{color:#fff}.layout-tab-bar-left-button{left:0}.layout-tab-bar-right-button{right:0}.layout-tab{margin:0;border:none;padding:0 24px;float:left;position:relative;display:block;-webkit-box-flex:0;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;height:48px;font-size:14px;color:rgba(255,255,255,.6);overflow:hidden}.radio,.radio__button,.switch__input,.switch__label{line-height:24px}@media screen and (max-width:1024px){.layout-tab{padding:0 12px}}.layout-fixed-tabs .layout-tab{float:none;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;padding:0}.layout.is-upgraded .layout-tab.is-active{color:#fff}.layout.is-upgraded .layout-tab.is-active::after{height:2px;width:100%;display:block;content:" ";bottom:0;left:0;position:absolute;background:#ff4081;-webkit-animation:border-expand .2s cubic-bezier(.4,0,.4,1) .01s alternate forwards;animation:border-expand .2s cubic-bezier(.4,0,.4,1) .01s alternate forwards;-webkit-transition:all 1s cubic-bezier(.4,0,1,1);transition:all 1s cubic-bezier(.4,0,1,1)}.layout-tab .layout-tab-ripple-container{display:block;position:absolute;height:100%;width:100%;left:0;top:0;z-index:1;overflow:hidden}.layout-tab .layout-tab-ripple-container .ripple{background-color:#fff}.layout-tab-panel{display:block}.layout.is-upgraded .layout-tab-panel{display:none}.layout.is-upgraded .layout-tab-panel.is-active{display:block}.radio,.radio__outer-circle{margin:0;box-sizing:border-box;display:inline-block}.radio{position:relative;font-size:16px;padding-left:0}.radio.is-upgraded{padding-left:24px}.radio.is-upgraded .radio__button{position:absolute;width:0;height:0;margin:0;padding:0;opacity:0;-ms-appearance:none;-moz-appearance:none;-webkit-appearance:none;appearance:none;border:none}.radio__outer-circle{position:absolute;top:2px;left:0;width:16px;height:16px;cursor:pointer;border:2px solid rgba(0,0,0,.54);border-radius:50%;z-index:2}.radio.is-checked .radio__outer-circle{border:2px solid #3f51b5}.radio.is-disabled .radio__outer-circle{border:2px solid rgba(0,0,0,.26);cursor:auto}.radio-ripple,.radio__inner-circle{position:absolute;border-radius:50%}.radio__inner-circle{z-index:1;margin:0;top:6px;left:4px;box-sizing:border-box;width:8px;height:8px;cursor:pointer;-webkit-transition-duration:.28s;transition-duration:.28s;-webkit-transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(.4,0,.2,1);-webkit-transition-property:-webkit-transform;transition-property:transform;-webkit-transform:scale3d(0,0,0);transform:scale3d(0,0,0);background:#3f51b5}.radio-ripple,.switch-ripple{box-sizing:border-box;z-index:2;-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000)}.radio.is-checked .radio__inner-circle{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}.radio.is-disabled .radio__inner-circle{background:rgba(0,0,0,.26);cursor:auto}.radio.is-focused .radio__inner-circle{box-shadow:0 0 0 10px rgba(0,0,0,.1)}.radio__label{cursor:pointer}.radio.is-disabled .radio__label{color:rgba(0,0,0,.26);cursor:auto}.radio-ripple{top:-9px;left:-13px;width:42px;height:42px;cursor:pointer;overflow:hidden}.radio-ripple .ripple{background:#3f51b5}.radio.is-disabled .radio-ripple{cursor:auto}.radio.is-disabled .radio-ripple .ripple{background:0 0}:root .slider.slider.is-upgraded,_:-ms-input-placeholder{-ms-appearance:none;height:32px;margin:0}.slider{width:calc(100% - 40px);margin:0 20px}.slider.is-upgraded{-webkit-appearance:none;-moz-appearance:none;appearance:none;height:2px;background:0 0;user-select:none;outline:0;padding:0;color:#3f51b5;-webkit-align-self:center;-ms-flex-item-align:center;align-self:center;z-index:1}.slider.is-upgraded,.switch{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.slider.is-upgraded::-moz-focus-outer{border:0}.slider.is-upgraded::-ms-tooltip{display:none}.slider.is-upgraded::-webkit-slider-runnable-track{background:0 0}.slider.is-upgraded::-moz-range-track{background:0 0;border:none}.slider.is-upgraded::-ms-track{background:0 0;color:transparent;height:2px;width:100%;border:none}.slider.is-upgraded::-ms-fill-lower{padding:0;background:linear-gradient(to right,transparent,transparent 16px,#3f51b5 16px,#3f51b5 0)}.slider.is-upgraded::-ms-fill-upper{padding:0;background:linear-gradient(to left,transparent,transparent 16px,rgba(0,0,0,.26) 16px,rgba(0,0,0,.26) 0)}.slider.is-upgraded::-webkit-slider-thumb{-webkit-appearance:none;width:12px;height:12px;box-sizing:border-box;border-radius:50%;background:#3f51b5;border:none;-webkit-transition:-webkit-transform .18s cubic-bezier(.4,0,.2,1),border .18s cubic-bezier(.4,0,.2,1),box-shadow .18s cubic-bezier(.4,0,.2,1),background .28s cubic-bezier(.4,0,.2,1);transition:transform .18s cubic-bezier(.4,0,.2,1),border .18s cubic-bezier(.4,0,.2,1),box-shadow .18s cubic-bezier(.4,0,.2,1),background .28s cubic-bezier(.4,0,.2,1)}.slider.is-upgraded::-moz-range-thumb{-moz-appearance:none;width:12px;height:12px;box-sizing:border-box;border-radius:50%;background:#3f51b5;border:none}.slider.is-upgraded:focus:not(:active)::-webkit-slider-thumb{box-shadow:0 0 0 10px rgba(63,81,181,.26)}.slider.is-upgraded:focus:not(:active)::-moz-range-thumb{box-shadow:0 0 0 10px rgba(63,81,181,.26)}.slider.is-upgraded:active::-webkit-slider-thumb{background:#3f51b5;-webkit-transform:scale(1.5);transform:scale(1.5)}.slider.is-upgraded:active::-moz-range-thumb{background:#3f51b5;transform:scale(1.5)}.slider.is-upgraded::-ms-thumb{width:32px;height:32px;border:none;border-radius:50%;background:#3f51b5;-ms-transform:scale(.375);transform:scale(.375);transition:transform .18s cubic-bezier(.4,0,.2,1),background .28s cubic-bezier(.4,0,.2,1)}.slider.is-upgraded:focus:not(:active)::-ms-thumb{background:radial-gradient(circle closest-side,#3f51b5 0,#3f51b5 37.5%,rgba(63,81,181,.26) 37.5%,rgba(63,81,181,.26) 100%);-ms-transform:scale(1);transform:scale(1)}.slider.is-upgraded:active::-ms-thumb{background:#3f51b5;-ms-transform:scale(.5625);transform:scale(.5625)}.slider.is-upgraded.is-lowest-value::-webkit-slider-thumb{border:2px solid rgba(0,0,0,.26);background:0 0}.slider.is-upgraded.is-lowest-value::-moz-range-thumb{border:2px solid rgba(0,0,0,.26);background:0 0}.slider.is-upgraded.is-lowest-value~.slider__background-flex>.slider__background-upper{left:6px}.slider.is-upgraded.is-lowest-value:focus:not(:active)::-webkit-slider-thumb{box-shadow:0 0 0 10px rgba(0,0,0,.12);background:rgba(0,0,0,.12)}.slider.is-upgraded.is-lowest-value:focus:not(:active)::-moz-range-thumb{box-shadow:0 0 0 10px rgba(0,0,0,.12);background:rgba(0,0,0,.12)}.slider.is-upgraded.is-lowest-value:active::-webkit-slider-thumb{border:1.6px solid rgba(0,0,0,.26);-webkit-transform:scale(1.5);transform:scale(1.5)}.slider.is-upgraded.is-lowest-value:active~.slider__background-flex>.slider__background-upper{left:9px}.slider.is-upgraded.is-lowest-value:active::-moz-range-thumb{border:1.5px solid rgba(0,0,0,.26);transform:scale(1.5)}.slider.is-upgraded.is-lowest-value::-ms-thumb{background:radial-gradient(circle closest-side,transparent 0,transparent 66.67%,rgba(0,0,0,.26) 66.67%,rgba(0,0,0,.26) 100%)}.slider.is-upgraded.is-lowest-value:focus:not(:active)::-ms-thumb{background:radial-gradient(circle closest-side,rgba(0,0,0,.12) 0,rgba(0,0,0,.12) 25%,rgba(0,0,0,.26) 25%,rgba(0,0,0,.26) 37.5%,rgba(0,0,0,.12) 37.5%,rgba(0,0,0,.12) 100%);-ms-transform:scale(1);transform:scale(1)}.slider.is-upgraded.is-lowest-value:active::-ms-thumb{-ms-transform:scale(.5625);transform:scale(.5625);background:radial-gradient(circle closest-side,transparent 0,transparent 77.78%,rgba(0,0,0,.26) 77.78%,rgba(0,0,0,.26) 100%)}.slider.is-upgraded.is-lowest-value::-ms-fill-lower{background:0 0}.slider.is-upgraded.is-lowest-value::-ms-fill-upper{margin-left:6px}.slider.is-upgraded.is-lowest-value:active::-ms-fill-upper{margin-left:9px}.slider.is-upgraded:disabled::-webkit-slider-thumb,.slider.is-upgraded:disabled:active::-webkit-slider-thumb,.slider.is-upgraded:disabled:focus::-webkit-slider-thumb{-webkit-transform:scale(.667);transform:scale(.667);background:rgba(0,0,0,.26)}.slider.is-upgraded:disabled::-moz-range-thumb,.slider.is-upgraded:disabled:active::-moz-range-thumb,.slider.is-upgraded:disabled:focus::-moz-range-thumb{transform:scale(.667);background:rgba(0,0,0,.26)}.slider.is-upgraded:disabled~.slider__background-flex>.slider__background-lower{background-color:rgba(0,0,0,.26);left:-6px}.slider.is-upgraded.is-lowest-value:disabled:active~.slider__background-flex>.slider__background-upper,.slider.is-upgraded:disabled~.slider__background-flex>.slider__background-upper{left:6px}.slider.is-upgraded.is-lowest-value:disabled::-webkit-slider-thumb,.slider.is-upgraded.is-lowest-value:disabled:active::-webkit-slider-thumb,.slider.is-upgraded.is-lowest-value:disabled:focus::-webkit-slider-thumb{border:3px solid rgba(0,0,0,.26);background:0 0;-webkit-transform:scale(.667);transform:scale(.667)}.slider.is-upgraded.is-lowest-value:disabled::-moz-range-thumb,.slider.is-upgraded.is-lowest-value:disabled:active::-moz-range-thumb,.slider.is-upgraded.is-lowest-value:disabled:focus::-moz-range-thumb{border:3px solid rgba(0,0,0,.26);background:0 0;transform:scale(.667)}.slider.is-upgraded:disabled::-ms-thumb,.slider.is-upgraded:disabled:active::-ms-thumb,.slider.is-upgraded:disabled:focus::-ms-thumb{-ms-transform:scale(.25);transform:scale(.25);background:rgba(0,0,0,.26)}.slider.is-upgraded.is-lowest-value:disabled::-ms-thumb,.slider.is-upgraded.is-lowest-value:disabled:active::-ms-thumb,.slider.is-upgraded.is-lowest-value:disabled:focus::-ms-thumb{-ms-transform:scale(.25);transform:scale(.25);background:radial-gradient(circle closest-side,transparent 0,transparent 50%,rgba(0,0,0,.26) 50%,rgba(0,0,0,.26) 100%)}.slider.is-upgraded:disabled::-ms-fill-lower{margin-right:6px;background:linear-gradient(to right,transparent,transparent 25px,rgba(0,0,0,.26) 25px,rgba(0,0,0,.26) 0)}.slider__background-flex,.slider__container{background:0 0;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox}.slider.is-upgraded:disabled::-ms-fill-upper{margin-left:6px}.slider.is-upgraded.is-lowest-value:disabled:active::-ms-fill-upper{margin-left:6px}.slider__ie-container{height:18px;overflow:visible;border:none;margin:none;padding:none}.slider__container{height:18px;position:relative;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row}.slider__background-flex{position:absolute;height:2px;width:calc(100% - 52px);top:50%;left:0;margin:0 26px;display:flex;overflow:hidden;border:0;padding:0;-webkit-transform:translate(0,-1px);-ms-transform:translate(0,-1px);transform:translate(0,-1px)}.spinner,.switch,.switch__focus-helper{display:inline-block}.slider__background-lower{background:#3f51b5;-webkit-box-flex:0;-webkit-flex:0;-ms-flex:0;flex:0;position:relative;border:0;padding:0}.slider__background-upper{background:rgba(0,0,0,.26);-webkit-box-flex:0;-webkit-flex:0;-ms-flex:0;flex:0;position:relative;border:0;padding:0;-webkit-transition:left .18s cubic-bezier(.4,0,.2,1);transition:left .18s cubic-bezier(.4,0,.2,1)}.spinner{position:relative;width:28px;height:28px}.spinner:not(.is-upgraded).is-active:after{content:"Loading..."}.spinner.is-upgraded.is-active{-webkit-animation:spinner__container-rotate 1568.23529412ms linear infinite;animation:spinner__container-rotate 1568.23529412ms linear infinite}@-webkit-keyframes spinner__container-rotate{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spinner__container-rotate{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.spinner__layer{position:absolute;width:100%;height:100%;opacity:0}.spinner__layer-1{border-color:#42a5f5}.spinner--single-color .spinner__layer-1{border-color:#3f51b5}.spinner.is-active .spinner__layer-1{-webkit-animation:spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1) infinite both,spinner__layer-1-fade-in-out 5332ms cubic-bezier(.4,0,.2,1) infinite both;animation:spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1) infinite both,spinner__layer-1-fade-in-out 5332ms cubic-bezier(.4,0,.2,1) infinite both}.spinner__layer-2{border-color:#f44336}.spinner--single-color .spinner__layer-2{border-color:#3f51b5}.spinner.is-active .spinner__layer-2{-webkit-animation:spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1) infinite both,spinner__layer-2-fade-in-out 5332ms cubic-bezier(.4,0,.2,1) infinite both;animation:spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1) infinite both,spinner__layer-2-fade-in-out 5332ms cubic-bezier(.4,0,.2,1) infinite both}.spinner__layer-3{border-color:#fdd835}.spinner--single-color .spinner__layer-3{border-color:#3f51b5}.spinner.is-active .spinner__layer-3{-webkit-animation:spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1) infinite both,spinner__layer-3-fade-in-out 5332ms cubic-bezier(.4,0,.2,1) infinite both;animation:spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1) infinite both,spinner__layer-3-fade-in-out 5332ms cubic-bezier(.4,0,.2,1) infinite both}.spinner__layer-4{border-color:#4caf50}.spinner--single-color .spinner__layer-4{border-color:#3f51b5}.spinner__circle,.spinner__circle-clipper,.spinner__gap-patch{height:100%;border-color:inherit}.spinner.is-active .spinner__layer-4{-webkit-animation:spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1) infinite both,spinner__layer-4-fade-in-out 5332ms cubic-bezier(.4,0,.2,1) infinite both;animation:spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1) infinite both,spinner__layer-4-fade-in-out 5332ms cubic-bezier(.4,0,.2,1) infinite both}@-webkit-keyframes spinner__fill-unfill-rotate{12.5%{-webkit-transform:rotate(135deg);transform:rotate(135deg)}25%{-webkit-transform:rotate(270deg);transform:rotate(270deg)}37.5%{-webkit-transform:rotate(405deg);transform:rotate(405deg)}50%{-webkit-transform:rotate(540deg);transform:rotate(540deg)}62.5%{-webkit-transform:rotate(675deg);transform:rotate(675deg)}75%{-webkit-transform:rotate(810deg);transform:rotate(810deg)}87.5%{-webkit-transform:rotate(945deg);transform:rotate(945deg)}to{-webkit-transform:rotate(1080deg);transform:rotate(1080deg)}}@keyframes spinner__fill-unfill-rotate{12.5%{-webkit-transform:rotate(135deg);transform:rotate(135deg)}25%{-webkit-transform:rotate(270deg);transform:rotate(270deg)}37.5%{-webkit-transform:rotate(405deg);transform:rotate(405deg)}50%{-webkit-transform:rotate(540deg);transform:rotate(540deg)}62.5%{-webkit-transform:rotate(675deg);transform:rotate(675deg)}75%{-webkit-transform:rotate(810deg);transform:rotate(810deg)}87.5%{-webkit-transform:rotate(945deg);transform:rotate(945deg)}to{-webkit-transform:rotate(1080deg);transform:rotate(1080deg)}}@-webkit-keyframes spinner__layer-1-fade-in-out{100%,25%,90%,from{opacity:.99}26%,89%{opacity:0}}@keyframes spinner__layer-1-fade-in-out{100%,25%,90%,from{opacity:.99}26%,89%{opacity:0}}@-webkit-keyframes spinner__layer-2-fade-in-out{15%,51%,from{opacity:0}25%,50%{opacity:.99}}@keyframes spinner__layer-2-fade-in-out{15%,51%,from{opacity:0}25%,50%{opacity:.99}}@-webkit-keyframes spinner__layer-3-fade-in-out{40%,76%,from{opacity:0}50%,75%{opacity:.99}}@keyframes spinner__layer-3-fade-in-out{40%,76%,from{opacity:0}50%,75%{opacity:.99}}@-webkit-keyframes spinner__layer-4-fade-in-out{100%,65%,from{opacity:0}75%,90%{opacity:.99}}@keyframes spinner__layer-4-fade-in-out{100%,65%,from{opacity:0}75%,90%{opacity:.99}}.spinner__gap-patch{position:absolute;box-sizing:border-box;top:0;left:45%;width:10%;overflow:hidden}.spinner__gap-patch .spinner__circle{width:1000%;left:-450%}.spinner__circle-clipper{display:inline-block;position:relative;width:50%;overflow:hidden}.spinner__circle-clipper .spinner__circle{width:200%}.spinner__circle{box-sizing:border-box;border-width:3px;border-style:solid;border-bottom-color:transparent!important;border-radius:50%;-webkit-animation:none;animation:none;position:absolute;top:0;right:0;bottom:0;left:0}.spinner__left .spinner__circle{border-right-color:transparent!important;-webkit-transform:rotate(129deg);-ms-transform:rotate(129deg);transform:rotate(129deg)}.spinner.is-active .spinner__left .spinner__circle{-webkit-animation:spinner__left-spin 1333ms cubic-bezier(.4,0,.2,1) infinite both;animation:spinner__left-spin 1333ms cubic-bezier(.4,0,.2,1) infinite both}.spinner__right .spinner__circle{left:-100%;border-left-color:transparent!important;-webkit-transform:rotate(-129deg);-ms-transform:rotate(-129deg);transform:rotate(-129deg)}.spinner.is-active .spinner__right .spinner__circle{-webkit-animation:spinner__right-spin 1333ms cubic-bezier(.4,0,.2,1) infinite both;animation:spinner__right-spin 1333ms cubic-bezier(.4,0,.2,1) infinite both}@-webkit-keyframes spinner__left-spin{from,to{-webkit-transform:rotate(130deg);transform:rotate(130deg)}50%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}}@keyframes spinner__left-spin{from,to{-webkit-transform:rotate(130deg);transform:rotate(130deg)}50%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}}@-webkit-keyframes spinner__right-spin{from,to{-webkit-transform:rotate(-130deg);transform:rotate(-130deg)}50%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}}@keyframes spinner__right-spin{from,to{-webkit-transform:rotate(-130deg);transform:rotate(-130deg)}50%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}}.switch{position:relative;z-index:1;box-sizing:border-box;width:100%;height:24px;margin:0;padding:0;overflow:visible;-webkit-touch-callout:none;user-select:none}.switch.is-upgraded{padding-left:28px}.switch.is-upgraded .switch__input{position:absolute;width:0;height:0;margin:0;padding:0;opacity:0;-ms-appearance:none;-moz-appearance:none;-webkit-appearance:none;appearance:none;border:none}.switch__track{background:rgba(0,0,0,.26);position:absolute;left:0;top:5px;height:14px;width:36px;border-radius:14px;cursor:pointer}.switch.is-checked .switch__track{background:rgba(63,81,181,.5)}.switch.is-disabled .switch__track{background:rgba(0,0,0,.12);cursor:auto}.switch__thumb{background:#fafafa;position:absolute;left:0;top:2px;height:20px;width:20px;cursor:pointer;-webkit-transition-duration:.28s;transition-duration:.28s;-webkit-transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(.4,0,.2,1);transition-property:left}.switch-ripple,.switch__thumb{border-radius:50%;-webkit-transition-property:left}.switch.is-checked .switch__thumb{background:#3f51b5;left:16px;box-shadow:0 3px 4px 0 rgba(0,0,0,.14),0 3px 3px -2px rgba(0,0,0,.2),0 1px 8px 0 rgba(0,0,0,.12)}.switch.is-disabled .switch__thumb{background:#bdbdbd;cursor:auto}.switch__focus-helper{position:absolute;top:50%;left:50%;-webkit-transform:translate(-4px,-4px);-ms-transform:translate(-4px,-4px);transform:translate(-4px,-4px);box-sizing:border-box;width:8px;height:8px;border-radius:50%;background-color:transparent}.switch.is-focused .switch__focus-helper{box-shadow:0 0 0 20px rgba(0,0,0,.1);background-color:rgba(0,0,0,.1)}.switch.is-focused.is-checked .switch__focus-helper{box-shadow:0 0 0 20px rgba(63,81,181,.26);background-color:rgba(63,81,181,.26)}.switch__label{position:relative;cursor:pointer;font-size:16px;margin:0;left:24px}.switch.is-disabled .switch__label{color:#bdbdbd;cursor:auto}.switch-ripple{position:absolute;top:-12px;left:-14px;width:48px;height:48px;cursor:pointer;overflow:hidden;-webkit-transition-duration:.4s;transition-duration:.4s;-webkit-transition-timing-function:step-end;transition-timing-function:step-end;transition-property:left}.switch-ripple .ripple{background:#3f51b5}.switch.is-disabled .switch-ripple{cursor:auto}.switch.is-disabled .switch-ripple .ripple{background:0 0}.switch.is-checked .switch-ripple{cursor:auto;left:2px}.tabs{display:block;width:100%}.tabs__tab-bar{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-align-content:space-between;-ms-flex-line-pack:justify;align-content:space-between;-webkit-box-align:start;-webkit-align-items:flex-start;-ms-flex-align:start;align-items:flex-start;height:48px;padding:0;margin:0;border-bottom:1px solid #e0e0e0}.tabs__tab{margin:0;border:none;padding:0 24px;float:left;position:relative;display:block;color:red;height:48px;line-height:48px;font-size:14px;color:rgba(0,0,0,.54);overflow:hidden}.tabs.is-upgraded .tabs__tab.is-active{color:rgba(0,0,0,.87)}.tabs.is-upgraded .tabs__tab.is-active:after{height:2px;width:100%;display:block;content:" ";bottom:0;left:0;position:absolute;background:#3f51b5;-webkit-animation:border-expand .2s cubic-bezier(.4,0,.4,1) .01s alternate forwards;animation:border-expand .2s cubic-bezier(.4,0,.4,1) .01s alternate forwards;-webkit-transition:all 1s cubic-bezier(.4,0,1,1);transition:all 1s cubic-bezier(.4,0,1,1)}.tabs__tab .tabs-ripple{display:block;position:absolute;height:100%;width:100%;left:0;top:0;z-index:1;overflow:hidden}.tabs__tab .tabs-ripple .ripple{background:#3f51b5}.tabs__panel{display:block}.tabs.is-upgraded .tabs__panel{display:none}.tabs.is-upgraded .tabs__panel.is-active{display:block}@-webkit-keyframes border-expand{0%{opacity:0;width:0}100%{opacity:1;width:100%}}@keyframes border-expand{0%{opacity:0;width:0}100%{opacity:1;width:100%}}.textfield{position:relative;font-size:16px;display:inline-block;box-sizing:border-box;width:300px;max-width:100%;margin:0;padding:20px 0}.textfield .button{position:absolute;bottom:20px}.textfield--align-right{text-align:right}.textfield--full-width{width:100%}.textfield--expandable{min-width:32px;width:auto;min-height:32px}.textfield__input,.textfield__label{display:block;font-size:16px;width:100%;text-align:left}.textfield__input{border:none;border-bottom:1px solid rgba(0,0,0,.12);margin:0;padding:4px 0;background:16px;color:inherit}.textfield.is-invalid .textfield__input{border-color:#de3226;box-shadow:none}.textfield.is-disabled .textfield__input{background-color:transparent;border-bottom:1px dotted rgba(0,0,0,.12)}.textfield textarea.textfield__input{display:block}.textfield__label{bottom:0;color:rgba(0,0,0,.26);left:0;right:0;pointer-events:none;position:absolute;top:24px;overflow:hidden}.textfield.is-dirty .textfield__label{visibility:hidden}.textfield--floating-label .textfield__label{-webkit-transition-duration:.2s;transition-duration:.2s;-webkit-transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(.4,0,.2,1)}.textfield--floating-label.is-dirty .textfield__label,.textfield--floating-label.is-focused .textfield__label{color:#3f51b5;font-size:12px;top:4px;visibility:visible}.textfield--floating-label.is-invalid .textfield__label,.textfield__error{color:#de3226;font-size:12px}.textfield--floating-label.is-dirty .textfield__expandable-holder .textfield__label,.textfield--floating-label.is-focused .textfield__expandable-holder .textfield__label{top:-16px}.textfield__label:after{background-color:#3f51b5;bottom:20px;content:'';height:2px;left:45%;position:absolute;-webkit-transition-duration:.2s;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1);visibility:hidden;width:10px}.textfield__expandable-holder,.textfield__label:after{-webkit-transition-timing-function:cubic-bezier(.4,0,.2,1)}.textfield.is-focused .textfield__label:after{left:0;visibility:visible;width:100%}.textfield.is-invalid .textfield__label:after{background-color:#de3226}.textfield__error{position:absolute;margin-top:3px;visibility:hidden;display:block}.textfield.is-invalid .textfield__error{visibility:visible}.textfield__expandable-holder{position:relative;margin-left:32px;-webkit-transition-duration:.2s;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1);display:inline-block;max-width:.1px}.textfield.is-dirty .textfield__expandable-holder,.textfield.is-focused .textfield__expandable-holder{max-width:600px}.textfield__expandable-holder .textfield__label:after{bottom:0}.tooltip{-webkit-transform:scale(0);-ms-transform:scale(0);transform:scale(0);-webkit-transform-origin:top center;-ms-transform-origin:top center;transform-origin:top center;z-index:999;background:rgba(97,97,97,.9);border-radius:2px;color:#fff;display:inline-block;font-size:10px;line-height:14px;max-width:170px;position:fixed;top:-500px;left:-500px;padding:8px}.skinned-content,.skinned-page{background-color:transparent;background-repeat:no-repeat;background-attachment:scroll}.tooltip.is-active{-webkit-animation:pulse 200ms cubic-bezier(0,0,.2,1) forwards;animation:pulse 200ms cubic-bezier(0,0,.2,1) forwards}.tooltip--large{line-height:14px;font-size:14px;padding:16px}@-webkit-keyframes pulse{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0}50%{-webkit-transform:scale(.99);transform:scale(.99)}100%{-webkit-transform:scale(1);transform:scale(1);opacity:1;visibility:visible}}@keyframes pulse{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0}50%{-webkit-transform:scale(.99);transform:scale(.99)}100%{-webkit-transform:scale(1);transform:scale(1);opacity:1;visibility:visible}}.glow--inset{box-shadow:inset 0 0 12px #000,inset 0 0 2px #999,inset 0 4px 20px -5px #555}.glow--2dp{box-shadow:0 2px 2px 0 rgba(255,255,255,.24),0 3px 1px -2px rgba(255,255,255,.3),0 1px 5px 0 rgba(255,255,255,.22)}.shadow--2dp{box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)}.shadow--3dp{box-shadow:0 3px 4px 0 rgba(0,0,0,.14),0 3px 3px -2px rgba(0,0,0,.2),0 1px 8px 0 rgba(0,0,0,.12)}.shadow--4dp{box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.2)}.shadow--6dp{box-shadow:0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12),0 3px 5px -1px rgba(0,0,0,.2)}.shadow--8dp{box-shadow:0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12),0 5px 5px -3px rgba(0,0,0,.2)}.shadow--16dp{box-shadow:0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12),0 8px 10px -5px rgba(0,0,0,.2)}.grid{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:row wrap;-ms-flex-flow:row wrap;flex-flow:row wrap;margin:0 auto;-webkit-box-align:stretch;-webkit-align-items:stretch;-ms-flex-align:stretch;align-items:stretch}.grid.no-spacing{padding:0}.cell{box-sizing:border-box}.cell-top{-webkit-align-self:flex-start;-ms-flex-item-align:start;align-self:flex-start}.cell-middle{-webkit-align-self:center;-ms-flex-item-align:center;align-self:center}.cell-bottom{-webkit-align-self:flex-end;-ms-flex-item-align:end;align-self:flex-end}.cell-stretch{-webkit-align-self:stretch;-ms-flex-item-align:stretch;align-self:stretch}.grid.no-spacing>.cell{margin:0}@media (max-width:479px){.grid{padding:8px}.cell{margin:8px;width:calc(100% - 16px)}.no-spacing>.cell{width:100%}.cell-hide-phone{display:none!important}.cell-1-col{width:calc(25% - 16px)}.no-spacing>.cell-1-col{width:25%}.cell-1-col-phone.cell-1-col-phone{width:calc(25% - 16px)}.no-spacing>.cell-1-col-phone.cell-1-col-phone{width:25%}.cell-2-col{width:calc(50% - 16px)}.no-spacing>.cell-2-col{width:50%}.cell-2-col-phone.cell-2-col-phone{width:calc(50% - 16px)}.no-spacing>.cell-2-col-phone.cell-2-col-phone{width:50%}.cell-3-col{width:calc(75% - 16px)}.no-spacing>.cell-3-col{width:75%}.cell-3-col-phone.cell-3-col-phone{width:calc(75% - 16px)}.no-spacing>.cell-3-col-phone.cell-3-col-phone{width:75%}.cell-4-col{width:calc(100% - 16px)}.no-spacing>.cell-4-col{width:100%}.cell-4-col-phone.cell-4-col-phone{width:calc(100% - 16px)}.no-spacing>.cell-4-col-phone.cell-4-col-phone{width:100%}.cell-5-col{width:calc(100% - 16px)}.no-spacing>.cell-5-col{width:100%}.cell-5-col-phone.cell-5-col-phone{width:calc(100% - 16px)}.no-spacing>.cell-5-col-phone.cell-5-col-phone{width:100%}.cell-6-col{width:calc(100% - 16px)}.no-spacing>.cell-6-col{width:100%}.cell-6-col-phone.cell-6-col-phone{width:calc(100% - 16px)}.no-spacing>.cell-6-col-phone.cell-6-col-phone{width:100%}.cell-7-col{width:calc(100% - 16px)}.no-spacing>.cell-7-col{width:100%}.cell-7-col-phone.cell-7-col-phone{width:calc(100% - 16px)}.no-spacing>.cell-7-col-phone.cell-7-col-phone{width:100%}.cell-8-col{width:calc(100% - 16px)}.no-spacing>.cell-8-col{width:100%}.cell-8-col-phone.cell-8-col-phone{width:calc(100% - 16px)}.no-spacing>.cell-8-col-phone.cell-8-col-phone{width:100%}.cell-9-col{width:calc(100% - 16px)}.no-spacing>.cell-9-col{width:100%}.cell-9-col-phone.cell-9-col-phone{width:calc(100% - 16px)}.no-spacing>.cell-9-col-phone.cell-9-col-phone{width:100%}.cell-10-col{width:calc(100% - 16px)}.no-spacing>.cell-10-col{width:100%}.cell-10-col-phone.cell-10-col-phone{width:calc(100% - 16px)}.no-spacing>.cell-10-col-phone.cell-10-col-phone{width:100%}.cell-11-col{width:calc(100% - 16px)}.no-spacing>.cell-11-col{width:100%}.cell-11-col-phone.cell-11-col-phone{width:calc(100% - 16px)}.no-spacing>.cell-11-col-phone.cell-11-col-phone{width:100%}.cell-12-col{width:calc(100% - 16px)}.no-spacing>.cell-12-col{width:100%}.cell-12-col-phone.cell-12-col-phone{width:calc(100% - 16px)}.no-spacing>.cell-12-col-phone.cell-12-col-phone{width:100%}}@media (min-width:480px) and (max-width:839px){.grid{padding:8px}.cell{margin:8px;width:calc(50% - 16px)}.no-spacing>.cell{width:50%}.cell-hide-tablet{display:none!important}.cell-1-col{width:calc(12.5% - 16px)}.no-spacing>.cell-1-col{width:12.5%}.cell-1-col-tablet.cell-1-col-tablet{width:calc(12.5% - 16px)}.no-spacing>.cell-1-col-tablet.cell-1-col-tablet{width:12.5%}.cell-2-col{width:calc(25% - 16px)}.no-spacing>.cell-2-col{width:25%}.cell-2-col-tablet.cell-2-col-tablet{width:calc(25% - 16px)}.no-spacing>.cell-2-col-tablet.cell-2-col-tablet{width:25%}.cell-3-col{width:calc(37.5% - 16px)}.no-spacing>.cell-3-col{width:37.5%}.cell-3-col-tablet.cell-3-col-tablet{width:calc(37.5% - 16px)}.no-spacing>.cell-3-col-tablet.cell-3-col-tablet{width:37.5%}.cell-4-col{width:calc(50% - 16px)}.no-spacing>.cell-4-col{width:50%}.cell-4-col-tablet.cell-4-col-tablet{width:calc(50% - 16px)}.no-spacing>.cell-4-col-tablet.cell-4-col-tablet{width:50%}.cell-5-col{width:calc(62.5% - 16px)}.no-spacing>.cell-5-col{width:62.5%}.cell-5-col-tablet.cell-5-col-tablet{width:calc(62.5% - 16px)}.no-spacing>.cell-5-col-tablet.cell-5-col-tablet{width:62.5%}.cell-6-col{width:calc(75% - 16px)}.no-spacing>.cell-6-col{width:75%}.cell-6-col-tablet.cell-6-col-tablet{width:calc(75% - 16px)}.no-spacing>.cell-6-col-tablet.cell-6-col-tablet{width:75%}.cell-7-col{width:calc(87.5% - 16px)}.no-spacing>.cell-7-col{width:87.5%}.cell-7-col-tablet.cell-7-col-tablet{width:calc(87.5% - 16px)}.no-spacing>.cell-7-col-tablet.cell-7-col-tablet{width:87.5%}.cell-8-col{width:calc(100% - 16px)}.no-spacing>.cell-8-col{width:100%}.cell-8-col-tablet.cell-8-col-tablet{width:calc(100% - 16px)}.no-spacing>.cell-8-col-tablet.cell-8-col-tablet{width:100%}.cell-9-col{width:calc(100% - 16px)}.no-spacing>.cell-9-col{width:100%}.cell-9-col-tablet.cell-9-col-tablet{width:calc(100% - 16px)}.no-spacing>.cell-9-col-tablet.cell-9-col-tablet{width:100%}.cell-10-col{width:calc(100% - 16px)}.no-spacing>.cell-10-col{width:100%}.cell-10-col-tablet.cell-10-col-tablet{width:calc(100% - 16px)}.no-spacing>.cell-10-col-tablet.cell-10-col-tablet{width:100%}.cell-11-col{width:calc(100% - 16px)}.no-spacing>.cell-11-col{width:100%}.cell-11-col-tablet.cell-11-col-tablet{width:calc(100% - 16px)}.no-spacing>.cell-11-col-tablet.cell-11-col-tablet{width:100%}.cell-12-col{width:calc(100% - 16px)}.no-spacing>.cell-12-col{width:100%}.cell-12-col-tablet.cell-12-col-tablet{width:calc(100% - 16px)}.no-spacing>.cell-12-col-tablet.cell-12-col-tablet{width:100%}}@media (min-width:840px){.grid{padding:8px}.cell{margin:8px;width:calc(33.3333333333% - 16px)}.no-spacing>.cell{width:33.3333333333%}.cell-hide-desktop{display:none!important}.cell-1-col{width:calc(8.3333333333% - 16px)}.no-spacing>.cell-1-col{width:8.3333333333%}.cell-1-col-desktop.cell-1-col-desktop{width:calc(8.3333333333% - 16px)}.no-spacing>.cell-1-col-desktop.cell-1-col-desktop{width:8.3333333333%}.cell-2-col{width:calc(16.6666666667% - 16px)}.no-spacing>.cell-2-col{width:16.6666666667%}.cell-2-col-desktop.cell-2-col-desktop{width:calc(16.6666666667% - 16px)}.no-spacing>.cell-2-col-desktop.cell-2-col-desktop{width:16.6666666667%}.cell-3-col{width:calc(25% - 16px)}.no-spacing>.cell-3-col{width:25%}.cell-3-col-desktop.cell-3-col-desktop{width:calc(25% - 16px)}.no-spacing>.cell-3-col-desktop.cell-3-col-desktop{width:25%}.cell-4-col{width:calc(33.3333333333% - 16px)}.no-spacing>.cell-4-col{width:33.3333333333%}.cell-4-col-desktop.cell-4-col-desktop{width:calc(33.3333333333% - 16px)}.no-spacing>.cell-4-col-desktop.cell-4-col-desktop{width:33.3333333333%}.cell-5-col{width:calc(41.6666666667% - 16px)}.no-spacing>.cell-5-col{width:41.6666666667%}.cell-5-col-desktop.cell-5-col-desktop{width:calc(41.6666666667% - 16px)}.no-spacing>.cell-5-col-desktop.cell-5-col-desktop{width:41.6666666667%}.cell-6-col{width:calc(50% - 16px)}.no-spacing>.cell-6-col{width:50%}.cell-6-col-desktop.cell-6-col-desktop{width:calc(50% - 16px)}.no-spacing>.cell-6-col-desktop.cell-6-col-desktop{width:50%}.cell-7-col{width:calc(58.3333333333% - 16px)}.no-spacing>.cell-7-col{width:58.3333333333%}.cell-7-col-desktop.cell-7-col-desktop{width:calc(58.3333333333% - 16px)}.no-spacing>.cell-7-col-desktop.cell-7-col-desktop{width:58.3333333333%}.cell-8-col{width:calc(66.6666666667% - 16px)}.no-spacing>.cell-8-col{width:66.6666666667%}.cell-8-col-desktop.cell-8-col-desktop{width:calc(66.6666666667% - 16px)}.no-spacing>.cell-8-col-desktop.cell-8-col-desktop{width:66.6666666667%}.cell-9-col{width:calc(75% - 16px)}.no-spacing>.cell-9-col{width:75%}.cell-9-col-desktop.cell-9-col-desktop{width:calc(75% - 16px)}.no-spacing>.cell-9-col-desktop.cell-9-col-desktop{width:75%}.cell-10-col{width:calc(83.3333333333% - 16px)}.no-spacing>.cell-10-col{width:83.3333333333%}.cell-10-col-desktop.cell-10-col-desktop{width:calc(83.3333333333% - 16px)}.no-spacing>.cell-10-col-desktop.cell-10-col-desktop{width:83.3333333333%}.cell-11-col{width:calc(91.6666666667% - 16px)}.no-spacing>.cell-11-col{width:91.6666666667%}.cell-11-col-desktop.cell-11-col-desktop{width:calc(91.6666666667% - 16px)}.no-spacing>.cell-11-col-desktop.cell-11-col-desktop{width:91.6666666667%}.cell-12-col{width:calc(100% - 16px)}.no-spacing>.cell-12-col{width:100%}.cell-12-col-desktop.cell-12-col-desktop{width:calc(100% - 16px)}.no-spacing>.cell-12-col-desktop.cell-12-col-desktop{width:100%}}.skinned-page{width:100%;height:100%;position:fixed;background-size:cover;background-position:center center;z-index:0}.skinned-content{background-size:100%;background-position:top center;z-index:2}header,section{position:relative;width:100%;height:auto;text-align:center;padding:0}@media (min-width:40em){header{padding:100px 0 50px}section{padding:50px 0}}.border--top{border-top:1px solid rgba(0,0,0,.1)}.border--bottom{border-bottom:1px solid rgba(0,0,0,.1)}.flex--expand{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.flex--centered{width:100%;-webkit-align-self:center;-ms-flex-item-align:center;align-self:center;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center}.absolute--overlay{position:absolute;top:0;left:0;width:100%;height:100%}.container>a>img,.container>img{display:inline-block;height:auto}.container,.media-viewer{position:relative;margin-right:auto;margin-left:auto}.container{padding:0}.container:after,.container:before{content:" ";display:table}.container>a{display:inline-block;max-width:600px;padding:4px;line-height:1.428571429;margin-right:auto;margin-left:auto;border:1px solid rgba(0,0,0,.75);border-radius:4px;transition:all .2s ease-in-out}.container>a,.media-viewer>a,.media-viewer>embed,.media-viewer>iframe,.media-viewer>object{min-height:80%;background-color:rgba(255,255,255,.65);box-shadow:0 0 35px rgba(0,0,0,.5);-webkit-transition:all .2s ease-in-out}.container-subtitle,.container-title{font-family:Roboto,Helvetica,Arial,sans-serif;text-align:center;margin-top:24px;line-height:1}.container>a>img{width:100%}.container>img{width:100%;max-width:600px}@media (min-width:40em){.container{padding:16px;max-width:80%}}.container-title{font-size:45px;font-weight:400;margin-bottom:24px}.container-subtitle{font-size:20px;font-weight:500;letter-spacing:.02em;margin-bottom:16px}.type,pre .keyword,pre .marker,pre .operator{font-weight:700}code,span.parameter,tt{font-family:monospace}.media-viewer{width:100%;max-width:600px;height:0;padding-bottom:56.25%;padding-top:25px}.media-viewer>a,.media-viewer>embed,.media-viewer>iframe,.media-viewer>object{display:block;position:absolute;top:0;left:0;width:100%;height:auto;padding:4px;line-height:1.428571429;border:1px solid rgba(0,0,0,.75);border-radius:4px;transition:all .2s ease-in-out}.media-viewer>a>img,.media-viewer>embed>img,.media-viewer>iframe>img,.media-viewer>object>img{display:inline-block;width:100%;height:100%!important}.no-phone{display:none}.no-desktop{display:block}@media (min-width:40em){.no-phone{display:block}.no-desktop{display:none}}code,tt{font-size:1.1em}p.name,pre{font-family:"Andale Mono",monospace}span.parameter:after{content:":"}span.types:before{content:"("}span.types:after{content:")"}.type{font-style:italic}blockquote{margin-left:3em}p.name{padding-top:1em}pre{background-color:#f5f5f5;border:1px solid silver;padding:10px;margin:10px 0;overflow:auto}pre.example{font-size:.85em}table.index{border:1px #00007f}#content,#main{border-left:2px solid #ccc}table.index td{text-align:left;vertical-align:top}#container{margin-left:1em;margin-right:1em;background-color:#f0f0f0}#product{text-align:center;border-bottom:1px solid #ccc;background-color:#fff}#main,#navigation{background-color:#f0f0f0}#product big{font-size:2em}#navigation{float:left;width:14em;vertical-align:top;overflow:visible}#navigation h2{background-color:#e7e7e7;font-size:1.1em;color:#000;text-align:left;padding:.2em;border-top:1px solid #ddd;border-bottom:1px solid #ddd}#about,#content{background-color:#fff}#navigation ul{font-size:1em;list-style-type:none;margin:1px 1px 10px}#navigation li{text-indent:-1em;display:block;margin:3px 0 0 22px}#navigation li li a{margin:0 3px 0 -1em}#content{margin-left:14em;padding:1em;width:700px;border-right:2px solid #ccc}table.function_list td.summary,table.module_list td.summary{width:100%}#about{padding:5px;border-top:2px solid #ccc}@media print{#container,#content,#main{background-color:#fff}#main{border-left:0}#container{margin-left:2%;margin-right:2%}#content{padding:1em}#navigation{display:none}pre.example{font-family:"Andale Mono",monospace;font-size:10pt;page-break-inside:avoid}}table.function_list td,table.module_list td{border-width:1px;padding:3px;border-style:solid;border-color:#ccc}table.function_list td.name,table.module_list td.name{background-color:#f0f0f0;min-width:200px}table.module_list{border-width:1px;border-style:solid;border-color:#ccc}table.function_list{border-width:1px;border-style:solid;border-color:#ccc}ul.nowrap{overflow:auto}dl.function dt,dl.table dt{border-top:1px solid #ccc;padding-top:1em}dl.function dd,dl.table dd{padding-bottom:1em;margin:10px 0 0 20px}dl.function h3,dl.table h3{font-size:.95em}ol ol,ol ul,ul ol,ul ul{margin-top:0}a:target+*{background-color:#FF9}pre .comment{color:#558817}pre .constant{color:#a8660d}pre .escape{color:#844631}pre .keyword{color:#aa5050}pre .library{color:#0e7c6b}pre .marker{color:#512b1e;background:#fedc56}pre .string{color:#8080ff}pre .number{color:#f8660d}pre .operator{color:#2239a8}pre .prepro,pre .preprocessor{color:#a33243}pre .global,pre .user-keyword{color:purple}pre .prompt{color:#558817}pre .url{color:#272fc2;text-decoration:underline}
+/***
+* BASE64 IMAGES
+*/
+.card-header,.comic,.menu-icon{background-size:cover;background-repeat:no-repeat;background-position:center}.menu-icon{display:inline-block;width:32px;height:32px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAA20SURBVHhe7ZoNVFRlGscV0/zY0nXTzpqZ9kG6YhtBCDknYjbrZFnJirrsup4sE53CsQmTSIqyb3MPNasrspEuak1iHjpoYri2BVmEYuzaKT8S3JzyizqyseTC3f//5X0u74yDgtk3D+d3Lg6Xuff/e5/73vcyduqojuqojuqojuqojjptdUYQx1fnINpXJ3//77haTq6zQpdjlOMMEh0V3dXEcRVe1+hdw/Q2dLW8f/MxTlXkaajQB5fgYNDgQd108O6asxC6twmCnw16COHDw7vFJcQxHkWQwGO0vH8YGTN2TBe8KvueWN5pKvtgSUlJ5sF5kmHJv0vuooI7ENiBcKMcPwf9wQBwAUJfaILQQ8BAzbkI3wf0AkpGfHy8KUOF5jHw3mfwOBBwJomMiuwGuhr7fjMVGR3ZNYDLA4mLjutpMMKZ4BxmcD2k/cYEr90IuF8zDmcU6CsMGzqsG0lMSlTbYPA7PzOJuyquB05Tuqalc75ujYwa2RX0DBaQcF1CX9AL4RUSXMBJXZ/1UNYbmr0+n2+XSdaDWdXY53EwA9yI0ElagiJmZMzFoN+1113bj1sJnhCfMBBE4XcuM6CAvpRgiPha3aAMSnjQD6HDhcyHMlPiRsX90uACCZ42O21D4ZrCXZv/vtkirdYxy9pcgn2aqZ4ze85usFGLSEJoJxARF+vgwtySt0uaXHe7FokEBL8InCcinKOdcgm1uxvUNa6D9wHnARV8YvJEH8IfXrFyxWGEHgHCNdH4upXBgVV7sFanPEFBgMmenXsUvpU+izIw8m4EH6dxctQ9d3tWcku8Od4mSgA7IWAcQl8NIgBF9I24LKInkLmhfRJiYmN6xMXCZDNRpLS01A8sjR+vXSlk3J9Rk/dCXl19fb0lUEIARwNpreqO1ikRldsrGz1pnsPgX+CTkuISy5vtJfMQ2AEera3Fe2nQeXvBHRiI0SA8/ur4wZkPZMrE2DYJDK6xg4P7CgsL9elZSkDiuMQX8Po4gvClJa+X2MHLy8styLAK1xaSYzbrArC2vLNFv2PrBQk2FKAliIBfFRUV2QIoGd23F+GVBAoIkkABrUoIM8ODi3X4JXIAqaeffpoCknX4GoZnmeHZDQi9PW1O2os26WmrDLZnP5e9jxLaKkKP/l91+IEUkJGRsdcUoCWwG5YjPL9sCRHDI7ohZ0gJnXFf7mqGB/EcdfvNtQCOPgT4tYBUCc8ywu9By74a54ibAEYYDDdJnpycAApERKiS0V/2t2WNGP1NrhmuP+jwSgBouQzkUtMg9A4tQYnAvr1DSsAihMvRHtjhHHAlKS4utmq/CLxO64/WW8Ubiq3MBzO3YYadmJGeUVmxrcKqP4bWB2xH8Cl+Pw1MwTjdAIbbBK4LhmGhE6NJLNlUUhM8RxStK7IW/mmhsNo92z0Ni6CBoA+BxEHg6vWvrVfdZ1ZDQ4NV9EqRlTE3g7fam8CvIyIizkdcc06wiwLOwk5KQOa8TPsNKUEQAQj/OAXk5+cfNgVwFNCSFLAApCH0dC2hmQSn00TCaxZseReXg2bZsmUiYEtKSspqkIzQQ08kwO4Ewd+MSKAAkTD/sfnNAmT0QX/spEaeb6be0AgfJGCW7oDjBBB2AkRYrumufyD4o9gqUu9KXWmSmZn5IkH4WQTvVwa+BPvBDoRm+GycVzKIP1UB7ARQjfCxQV0QIGAwRn53sAD/Qf+JBPhDCRDQ1gGUvVkWQPDPMfJfYuRtMPr7EJwCeEmxA64B0VrCwLYKEAkY9c3HCWDFXBPzi8TbEp8o24YTMzBlyAE4ujiZWWAi5oLHKcUG+1TXVCv4/UlLL4Aa6huawXVrFo+3ft16q+r9qv/l5uT6cUwum/n80Lzyc8SRG7kPj2/OH5XvV1pFxRh5gwJfwSEwBZGPvxNQgnexd+zUKVPdwAt2UkBARwQJQBdMQkf4TQEmwbNy7aEgZKQM6urqbIJ/pidZHl89OzB8KAG8e3mf9arQC7MXbkiZkeIhntmeKeByxD1eACtyKB4rmxlGeBAIqLYD6ZPA9b1NSRjtzEMX+CmBl4aMvGzrvkCINgjgyk8RInQo9DmsCCWA4TUHEJrPCfK02QsRJfhJBSgJ+CW2GiUEC2A7zmJowtsiRcB4Y/nWcvsyoABWw3/R3qD+PxBpIK0fHLAt8DwQfgYJIaAOHbBOB1fhCSK2KkBeCMNjbTfQE/TFCIeD0VlZWepaLSvH3ABy83Jrx9wwJrvwlULLv89vcYt/vzX/4fl7wOflW8q/AlbFuxUBBE96q15eFUDRerS4wY6qHQFsr9xu0uS5x7MXi7E/+/1+i2wt36rIez5vJ847CXJiwfnjJ4zvQpjPyNpqiQRbwOZNeKQ1BBAEfsEUwC1DQwD5ijJwlzhgcDBjns0BxcMZnwkQ8BlCH8l4IOMItxSQvzy/VQEbN2y0ClYXWIiYH0JAIxZNfwkh4ITBpZQABKQAO3wrAo4yuBBwvQO2ZRs6oAk0EIS3KADt+hSBgA/AQRFhCiAUAGqDBUgXnLIAhGMH9KcACU8REh6XgOW518PLoEBGXzpAEAEmJyuZxeUSwIz9JkTcyy0lMKSMPmhieEpoRUDjgqcWPHEqArogfA+E6w9ulpPnY2jFVoykpmBNQZPb494G/Fu34aAh2LENrWtw3D5VgXAClUmUk27Z22VWztKcKgxESqo7tWrH+3gfUFQIQcC3yldXWVHZyPPD1n5fdlfu87kNuAy9ePjpj0xh+F6u/5NWF3aAFnAh3rypFQFW3rI89VxAEfw+IBzgY6nQHgEiQQv4TAt4kechEjDLH0OoBgYX5H1Xr1lNAR9OmjBpZpCANhU7QM0BFPBI1iMhBdAyD0YBYBYk5Lnd7k/y8vA4DPgzUwDhrSuAoJWaKYBQAKCAeRCwiefBkUf4RvAFQ/O1UALABoTnlxKgaVtpAb1NAcQUsOfjPaoDdBeoZwNcrzdAwjzBdbfrMc1iUJ67NPdjsBfUYET2zX+qhdzlubUI3WSKMDuAIqT9Eb4BW9X6oQSw/YHvlAXwExfQKzIicljaPWluoCYpUwCR29Pc9Lnbsf9tmHBuAVEChIzU/JaMGT3m95p7CF7jkrqF0c7709PTD61ds9Yivpd8X3rSPKV4KNrNh6fSd0o5AdfhtQP8nhNv1fYqG3Zl9rPZ3BZPmz5tvCPeMQD0Sp6c3KUT/z7cjuqsPnGJwHqgWYJV/FqxGvVgAatW4lYGsP9CLcCWgFB2eODGc3kl8Av5K/I/Jx6PRwEBz1ACwn8IDiF4BdgPEerpEaEZvhrbJt4tzPD887sIAMU4/hUI3xecifDtF8CPmgwBXgqQ4DwQkQ4QCVjcvIED36Ul3ILQLyFgzY4PsB+gQBN5XZDbKbsAIl5F8CMMTyDiCMJvlfDsAPncQdCjvwujPwfH7xMw+u0UwOqsBdgS8OZNFMA7AJHghoBjOPAT3GLfY2Y4iLBWv4zJycD8GZHWFxEcdQSX8BVofxWecC0i58Hw3DI8JKjwZNCQQS2jfyoCUu5I6Rp9RXRP0A9cgollA1C3LG75JysT+Qvvvn/vU1tZOOU8n6OgwCDsbiJqAbMUdxC9mFmyeIm1pXTLp64Zrn/ie3vSK3+7XE2G+i5h5SzO4XZ3bk7u0uio6AjAia8TP9xRSb5OIbgtIS46bsTMGTNtCfkr8wMEyIgwPLYNCL0fbBWys7M3m2A2Jx8jPLGDUwJBaIb/NFR4bhlcwqdOT73PDK+rTQufk5ZIgAD14SckLKIE2mdwGQkd3JaQOjt1P67l+eAuMB4r89GaS4nT4bwEXEtc013LEPo9we1yv4fwi9kFZniBEnT4jQzvjHX2DQp/eosStACR4PEu8paBxtYEsP0hgeuEEwkQKGIsuFNTKMFxGSgkOGgCNRCwBOGTGJ7oU/3GqrP+zwlngrPBANwpwqfeOTXVm+P9SH1QGXRNi5iFzyzkg82HuCvwfp8IYhQOZ6TBzbdPu/12sNPr9X4l4UvfLFXgNWuFb0WTZh3EznKOcl4KzgV9QHd9zbd9wdPuap5N+b9AKIF/YQmjBFuE1/t6KAHE5/OpJTJWiDW2CITWuNLnpL/F4AxrBg8SwODPjYwdOZRI8CHnD+mOc+H1fnqu+VZLbieQwG7Ad7LEVCIQaqRrpiudJxssgMhSlSgRDueTCF69di1ufyDUqOvv9+L75Qh/kw7flTA8jv0tBJdqEdCMIYBAAD9c6Q8Jk8DrGPW61gSwGyQ4P3sgZnDAblDBcVnwS426hCc45rcYPnTJCYRhBpbbZW8wAFySMi3FvXjR4vUigE+UJrJOENg1DI/tLmwXocv+6BjlGKr/k9VZeLDpCfjhpkj/TsObpSTohZMtAneLoZqbIOKEArgSlPDoolvBCAku4DX23fcqeMjSEnjbFJQIb7a32hRQ9BrWEDo8aGR4XDoqPOglwfXbsqTjfhhlCFASECoKEt4SAVgF2uEho1IHN/+O/4OvzslJyV1AN0eso3d0bHQ4yfXlfgRkUUPWT54w2Y155CJwDujJOQW///1v9zaUaltKwDZMJKTMTvnIDM9PooLC/6hKrl01e2sBYxDe++T8J8cyPD+O+7GGl7IFMDwI059B2qTcmfKjDR9QCBqLZ/fBvKcTTHg/jNvb6SoI6A4BXMaqjgByifzk6icZuqM6qqM66ntQnTr9HxzJ0mIqNkzFAAAAAElFTkSuQmCC)}.comic{background-image:url(data:image/png;base64,/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAICAgICAgICAgIDAgICAwQDAgIDBAUEBAQEBAUGBQUFBQUFBgYHBwgHBwYJCQoKCQkMDAwMDAwMDAwMDAwMDAz/2wBDAQMDAwUEBQkGBgkNCwkLDQ8ODg4ODw8MDAwMDA8PDAwMDAwMDwwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wgARCACGAMgDAREAAhEBAxEB/8QAGgABAQEBAQEBAAAAAAAAAAAAAQACAwQFCP/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAfwwBAQAIEREIGwAjIEZET3mTBgyAEBEBEQkZACAhE+sYORk5gZMkQEREAERkBAhPsGDBgyYMmTICRGSECMkQCRH1DIGQMgYMkAERAZIgAiEj6BkCIjIGTJEZIDJEQGSISPYACRGjJABkAAyQAAgQkeowAkJo0IAZMgZICAAIQA7mQA0Jo2JERgDIEAgQAAGyMkJojoaESIDIGRICMgAEQARsTRo6GyNABkAAyZMARo5kREaI0Js6HQ2AnMyYMmTIERGCEiASNGzodDZEYMHMyBEAmzkIEQEImzRo2IGTBgyRohNCcBICICETRo2RGTIEImyNEeQhIgAiE0aNEIAQmjRoRMniECEAMkJo0JoiIhNGzZER//EABwQAQACAgMBAAAAAAAAAAAAABEAUBBAATBBcP/aAAgBAQABBQIhsEIfBC2ND3D0GuWbcllxGOP/xAAUEQEAAAAAAAAAAAAAAAAAAACA/9oACAEDAQE/AVT/AP/EABQRAQAAAAAAAAAAAAAAAAAAAID/2gAIAQIBAT8BVP8A/8QAIRAAAQMDBAMAAAAAAAAAAAAAEQCB8BAhYDAxUHFhcJH/2gAIAQEABj8Cy+/pib4XIebkNJBrOKMV0nFD4KcfU4TFdXThf//EACcQAAECBAUFAQEBAAAAAAAAAAABESExUWFBcYGR8BChscHR8eEg/9oACAEBAAE/IXy5+9Dfo2E2Gv2Mp9dOk8OmnR6nYcdsR80HIDjmSDi82+XF454FZ5FGtuQk3TfpDraX+Xc8kciJxyFej2FhSCPGWMZyogqVwg2OsZ0FS1oT/aipiLkdukvhxB/E+kTsa6j1UzOQ6Ls4y9XXW/Vc1SlXjFmnYlpBMYQtK4vKcuR9ux5GWgy6nYivSOA1+nEMp0QZby5gK7xga9MzLcYyj1fB7Qm+86qfsJaWHSevLDfL/pOUchucwGqK3cVunmpmGI5GxroSx0G45jOJIaN6DE+lR8MKLSkpXH3eOd7jrlHOJzSmRnI1/RapgNmNQzmYzIoJdejvI0dTFITFhiqUJwMYFGh4MKlYEU16PjhO34PHLDmI/JcUdE5AfHDkzz7+m6qmJ4mMWOcQb9MnuR2GqQG1JQWA1iVrngdxEoVgR/g6zi6eRx0k246/R2i5xh+SI8r9GxQakjimEJ9y4oqPLo2OxSEsTNW6QJRWAvYjoWHHtDAWEZWQcdrjrgh6mJxFE3NpPp8M8J6ycVF9a/RU1XAXcWpMbcnlkNpiMMv8GpAUiqxXJBlrOf8AD2KqYyHX6Rex2IBHEVpFWEuKd6/0fOuv2wjOnbWbexoaNp8uNvj/AH0NzmIzLlLWhdlyw3PozVeev0ZNpEJTeHLExe+/VHX3n0ewq7lXHwgt+j/g4iz7uOvK/biZzl7b2STR5YVysZ64zk8dqGp5bJZ3Gk0sGtP+jd0eNPlhm9+niR190zuZStIjp2b4Ouor7+SbDapNRt6XInHJjEKGUHJYiLmOzdv4J2ZuWH1f1X0Iv3X7Y4mtIbjI2Em0+XF49qw2qb1u+07C0pKkaexdJNODfLiq/PJd4zv+ji8c5y56KbQ5Lp46MaxOOZqcQQRs/nwRa6+hJStrTO4iyvJrTaML1HRrM+lWeVhfKOsnjtQe0ZJm0s7ir9h6FXx2rlYfeng82qXwPA0e2tBlvZMSeMGd2wrlYQ99NurdMySJ75MTvh/PY+Ums3wf+vavofy+tfgdLYs3dvYssGZrN8FXi2r6HvflziDc5gc5c46T/RvkJfg2TXlrahvVXm/2nTsd6f7/AD+Cb0wEXw72rlYdp6+n9E/E8aZ3HWDYy5buLmjM72rlYV8YVI/y9M7l53ETJmdcq/wZZY450zUdSKwbF6Z3G+ouDVysN9VbYQ9DLRaNi8ITnc5y5zljik+cj/nI256H4o/OYj/xvXs2k2nw4r+/Rq0e/wBKN29ezakZfhyPu9BNa3/aiaUhLS1RktJoyaM7UPrxm8Jw0IYwrhPGUJ1MMGZoSaFtSjsmj7lbKxPdthI6o4sIjZdHHEX4ez45WzSuJPg/wRXZsXbSY8ODfRVZVuRNxJtj3E9CK7LVFXYeFCI0L7uSVUohWbG0sKdURJqpFHR3xlYYyLFlWirI153FY6xZCKaiu2tVFgqpiiLXWzysf//aAAwDAQACAAMAAAAQEAAgkAAgkEgkgAAEEEkAAkgEAAAAEgAgggEgkEkggEggkEkEkgAEEAgggAkgggAgEgggEAkgkkAggEEEggkAkEkAEgEAAgAAgEgkEEgEkgAkAAAkkAgEEkEAEkggEgAgAkAAEgAEAEAgAEAEgkkkAEkkEkgAAgEkgkAAAEEAkAAEggAkEgAEkEgkAggAkAAEkkgEAEkAgEEgAgggkgkAH//EABQRAQAAAAAAAAAAAAAAAAAAAID/2gAIAQMBAT8QVP8A/8QAFBEBAAAAAAAAAAAAAAAAAAAAgP/aAAgBAgEBPxBU/wD/xAAlEAEBAAIDAAEEAgMBAAAAAAABEQAhMUFRYXGBkbGhwdHh8PH/2gAIAQEAAT8Q3UKqkOWdG/uchibHZONcpejvEbsALWydP08x5VsnNnxNbwQPL/nOQqU8rLv64m6yvVJPsZQ/t615hQu3c+v0Lgzc4eLv70zUV1dHK/a5IGic3f8AOEvDXK9XBR9TnbrAK9uzX8/1g+L6hy/X35zo03Zr9eHp3kDVDu9T6eeGR3Dx2/d98xeza/H+fcq3ddeT6TvGlkfrrKUH45q/+4edm00/Mf3ny152Q/GsVEQRARUIsLNDrti7WqoqiKkinSddsAeTSc15Z2vZ1+omhQ0FU+z2fObV0X+H5/rEW0PRreR3tDv/ANH8ZHmI7UnHbjyDdcF98PnKoJs4sS/Gn85e+b/Me9f+4q6vOx7dc/X4ywEEfxvrNui8bHj/AL5yaER/7fOb7Fps5/O8qcRXSd/kzZNqeJzilkDp79KOJwSknPX0P6xF3s5ZOfjNFJHiG/vN4Cfmj/eNsi/E5MeygO2c/bADaAEwgdEdv1DGrCKEk2ZBGy7HGbIbV2FJaFeHbvO0jq0Jo8vB6YABoO+JHj89Yw6U9T95LF2fO3+sTbro2f1gxDfKRr8V/OVC65Csn36+MtXUObz38v43rIB1p0FHc473854gJdTRz1vXziHCBlUEOqb4xHPIzf6/xjFDk9UvHH1y9lm9wfGr/OWhUh7GfKUwcEhb5fOd/jEOTXAD35TvGxTVda6PrqYfUvZ/5myX5eMFsvNZf+1lSVPig/vEiIwagoRQ5F30x4QgICgWwPJPPTNyIRIiogsFmg67Yitq8khpIpNJ0d4m4Cqxl28/f06xKQXggsPL584iq300+mRCL9fF++cnfuyw/OHddG3fDOfrkiqnUv3ie95BSGnMQ44Xs+cd1dpst99nXV5xYVZ39U54d/GsRsBtDcfT5/rEibaUmnXErR7kRFLWk/PkweAVtXlL2B3kSt+kUo9bwJyFdQ4fizj5xEarWo5ZOobMKVXZORv49yIxQdyn0ub4qC6T/ebbtR4b/WNMKqmghaHA/MyjESJHBBNi69HeIciBS8Rspd+DrIiLsgFGmQVfsesQ4LFLFpyDYPq8408CxdcTtn8jEygIXZNfO9/HmISoWHtr1oxAKu3h9PcbA3OzR+x3k2ha4i93kgfOIAIb0HP4GaxGixVlW/e/7zXoDwCb16JvNShEqh0fJv65IVAJqlp67NfGG2015T48e8RwFOwG2aOecDgDshCe9/nJFkHdjDnmajksKvXS9fPeIbFthrnkn+5mlTc4Jb17+s3dj3DZ+85BJzERv2xoV0BSE2VGnXbFqqqqSRiRE0OjvAFaoTrarUO17OsocEok5BShl25esXS9AO4IcCzg6e8qqqXmJvwx4fDvAOzaYgu3mHb75kHEWFNk+E6+XEyrYR611kv4Ihbz85B0q9QPzmgKAROOf7xsBNaqcfjFCemuSbwUIDe42+ccYgvNOG/G2d4hK3pufgdvznQ2kZUnZvr5xiiaZZEL8aEwqitcb3sTgO/MbpA4H5TjnzH0w8uvePxm3ag64n8ayUvK6N8cvmCvI36d/wCcRwQjZ2hspfsOssVeUUii8C3a6esrgocGxU5j/J7wkSRKJ0nk49LvN3wi3idRqnh1lbui1wLp6z6HjJTjQeqPBvT695SamihJo5Q5l6lx5aKJe4PFLd9eZWgBNIy3yjz8423leFJrn/rglObKxB/cPrvJKAJ1Xv4jiKuk8C6/GPLYV7YccRwBsFe2cH1MU2aHeh58ZMNHpd874vXeeRCTb/28V5Ca0N/zveLGa9S7+nH4xSCKBDW/pnBG3/vpzgTSEiu1+7h660hu/md5yJCUm2rde+nBioACbE5J2FOPXrHoQ0LoIPHwfvBARgO7ap3AzcCo3ir7DK60BEBxOxPPnDVNVlHTXG+jz3KqxW1ALob3+BjsB7qlrzNb+fM0CLEpwH36+ceVdQg0a6vnx7i6Iiaicu9e/GAohPibPn/eUHMHbJs9uJQmcqDfd5/PnI/oN4W3bA6R78usenycQvvO8V58CyP03c5YTW7N/oz4Chxzv7+YQaB8HAfP3wRqp45f6y132rz88YUAHUTkT79fOVIl3qc0N75vrf8AYmcI2APnW9HxiEJXxya4wbNcvK/zgq2Btmj+PnOFSLzwff4wZGw4Xh+368ynldwOQeea7+cZQE2QmqjuefPudO4Ej9p+mKCqhEO58jm9ed51Ha6UunFP5YSEKLRo079nz7g7eOSxdWU26vWIjrHgdp5048JSpF3e9zIoJBsNL7J/NyA6HZ3r3g18Yot6ghBV4Gd+Nx4g7QDG9/f1w0J4XiCdz4wcC8Ax8eNfrJ5BnYfHIXFFCNtEKn1c+3EXhsXjUv69M0BVBxuHXfGUkbXbf4mVLSLpYb36uOnQoeOH+J/GGzV9CP8ArHCkC8zv6YHZ8pPuh+9Zw0NKR6/p64NUiGArNcVNfHuCipTzhYPMAIQBdYpV2G/0xIIBs96AVKn91x2Ztd9aHWhrX3ZfPFapzU8l+jIAPUzXrhU98/jFGo0VWa+vP1ZatKO9m6ccCPnuO4vola899GBSR2I2R6EGnr1iKaICKydb/g9/q7OxfQN9UmnzBdlKohQvMN79MgNocyUD6a4+ca1dDBqg/fcPnvFwEeag9NnvhlHTt4sOOvtgpG/Gv+82T+EQ6xZVKeR8mAeFN1t84JjBL3oVS4RKgOgKOv5wAKT210e8OvjHdjiPJpdXi/HmFAGVi7HTgcEqSl6Clj6an5fzgiGpycCel7YiXYBAOxX1FwRsCj8Oza/f9mfUJeoRcN6nrnERnpQpdjF7fZjSqiQC1F+4U4eseWqlANOra6/kxdBdVGqDlAujs7/nEBqQWu9HM/gdft3jQMRa14F1tOHrFQWKmpfRfTt7/atDWrqghyzz47zktEBWJH30ejHYoiQfC2Hl8esWZH2H5+N+5oKB9Xf3scEqNDgt57w02rTet+5eH3GifHeAwoHT/wAxTgFOW6305o27cXe/Z7kIJE5Quzf+WCTZHB0ef5YCx0hbo2pU1+2Q5orKcscyf1d4IRgxQBYLdcr+GCxIL7hpZZ/dclY9peFUTSDBQsNHcLQahp88IKIFQTRbqbPXWI44IXgsHX2cnF2jyLedcQEHw7x6ocCHJNs/kZBr7QaTuPnr1iFW64uhDiocePeNYwFaqA09n4HeAiO9qTbXmEa+nWEoJojpHnr7nrCESW8HN8+uDJrhTrjufGJaro2XfPDsxJaGmQLPl53gpoVMvWufc7olnyvz1ivrDhZby5uh9lrT8T95pY8ugZZ4P84O10tn5T9JiTaAj8K8i7vXmXBQ3k717Xr/AM4xVjdPMWvsGHNpy2M1f+n7kFo6ENUUbOS4K0CQwu91q/f24wdIqNGwIO4ug7O8BOgaqUrhHrrCqrQIKqi8F2K9PWa8aYCL6PqdveUTRULZpA2ngdneBuroVUoDww5Ho6yjY3RC7rhPa9PX6ESFVCYk5BXSdvf7CL2OATLp07XOC9nm3XPp144nKaqpI/F+fPc/91z9j30yFAERAq99PZ7hUTnrevzA157jp455rP8AnINzZsgd/NyFAB1JZ+PjCLKnCL+/69w5Crz036c/Zk6REKxNXnbl/hhpKE+AeL+/vebWtVFacqcNT8so2qJHW9J0n9H5xJE0GCEBfHY/hkKJQMZo64Ppfc5LaxURvCJpPyxVYraTbft+RkOOAoB1HkPT16yHTEQGuofP8HvJekVtSN6v6HeB4tFTZTbCb9HWHGSAi+DzGP1vWBREoA8ILKmvTvJd8rqQCApH6XeETUCDXeumefHWP5DEax6F7Xp6x3BKqA1XwfTt7z6bJSEEO/gOzIzaznZdPD8j0dYyw02Itb59fnNKUvgTnudE7e8o1EKXuT36fGF4oBNPQ/u9eYLeKCfK/K8/OdNNcDlHcbqdveaKMNDNadL/AMcYUXSJtuK+m7+GK9FbQbadxMuZttpQY7h16wmXsCNCOn/hiiDRAO0WQW7Xp6ycAash2j1477ZFgg3AaQ5Qug7O8CViSIJVkePXTAlhAhW0UibvoesKAJRA0gNDdDvtgUEREQCISguh32yxroAQKCtNbHrpkqINElQiG8n11zRxRG6218v5GH8yANI+fs9ZstB1K0Q6XzxxTQ20ahRO39MNWbjabb8XV9xAIF1CbJ9usfmHT59/jzKW1d3em+/X4wVkSV0VL5/eCcIGR315/lgDo3Lws4vk69wY6Vjfm+8fjeMIjQliIXnhu/hlEljsYfC/v7i8/KdKx1w0/wAs72k0Tbpt4+88zREas5ALuuz11k6kBppHln2uAu21aoipJAa8O8DRBIoQELahPtdYOAgBArDKKb9uspbohGsNBTR7d5Kq1UJAS0RwH3MBA0IkSNOyOT69ZJAAMCGxQPL7gcUz0D5Th9/XDpBguivGvPjvLQAFUdXlrs8OsQBjEF8Gb+fHNDvAHncf799yq8Jo12/HR8ZV95d87OecQTXyP0f385taccz58weK6dNS/wCPjBsnoKdnvvGvMG63rX8cQffnB3Wnm03wnnz7iVBzTvGl4/TNoklp2x8t7+PMRtuB5RrQX+TkCyoITe5PD33FYzZuUhvX8DrIAUAbtj3Xt1p6yB7UAKOyA3Xrti1GssIbEF167Yi4KsLyROXjpghXZJXlheWmumEWYMSNRDdfkZSaUkEiIn5HbP/Z);background-color:#000;background-attachment:scroll;border:1px solid #333;box-shadow:5px 7px 20px #000;padding:16px;margin-bottom:16px}.card-header{color:#fff;background-image:url(data:image/png;base64,/9j/4AAQSkZJRgABAQEASABIAAD//gATQ3JlYXRlZCB3aXRoIEdJTVD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wgARCABGAZADAREAAhEBAxEB/8QAHAAAAgMBAQEBAAAAAAAAAAAAAAECAwQFBgcI/8QAGQEBAQEBAQEAAAAAAAAAAAAAAAECAwQF/9oADAMBAAIQAxAAAAH8qAM3y5LJylhATlsSS1kRUhJGkdTN5llNAAAAAAAAAAAAAAAEhEhEisAPRZvEssKKCyNONvWLChWQFQgsE70vIswUCAAAAAYABYdLluNM3Y3KXL0xPOqrmJn3msjYoq1KwA9Xm8CyNRJw6UrgIVogqpEQqB6zNwp5zRgIkXxoLzVLoM5cnXlZWc/O7eXbfz6YOmNeNVWQri9uG7HTDrGHpzFzXEaQAeuzeJZRRDlmSK7CK6QyIzcWR6GXRLgsuLAJGcy1QU1TZmKbAhLWdTO/X+L6GbWPO9/N2efasz6wly6xnucu8VpXZVYgA9fm85d0nLavyNS9La1Zal1FkSKayplrPZnrOZ7KKFkBYiGIRWsUmMmX46e5535z0jJx1eeoVj3zkuTU1GUx2XRoNkvoI1yxq+KjIZ6qjYTPJ9MRoJkgBK1itiAArRolCI6plBlqMrPpXDp8065pltXq89X516qTNqcHUoueNqY9To5t8uqWnUtlvw3Z6cbpjKTXXG+46B5LrgIE0YBQIJYEFhDsZEsJ0hRYMQCPccd+R3OVUpeljV0uHebBpzdSqxm3GtMuqa0RozbZqjU4nTmpoSNlzPTPO9MgpWkqAQXPLEYhgSRKE0azRDJ0DOpjUZXjea5jVNZrmFMgjIU4ZIkrCFVaCiAFhTQAAAAIAAAGAAIYwAAJQDUABJEjQAH/xAAoEAABBAICAgICAgMBAAAAAAABAAIDBBESBRMQIRQgIjIVIyQwMUD/2gAIAQEAAQUC86egsLXwPa0TY8rpRZharCwseCmR5bKNZP8A0YPjVYWv0jbln/HZ8tOD2pp8OOD6Cysr2sFOaQKo2gvN1m/3CNzlUpdstiiYZJOOkiNWgx8dihE2GOr/AGsqN3cIy5keCQdsez+zvQ2P0qDaGQYmWqx9XFZYi72ZCt34y5FcV+VbmI9XfQNJQrSlDj53IcVOU3hnpvCq1Siqqlxn4iCpEvlVYkeVrtT7gt2AySS/eYX1rr/i154C+vBCYYv1rVo8yY9yODEz83Ywic/Xjvde03W15awuXW5Y8ORcUJEXIRlyFKVwbxdkrjqr6rblL5jRwkSbxMAX8dCxf48aN+s1O5WsEeZjCPLvKPKWCjetFOlnctCV1BPaGpvs1z12JdYhUe58PIOdJavSSRwlx/joX7wRxCnDBM0tEu7WlrDn8n/XiDmHkABcpy0GPmliMzLD1DFaDm0Ljj/C2ChwBQ4CFDhqrUKtOFfJpRKTlagR5yunc2Mu5iXL+VskfPtPBlmKLNj1haAJo+uUZAF3BZEgazXw61KrFJr1vkl+VF+zsFz6bSvgzODqMjAa7sx1zGrH/UIHFCo4pnHZVOsK4kqwzObDVjXyqbE7mKrUedjCfzjkeXtOVG7ObXNyPZG7L11NXWFgfRwymtDCfY+5WowIxktDkW4Z4k/SpJ2Vp2ddhRnWTP8Aa6XLYbLXxyESL45zM4BTHPgSuTXSla2CA2w9NqPehxuQ3jImGcNZJ7e3X2D6jwL3OY+GFlF2PvlbtRlauwoSrtXat8howiV+yxhYWPB9jh5A6hyrCy/vlBb5Y5zcSPxI+w96ktSNa6Qv8h6bKhOmzoWcL5aks7GZ20ucLfK3Xb+V6fsrB3o+1khbrZbLZbIu95WVlYWVlZKGWrsKDgtlssrZbrZcdY647020xkDkWRk66o7J5ytlt4Jz4ytl2FdpXcV3OXc5bEnYrYrYrYoykjKysrPjKz/uysrKyspry1OeXLsK7CuwrsK3Wfr/AP/EACURAAICAQIGAgMAAAAAAAAAAAABAhEhEBIDIDAxQFATIkJDcf/aAAgBAwEBPwHo17K/LhHcyUadDg0RhayOCoirFEx2EivR1zQ74Nrc8k19Sf1Q42qIx2rJ+NkVkoeBefZZfPB/ZDxk4b3ROJmVHEbij9dkXcaEtiyRkXeGdtH0LVFl6UUUVyXpfhOcnhibXY/o9XEoorrZ0fn3yvWjbpRtPjXKx+Uh9Wyyyxu/UX0LLL0v0F9L/8QAJBEAAwABBAIBBQEAAAAAAAAAAAERAhASICEwQDEiMkFCUHH/2gAIAQIBAT8B8N/pT288tq6Mctyos1kZZx9GObpk4PM7+RsvsMXgpS6XSEMvgsw6MPuMPqdE5lTJ7mftDJ9aLv1qUelKXSEIQhCcc1cRV9GajMOlTBJs/cajo3ufQ0SfHgejv4IbdOkbjcbisrOyMhDaQhPPtSP91em4pS8qPXsjIQiIYk9l6s/BOK4VFKPI3Plj7T+RfHFEJxhNIQSnJe09e/JCEJ/ChCE5/wD/xAA0EAACAQIDBQYEBgMBAAAAAAAAAQIRIQMSMRAgIlFxMDIzQWGBBBORoUBCUFJiciOCweH/2gAIAQEABj8C/BpjX6Ch7um5qWvt89kTqu3tFsy4qlC1USUeJKjI5mqN0qiTle9mOStRDWWsdLknThWhkUatE63JRjstvRJr17Lhjb1NEj/w1+5qdJGHLdsqlsOf0PDPJdWcWJFdC+I/ZEVTEnKWnIk8eNOVzTD9zvRXRHm+iMNYSdaPUj8xUSjmJKOrap9TLHSmVDhHX1ON1lq2Z/45ivoSHYY95E9yyqabnIvRlanDCT9hZfh8T1qeGl1ZNTpe6oRWbLR6l5TZo31Z4a9y/wAqP0PFXsfmfRHDhyfU4cGnUtGKO/T2L4sn7l5M8zQ0MJ/yJYr8kca402pV51MjehHK6TbM1avLqfKk1GSVL8hubuTcnR5q0KT8/Mkqj5Ft1r1L6UP88XJehL5cXkrYllwaqXoVjgv3NFE4pxRfG+xec2d2vVl44a/sWnhL+p4leiZ3cR+xw4DfucGDGPV1PyR6I8b6Ivjzf+xdt7NDRdnHNNyhVVTJYkHKE+cXqSzXdRXdtLlPsNPiVdBZeFlsNv1OK2yrFt1LyHR1qZsRVZ3YGsEWv0RbDkzhwfqy2HFCw8al45jCcJOKrehxTlLq9+nZURQ57KbmHLnFGLHlLZF+pF+TLCuq0Gnu2iWid5I77HmlL6jLkormcxVWpc+DnzhT/gqfu7PXZ5FzQ0LbeS3WYfNWJtJ8V1tgxU0E06WFxsST9y/Yq9kSLGuz4aX7XT7kl+G13Jx9amFPkcSUv7XNKdC0q9Tn+Dp+jf/EACkQAQACAQMDAwUBAAMAAAAAAAEAESExQVEQYXEggZGhscHR8OEwQPH/2gAIAQEAAT8h6Gsz9sOvWoJSLcQBO2X69HadDjSph7U/7SV2zKgn1duraaXvNM3hhgC01EJhwK1g95Yy82fiIvYniS1ofBL9svaXFMS564qbDVD0r/hv0fT5LlzxaVeTmPDSya5aCYgC4Fwic0G1g3JYK77u7haKtuDRL2slF+sci1CYqUqlENJWKjHtAgHaHRFKfSewOnCprlJUrqlwqG89rmVe9i4DFw4MxxNoSloVsw3nIfaBuCJ/fPWumongTX175pT90JrJMf8AQCw9XHFEO0MZBbzUF1WoNPLCyx8xfrDRf2No9hkFyEdl6P4laBSDORa+q/E0Dp8qxNK/k+IvxcAfKUIUU0HSfsq4OuauvdiPA0/BLEvzEpZqCM/TomtyqPWli9Mu0u3xphwyoF0lEyU7ygQI5uZwBdKrSfThtKFDuxvxZNZ7kI/bsWbh51swuGMt2o/EGy/ufiGfh933jvm9kwD7BZor/LvGPlQfuaYeS59qP9sHyfATRY4vFdqZdqqci8sxykI0DA+cfmMp52BjAxs2IYAmJWhc03ZxxTGBNd7d/wDYFvC+XIgjVZU+gQUiKzjEJazZsSVMo6McYz2Snh6eyUK3BQRoN53RAZo02mHcVVGxsrCX8b3YNu+8x1fT/wBwpnPJCMvvWDe5I/ME5Pw/Eypfx+lNj4B/cVg3ekdb+ScTDzuf6TtHsfqN4rymUc5WHHKW6cgePTu7Tunidh6KXesSypgTDUM03E0eXhirc0l2tZKu8ShU0HAiE5ZfBgDDIsXirmni7ukPbBGIQA+UNQphDq9ZsU1wE/VYHJ3JVABWsyaPmAWqnBNZKgX8liK2WBHyBNm/K7ln0j4c7Oofv0Q4J2YcR8ehjTBuzVGWDQ9B6FbufaWcENbRHkMJuSyEGsdDamStVftFrdY+su524Epd2fiqhBg8eIEFAKEFFLM2gmusMiN9N4TRw8wVfGJsFCrJ2i6ZeLZuSlY5mCWlmtIuSoNrhlNq7k3jMfc19h/CFWLov0YhCUurlgw1zBHrfSy5QI8SAMNy/QjNRp7RW3zljWa8iUe+8PmiF/ZbwAolGYdBS5IcXlX8v+QfAohvjMFqB8kdvEoBqWMA9imj5itypkg9gTciFENeUOpX0Klcple8Igwd0bSMmusFnLcBWFU3HM8rlyxrfc/MC64ZjRGqcy/MPb6fuuYZnrmIvBG+xCxjWCHOsekuWVHcJqLzPOpltfdllz7DpOjsz/X4ikOqrJ9GFb51hTR7/wB3K41bvCo+NDhlI5IU3i3eXDBiul4MgED6spvG49FWIOG4+WjLS0tLS2Wlpa+u5bLZfS5eXl5eXijW8FB9Pha15jbb0//aAAwDAQACAAMAAAAQkEoif8aCcCckkkkkkkkkkkgAgkj7E79X8UeoEkkkgAgeZohYpYkg4iE2mJ4lcAk1qOpu30fRus8kk86+rfvR53JN9UItWByNsurUkhWf7rx5HTOZAyy6FpypO4roA5XUExe3A2T8X+bWREDUxcaU9ce4FV7DyW/ZNzCptE2Sf5a7JIgZBdJNTpIYBCkkjE+bYkgjIevY/wDAr8/nJIJBJJIABAJJNpAG5JP/xAAiEQADAAIDAAICAwAAAAAAAAAAAREQISAxQTBRQFBhcbH/2gAIAQMBAT8Qz5iZSK4wnF/o7lOMg6LweWIf4CIM0QU1iqBakfSE1vwaqERqY9oiDX0OJcn8dLlD5whMGoJGhtFKchIH4RZkv4/06aHxGgHX9Apjs8GzZIN3ih4WGobKUpSlxCC0MiIiJGiouSisvGTiVb+DENjurwUY9jfY/BFr2JY2ENNsSoCjNUuyLrihRvYpdnQgp6Q2ZWyskERoqRBVhSlZed5LQlpUdiha2GuqL6InpnohsbDEg8QhBEIjRUUr+sNrsYrKUvBZ7y8XN4PCEdPCLujRrEHwLZRQk/RUJ2QVbFISok7x4yhPgXBIhBixc6x0KpSiekNrwb2PY6NvNE8IEosQn4aXRW+yjGTMJmfLMzCZeipjSOuhtjdKMXNKUuFFFKKyv86ispSl4//EACERAAMAAgIDAQADAAAAAAAAAAABERAhIDEwQVFAUGFx/9oACAECAQE/EONy3hS5pS8F/BzLVRricFhiGLr8DKDeBxEOgG4ZNpjIl7E0VMrGhaVlohOvi+xZvPRome3NUVEEYp0fwbZRYqTtjVi9mPEbE3hdBtEd/wCgwXSEYeliTi+xdYeKLbiGpiEIQqIIGonCyijZRWWScITNBCsSiXwVRex7q0JLRIdGMUg9NJDtQ60iaFyLrQrL6Km2O42yL2J7Box/0K+ZiMfYsv6ISQQQnhp3lPVIe9JSRKEOgm1tCfpiQjCixSrBqVlZMrH0gNGtCfSETk/HCcWJGJ1YSpnshDaYmJiy6G0eoj0OBykYmezZ0X4Q9M7c4MeKilKUvjnTExI2JMTUZKEgklmDDEY2GVBkpJhLsSMuaUpcXw0pS4pSiUS7RGuhMW9igiEx1iEIQQQQQiIiEJ+uEEEEEJx//8QAKRABAAICAQMEAgMBAAMAAAAAAQARITFBUWFxgZGhsRDBINHw4TBA8f/aAAgBAQABPxD8aIJkN2l9K0wa6lDaR5hAwF28RLNql8vMbMZE3LNtY8xJ5ngE8gmFoPS4gVWWIpFqX4mOKp/9ELjh/lUNBvSX7Qayk7MvdWXLfk2StrXNtBpko6VFtRELkg6EQCO8y2D5nQv6xhOb5ZvEuhr7luB4FM/ESLj7N/3NiyuRf1LVobW2JceJq7HMQEwWnRSWrwBXk/UCPREr/wAFAlkxKLnzHf0jl8vc0Dh3lVVRoZdTlsrHxLdLFVGgLwYtj6sZBYmzlHfaCGuroqXk71xW4zD4tFuk67UnVM29bPUGw8Md6FZNeTdRRoAqMlWfcxsO3GFtebgo1T2lVALMpx3n0Y7yzk9vyRl7ukuw0vxBlAtEpMeYUdZbd3mCKt+YdxaggCdYZVoC+gzFg8zQ6s5jUxsA2PTNXMpfnQ53zMwHQyr61LCpo/ZfuAYpf6In2hKes8vw3T3cYCIjyVe9TXH/AGZZvC6f0DAb/wAI5qYqlwV7q/UGGg7mlPJrFQV+zqKUwNVdVni9JDKj/wDpix2qv1/ZKkac4PlIPxwkswmNbzCUSQQTfWxF7QxHCEYAzxUC71fbBb6wr5YaNLujoPEeOTJRVu7e1QQIsvE2rfdWOcgb+VufZlJKUfJZ+4zQVtBhYO2GrenaIRsdpaH0P4G5cIsIibEtyqlMMgFJi/10bxBlDuXXTLFdD0HErKjqKZoiyxCZAwhvWsJKFgLHMepXtOTPV1vYlJGvU6VQK53d41Aasf8AeKw8cYSmEbsO0YWBRmERKs7PpNNTlZe1pT9OW8PsiLjFpaPkwLYJwC/tNOJ0D0oYoh/Wj7EoBX+GoqLzqo+Anuul09yKAR6F+CBIsS0hvGJY2uVV+5a+UgZSvpgqau84vEO6CUKos2DvDuMoWh5ta8ymAQlUK/QVFJOMatDl5wnvKM7+0yEd60QczlyLWUvmkyGIbNFHVoT2jQrtsIcjf/Zap0GRAPOq9I2QFWxY09GFWrd/eH3im4sOVQFLW86/gQKDP64nqQr6QVvIsumCo1+2ymeoFEYldDs1iXELdcNes3ELIldZndGW0/UCS54/dB95hQH1KusHXvZCHmn2h9mLgx1uD2k3kvnD5lItD/WzLIGqk37AyvGrTL4hxh82lPdEFRz8jfcDKck2NPtcNO86YHk+Vlkh7Ku/eLlzOAalTTKuJiAUG9o3V3OIEckRoC0EUcQhBsZa4hsrrs1DBuRqgZNW65l2l9QVCy1ozV94UwvI2dqOJohJBHsN16Q4VAaKINlhh1DH2kQUAl9j5lxplWK3xx7+kqGSxcgLB249IbNXTdQ4w1DpPsfitoHljsbogeiWtxbB2qxdSDU06xZywdrX6mCPRRVN4QQs3arTftM9922fuPEq65dBoxtcPmYi1rGT1lHhev8AaAMp8rFSse4wDgvAlTTK7y+gm36hwElWXc3wzSJ5iVKxBYIlTcItt1r0TIh6s5Ynsg4ExAYNgMeIXIeercqFMBBueAgwlrWnQ1v5uXFBVGaClwGjc3vkY8xN1qCmxIPmUYG9OA3/AFGDFCLFB16wmgpi4oopvB3l6Cd4HjLh/DkteYl6koYAhfJOK3bHpMsUyMK5uC7oC3d3lgumcG2Y59CUfM+ACaDF9IlMUVOWrPYuUpFkXkrat3zOAbesYSAvoX9I3WK7pgiFey43KL6QiKLYzUIERlks6ynWKJU0rFPiOWQIbbeMxUo+gM+rluGLoBG5dy11VQz8XZlM5LFdGAl5WV3lJvqXlehBivojb+ocAAiDcYVUDrIEbhL1dOL4YTC1t47Fd7mDp8uB9Uz8wwaUN7sguEEAcCpXv8QxcAYG7XG0+xabMfqJhpQ1X5gOY6qv6l5dG8y8ZlneWBvU6iMK+0C0SopCGGsbGyBSFSjguy1ahL8C+Su1QFKAquF7r4l7FxZiSbL4X9JylOAvkSMHeiL2Mmkww1K+m3vKGm13l3mX6y/WPfGZnqEyWb9VlZRR23LuQOxAvVRSBhzMvV7S7ABxmYUT3leqetcw4K2uTXiXC0Hq5Zd2JnLR7SktAzoljm5kzA9oN3QzPRCEejcamrOfFzNgJVinq/aMAmQy/wDTxiN4eA/Yv9QoCAPN/wBi2RyHiMK+UJynEC7gACnSG9wCctNMwbDF+Z3Pwi8XOIsbgHMWKWLXsUfOP6iMWFMAKGd6d6KbzAtNTvTvRJli3/AU0xVljWJ3p3mWeYtwYwAq/wCFXfiK+6PDgbJ3J3J353YDgLtcv5B4l9Mfw//Z)}.skinned-page{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAC4CAYAAAAMnDLKAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAB3RJTUUH3wgZDwkyIJT6egAAIABJREFUeNrsvXeTLNmR5XdvRKQWpZ9+ryW60Q05wGCwuyR3zcgPxs+2Ri5nhzuDgWy0wtOydGVV6oy4+0cff/UrR9RrkEajGTkZZrCHyr4ZGXHD/bj7cRExhPC/hvWxPtbHv8kjW2/B+lgfawBYH+tjfawBYH2sj/WxBoD1sT7WxxoA1sf6WB9rAFgf62N9rAFgfayP9bEGgPWxPtbHGgDWx/pYH2sAWB/rY32sAWB9rI/1sQaA9bE+1scaANbH+lgfawBYH+tjfawBYH2sj/WxBoD1sT7WxxoA1sf6WB9rAFgf62N9rAFgfayP9bEGgPWxPtbHGgDWx/pYH2sAWB/rY32sAWB9rI/1sQaA9bE+1scaANbH+lgfawBYH+tjfawBYH2sj/WxBoD1sT7WxxoA1sf6WB9rAFgf62N9rAFgfayP9bEGgPWxPtbHGgDWx/pYH2sAWB/rY32sAWB9rI/1sQaA9bE+1scaANbH+lgDwPpYH+tjDQDrY32sjzUArI/1sT7WALA+1sf6+LcMAGm9Netjffz//yjeoewJ/8b/j9xPdPcT33F/dWuvA8Drzhv/H1r7t1z3u9b65xZr/r7u8/XxbxwAKnkCXriSPqfwVBCa6z7/PiW4bm2CV3LdtYSaz/x5uba6Zm3Cf/tb1ianbBV+87r7CO663rU21exR3V6mGmBI71hbBwKp5trqwCa4telvBM3/qyDztwJRugbw/u8Yhnet+VsA/P+NtX/L/vwta9+5vwUWeeX2wpu5kyacnBdeYm38nrVeae066sCgqgGDyikkryF+z9pwzXljzTmza9bav6X7/czdR3jHWgoAr82fI70DSDN3bXWCkb5nrX8G1629DsT4e9XfoPD8vb9FeP3+f58sVfg3XgPK/hquWxuuMUrX7cffujbUgHDdnqZ3eHPV96y9zhiEEELIQwj/k1NwKlBVwxMkxyFUTvGvEwRudOmE14NK7pQ5vGPtdQqTueug0ER8lmrOW9UouF9bB5yZO69/0O9SWr9PdUoba/a0esfa5K67qvmMClRdo5hVjWEIbp+uA5S6/Yg1zy/W7Eedx1anbO/ygN7lWYV3eJ91BscrXHLPq7rmHH/L2rr9SDX7HGv2+vu89OCe39t7yUMI/wkflm7jeBOlU0yvsOGaC85qPudFlPhuDoGp3AVHp4iFAxReM5W2umatnYPCX+FeolPa3AEH7zEPIaycYvmHHQG65TUP0IcihVvrBbdubZ2VrbvvygFTVgM+fCa2p9yPUAOkHlA8cFc1FrgOYKM7f8C1hBr5SDXGoqpRxOA8TRqcUAN2qcYrSk4W6u4xfc9aD5rXgY/3iryHXV3jvaQaz/ivDLB5AKUT3CiBDlCgiE2mq2trTUGLa246Ohd4hY3PncBEtyErp2yVeyhU2pUT9OTOneMhLLFhXgjq7rHCfvCBVFhLRalqFKis2Y9Us9Zb5KxGgcI1+/EuQKmuseqhBmCra6xNcNfXcF4jBT1ec97rPLbrALbOOCUHYFzrQSJBfrOaeyy/xzgRYEsnG8HJWOH2g3sRvwdg3+XtZs6zCjXebnL7+04DnIcQ/gcn0EsnXB7Vcvz3JW7oXdaUysbPg3so0T3A0l1b5R5qXvMA+bAoYAW+66+7qgGJVAMoDexF6byf6LyAphPm5O5x5RTI7zO9mVWNN0OgCTV7x/Atd2tDzd5Fp8zVNbxB6fajvMbaB1x3dCBROmufub1ruN/j3tXtR+XANNZwMdd5d9ftXR3A2nXkNdbUe2z0lFKNh53X7Gnu9i7UeLvXATd1yxvgurCzCiHk5gGYMufO2vDEDVzEEhuRXyMYdizw8Aq3EV6gV26DvMtd4L95QKHVW+G6CicwuUPilRP+CvceXbqU19fAPftzJF2fX0tACdinpQPYBNBM13gzyQEeAaVwrqsX6JWzQHSNV/i7UeOhhBr5CE74yxoFWtYAh/cOGgDXqga460Ciusaart4RAtaBcbpGgaoa8GFITMXyMkP5yGr2vwI40jhlDsDCNYCyuub3qndwaQTNkIcQ/gN+zB7QAl+m27iqiYcX+G7jHWvtvBGAUjlAYWy5dGtLPIDo1nJDuXbpAIVeRIl78x5D7ly1FSxME8pWOquScC9VCKHlQofMPUQqRcspUHBrGZI13X4QJEKNopRO8IID48oJvweU3FlTeltN7HPlAKVyMWvDgV3mPC4KdMudN9bsB72t0hmiOuD2IcjS7VOoMTgejKsa41S6e1k6Q/R9+8FzZDWhJQ0Zz8vsVB3oUo9iTZYnGAm4wuKixtWygxu9hBDZxZXO5UsOUKJzue2m6V14QCmdFSugHHMIZrNGgQoXgkQoceniLsbwK5ynAWFYOeHN3drCgUR5jQKt8JBs7eoaF5PhigeU6GLR6wAlOdc/XAMosSYUymq8iwouc4nPs2usqZePokaBcqcUfu9SDUh4MM5cCFK3d3UKG2CcfPhWun3OagxOclwY9650slQXEhcuTCudbi2ct5vjnGWNt0sPpagJtd+uNQ7Au4Klc7kLh1SFI8f8A7SHssLaHIKeOUCpHPjYjdAz4EOZO0BZ1bjnFR5s7rwOupgNbOzcWbbKudENh/KVs0DR3bedf4FztLBfpbtHWkgCSRP7Ed1aKhC9jiWAzXtxmQNCxur0aOoAparxlDLdY3L3SFnKIAe87pYLB1ZYWzgFb0Iul1C4rEbuGjUAG3DeEl5Ygee4cmFC7gxZ5q6lvIYUXDiD4wGd+zGHLjVr9j/iuhd4jk3c08KtJaDQE8nJL+QhhP/RucaVU4oZhCJ3VoKoVmhtxOcZLnaJC27opnkOcglLfRadAi2x1jZsgWto6e8SG0RmngrUwgYvHNhVeIABSpUBJAgedDGp4HMoS8vtMb0LWr3gBMaupQlXdYnfbF4DKAHueeksfYH9pIX0IF9dAz70tlaQiVbNfjRdfGsg0b4GULx82NrKWT1vIUt3DZkzOJnbZyqmN065A5+V2/+yBny8Iatw73XGKXMGpwH5Lx1HlAEk7LzRhYYF7nOOczXw3BY4X2Yk4C/hxhQ1lpOpuplzISoofu5QhnFQCwAydXEN0ZyoVmgtY1Yq3ALnNZBYQvALt7YB4V3A0hYu/pvBIrQdoBTOnSdItHHOlfNQknPjOlAouv6eFCwBPjmEN2KfVri+NvbQ7wfTYEsIbUdrCSgEHwp02ylm4bIMBJ8Wrs17iJ4Parv4NuAclXOXW3BlF/BQ2lhLMEgAlBLnJWdTOuM0c+cgM7+EAtI4rfB7ZnAW13gXq+8xOHxec7fPoYZQtd+cOv2M2H8Cx9u1xgF4kqNwzOQUClTH9vq1+TWueHRgM62xCAY0FSx4oY2wB9DGOebwVgp9Z45N7cDKzoHyTWch5xAMrrX7aODvKdC9DeHye5ccynedAkVnIed48F0IeIl7oMtdubUMyQpYhQUEoQOlXkJpDdy4tg13eonf8NzACoDSBqBUuIbKKUWJ6y6h1MzSzCHoHezPqqamYw5Z6sFdX0A+GpBF7keJc3BtBvlYYW2BZ57huZRY23JyR0+QpOAca5sA4qV73gmGtnRrF84DiPDG6YUFGPG3HsCvIRA5FNNO0nLEUZ1LRZDInEVIcLlX8AIKBxKlQ2jb6ImzFAkbVAEt7borPCyuXQEBm1i7lCAmuElLbKitLQE+EcIxxz23tGfpGrd9ge/6EKSBe1y6vaOFpNXrOovHUCOvUYqVC0N8DFm680Y888LFofabXVw/ASVzYEwPpYX94NrShXornH/pYvjKxeX0rFY1BHMG4S+1H8sa4xQhSwF7Vzo3muHlDDLcgSFbOBDMXTjbcRmJEvfH9PXceTOl4ylIuM9qdIteKZ/5JA8h/EfcyNSlsFiBtdADzFz8ssRaWr0mNmqG77RcwQMtZBsPdIp4P8ODSrAIdlMTKFYTAr2CkFZYa2jYwT1UEDjb6AmEoOu4BAMDA6wpBK9bY/XMsnVwDSvnllXYj6jzzFzcSy9sDne9hzhx6fiLCoIX4InksLIBXhgJTu4z3eius3glvt90HlTHZY/oAredy912efiFC8nmAHUfly/gPdArImncwHkT7mXpdCDCEJFU7cBjm+D3OtiPZY3cMZxtu1x+CVniM1m5EKR0MlPguggSuQNBz9u89WDzEMK/x003oXAzp+AZ3F+ykiQd5tqICK8gYOMbENIZLthAgmkRphxnQLkOUHjhYvjoztODJZ3jOgo87AoWocQ9BiBm7ryLHjyhGQSijbUreBdGxkzxENrO5aZAmyexwt+FE7AGrPUMYNdwNQ+MLXtO2TJX5s0QpI99WDrCK+C+UwhhgP1dOK8vOTDuwzuaw7K24d6XLkPQwtoEZamwzy1Y4JmLe7OauhWGThW8mMKBcQRILCAfDVjqqmbvlgCJDDJd4R4rACzBJ6upOi0d+Mwc0Uoif4lQI3OAQnI+WQjQxgZdAHEbLlYJAIMYQhgDfVtwTedOyDOtzeD6cC0Ft4GNmONhM94PcKMJKG1cy8IV67RcuFIAUEqXJSCSToC+fTw8uo28R3toQ+fCJQiMhTb2uwNYoDmuuQFPpC4OXYCNbrh4k0phlnOJ58qUI4m+rlubuxhyDsDow9KTnCSgBIAEwS4g7IwAlAqAktfE8NFlkPoARA8oWY3LvYLBIUjQXZ4BjL3X0biGNA5u7VzruB8z5zHQeufOk+Y+t51xygFAyXFF9KCm4GwarkhsGUJomQcQJLxNCHTpynvptpw7gi65WJQKfoEfJ8qvsNaQ6hxZh7ZLC64APoXOG50rXjkSzH5zAsHpQLB9zNqG0M6ArG1kEwKs6dI9lAogMXehRuWAsARI0LWmKzjGHgxqXO4GrMUEe9t3aboVhKDpQhC6qUuAYAOhTQlAqQCwcyhyG1Zp7jyUOTyD3HlxM1gkU/w5LB2Z9QmUwgNKctmmsQPuJfaDBodk9AL7UbjrIMcT4MEyzGVvB9OqU1jktuMMCshXpXtsYC3BJ3eyPoG318azI6BEJ6NMVcc8hPAr50avEMOTEadStMB6+rSZ3cgY6biGu+ASGx0AEgWEbOoImwogUUBhg7MIXTzgC3g2HceS0z1va21AHMoahjnAq1NDCrIKawrhH0DZ5s7FL13apo/7mGPPLNyYOBdzgRAkAHxKCDRJqQY8lARAIWlGgZ4ARPqOTGLtRVfnXeH3kiNJzUPqOW+mDYVZORe4h7CLnJKBB8PLHhRlBkHv4RoSvk/uKEdY5wGWxNsY4VAXBm7p0tctyNJca5nVWCHs6uBZzcAdFQjrAvRiDt1qI2yfOVKwg+9eOPJ7ydJ0IwHniKlJMEzC1TZLVo5N4eIXQH+7wQ4E5sIp0BwkVoGbqUIII+R0yXLPYMHsms4BPoz3JwCeBjbChLLvMhLRcSA+3rf4fOwIM5KNc2x8V9ewcKFQCQVtwd2dwlUl0UqLUIUQNrQPC8RzAS76GN8bwNIwP9/GeYMLQZg+MkAJAB9yJTkE2oAquBCkg3ua4B57jtRiTUfPAUrPgfEM920Au4RikiSdwBMcAHwWznuqnIX0pGDTecEzhHr0oC5cRoLE6QqecRNrDQhZsbiEHLSw1mSshfsgsd52gNKCsV64attWCGFuHADdSVOWHJasCfdrCYE2HoBNPy0IxlQPsHDkmBUNUcHP8bDN1ZrDpesCuUZ42B2gvCFxF+7YCFa6B+VZAqjs+keIhfsuhi+wmU2tTXDlFwDCEg+lpb0zQd9EfcIUFqvpyL8Z3Ny+/p5if5oOHI2kMpCYwdtgldkU97iBfa5cFoUgsdJ1z10FYQGDQZDYcEQteZhCMmMAu4HYeop9bAN0be+G8PLG4GG62DuThR7c/zE8pQ4Ac6nf7ACYps4DKJyn2oHiz5yHkju9KJx3EZ2L33CeGVPShXSiAS+kCX5mAY+hobXsSG1jL+Zurf3e214A5vgjkCoLIZy5irsc1ruCy9dwCtQG2kzgHkagWsLFNUBczAEyhmr2sLrO65ghJOhBCMb6O0I4xvhuD8J57hR2CS8ggxdg+5HDbV8CVAIedgOuYJLwknRbam3CfqygbAvEoTMQtR0I/wrgY8LB9GkPFnKB0MHCjQn2g/n2OQRoA+clGK9gOQ2MNhHvVy5MYwZpFULYwu8tIUsGQucAuC1XhLWAfLW01kB9yxWUmYVsY5+XAMsSIL3EOZsA46l7VlOAYBOciPFjXVcktkS83wKvMIJX3YUbP8M+BOhW5uQmwutrwmhPEB724FGeu6raVh5C+KkjRJa4uI4jEsYuZ29u6AkUqMCPrxwCNkMIp84NyQAoC8SbbSkbXa0CXMQULmrHCUHfVX0RDMzFLHGOJty1c1xXHw9wDG+mgc9sbzbgJY3B9jNmTVg7B7FlhycFaSGb8CTsHHQZ5+AAzELOAT4l9mMGXmWAtfb3CoAygZUfAKCXAIIeADbD2hmebRvhxgL3nRCCBAhvJUApa/gI89jOwWlswC1ewPobmXYCD3IL/3+KsM08mjOkBocA/AlCGzMWY2QDevCMZvAMGgCJ5OSxgMGJjhQMzoNlTcfKpU9z6VYDhHkObzKDEcl1jwULgRaIFdoOqc500w2knyKEg/nJcygqc5wXLt7PEGqsoPj2YDNsHtNmcwlMBUtROrdxAeHdAHKPatxGs0LnOm8EKUhAYZHMCK7aABbZhKMNr+ocYLSp77L0uAGloRu3Dc5hBnKoBXfUOIUduJZTF95kENwV3P6Oc6N7AEGzkAP8e4HUVNfF8FOEYptYW+IaLN4dI+7eci5+21X6XSC7sgWXm260ycI5jMUmWHNavT4M2RLnpSGzax1AH2bwhkxJT13KN+K5zvQZ5S5BljhRa6LPMngX0YXPERxPA5mUGe6RBjjWVIFaUdApyd48hPDzcLV3uAFChIrPwp4A12cO17iHC5y4yqUOGOETIFcX1mAKl9uU+gS1BgMAyhgsdAByJzwsIyRHsIwWVowgTJtI/VxAIJrwLkwgN5EKG4GNb+NeTNAHALcLxKEtuOdkas1aj2HFGM+RaDLF59roSpUvIAR7yEgsXbVnDpKuDCHsQtimiNGbSLGVCFemCNVmAKqGi8sHUA7uR9M1y0wRkmy6ayOnkRB2rgSaNBQ5MlFB8mEhyC54kguAYAF5NpDbhNydIRSzkPYCxmHLufgBIVbuZH0Dz/jcedes8htLhhK8juAIxBLeRRse9sL1r7Dd+MJGghUu3p+7E69cPFGgFmDiiJUVYtYCimJxzMCRUjOgag+CdwoeoBGudnoxD2xA1QQgJNfwMQQYnCJtNsB1LBCCpBpXcANWzNb2gMZnIIS2XeEMeyr62ocVlCK5GN72eAghIlnlU2GFrm8Mi18AUOZQ/qjPZk4gg4R3DkKV7rkx1+Y677j8Oes/GJcbUM1gURc1nMbqHZxGAU5jitz6wDU4zRAz9/Gb59i7ITxEA9UhAPQUgDHEdRlfsoFQ7gSk3wD3O8H3c3jRAdfAEMTClRwgH+AxsA7C9pnG2rzxAVz8qSsoa8HbM54iWBbgHPFPFq5O25njB5NuhCkUFkxMHUicIpRo46EmuD4RFjkDu9lyNQUtuJ/nsEQtV5fAKr8BFOoC1qOFawhgxOfwGAqXJZgBKEjSnTqiL3N8xCb4D2YOtrDPZK4tpTmCVdlwfQhThBlDPZMVQpDM7YcJoQ9BqLBLl+bcgltNorULD8dAbgchHnmRTVyvAcomrNEFzrGJe1gCDJZ45qycZN/JAunNPjw2hosZQKKAm38By9mFK76AhxBdFuQEBo6FTuYlbMB6n8AL6Tui1cA44LwNRzBXjp8xWTsNV7sqkyPnu5CDC3hjXTyfeR5C+AcIk+XW2+Fqb3hEPNZ1efimS0lUUGbGuCOAxQAXcYbww9afAfE2gOpn4Wr/Pav8zoGWHlCacCmTS+cM4AJaoVMbrvMIxMoGrC45jQLWgy7m1NUgcP8YruxAIC6QgekhPWmexxaq8s4haAMg/xIeykr/7RyWeuBKZ+ldbGjtHHn4AgI2hoXcxnmXjomusK9BIcjIAUoObuUCSr0LkL+AVesBuEu4/QSUBAViLLyA9e+BG1hBHpPbD8vqXDhXvAlAGbvw7QK60Q1X287HAOMNpLlPwR014HEEeBf2nI+hJ22n9CVAIoCcj+6abe/6eQjh7yF4bSgsO+9iuNpeewrWlJNT5rjgCFSj61qBOCL5FEIIR3Bvh444yvGbDa1tIJZKeEgBqNuGGz0B4lJgItzGC6wdwCLTWjWQRqzgYpYg72bgEvpg4U/Baezqd+Yg7tg/cYo9uIEioDmuo4O1Bii7rkdiif2z8KpEaLOoyTIMnNcyA1FrWYYplIRdjhPsh5GCE4BzGx7BBTyyXQDKArxKcvF+EmieI+SkAYlu77ZgKCbYu4bLoS/g9vPzgHNPcY99/LcRipU6kGMDty726hxhTBuFUUvIUtT5JwC9FgjDJQjmiIxVhJfeg376Kty3Od2/c27xFBbGFGUKl7uN+G0Bq8minCTF76OYwiNgH4h/gNCh41A+QcFjCOENLAFZ3RVcKlPoN+AmhgC2GZDfCLwDWIwh2OcJ3FBz+Y4Ql2+6Yqkx0kQbEgy79w24thMQP7mE9MIVOtHCnYPcGyKeO0Na0kDiAoDTx7M+g6UgoCydYDBttgKgBLi7phBdKdsS3swSNfYTeFUDrTWl3UCcO4an1NJ/O3OEaoI3M0H4OEBIMkIefttlJBrhaifnCcKfTbj8U4Cx6cAJQtgh+Kexawpj+prGqQni2TJcfXx25uTxDF55E+XOpa5lgJBs5BrA+jDKR/q7QJbBwvWGzQScufLNBjaIgxg5rGLqapfP4Fa2sHkLXWCvxpqam9RB59cp3C+Ws57Aglkp5JlLKZm7dwTPoofvRxBYRoIdOIIuwrU2BbTqx324ihsoFZ3DmprSHYMU2nLdYwYGJqSnAN4tMPRT7Z2B8a7ueeEsch9714A1vQD6t3E/cxdObbkcNbMMSzwv1iW0ACiWZVgCXBcQ0o72fwnwYRnwFCTYpp6feQG7CIkmKKNu6LqP8Ls7YL/HyK60dN5TlKZvgDSeIbTJQJJmeo4915cxBzHHUvEjeD4DeGRzyL55wkeQnyEI9zHqEnLsXUT9QBte+wr600PoZFm5LjiwJUK0TtBAkF8iBjfrfARLnzlyZ4kCIR+T5DUo08ePnoar/c59CMBID4lE3xwE4gCM7AEU0FJvMxBbAzyg1/h7AxbPSJ8+XO43iJk2HZHTAQDZwzYh3oNVPEEz0gDFTyYIt8CZnMJ9HWLvTCBv6DtbWnsBwoxDQc5BmBlIjOGCc2z4GbyLW9r3KbycDMTWCGBwE+k4TvKx8OYUMfSeK4pKAJrKkZa7rkjMLOsOXGsr/LoBDuMIRUPb2LuJ9mkXHuEhwpMdEMyUOyMFj10dRBPe7ilIxQE8uDNwMA2Q5S0QtZYJOoKhYWk0y8oTDE4bgNBE7YB5sBYSH+K+WgidLlCsVbhivEkeQvh3IEOmQAdzVfYRdxRwjUdwiY2kOcJFdhGvjWCpcqQEmQ/N8PkKfEQXN3EG4bc03RQuZh+lokc6r3kuY8R/TShMqXscurhrCqUewqV6Aw9lG+vGcOUDvIsABZqCIAoglAxQTCnuwEMZgTht6bdPAXi34CKfo7y04+oPpsiT72rdCJ5PF0BwDsLTQOICeegOYtYLsOZ39PcUcXQLSnSMQrI7CPPGUAgLBY/AU9xBPvsMRmFD3zl0+2FFYod4hptI11pa9AZCniPUnmwgpDMPdgcG7thlJDgXkiDRg6c1geGsnGFJ4WpH4whZs+CKlFaOpzgIV7tuWetvnFeBPSUp2M5DCD8CmddEfHQAwQggggJcEytBfAUBzYGYJAWtX+A1vtt1BR1msQLQsoG4q4G1SxB6XSD3VEpYIDQZAaH7iAvPtLaJmJWbT1b3COBj2YczANo2BP8YsbdVsJ2jEcrccHuAllW5iZBihopAa1k+hODdwe/NUGBjluwE//0WuJoJMiYZvAvjOvaQY79ACNLQ/Z87QJkhG3CO/RggNLpAXv6GfmuEppcBiL4TEGg3AK6Wot1E3cg+lOIWUnHnaEpq63yvALA3EP4cw/K2AShGau/CwB2jsMtYe4YVuzBkJygF7sJTNZDYBN8xDldHsHWRZj5wcj5H/QwtfUP70YUHwUwbK0Mto9awQqDoLE4HREoJpWggVs/xsPqwdGfhanuixR372IgMjRMJ+eEllKIAH8HRWQsU2pjlZF63gJs6EXInoHwC0DQRqpy5EOQUXtEmOI2Z1vZB9J0hrNhy9RGnsIA3wC+MUEBlodAJUjhmeaNLlW7h+0aS3oIlPkVRyw1Y6SViauMPzgA0e4hvZ7hvK2w6BiO9hyKTKRTcXOwTKD85jRlkKcETWSHFxmKgU8jKHkJLWs4teIcl1s4hdxbi7cLjsJDgBojYV8hIbaGnxVzuHTyH10jZ7SD9e4GwzQzJATiMHZQ6j1E704R7bmHFECz/DMVs5uFNHUhEEJULGJwuvJs3yDo08hDCT5BvbCCOMJdtAC6APfUt1PqT9W/ClW+AgOJQiUOkCvtwzUcuhk9wWxLKZ3O4k2S5TwEWRmw1tDaHC1ZA2SYgu1oAiSZQ3kKQkYRo5YgtyzJ0XLiyDYb5BMC0gdJo8xiGIMiOwY304LZVALwqhHAbVomhUIHnZ9+7AzJp6kpUMwCeeRcWSozB6vdhJMzDu4E+ihEKyDbxW3YvuwDJU3A8m+AabJ8tBNlzHAqzPBXCzpU8qAt4AT2QgLbWUmG3kDI+gPU39/0UxPgewPYNPMYh5LbEWlPUVzAGG8gMzHFvCRmrRk2dxgqkce7i/Qnko3K8m2UTzmHxe+AlViGEqb0cNANCNVzdcEQs1MVFnAOxekD1i3B1BHEbFYGHetgtVMxxjHcf3MK+c7nH4Wr76SZKXg8AUj1U/42bDjVvAAAgAElEQVRdFVcDgLKCNQ2whEPHaRRgmFdgyldQCEsNWtrwFsi9CVxBIzMPUSC0h36Jc5SvdsBcW9gzRP39CJxCB/yHEVBtEHIjuJ9txJsNuIerEMJdKPEC91aXRryPa5uGq+28LQeO95CxucB1dCBDyXEaBry8jq4rtLHMz4ZL97URgiTE5QuAEJuYNqDgB5DPLed1NAXqNjjk0BVFGU90DD7I4vhDZK+2IUvHWrMBfTtDY9aGq5PJsW+sVRhLLlhDwklAbZfpGdhD/RWqmfhiAb6ss4uLOHVthQ3XAzBwSNVx5b0LIOAAPQBvUBc+hADPUL1lZZbHIAGHiFEnEOyoB3AGj6Efrg7e4NuLtpEKOoIw+8GX7CDLQMIkgMQFioS20MSyj/LqG0iD+W6zAQjEqSwbB1bO3H4cwqXcxu9NcU8NXd8RlLaP+HcGYraltaeucpKdhyNkO1gKfOY8lDGMQoaqxyYEOmk/xq6mfxuE8DHk8QYyABOw5Pa86N1tw7ujfGTgNIyQ2wRZzY7BBsq/V/BgWTy2Ak+xA+9hH0T5hiuWaiLUWIFwD/CYS8jwBrI/h+Fqi3WA5xKR+4/wxqdo2AshhDOrBGwiNl6Ev36HXA5XguTCHEU+7EI7QBqxQClw7sgqS9M1kS9u4KEQ1XKBRBvFIx1YlAs9bCNL9mG9hwhXFq5seIi46xyWJiGut/h/Q4JiIUQP6DrDPSbE8EY0taGwJYSUrmuhB5tBASoQZgsU8BgbnUCCVdiPKfoQhsitW+qNI7XPIXg7YM8XWFuAEbcw6gbWzuA9tcF/WMx8B6A2gsJugIOx1O1tsOcnqI7cAoNv8f4NeKMMj3ZQYblEjYWBxSHAeAthsHk/HRCJxwh9tsLVyTpTcF4DpF+P4O1apyRDr014bK9BovMdEysAlWUOXqJuoI3n5EOvoPP2wtXhIiWyBANrB+ZYbY40YlagAzdpEq5Or12is6xwXXbHUDae4wQpNvMu9qGobHw4AOfQhHfRABudIZ5rIp1p7HlEvG9C+gYA1UEqbYWHbdVnb3BPPTQaLUEgBhBmnCXQg/U6RkHJbaT0ZgCUDtKTTZezX6FfI8c+HSDXfwd8zRm8uV0AkrHcN1G8dYaKv13wKitkV1Yo1pmCt+AQmAvwOLvIwy+1P5yyfIr9uSuhnaNApoNGFta230Tq7sIx8wtwRBFhUMQ5mijMOcfz2URhzyGMYy/89VyKDaT7DlA1O8Bzm8LltrqEYxScDQCcE5QNs7DHvNIu0noThMO56xd4o7970E9OEH47UYiFQM1w9b0AHAM2RcEC85MTgEAA8meOQIxAO0sdMrf+UsKVh6utnQvER1YN9gx/9xC/j0C2mMv7DF1V2yAIj0HiWEjwHJu1jVhqH1WJVmZ5gPTUHu59H+5mD0UoSwn6TRQkHeHh9tGEYzUMu0hZncId79UURZlXdFdKfIH89wCe2RtY8veg8DOXgjL23IitB3Bdrc+hg1DtDVzg24itz+Dq7ujc3LtbIFAP4UHt6jNLZZ5in3f1exMQiBsA44Nw2Wm5p/uwa9t0ZbL7qFbcQoHMKaroTA4OUeOyhbTqATwiA5ZjeMjbKJ577crmOyBJR04H9iGPbSg4a1ya4FsKhGpDeJcncPsbqHA8CSF08xjjr2OMyxDCIsaYxxjbUUcIYT/G2I8xhhhjpv9WhhBmMcYqxtjV53kI4STG2AkhTLSuF2M0QJnqPHmMsRVjPIsxNkIIRzHGjRBCO8ZoefjzGGMvhJDFGAcxxkmMMYUQXsUYt0IIzRhjC2mzIoQQYoy7McaprvtZjHFT52ApsD34myGEpOt+bFY0xrip75+hBPkW3NgnxrjGGHfhMp6iZt5Q/ike2J1w2Yt/gtjUSKUXUIp7qOY6Q5VZU2BwgFy+hQNm4Y7Ah9wAqXiOVONtPZMTALyVRpcgbA0kRqjcCwizMleX8B6s0gyZGKu9eAmr/wCE1BnSkl0p6XO4zPdhZI4h5Bs6/ytwErdgGA6QVepp7aGu4UgyEFG2PUcV5BAE8mu4/T2EWDMArBmqV8jhszT9Ah6HGYvXqCfZdMVjDVeVeQxvbAMe7j4K9BroCzAA3whXu08L1F70QwiLPMb4CymKuUshpbQvBe7iYb+d9xZjNLcjpJRexhiH+ixKOacppYWAYqjP8pTSa62rpPR9xFxnUtqWwOEkxpillKa6lmEIoYwxzlNKx1rb0DWe6fPzGOOGQCXGGJcppRf6OxOAjAVir6Xw/RhjEWPMU0qvdK1ZjHEnxriMMWYhhCcxxi0BXldr3+h6yhjjvRjjQt99FmNsxBibAiUrChkLZB+EEOa6n2cWPsUYb+k6rPFnGmO8q9/YlgJdhBCWMcb3Bcrm/p5amWyM8ZYe/pl+744+t8lGx8bsxxjvSRmsWnBXa61ZycKsqLVnKFPuhhBWMcbbWmvkYtJ1T0GuRa29j7TnTJ/d1b8D3WOFaytQ3TiPMd6REdkSGC/0+QM09Ryh2rGjZ/8sXA46uSMZs+zAOISwrec1QM7evI42MiAjKOAQ3My+fq+N9N05itE20CT2DJxDB1zTEkSfpTlfhMvhIW2EhsfwoiO8iz66KHvIKKwQDjQASId5jPFXFmunlC5kod/GCFK2Log4W3ymteZuxJTSYYyxLSHoSPiDlLArhbdChuOUUpDHsBVCKARCL6WAbT2odghhklKqQginUsw2CLNKlnygBzhLKc3lvezpvF0J4kxKM5BglCGEZUrpuQAl1zXOYoxT3WNP1xdDCKuU0lP9Togx7qWUZjHGRUrpCEDV0n5YWLGSkNrvH0rZ+wKsIqX0yoQ0xvihPKGW3N2lrnkrxthNKZkXMNHasX73AKz/rRhjK6VkfQHnVj0opT0A+bmrPZ1rrVWqzWKM72mfz3QfO9pTE/RDa4iJMb4v4RzDqre0/xXy4osY4we6xxKeXFNgl0sOFlr7nn47Tym9tBy3rqWpPRrb9QqUuwKJpc57U/doHs1IwJ1rn55K5qsY47a+P9H/TgXQ5n2aKz/R2h7y9UeW/pMsWdPPqWSsp3su0fhmcmfFXC/1PJuS7aTnlmkfNvVvI4TwQmsLM2RIXa4kk7k+f63fqbS2k8cYf2zMpKxzktK+gReQwEIvZXnbWGuhQgtlrWVKaSJraGRJnlJ6FmMcppSihRBWpGHors8KWeR2SmkupYvyCg5gqQo9QCNWRrK8LdQ/r2QBO3pYp/JQjgQSLd37iZSp0NqhubQCsV0pfj/GeA6l6EoY57pvhiA7EvSRBLSt3ywFEs+0l0sJ+gReQC7Ay7UPz8xiQIESWkc3JDRDWY+pAOUHEkADQuvOHAA4zAt4T+fd1lqr7OwKCM9AVt0MIVwIUI7B+g8VvpnVPbH0oSz7qZGtEsj+d5FXWEmZuxL499BbcK5ntCFFbKSUnljlm9bOY4xJ8tjQ2n6MsaO9C3oGD/QcM4D0UGDcTilZWvVcHlXDrW3ivFZ5eRZjvKH/1hCANfQ7wxhjL6Vk8xtPJAMNyallJGaSpYEMi+nAhhS4oT1s2vOEQpuxHsg7bEo2spTSiYXluO/zGGMzjzH+GrX7mbyAphazvLEJxnElZT4USPThylh+tgGrwhvpSzFWUqxKPIIV5WQppSda24G7Zkx5JQW31JS53MYZpBBCpc2exBhv6jttIWAhq7KnB5VijBNtyK4sS1v3FrQfN7S2gGcwSCk1dN2n8iQOZWlyAchED6Wl8xqhVykc2tb1bNhaS7nFGO/GGC/kmb1GaHJba61zzlzusa7xtdWVyyJPdJ6ZwombApAevItVjPEjCTzrGLZMgME9LHReA8pzdCNG7eG+pet0bRMB+AUINrP2xp+can8WAk8j/zJ5mrsKB6Nkqa/r3kPn4lRyYM88SPE7uo8bAogL3WuUZc/lXTw28lvPJqaUlvA0b0iRMnkihX5zV3tRaZ8qhZddKbF1mZ7rek059/WcelrbSimNwI9tmvctJc50bU3zjKUvb2Q4Wbhnk7pMD0uEBD2dK89jjD8Jl6O8cp3EQoKxCS9OXODEPRSonKLU0BjJXDfUtRgeJExPgm6xaUNudB8u9xztq1FIutB5X2rjBkj9nKWUcoubY4zW3/BCIUkHddEXKaUo1N0CoLySwEUppqVElwKDXT28ppQtmWssxZ+LAzmV9V/FGLckBEspjnEDWQhhDE4jSHjfxBgrPfQdPZOGwMdY/0qW7EBKeyJPKxcQLvWbGcBgX/dzyrZn/dYBgMPOywKcKAJxibbdt9WDer6HAKU7uvcp6ulvy2PYEfiU4BHmujZT5m09x52Ukt3jhUCignE5EbimGOMd7aV5AZsChA1xRKfa40prDVCeWSim7yxSSiPdRxKoV9KJR5LDXN+pUkoTydFSgGJc2kMr6NHaLKU0FSCuZISMH3uq57eQXLdCCAsZpkr/rZDn80oexZmut4N05tJ1745CCC3JEsuGJyGESA4gwrIbF1Cg2iohZ547j4GzAzgplUhlhTybGGBwhJxmX6g+AmG4jfTFsW7EAMUm6ARtyDaY/CN5Hcda+7b0Umu7eribMcbjEEIzpXSkDbbcf2YejtVtxxgntlYC0JNFKCRwliq9J6vbUrxvqD3QwzqU+3+kONTyxAcCl5XF+1YurbU3JSDbsjRz+1vXOZFAHlq7s4i3faSbBkbE6rcsc2Bhxb5Adqbn0RSoWIFXru9+JKBK8D6aOn8QoJRS4o91b02Qgg2BW9D1JnAOJ/rtA7NUWmuua5TwG6Bs6VmvdB87suhVjLE0gJXS7Yp/quS2D80rFcifIrtl5F2Uld2w2Nw8Pkuf67wLPatnOseu9GiVUjK9WAjEVjrvUxmnofbE6mxiSmkJTiTB6LUQaozFTZnn1EQtgFUTNiV3K2RoBiGEzLIAC9Q0WwowQ7VYC7nkGcp/jVzIwA9Y5ZFZ9I5rHkqoKbda+r5ibOtQ20AGwmKsrn5vaGSjHuyO1lqsE0Cs7GpNJgXdlhD27HMDNp1nLsGwh51p7YXOO9P+7IhDSFo7lPDtyXIYmVfEGLeTCA+BT1Ocxl258jMpUJQ3kyu2fGkFWVo7QyooCVA62o831i8gpnwqQDjDnIIhXPlKa/cAKJZyjAKqDe2Rka9D3ZNlDk6l3BbfTiQLb1tSRVC+5RckvBaCmBttCvQBPIix7m9HIYCtbWmf76CR51Qh4MAySNqPQoB4SyDRkzwGhW6dGGNfz6sKIZgsZSGErryOTErY1h5ZyfZxCGELIHEqIzDReXfMkApQN/R8N+TFJRmGroAjDyHM9ZuWKuyKLDTZbRlRLZ7pDK79AF7HvvShC2M9gudug0VSSumlAUABZU/IF+Zo+5ygsymifzkLV1+PnAlFjVgzJatQH23FF4z3rTqvIddsjqKLQp8/lXAuFMd0tHEW/1k/dhuZh/MQwo42di5lnplLFUIYam1bQrCNuOtUa21I4zbIxtdw5buyTBOkAG8I9aPCih0p9xZSW0kgcVv3YOHKQF6ADc2wbrhKCmTvbXhu5axy26fIw1v6MCG3XsHKWn3F2LrN9Ly2RGAZiN0VSFgt/Yn4jXaM8aYUs5KS7el3jRc5AmF2W17BVPHttvbDuh9PtB/9GONd7XOpvTOX+6Y+N3KzKQWfgVAdIh1qbdAzfX9X+9qUNW3pPAaEhZ55AlfVEXBEGZg9S++ZwQE/ZDMPzWPYA6Cfar+DZMQajUrJnxmyhmQ0SQ8aUvwKa+1ZWSbGuCoj3C2GP5bsFtDbZLxUjHEjjzH+DMpcuF79NspIm2hOWFLhUQgxdhmCZbg6IbaBFt1D5GkDBhe0hfJDAMoTCYHdTCa0NJfKkDtTjNbXQ2lLOY/khk31UII+fySrZNOJ+3qoBhS7VmChtW1Z1y097LlCkjMUBu2IeDKl2LXCJim9gUweY7wlBXrLIoNzGcua9qQY91HIcmj7BtfTetlL5OwzVJRVApQFmoeWWmslpfuIy99HEdEc1rSKMW7quqdIcZaYI3Cm3HqU4j+23LjAx9KIZwKJoQTynvZuqv24bdkbKf6RAb9ieONV3mif27KGZ0p/ZgLYWwgXn8MTtOacsaWTBdQLGJyh5KMv72gh2SiNt5F8vBCJN4OsWphRIgXeEzhYq655ZhYSJpNzyc2FwOYNa1xQNVoIZHog0a02p432fTPAGdL84W0hULj6AlBOCY5oyUyuHoAv7EgoxrCGj74rG87RKvy2dlnx/lZNueJIIGEddVZTYKlCe4XYQoAwQIxWpJQeS8FLCaSRm/ZgbeBCW5vWVFXkrsClSCn9xWJ9gMTLGONMVv+BtSxrbTKOQu75ERT/ga5hU0oxM+JPWQUbrvFG3ECUhXyBQqI7shTW8PPShFZutOXEx0YQIf57Yc1bMcZPwuUoLXtxRBtC/dzKSZFGDGjzbSsGDwIf4w0+EFj0U0qv7bnrfvqqdxjrfPfNq0kp/cXKe7V2IBd6JC7gnizcTZFrU/3ebVjTC4VZewLr3ZTSC7j4u0aUqrbkLXsuUDuFd7AtkG8I6I/lzRQ6x1yc1CPtc1N7koUQzmVszAsrBWKPUEPSQem81TtsQHYtZ7/Q7w5A3o3d7I1TEn2ozbG5FB2EA0uU6vcMACrU+zedRearwiOagf7qPWMAgAa8hxPUSfPVz4Vi+Q3bFJRkch7gWGvtofTRrPT2fXGI0UJK6VsJgZWhzhUzzbR2F97Fl2aRrVRTKL6vjb9tzUMppa8EHPMQwm25dAs9rEznHcgifCnLcR5j/BAx2nNVDe7pXJsppUfa/5Hi5kpu43MpU0/XuC3LO5Yb/ZEEx+rjzeXelqdzLIb6QEAyRVxuXkDP+A/tpw2inMUYf6h1xvq3dO4MIJEJUH6ICr+xuINN5MsfmUcYY/wUMmT1Cn3tyZYU3KpDP9S5+gLNhRRtD/txIa/ofV3bpgBlZmGGQPJUWZfn4lVaOu8T82xlROylpfa8bggk+jI0Hf27KcC0ephnUPBtyO5zWO+AdG0LTU9BBLMRiB3XdZi7ASAFCG0jVeteh9aGMW1CP3shhMoKgXL0CAfEUvQCpgCCBkDiBA1CCSizQC1zJhfHqpYqXPAcTSnWKWZluR252D2kEcdCOhsW0lVM0xBI7FlGQOzogb6b6/ORruWRHuzb15BZWCE238ZpRSm+uec9Xd+BlKaQJZvpWv4kq5JUjZfJHT2WRfhQ+9RPKf1Zn8UY4wcS3qn4BSMKmyGErZTSt1bbH2P8TGGStVOfyhK2FVY8tUYaKeZUwneg/3VFMj2w70tp71jJrcDEyLSG1p6iUtCq/z6U4u/bdBvxBlaU89LStMoGTEBOmrUPIh2/tU67GONHIuwW8ojmFhIINL8GSPxACmPe3UzpuD4AZaK1H5iLLYA9BxjbsBZLM9/SZxZyllJeC11PZBieyIvrSYlHAq2l9vntDEgZp5swinzZTluyanr0At2yOUL0E+hPRHs6R39xuEgDfxccVpPHGP8ecf5UJ/6ruBw9+8l93kHdwAjFCPQO3gjhB663IKG9tAXF7MvltjTiFGWqW2D9n0kgSlkyCytm8i529MBaSvdZY8YOSoEX8C7sDTcjpXMsc2BucSkBM97gBmoEniFN1NH1PZVnERX7Gln1EDUMe/rspZR7JaU1F/NbgVJTwtuQa30mjsHAYANudBZj/Fi/baWvZ1LWpRT0uT5fmrKFy5HdxzbUQi79S5sqJLBLegZjpJvepvvgzdyyrAl4iras4AcWVgjsB0b0iXCztuBVjPFDZU662o+2zntHcbdVLFppdA6Pzaos77t+iJk+a2OfzSU399+MwkQela19qSzUieRjQzJwprVddFbuK+5/KXncwDSoKepmzN0vJEtbqOe31nIzxm8VHWXsDTfIx4ClDT08x99vC4F+iricln3sXHnLEMzQhmiafwClDSAczjAPMCEPP0ALckDe0vL7OXrc+yhuaMAtayFmsi4qq0vYtkIbrbUMQxdtqlHXfUOCYW6ZbaLlh8cCiRdY2wmXQzLnWmu1BnNZhD0B060Y44lizhMJ+g6aqf6iz0pTCgHNS6w1QHkoz2IZY/yRFCjTtWWyYjdRJjuTUnwuS9dBvN5WTGyx+oW8gB8qD39T+3EmL8cIORsnbvzHhf59Aybf1s7g0dzS+c3rsBj+JrJFJYTf+ASbpXiEcLGl+34qb21pWRB9/ghu9Ibi+jfySOwakhToW+TWNzBYJEOtQUNewTfW1SqD1oEM2J5ZN+bTcPnSEfMubLTeGdqjTXaN8OvA253D7WdNjrUhmxGxArsJivYi9PoMw0YShv/keYzxlxjImGEQSBMnKUEiFPj7Ak0PAaOzIgZyrLSZr+BmRQyTsOmtm1j7WArVQZrRUlZmUawB6QkKOYZSEJu1lvRQmrDIb9s1BQzsfd+Ga7YfLoeE3pSgNRRXW5FMX678gSzZazWj8PVO9lLVjuLwMyn+E5Q02zvxznXuttzwmTyRxxL+oFbakxijue0dCan1FvxFwryU4lv78THapq1/wroRFwoFT0SCnmEaTkPu+XMQfZ9pbQtxfw/1A9bYdCGeYoLGGBPyTa09UPHSsaU99XxPQJIOZeUmCFF35HXcEOs/s3y/rHWFDJJlUvbEA1X63YaeSQ5jYaO/rA7EiGcjo9s0WCL7rAAn6ll1MKrOBos05CHvgg97Ea6+sdrGtkc0ZLXC1XHpCfyYcWAj/F4IV9/V0MQ5Sjf4J+QSkgyTfxpwIThxJEC5Zy6GKeEZNMLVd9SPwWIG5KrbuLiJNsjSF1vIHIwxcqmD3oJnJkQYWmIEiL140zIHD61gJVzOp+frvm/CIj8WAmeYGFOhkm7HSoFNuCRUN60SDVNg9pD6eS6BOgsh3JEy26i1MxtyovTWK1WwvZE1rURsncQYT6V4RYzxfYHOEux3VNXimfLuVjT0oYhN6y0Yoq5/hNLcQhbySKBno9XmIu9G4XLsd9Ra6414YcZEa0+1N+dom15J8R/rWmcKHUYou55a+KZMygt5NSPxIksBzinApyHW38D4jWL4SmB/gpZ2U/wxwHjHpWDfvgJM3ksJg2P1Jh09c8t6BQDKSnJnstxHFupQsmCVrjnGd9kr99owZBkK7PimbXtVmKUcbWReCzM7jUCcAmSsdL9pWYCINGBkfhE1+Rlih8JlBFrORcmAVE0UAp2Eqy8Q2cc8PXN9lqjx3kRG4ADuex/FEda3voGhkKdC5+cCCRvSaM05GyiQsTn1T3XebWyuZUGsV34m8HmCTskeqsPsJZ3WHdfDWptpl1CTPpZFvwghDHS9hZTijgpTRlKoYxF8Y+XWn0oozwUSTVm2qVj/HSntB0aMKW15R6FJSzntV5b9UPz8TM/fQqloNeqyWNbh9omKlpK8gYG5/9onq2SMMcYfSiEtfOsqRLNqSGugWYm7ONPePZQ3lLR2hsk/Y/UhTMR/PNXaiUqxSyjxOFwObN1Bzv7IGP5wOSF5gkI16/nPkH7eROHNCsZxw7IOAJShDMW5itcy3afJYwRIcJz7EgNT7Fps9sYAHnaBdHCFwSUBHkPAwJAKg0561gvwM8QKFQDAXmFdwSvIMLjAPIYW5qlVjm2cA30amI46wuQWc5dtVtsIs+CiYtZmuPoCz0PMSdvC3LhncNEa2uiRlO6FhL8NF7+NQqVdK2zRRlvo0BNi27W19N9KNf28Qvx/U8RhpfiRjU0W129I0K1xpUQTlPWAG8HZjDGOZelPpTSWqcitW0xKbEUn76kPYUNlqKUUc9vKYdF9d1cAclPW40Jgc1tEnL1uax99CO8LCI4VZtzEjL8S05hKhRWPbWKPlG3XWniV1hsKUD5VYc9YKb0tnHshTsOmTFmhU+WawvoYsmlgfEv30AWBm8vFbyukSwIOe2NQVx6KjV7rAgSthmEXsyStQWuka9zFeL0RalyMhLTQsotwdorZjBFj3goUzQ1QhTtBuX4Him+l2PQCFuDmWqjpOc5jjD/Hl5eODMxQCrxyRUAlQKNCL0GG9uEAtyUDSLTx2QHYzgJs5hhWOg9X3y7EufLm+thctwYeoE383UII8ixcjt62CSwHmMO2B07htSyYAYwNw0xS0HvG+AoIllYaLLfxSIr/WOCTqZzY0loreR23rOFKFuGW3MVbajiZYKzaTVSqPVRYM1OxziGqCiOGd/SkbJV4g0/D5ajpUytCkWXeRF78QpZ+pD2xkl2rYd/EOLNjDO64JQ/gQEC8qyo/m+X33PZDIcRTawtWGHPPQEN7d0su/l3t3UyAuCXewAa7PES9/C0Bd8KEKxsIa913bCm2eRUvkHYuMHqrcKPcCvALLeTWz9Hxuoe1Vnq8wigxvs16C5k2i+HnyBCQWO/g2kxnT0C4B/TRsI8nIDXYCiF0rB14BVchAJEKpB4ylPcGoEgEVzAHu5+QusgBEiU6ATuw2CuEGlW4OnX4Faa+EtX4+m2Ly79k+g/exQRTcK36708SZL5MYhou3/Br4UAHwnWqSkFjal9LqW7p97ZTSl+rG+1AqaYhiNCRBLERQrgtITLv4IGuu6fvHksYexL+fZU0P5P1jqilf2XTj2KMD8QXRACh5eFPQLAlS0+KKbeBIwsRfWc2ngxViEGZg8cWrmntBYq5rKy5o3DloQD9WDl7q994qc5NG8bxQPu8UKjwoay09TJcWPGO0pHH8sIeIs23I47jTPc3VFhinuA3mA40tNFp4hfarkjsL9aQhJFaNqXaGoQsJDZvxjJWpnjP5DUaoHTgfZ5jyGvAQJUGiuamaK9vQwfOnNHtWt1KuBzdTt0KqAK0z5N5ADk4gHMgWgBBGNEvEOH2F7gQU3DzEJpAngu4inxfGcc6F1BuY0+7cO2YWsyBgA2lfrZRBGQDHbvwDkqBxJ9kaTZxnjeIv3bRc/BHndcIlAFSgGMNrTSv44+yVG2RhZu63n0p5Efa26GuYanY8D1Un52ovBNIwrQAACAASURBVPdDXcNeSulLq8uXUnTRVfkMRUDvqeJuImX7wABFz/UJOiV/KOs9E+HXs5JdrX2KUuDPBdgR7nUQoKyknAsQhVMRfd9YBke1BoWKog7kRn9s+fyU0p8kuAtdt5XbvpFCP9Cz3NWzLmXh74O3sbU31RNwQ9dmTTT3tNbmHLyW0g7RwNRJKX0hr2MTYe8Fulo54epbgUYfBnMB8nob3bFfIQQyEr3E/MA2vF2Ojy+gtHMMFs0cwTdxir90Xjjf8zEKIbStDiBcUwo8dQ1Cvl8gx1pa79wpfhOAYhds/3aQTThwLksX8Yu9e7DtKpwu0C9gSPdI7pflWc06Heph3wCofSuFbyKksHNsINaznLG9/OGmgaMVnMhaDAUGX4nVvgghfIzegj8pft/WOYay0hcCiR+iwvGPKhvuKbbfkJUeKbf+mRjxG/I6LqSYD7Qfh6qcfIYioI91bwfWDISKsnNUn5WSjRdSjKniW5tSs5TVs1Lgn2NAijW7WHlvS5V7K3kbnyvdZwU4SRb1rlj/Z9q3oxjjp/rv2yml32s4hlVZbllYIo/hI8vna+8ytejekZt/ISL4qYCup/3/FinNLcmHyflLzLCwF9HYde+C41mAC7A3Ak9lcL7R2k0YmRH0h+X2z8LluPoALi1DQ52R9vuYNBzB8CfweBFEfuG5u1zumy8COgX7HmB952D27TiCexRBUoyRdrALPES8n4GZtFcX9cPVOew95C0tLXKOTSuA5h0rwNEDs/fpjVEEsYkJKX+Wa7iFhzLGTAN73Xc7pfQHWdkhNtmyD0250ZXW/tamyoiltuaQp1L89+x+JNAtKfFHAoyFXFqbxDuUkP5R03VGMcafGwMt9/pUIcieZhV8ba6+FHMhJX9KEFRY8QzNSp9YuawE8Q2Ght6JMY6UwdgXwFq/wKtw+f6DoeLyscKgv1gRjBTfBnccyD23wa1bAse27ueHIvyCLH4hy97Vs/lWw18PBRKFnuuXIll3BOBbAiYr5vrAOvOkxAXCAXtpRyHguxEu3zPxIly+7KOt8y7E5Ft5bx9TeN6+XBfzIqNA8yas/Qrp4Db6AiycGrhmvQzxfs/14nRcyJ7VpPJppMs8xvh3KB9k9Z8p/hxuf4G1M8Q0CWtzxC8JzKS9aIFrLVzo4qafAwEzhCCVG28chc72ogdjSe3VX/YW2h6mzBpYbGLyzwghiAHNqRT0mdz/HdzzMXKtu2Cjv7b6cwtv5I7amOuPzKOS4tvMwxsSoteaXZCkVElu429tXpyBhJj8fYUQP5LwD3XelazkL5QBGEtBxwofWuqo+zOGoP5SgGV5Z5ub3xQYPLR6BTH7M1kz6xcYyjv4QM9vJgV/T/ezo3SfvQG3ofTkgcKChyoiylQjsRIBOBNR+IFVL8o937DqP5tLaAVF8nQyFWgZoMx0Xhug8VJhyn08S7O89iZeM1QH4fJFshYam9E7RPhga/lm6R6acJ5KXjZRkl6BmW8iRrfz91CrEjF/ow1P9RRDPip4thV0tnJNfHaURgKWTmljDRdQXRP3B1QPNhD/s0Owj3PwvA1c6EugcAxX33IbnCdhis8SyVO0Em8CQL4GoPRQoWebt4f05HOtWYjpHgCoDtCs1IR1PAsh3AApOJW1vyXhtCGZ9gakG/aCE1h7m3X4IYaGfivwGep3l7KmDYUFn+uBlgKfgeL4e5ZNkJAv5DGcSYG+VVxfyMratJ2RwOAzDPewFF5pawUa5/JEfqDv3A8h/EVyUIroi5gfeChlrbT2ofbqRKGNycLEjXe7a2XfAuObAkID2CP9XYojOJdX9LVCDyu2sVeDV3q29vKVt3wQQs7c1Q/sgpt6Gi7f7diCR2Dp0i2Exo8lh2ZcBpB/e4luA9bf5mmwv2YO3iGDK28xPAuGZi4NH6HXE1yvFe4lqwP4KdwCVvk1wSAmNhDUeAxN1y9gLkYLVv4cBEVEyaMRfkNc2L5j/RfgExrh8tVgNmt+AGJkiZRhK1y+t65ENmEK1z9HgcsmHvYhPIZtXMsTbKY1fBxi5uEDGyslhbdjU9c5Em/wRASWvcjyTbh8ocS2uIe58uUPFVYkFQ4dCDysvPqWrn8l4e9K8X+qa7tQ+myAApVKYBBlTX+l6TulrHchXuOGMgQPMRjkF5jx91ozENis9Fjpt5FCkDOkIpPOa+24+1LmffETM3lcj8PlCPQ9TBW2Oo1dgYy9HShHavAtH4TZklbxeaRn99I4CniZb1CS3kfM/UyGYQPGaYbM1wDx+htY/wJKa6Xsm1DSl26AZxMDd+aob0nQtRW8dLP4C4TEbO1fwbD7iV+ZAcCPcVMRlr2CIkfEyYxbWgCJCgwmC4amLqxYoie5QL8zXasBFJ7Vhx3clL0AcYCSxwTWlG9U/VZAYC/fnAHscim4xVhPpZCenLFuwht4sH9BPvftK7wlzPbSTJt5+EgWehRCuK9WYms8sVc8WxrrpUDktTIElpl4g2EpfaQGFwIUK5N9H805leLQ+0h5PbRSWBWCvdT/bMbfDXQuPsLLUv5e607C5Svg7qIz7SvMEvg7hSmWZWiKR9kAGdrTc/uhCnFKEYi5PLOhCMeHSOe+pxoJe/GHucR8x4E12NwWSAxQUJbA8dhrvff1/FqoOu1DLrfRcLMv0KkgS3ZtDcTw5nUMUaxj1bHHWBtR9m5z+1qQsZOadt45PIQWQOIEhT4ZDHsF4MgJKBYCBFj1AAUPzqWvHCGRQAzmiJP5xmC6HVNccIRFX4IEDNd0QZ2D9W9hoxnDN9Cp1wZI7KDoaArOYYDw5RVCkAydW+ZKbaIy6wsJqFWf2dtwSutxt0yHsgFbEto9rbsAaN61enYRWEMQiOfhchy5vddvKtb/K3PJxX4bYXmsundLP70nr2ApL+ADxPBnmLlncfljAcq+YnibE3Aqq9xVfv9DNP08l3IncR1Hsppm7T+XJxJEZpr1tvZhayhqKKyYKYz5oyz0Knz3whKbmGRvNHrPeCGtNe/uHp6dvbjUqvyGApSefvcOyDQbnzZESGCZqUPJwBDFO00olNWQGHBvgug7dbF4H4bMXtVWoPmuQClwF6HvGMqewziPUKsQoRdN1N0UyOyZVxCtGSi5wp7K9f4zDZjw3yIuonQeRIHPFuHqG4dH4BEydC5FtDS2wYSy16ADRLMXUhjR90QPogTrb+9wP1BZqKUdn2ImXBuun72Vx2oE2sjJHunh3cS1vZRiWrz/TOTdY7nPN1HdZSmlICF9DZbbiossxWYvmrSZ/keKWR9iKs+uXO03WmevFTtV2uyh1i1ByI1ZJ6B4/65z8T9Gp+ZMlvyezQ7Q3AF7ucZHyuW3lCF4Kg8iizH+RPd2Zrl8KXRfJbiP8V6HH0hZF+I/7uk85vq/hhzYG4MWIgVv6DwWNr2CfN5D/ccf8DqxPuJu85T2kPJlI4+FqHPwR0Mo1gv0ArQgS0eukacJtv4UIWSCVecLPEsw+Y1rwnLf83/hunlzeC8BxjeEEI7zLMt+ig/mNXn/yrn/ES4OBxDw/y9xjuD6CBKAgKhWgWMwYiRD7J1h7RIpwEwPvIWGoDaAY6KHZSnGRyjFLPQAzM06Qc43oqe7heaQcxB6d8FVPLTJQsoy3NX1nkuYPtC6TZBg5yIF7xrpJOG3N+Le1jVYOeuelCIh87ClTrsfKM1VYoCkvaOuUFFOLuv/Y8XubRUdJZTKGjha4dFP5cJvqehoYhOCrFMP9fufy2N4T+SrVePdF09xHkI4FCh8JHD6UKHUmWL4e1ZSHEI4kqdzV8/0lpQtiRy8o/+Wi3z9Fvdwx9qaUf3HvoVHkJ89KN3XKuIaIvQ8RUw9gLW2jFUX9fvnIBG3UNX3DN5DjiYyxvtZTWVtgRi+grecwfDmjo8LqMSNAILgPO+37wacK93SkDAENaHY35n+FzVuyf62tSvluEu3dqnPM5zH1kzt5SM6x8Kds6l/c5FIbazN9O9U/w70e0UI4bEIs0LrWjqnEVvb+rcZQrCBjkZi9fT/X8uCbWNE2CMrBbb5bkpXGat+Q/u1LSHqqlvufdXwNyWgS8tPSyCfy5L9JcuyTxTbd8X4T5Uj35Wgm4X8ykaIqYruiSbRlCGEG1mW3bXhHAor7sQYl1mW/dCNC+thnHhDIFGEEJZZlv1CXMRc91zqGppq/f0qXM7w/4WeUaF7tknNmwofvtaUpv0Y4+e6zl1dm4Vku/IyXgo0v1V+v6sQ7ht0ve3ovCORpH9WNmEoI/Ac3ad7ANiZuIc7IPUsHn+ssGkPg24euqEzAUVim+CqMvSpZK4H30qE2cV3CkNGdv44XL40JyCrxZA6d0pc4bwVem5ygMQSnkBkfU8eY/wxXw1e425EdAVmrhR4AjQKCA3Kmt6ChXNr7ILLcPXlI0bONSyOEVucUPuf4/wruWw26XcD17DEtQyQW/+TFHYDIc0SKZY+XlD6Fd9IjBedHGlM1X2BSSel9Dt78DYqSkM590MIZ1mWfSig2Ugp/VYP+0j5+Y2U0kphzLHWDtTj/mdxAa+zLPvMYnYp8wvF39sqbPpGa59kWfa5rnkzpfRK1roXY9zKsuwH+q2QUnqcZdmdEELIsuyjlNJre5lmjLGZZdlnEs4cLbpVlmU/UqvroVm+LMs+l5HYtboEFSL90ARRgDXPsuwDgeaeVfmllI4FhBbWPRS43MOwjyeSnccCwi09l0fyRHbQOHUg+f5Ca62x6EAEpb1TclfXnYcQ3lb5CWQX4mDGmPgcxGPYvMiuPgu6Z3th7qaMUwyXr5lv6aNcmR2b/9/Bec+1LjdDKB5pagYMxnCmVGqF85phznSPQf8mewVbjLHINVoqQPiptJWrJaYy++rB0nEGHiTogjBdSAAZI3YxbqCOxQzIbdpUIsvPrlRSO0RKz/oQnqO81wDlDPnfBlI/T+TKW/lmUN7Z0i82oaeoqupf5GIObR67JugslS//UILVqqrqvxlhqe9sau0FKuD6IYR2VVX/ZPsjT2JTvfOvQwivsyz7ib2ZuKqq/9Py0SoOGqaULlJK+1K4D2OMrSzL3k8p/Vbx+ijLsk/4ZiXF5Te/w4Lsp6oqnKHuvqFpvBfiDZohhJhl2c8EGladuJllWQejw5+qsGeZZdmPxEFsV1X1W+1lkgfQQq2BTRTKY4zDqqr+RcBg5b1DXdsLne99kZTDlNIXVlOvfbZMz0FVVc8VkvR17/sqvbY+/i0YIqu6a2NmYI4ZkDvQCQtbm3hvpg2V3YXBsaKcIIB+W2CHF+423fgum61QwEMZYfZ/wFxH6q19biBR6jxvJwJ9WqP4I2eRE5hx3wMwRtFNrGkJJkhcOAWPINM6zuuY0MLjN6euEKkBj+EwXL5WLCG2r9DIc66S0YeyJl2XZz0Hn2BcxlPl5vvI61aK67YQlzeqqvpXvMDyptj3UhZoW4LbVF78jzZHXu7uSoDyWwzI3FNI8EdjtVXll0IIuRQoZFm2Kws3VPPQaUrpTZZl/yALvJlS+oOBWJZlP5YiP0spHaeUXsqiz7Mse5BS+hqDOj7IsmwvxniYUpqllJ5mWfZBSmmaZdlnKaVvNMN/EmN8kGXZpu67kpt/Q2HFZ4rhbTzbTSlchbAil6X9RIA4FHm3rWfb09pXlg4WaEZ5Yf+q599G/cChDIOFZD1lTP6IAi5rAbZ39tnLV4yhPw+Xo7mt6jQh7UvW/wJ9/H2ARGnVg9CZFQrK2nhpB2sNMse7jeEZBxQ4tZwnHuHRF85Y5xYC/CRcnQpcoLooQQmiO8kE1XxMH0Y0JiQHKC1cQIlwoIu1p4iDSDguw9VpwwHsfAXG3soscxRHRBQX2UShDfQhJDDMTVzvSwGBIfcpQqG2YsYzMcxf4aUdXZW+jhU7F7JOFyGEUFXV7zE484ZafM+RL/8UgPIvEq6ViLMqpTRFb8En9hp1eRdNKdCvbCiFQoV5lmUfyRJtV1X1G5uQlGXZf0Lt/hN5LdsxxttZlt1TCHKeUjrKsuzv5YYaAXgqV/e+uIdvpeDPZOmtLv8FQHZT592PMeZVVX0l6x9sSAksaldey7nGxH9plZFyvW1K02vt3T1kJb5Rj8G5uf7hcm5iE0Nf3r6+XinXjiyw9dlHV7eyYEcd3mM5gbG0lLT1C7wRwPQgo5mTXXsDsbU9N1xIXTrPO4Wrk4WrmpR9w+lyAYBYWQjAuDy44SCF+3FWFxFRMljpyqFPXW9BgQq9TJapi+Kb0vUWEHxO0J0VXClk5fKhT1F9ZQq+wHCSPkDiADnaJv7/Qucfgjl+or9fobx3KUWxF03G8N1M/1cSSKv+s4KkU1kle431fSPvqqr6kwBlQ5ZvZt12spg/tJSUvI5dhRUf6tVmr6SoZYzxp/ZadSn+QCnDf9C9PVVIsMyy7Cey5DsppT/ovy+zLPt35hLrLTkjxeoNvQfxX8U9jLMs+7mKiqY2HyCE8AEyDX+UMh4p5Whu8Asp/R7e+/dUax8p89BU2HOSUrJX0dlr1g7lLX0pzqBtYExeSCBjA2i/FZDksqoV8vClZCC6Gv0VZDiH4rfx2TmyUGbZLawoXcHODANHaNnnyBpkrjV/7qpwl64JyGflcteunFkI8LkrBV66mH9Vk87zDUEZThzD1QGjqUbx6S0sw+X7ygI67ZjLnMO1aqE4YoX43jiDJfqpOyjfXCGeW6DoiG2VbQCHsaxzV6jxFC6c1RScIe97z+J91OjPxHIPtHaptXcFEpazt5ec3OCseRXr2Biy+zaFR+BxS6FMUy3F9k76eYzxx7LSM8tr24s6Bc5fm7BLwV/JG7EhIlEGYiqlSlr7a5FthT7vSol/pDTko3A5r/DnytZ0BVRDgdjHuvcjFR6dyZtpxRibVVX9QXswg2d1IY9movvOZOG/1nn3sXeliNozzODbgBI/EdBsh6tz9TpQUHPBbbJOB/F+hAy2YcmPsI68F9N90TH5CQbU1q4g//TOWUWbEI42XTqfxjp3pfomy9EGQ+QuDx9gWTPX5htdRiDARclxjtKVBDeAgDwna5Ynruxxik3JXG/BBQqGLC7K4eb0gPpv9PBb4a9nFeZI5yQ0WTDjEVFXsIGNfogehm3Ej1+hRr+pa/wmXM6Ne2AgpLU2Wt1Ck+f6bRvqkavH/Wu4pjbs1N6y8yKE8L4Y4Y/EkM/l2t/AK6vPUkpfZVl2zzoBxZ5zko+VMC9SSn/IsuyWvIn/oLX7WmsKtBdjnEjBt8U5/EKAe4YJznfFpZTyLqzE+BN7/bnCIxvsYi/xfBQuR2bbG5Sa4ko2ZTE3BQKvED480N7ZG5vsGXWUWrQiMWv6ydBu23XDa1YOJIIjmOcunF2B5F657tZxuPr2HvbXlI7zmoerA3pZqr+CZ5tgkIPTZbsW1vjMQghvswAJzGGAgodw9eWgZbg6QZhrs5q1mbvgpSMMF1BIbsgCE4WiA5IlYqYANrWJ0uMZ8q1d1FyfYCMaKNwx978H8nPq9mWAe36mIg8rArLioAu5pO/bfaid93a4HDxqcwIPZO3es/BKwm/DSe8rdrXZ9jleUtERgdXTPX0qq9iQV1BJ2Btyjb+RlX2tCb1HipWfBbxgIsZ4Xx7DSETfp2KaP9Hal/Ia91QK/BJ5+A+lzD8TMB6Gy/HeH9uMiKqq/hnx/g80EuxE+9FTKXAMIZTiP2xe330pToW3R9lshUoVgVt69lZIZc1RG3hpR8capsLl6PaWYu9vMTEohqvv5VtIPhooBWapesP1mHShQ8fh8s0/EYaMSluFqzM4ZzW828IZ6+iMX8PpbHQkekIpcMNCgB+4kt4Ai1zVuDK+QjC6foEM36kcSBSO4c+gvBXiFSLe2HETBRB2AeaVrjzJRauVXkqJLTPxAo08DcR69tLRLjbKhige6fMNNCRNkLPe0ZqWmOu7KjppQdkGignvGRhUVfUbxe67Ov8xGPi2BP3IiD6d1yoFRyjsaQl8xuIefmNvzsUg0InmEi5RCnxfFnKRUhophj+TZT1S1eD7IvQ+U4rtRKTgT3Sdu7K+L8XudxRePlTK8BtlOjZUl/9YLntH+/GZfutclv0jlPceCHySwMr6AmJVVf/F6ii0t7Nw+faiLgC2mVL6R4QTNrdvLIKuayXMaILahm6Y0tqYuR4s7WG4HNzJyj0LHXpoBDLvYu6yZFMXThc1vBu9c8b4zZpq3txl25YAtbdeALsBQ038H4FUlasFWDk+ICLe92XCyREYhSMbmbYILlTwswnJnBqgnIXLMUwBsVKGuMs8jxd6WF1kFZa4pxY29MgROz24Xq9UbtqRwtvkmwO5rlZ9dibG/mP97qaY8j7m1L2v8x5I8N6XQN4WcNgbjz8QoCQrGxZB2MZM/7yqqj8j9z1QSu6RAD+LMf7Upt9KMbvhu8GVH4IUtFd3/VLFNDZ2zKoTP7XpN3q12IEyShP1C/zeypsV79/SPr9RSPAD/e7dEMJX8pbeSJnv69yvtHd35MXdFshbo9B97XNL+/4Evfd71kCWUvpv2ue7IPgOreNT+2Ty942e3wYIuAvI/wBy+toAPVx9MS6H5djaIwzuCKg5Wbl5FwEcmDeqqxo9WcFjyB0RH1xtjm/jfxsCzFzcQQX3hUBLh0YRil2Gq/MAF65ykK8gWzgvINW0JUfEKw1343xhCXsLRqjdD/iNI51jULOW92gxYNP1IfjXK5sg/FlWycKHHXOV5Qq/Z9NjlaM2BN6UxTkQ2fe1LORmuBxM2dLDuoMpuCO53J9J8W+LR7BR2e/LuzgNISyqqvqdPIYYY/xE351J2fakXFWMMYh4G6ii79ci+OzVWNY7by+f+MLIM5GCL0XIfaHf2tL/dkMIj1Un8FJE4SJ8N7b7X7Qfefhuxp+9Im0kIPxU3MiGKgXNJbfy3pkyKV/LmxkKYB/J4ttI8QcmRxjMOQiXMycz9SPsiMthtqldUwr8Gp2gAQN0Csd3WdnwtmvYmcIy+4G8bRfHl9CPvKZfgPpSuXkc0YXaf0XO5xhCGRw6+EGgq5qKQP9Z5sKBvMbSV474WNZ0HK5cF1Rew1MkFw8dwdInl9WIYHdzdG+1XBu0H5sckU1ouyrHY51rD9zD7/X3Quc37uFrdORZCPHncPlGog/tFeayhiNYve0QwpcqXPlSCrSj3PXXMcZz/X1b3/n2u8xg9acY49+JRNuTt/AKqcIPtA+rqqq+0N9BIeEjWciF6hU+sRbrqqp+l2WZvZfvFyIbbaBHF/H+pkKbTBWAn4uUtAIceydAgXucKwvyESb/fKXruAkPyjoDv9He2VDXr1Ffv4V3MUaFZPcFYjbr3zJO/XA5Wt44nk08cyuFt5n8nL2/j87CCCU8QfMXXwHO2pSEmoCmq52ZOxI61lTspnB18k+4JizP4YVX9BwMAEjeNWvmAESn+FMHEgk3njmXfu68i+i+4y194YopUrj68hE/kpxMbYWQhWg5dwNHhuHqaKQM92ggYSPJOw6oEoaFGAv7heLaTXgcY9Qb3LOiKcWht3SOnXA5stvezGOhQlsWsmM97lYQpPj5SMq6pXDin1SC/FL9HVu670eK4T+wl26klP5rjHFWVdVLzQO0zMtLnXtH1vtzeS3zqqqeQDG3tZdPzIUWufhIJbv/KmUr5AEdqz7iXF7Lp7qnnq5lL6W0EjBZJ51NGL6PPv7fqhXb5j120Y47U4hgo+K+1XU+V52GvZH5Zbh8/VcfHXztcDkReQjjsYSL3oYCvdb3ObJ+gVifAzqfhss3WKWazj7qHL2A9I40uhnrFvStcrpM/Sxdy//bNODHNQTD3LkmyeXjC1fYwy4lliAW1wwWyRyZMUI6I7o6geBAZeaUm23GU9QEJKQVEzIHJRj7jjtvA98hoJw7VneMFmDrILPGo+cCAnu77lgu/W/lim8g0/BN+G6Y5yl68Bsppf8isqqv87ekyDbXwKo3Wyml/02Vhl2lAYcoqHkRQviVrrWXUvrfVeiyjDH+e33nsbiHVwKDKsb4nvoQRuIB/p3WnoYQTqqqepxl2cdqOPmsqqr/qmGlrxSa2Bt2V+JG7hohJ0tsE4A/1j021CH4DO26HxlpKnB7EC5f8W7WdKn7vG/lvCmlf9bvZajTsCayA3EONpvioRRzjjy/GYEJKlJzyLPJRw/WdwTLnsGTZC1Kgix1oHMr52nyhbsc7f2uUXwl2P7g9MvX6iTO9GAaMNak7pIDALoSF+Hq6KKVY/wb+N6FS/9Vzs1p1xAgmas58DXNEQhYIlRg5qABkDD3y0CiBdDgdxu4rhm4gIS+B+MWtsLlNJa/iBS0ysI3SCN1FMOf6vtfqhbA8tc2Fv2NGPGPDNSkMDd0nT8wq6RYtq+1G7r+3+laRwKJUuf4rbUOyyL3Qgi/kYK+iTH+LyL3rHbf3r77E5XH/rO8gNcxxv+oyrphVVVfCCB68g5uCNRKKf5P8FLUL9CVdlsEp70e+yspfFNeESf2bEj5rXT2sSz9ShkCy8M/DN+NELsJpbABLDa3r9T+PNXfW5BRI4CnLv08g+x77muC1t8A4rqqkespvAiW2JfwYEO4OtaucKF26TivClkzZsd8/U2AMSMYVBYCrMJfj/rybGNylrnliheyGqX1rxFnpxKJi+BCkORi/uh6n8euDyFhM7hBbDRquIKmGe7DNysFV0E1R8bAzmEDRs8hTGW4fFnGNsqJX+r/P1E4sAHXcIGhI3vh8sWnX8ui2zSaY5Q7F1L8cynxbwQwMXw3LedcLvqpVejZ3lVV9X9YajCE8GtNCDoQEDTknndjjBtKsXUFUP+z/rXy5SgLvhtjHOi8VhPx96oatHkJmaz0lu7l93omrwRqVvf+pf61F6xswSt4EkL4AO75I2RyGuHyjcyFwPgBFM7cdVPQ3XA5aPYAzy5H1yknXCXIaNNxXxnCBMrYEmXCNEYTl55jut1zapXzlDNX+s6KwKXzwLOa8IEVgZEAEJ0y19UEQKkC5QAAIABJREFU1J04uJvxa4saVGO5Y1ET21Q1ww/8VKKmO28Or6N0DH/X9RZkUPwq/PUI9IjzBlfFxT6EJvLD53qwKwmiZQ9+E76bYrOQJepqnb1a7B7cyT9qzaG+Y3nl/XD1TUR7UqqewOYBwoo3IqpsKu4nAplSxNt7mMJzoPM0lQX4me5trIKkPVnrnwpIvrXnKvLvQjUM/6zqwWUI4Zda+1wAs9L3cxFx/1kWei6uo9Be7Gvtx+gd+Sftw4X+tQk69nLXe2gw+1qAa8M9dyydGS6HetorsV+Hy7mRQ+zzETiFyrHmc5cJ4MxM5uzJuHN0Xo4wpOXKg1nc5lPvZPJXjsRr1GTlokuX++ahufNishzvoPNu/soxigwRShdnlDVrK/dv7mL46PKhvmmBBUNVjcfgiyPm4eorzts1sZQB0BzVXbnzZiYudIioImw7t+4Uoc4Q638vK3MLv/ksXE6BuYNqxH8UaNgoMhsnPtX1PTA+Qa64CbNZ04mE1whEm0b8p3D5kpP3BBKWwnopazoLIfxMlnckL+Ajxfs3tPaPUrZZCOHXUqqTqqoei7TbDJcDTH+vew4676FSb7/DO/zsTcjfgEj9zCyVSNL7yKK0ZNGNu3kAg/Gfw3cTkNuo+DxC1+YDKO5v9ds2aHOg67BxXyzxPgHXwOE1U2dJmYevrmmIy5GWq8JfT/fxMbsfvLtw4BBdZqKupia4LNzSpcTfhiDWDEQlTq76r640OLqUR1aDVMldcOXyntw87zHMXeVghrUrh3h1pKBH4+Ka3oJGTZll0zVFLVHUEZDi6aKSa+yKjO7iHF+Gy5HTQ7ihX0npPwQw/KssfNQ5zBL8QcUp98H6fhEu58Z9JADoStBt7PUQnoKRYD/V2l3VBJjLayDxQl7EwxDCL2Qpf6z8/hvtwQPF+3NZ3d9LiechhM+l3GdSrvso7BmHEP5F99wREL7SnvxF3MD9cPlevd/pPhpaazXttk8PID9foDrvBuT3H/XdmwgPX0FGN2EAvwXpGkB8r1wImOAxsEmObeu5y241nW6xzZf6svzvrX1pkxRXluV194jIPRMyWcUmQAhJpS5Nd5u1lY11z7f5OH94umxa3VUqNZJKKwghAaLETookM8k1Fvf5oHN5J07c55E9NjLDBBEe7s/d393OPfde8j4KyQaU4qWb7NUo0zYScH0sK1chltT8fiNCG1l2C/KTSvqpBURs8xgYe4haiVnw8GpBPhkUVIVSU+jA01jUhToUBcgaWxleryhm9Hy2x3jfYeM5T+AXS/0HlonGW5rZXyDEp3DudRz7nJSEj0P/dxzrjS9/tTQefI2UwaqZfYzr1/jce+PfR+HRJdzvebjcHQjuH3DsgrcJB7loEZ7Dl5ZGjv0Trvc2vI59WNNFeCRP8P1NKIlZrOlHAqZO4B438Ky/ADbgodBDHLeB5/E2eYE3oAiOEd/+kIg9b5Nx+Iqe8QxZ9p+x5tUAYC4lm7VBnpof+yuxRFkGnhNNXIHDxuLOWaUwXysReGbWRlm1vhjV1jZ9jgGoJmHhbkToSwEDGznxSLSVBbEOgxyN3JwFoYMCkeqJMNDSCO1xbBKKpXFjPbmfRkslJUNgkvHoEwGki7jXm0wuYfM6nfgFQLA5uO5eh/A9Pr9EAr9uqeHkSUvtwf8TMf0FS3MMfN6hC9ATCivewefetOShpZ4GHzgS3jTNZ0gdzuEc29jQm0jP/SPW/xaEzZ/9f8NzHwGg20PmoYZC+cLSKKxrWEcHVvYVrlXhvD/gvHdx7Fnc40M8v5NY9xox7j7Hc7tAvI1NouueIW/rBjyqM8RC3aGM0HHaV8+l6Mf3tO/duYApOG/jLfXdaC1Ifn9GBLCxuL2egvI66qsI6PGaoh8JZhByc6qyLK+jMKSkbruGfLBJF943jQbps4KObagjsPepr+hYb0rY4JpdOtYbGo6K9J9fcyRr0DV2ZX0V/bvBuXaRL5+hzsPetbiRY705ZEfOw2vx+3oOcos3cJxHsU2JYpeTqEariqJwl3aA1NkZrGsHFusq3PC5oijuYCM/gkBcwGZ5Bet5BQKxBm9jEYL0LgRjgBj+NgRyAd/dwqb50X4bW34a19kkdL4Hy/4TMge3kTk4AWEc4jvffP+Eda5CUflQ1gvE0nSc4gNcY8nMPoFgDyGgJyC0L6DgLhOx5ybu9QWu8xaBvb9AuB1ofUpkoFO4/4LO7cU8PEruIXkuJmm9SoyUG5E5EdrGJtvrPafCIz62Ds67I5mmgjJnWoV7IEqjssnGIGbxaHC/5qgqy/J6QALqBC56RAWuZbGFaJ9OACAqQNEP6MS18J2LltChCVw2C67HacQ9G5/qUkvutAItlnkJjGV0KMuwQC/Ay499hPQseQcdS51uZikX/Qgsv1Uone98xj2UyWpRFL/gd7fAj19Gtd3XUFYzUCZvodttXRTF5+gduILjv8Xn2+gQdKEoimf4/RdFUXxEA0P9vOtFUVxD9949KEBH/Q3EoR9xfW9VfhFKeB7X9G65V4ui2IHi+xz3dQbfzxZF8QDrcyrwPO75S/x9Cf9fKIpiEwrVuf7LOPY+nktD3XuHuP49KONF3OcOzrGF3yyRst/AZx0xcN4qf4aOZSNXkKHYoVbzJr8vYSD82NdI9/aw5wxZFU6t+37sCxXYMh66YgORZ1xWaOtU2GQLMI3fIxdCAb7I3RgFFYZ8/k4L4tmVcKMM0pNDQfK5OUkhaZt94VyrAuMMB/coaKQ4qpB88FPhjnvfg9eE2BsVCHkT0QUKXXwMNQN93+HYbVi4ZWIQ7iOu93DhJpTPz7D0yzjvHSjHUwDCzuBYg8fwB1rHbVjIFbjil8hjuA23vweLegcKr8A536O02+ew3j3czzPiTpxCXL6L636OYzpYnyvcB/j+HCnre/j9AVnwHkKqgrgX3pBzydL4cq+12CZ8qEvp4MomW80N6X12pPhmW1z6RjArre7rkhfQQKDHJmZBwHe96Qt5uQWIWl3ybhuZu8EerHrpDXnG7FkXVVmWV8Ut0Nbe3BW4H1CB9fhGmHu5ar/Iu4ji/Zzgl3Jd7UrEL64R1F9bI5kALqWwsEyyF47qvrI0zNTpxc4zd+qxU45vwW1dJhfugNKSXkQ0C1f8HMWXA3w3gPt5jXCN/4Dg9Ild+BIC8NLMPsSxSwAFZ7B5PyLA8TmE8yMI/1kz+yMxGv+HpXFWj4E1XMVx58zsz3gO95A58ClMz7EGB+jOU/bjMygqd/HXLY2MW4BScTzlc1zPJ+k6DuAU8DVLDWTu4Dlzm6wOPb9F8kC3qUisJL5HI3n4KpABzghws01ORW8K3lQH9F71vJXl16V0OZPb5iXej/Z/Qwq1E5GLKrRqrjOWfWSTcwA1/6kpvahp6GEQDlRB0UIUgtQZT4LjoFpekj94TcVUNt5yiUGYQphZBb2sktbGHIF5YufxCLIGwnCCgCYvYvG5f+eI9PKUwoEVCMo+HevU11VLLctukVV3BPohrv8K6T4Pr74g3oCDbz9gnc/N7J/JO/qUcIC/x9+/tzQ++19wrWWK4Udm9jus/S6OfQSFsoA13bDUhussBPxXXPchPAafr3gT3/8NivEcjtuHAjxDXP9nuO4T3KMr0j0iYA3wnH2WxJawQ7mWfpjJ2Zuk/BSUY+arfz4rYB8D1aMMZZcLdzriqfr/50mYtTfGUDzYGQHnx2TWMQALmHsaT+S6kyhvoAyEtpuhNnaCsKIr57Ug1RE9NPYu5oI0YiWex4F8zp8pTjG0yR6Bu5RGnCVX8jE2/THKO7+wNOlo1dLo8psEmDkF9iW+e4aN75r+vqVOMrP4bo/otlfpHL8SSr0M4fKN/i0Rdz7C9V5b6p583tKQzE/w2YaZ/XdLk41/wFrexrEu4MfJuyiIFLUMq+wg3V3cwwsKV5w56c+DyUiedz9LIN1dHOvh33ES+i381sPCp1ASXjPi053cys6LN1oFe8CC/W1S29LJZLNKMnSH4l1rD44qyLRpyp2VRNUSPhdSKKQkpYErgMImJwOra9zIgpsgl6lNQ8uWsEK9C1UShYQgUbFSLSFFEXgzldQLNDY+t6AICoIswBOMKrF6UhwytNQ09Bgd70JVUO54QOm7c+R2fkNewhp+1wdaP0cbegWf+aSji2Sxf8I9eghyHpvf4Bpfs9Sb0PPzPiD1PSiMA+TLr+Lvfw8hfEYhyu+onuITeBX7OMdrKAEnylyj93WDUp6nyTL+BKG/TDn6b7BOxy8W8ezuWOqT0CG8wLsGe6/GEbywY8TS9PZuHhJw/4gt8hpZGUT0+EMR9jLI0bM8VWSB28JOTu2pvCgdnsFuDVFHYrQ7Nl7N+4aFyyCgZZD8MkDymykkIKZG5qiNUaGRHjvIaONIoQwzCoU7pJQC9NUBI9AkHNDnodOL/Jglela3YRmXaN1bBAat0TU+h6CuElC0ZWlo5QXyjD6mvLcz/baJZvw2gY5/xebfgqLx9TkB5wKe2RV8tgOL/AHxFR5AyXg67wO45esAG9+HsJ1BePAA6yoh+Nt43zcIsFykdJxTti8ToepjrMkZeU7a8rZvb1G87UpzjjIye1C8C1Ac/k7ukXLmvn0blNLT+ZgW0M074iUOMlRdtuaN7Lcm4LiwsasCQ2nCMBwFdPVIXgqhAnOoXXEIoG60EmQi5l5tkz3+RpKvVAGqghSetdCG1ZXKKZ9opLk+6EMb75xaBu6XrncQACtcglmRi+Wb6RSdw/POM1R44kzB0xBO3xyPaDMfp3v+Ahv/Iq3/HinbK/T3f4ervELu9ANL03beh7CfRLzvWZHLWOcWhPkVUP8+hPcrEo4PoXx8TPozM7uOtZ8jYs9TKI+zhNY/gcKYgYX/Fd99TfforvIzQuW9GUqPBP8U7Yl1AstO0Lv8mjgCvld36B3O22Tfvq7s3QOLm3H0RAAtoOXyvmuCY6uAJVtlMK9CvAyL0tc22XSnCgxw5SDglcDS1xnXp84syCQFGAm4xvCd4DwR4aGfObaxuMFoJ9CqB5K9YPeoscnuqRqjKaZR2WSxkrLEvFPsIqWYnGo7D6Hwc34BQfGuxbtY109CZGmAnp/Hhj5uqQT2G5zzHbqvTyEMHSiJLXzuRTsXKHX2GWVv/gGYw1l4KD2Kv9cQf3tV4z9AuZzFOTxzcRLHruN+HiFEcBzgOzyvXSirS3hPuzi/ey1e5Thnqf3WWXpvD8izmCFh/QnXP0Pv/BnVcLDwOllnPkjdqeV0Rh97ggeSMfA9qqlCZdtWwXkLEewykLWh/LaScKAIZCBSEkPPAqjro23AGG1UIK4fWM6cRVfLXgcLbqakBovggeQ0oLVwDcpAoWgsxai/or8jemEVZSTcMszT5ji01ChknlBoxwjcC9ig83jc770P/gQrfY54A7vYZKcgzK/x3R8hbBdwXUfbn8PKvkshxv+BNZ2FFX+MZ+QZid/T+j8hsPP35Frewe+v4TmegOVdwb1eoXTYt7hXBziPIYTxpipvWyrc+RuBvXPwOjxb8TMUoIOte2RtZyH8brBYSXARmzPvFgM2Xlfiem3GoSGBsvQ6cqziTEWGI8BFbEUQVpQBlsYDcaLW/mrI3pzHQ4BhEAvXAnKUGWGrhF1UtcTwyucvA4seued1gIIWmYxEVDhRiOuj17MpYGOT0aqek5618QGqfg4HzfzFbxAC3aMN2cd3a5Se8iYWD2GlmfP+DELmffOdNPMtBOgS1uH1Aj7g9AL+XcBaf2ip1t5j+B4UyocQsnI0Gn1WluVlCNFFeDNPLbW3+jts8DnwEs5CuN0V37HURPVtS12WbhAWsYo1elx+SIrJ+xV6RmKBXPpd/PHjfGT8LPH6j5FQDOjd9khJaM6e+SLqikckoDrIplmQ3fL9HM3jZIDZAgNXtmAPyqytAiqwhvd9VwBlIDA5em+VKVoogsVVQVxeZzIHFrj/wynHMrVxKFhAHaRhNCd71OxFNAlpIAxEnnzEIU/H0nyBGTp/nzwGxwi8W22PNtgi8bvvW+oo5LGwW1mPib3I5Ra8gEVYzlv4zSNY6nM4dtdSpd4yBPRbS511/tFHg+HP97jWEsKNH/B3J/a8ZWk60y8kbBfw2RxCk/NQEF2KvytSBmap2cdJEgymdO9YKshiDKZPSsb/c6+rI4Qet9azInClgHicLWJGH2NQbEReB0oid94DYQ+yQikzhCE1crWEpxYQ91TGq6osy2tCYsgJRTEFKCxEGzWiDAqx/FHFU470Uwe8hDq4ZqQ0uGxySJuosbi6KgcK1nIPFbmSfXIb3bWcsfF+b54GekVsQGcBzuPzijIHnppawsbz2HWWqK9vxl2Rx/AAQuyI903cl6PiK3CtC7juH1rqfvwNva9LUBL3cexNgIIOsn1vqSbiMq75hHL/l3GtNSgdH8h5Al7EgFJ1pyxNZ/IGrM/Jw/ENvkkcCn/+XXhFczY+eJPJPz0idGnn6YiLUk1JVVtgwdV7nBE8oWeTlXq78nnEW1FvV7tsVdZS7Rd4HGOp9aosy3cyZJ1CYt4qEOYoO9BkEPgmUALqnreVP7Zd0wKlZJINKAUsyaX5NKyoA74Dr5uHM+6TV8DsMKedLhBrz5uKuLJcoOfwBIJT2vhU5H1L9fMuBLcsVQq6YulBgPoQZPcuvoY1fQEvwC31fWwaJ/YswD2fwVo+Ik/He++fwRrPIkNwHArlA0vTcu6QIK7ieB+r/rWlisYOvAUHVH12wgHu52dcb5YULAN0C4RTbeC3HVHOg4BoNgiyQkVgcMziOpgiQ1jLkdtqSWHPtHgMWodQBkqikzHWrCQOJKwY0b7sMhXYLD9RRNt6Rej8KAMKajeTtjRdE6Q46ozHoB2Mohi+yOAPZQsoWJLGVPxjT/LDPKK5sfGW5DsEmHGb8W38nluIeZy+TTn4ASye4TvnsfukY88QHCMswuPwLSgF7xL0Vwj3An7bh8vt/RE+pI3yCZTAIT73VOYO1vN7ClH+hDVsWird3cKf10Q8WqZU5ivKEDhzcg/exgx5MSuWmpycwPtftzQjwPeNz99zz8GrMzcIPPT04CF5Xdzn8TDI2bPX2JE9VmX2mZLpuhnSHBexcQs7Bpg7tMdGFtfi1DbZDlyVTy8gDLmRMKUCl5k8vC6Yb069gk6Qy2yL93MMRD2vuued4BwKlqiimoZpjCRFo0qiK8BKZZMjmrmhhANCe+SyLVKo4Ei794n3ibUOVh0nK/ETucM9WERm3TlZZ9FSqfFL/N+Btm0I3EUI/EWKve8iLj9FSuI2/u25fx+y+h0s/ymy4N6o1HsT+r1/CuH2+1yyVB24Z+N05y+J2NPFb/bw5wD370r1GYGoTO/1ZqTLZLC2xCvr2njfy24m1V0GxqkTUIP7QSZA91Qu1R1xAHQMn7UYyo7ISxSa1DZJMS6NagGKgGFnLQtmkKINbawyD6GYArwVGSQ/d15GX9tSjjn3rg5Az2IK8FnJb3YojvXf/0q55S4BWI8gCGzJnpK18uajTGf1kGCOYu3XlC83uOI+Ydhbbz3Ge/EGG+4y36J1eqWesxVvA0AcIoT4G+XoT8KbGODYby31NfQCn8ZS16OrtEHv4vcjSyOzKuAJxy01US0h4D6JZ4G8q3uU0iuJ2OP7YYGs3jP6N7fwdvxHC706AY/FLB7PFbWpi7AqLpIrMgDzyGKafCQDOhqcW4mxl36UeoE3IGCEwg8ylN0oQ6CMwCJIIyogooChuviRgLfRlHOWPgIbG4tHnEdlyG1EJ8YHegEBZJ42iFsn70Dr57lpqU+du3f7RE5Zo/V/QbGwj7j2DrtOpjFy+33qjRfiDAD0LcL6u5L43lLBjbfmXoKS8LHn3gfgF5zzPuL9Ls59B+/Aq//OwT0fwmO4aom/v2XjA2PeIk/qa7rHDinNdcrvGxF45ikedqv3iEhY/n7XCSRkfvwrGx/IySGBWmgXto4IeNmCKVVB2DkKzp9LgefYsi7k3WAtJqSkvngLb0LqqizL92TBo8D1GQZIfo7KWE9REt1AO2pfwIisk2MVRrxqyyifnJKI0p+5uge9RyZbaAlmI3nZHr38R/AATpEycQbgDHkHRvHzWbrmr9i8i/jO7/WPsMgnLNGK18mivotrzJnZvxEC723DtmCpa+T3DYJ7A8f1LXX1LS3NALiG8x+zVNzzGOc9J/G+sw+XiBtxB8roDBFnRvS8FknZeuOOBRsvlnEFy89uncDXQvCcjqQKefpUZAy7QTqunJKz5/MqUK01NCzEw4xCsUBh5JruNAE3Z4xkxA1BSgESzPK9zuvATR8FFjz3eRNYU8ucdxgQI6KH13ZsxEvINSgZBO59nfEY+gLSdFo2k444W6ZjXxIXgM/nfQLeouf2wNJo62OWRk1/Cg/gCj1XZ+M59djX8DHCgUuW6hNuUaz4d7DOK1AoZ2F5zxEouIXn7S3lnAR0moTQ+xdsUuZgCd//QLyFRfx9QKHGEj0/B/jWKWXJz7mSuJeJPQuyDwqJ+3UwDO+lOnDFXxGfwAKjFVWOdsVrjBqBviT2KHsTe0HeX/ddGWTwLGPQxgylZwEiYdU0YI7nH40zyllrFdpoBFlOkyoppzPlWM3ZWwseYcGxkcBbQK9UkJTztV7Uwi4gNzDxzTRPx/Ik5EW6lzuE+lfYMAYlcRJAn6PC/4l/nyHB8fkCF6EkfFLNn2Cl3W13oO9rnOO6JUr0DRLAK5Zaq38Ggb9maWil04N3bLzs+balQiVXHBv4/iWUhiPiz8Ryz9t44dW8jTf16JDQzdKz0wYxundnMnuJ9/tBi8eg+2bPJqf+DgO2KF9vPsDSTABKV1S67wqbLPoZCCYW9el4kwXoTxGgaUh+KWkzRc+1cKcO3PA276LJcAEioC/Xo2B0BJZfTkm08R0i7IKvzR2EvCON/2aWXiJnE3gw6TbFvr45nD04D0HyZqQ+i8BLiB/j2A5Z8Kf49ycA+rxs+RHWt43w4X2EGRWO9dbePovALfuapaGlXrNwwVId/pAAuVlL3Xy8NPm0paGds7TRmSpdkRfgAjNL7DxWuD2ykC4ws5IKi8bYawv4xibb3mu2SbkzEe13R1KOjRCSovoaJRcx6zRSPlGquhJ8rAoA94F2BdY8PC94mHHxixbhqOS4JiD25IC+JhN/W5AyNNqARQbTKAPaZJlRPmUmfxuhsRFbUdfQt/FxznXAQCyI9NOz8VZPJTHhmPr6AhbyNT5foc31kCz7PNDzZYQQFyHIB7C6D+Hme0ut7yy14n4fn3UIS1iCMjhPac9PLQ3zmIF3s0F5++OkAL+EklgjQ9GneHWO3sWGpYrKKIxkBctdpLUnBE/IYY9t3yYHzY5sska/zCgJ3jOdINTryXm5dbhOz1ZD1gQhSKQkzOLeFso01F4Fb7IAFmx0zuUr717LhKO8f5MBLLQLStmS7svRcMvg/J3ghWgIotdsK1bSIpCINszPg1NKmm7hCa61ZAycMBR1Ifac/yGdvwuh7dn4QFNn3Pm0W+92c4+4BwvkljdI712jWPkrsrIuoE8tzQF4B+c6hmOXLPU3PA8BP4SSuQDB93Fji1AexwlL2IMSW7NUNOVj3F8SeOdg6lDy+UMinzEzjrvvjDLWUEPJqNxbDUM3gytFNPaINlzZ+NDOCDRWTr/WC1TBsVEvS/YYRpLif+OVcy1AkUl3lZYvrNEYuWyxkDkBikhAOUUQ4RRtvQSUcVgKizAHCmpLtFxKkPOsjQBBhaRDhzbeFJJBQt8wA1Igc3TeHbKKzuv3eH8TQnWAF+6puHUcu0aWyQdobFpqTT4H4Z6FV+A1B3ctNdt8l9hqNylNeAJC/hjf/QRw8bilcd8uwIsEWjoJ6hR5LU8p7z9L4KS3WztGz+5QhLtL73Vg43X1apxyAsRGIKKm1xb3j8jNwuSwohTLy1a8kfR4KYbyIAgr1BNRhRIVvlWyZ/cNVOD3MmkwC/KKZQtHIHfsMBDYWqiNbfhCrhfaUKxw2ZLfZw1vFnf+iWoLzCb7r0XMrGEA7uwR4McNRTctNaQoxAVUJeE01zmyVlvkBbilb4gZ5xtslWLpu5ZaaXmZ7KylLsWXSCl+DSF2kpGz8Lyf/lVSBt7ObMfSQM4SimaIa3oM/jOE2EefHcd5HuM3y+TV+DPaw2+XiKfAz46nRe8Lkr8rgsPtvvvihfXFc2WsaiSA81CsfhWEGSN5542kujuBUe1lwvCuTXan6kl+nydtRziFH8tyFVKBlfBQZph7nSl5/zp4QIW4xrkH0UZqYCt9lJSeZTISUbyfCwks0OSFxUVTFmjsipD9mvLnnPrpkIs5sjSSap6O9ZSgexhLBAiapanCXvK7AiF2rsEhrud1Aj5G/AnW9CME3i3tHuL403guly315fsGbMBVS5N8N8lLOUd8hi+hCBZIAbn7PyCSUUlKoqRjvbd9Y6mvYUN7tBEkf5/+XYpnxvMhmoziHmYAs4idp30vywAfa1pYhDlmIFc05qjAtfAVdP4mtwlvbLzC8E3GyhWACtC0QYW5z3M856i7T1szxdLaS3+LKSwpa8ER2pRElQlBui3sRP1crQVnSkpBhuclzVSSEPtadGadI+J+Pa4t8LZgiwS+bUBw++TidyGYq3gP3g58Axb6pSV67wJSd+59rELAvVjpBWUdlkmpPaBjHf/YoPBljphs9y01LSnIO/T3xlVy3IyDM1AjsoKlpM3UA+1bvna+DPZNYzEd3AJAWw2NgtGdAOTWfpfa+acRWWgblKMKiu9pVzgJldYCtJF1GExQbbcnCLzeYJkBRMzay3kHAVMqp3z2Je/aVnzRtKTtihaOgGXYVrruqGGkl2Zqfphz1Jya8jbVK3S9JyTwju4OLNGJz9Im+B6/9aKaBTx7b8Zxlth43sRzC/G+u9J/oRTkMXgZj3DNB+AIeAx/E9dw6+sknxppw1XyaDzF6RvyOO2rFxTKMMD1CudybCd7AAAL3UlEQVSdkXfOvfhK+rwjxw7o2TJGo114OFTUkHhXUnoFyUTkCXYzBLsotV5mPNWRxQVIkaEcZnCKQ5ssZqsdBLw+BXhTbnx5RAupVjaiTtZTlE81xZXnB93JHFscwXpbyxqa4NjG2huZ9CQ1aPSctAfCrJxnJJ+z+79k441OvcfAaVqPd8xds/FKsR8hrO+Qkvg3eAVLdPwhKY/rluoObhCI53n+Gp7EvKXagjlkFxbhTZwkQpMXR1WkKHxfbAtzT9lus/TuOXXHQqojsk1SbEUA9EVknTID5vVk31XB8bkWYDmAuQwMZARcK4mutPHmvZqSLm1yaI9iGMZU4KO40VH+v81jMJvsZGItnIJptQUWfN45wnqj2gLtHXhUpqC1cBj0RVYB8Bm1dDoI2GdscZbE2yoIHPR7/gYI/xl6Pi/wrJcgiH7svwLMO29pRPYveE6LBPSVZva/EQ4sWuLwvyBA7h1C3T+GcvDwxnGKV/j+mE32QNgn5p7z+U3y+5zuy02EUjbeDgGGfOwoMC4HFvP6o/Rf1Ai0sMmZAWapzkELfTaF0cehjYYrB4FS89BGsYfDYJ9ranAMc2AqcM7aKeBlUwS0yVhrLioqgxjZLN9v0DJAyTTmXq7hSK6dWY43kKtvKKcAkW3NT4rAOmmfumgaLbe2KimuPkUb3PvoLWMDvsZ5v4KAXiH39yYEc9VSn/7Kfhv4+TYE3GfL/0gMxLfI+3L23yXych6SUK3Q87qD6yzQ89in+16gZ86t1dj75Bp8Bpg7JOA92i/cLp7z8FG//wNR3EoC6mSwgE6Qs58TxVGR8vZ1v5bQxveXZo9YUc1kPNauZKF6krqvNYz3ECDXtCBKDeaqkpqW3HwkiJZJAUbuTGPxqLDI62haFFUbvdeCNGKZueeyxesopijLKmCxabOJjuZrycoOhPU1TxvcZxGcJKXhG3UBcf8ufvsZLP0J/OYRrrmB464QYegvltp3LSPl6JWAq1ASvmm/g2fhyqdPMfw8ra221N2IuRMlpS9n6Hn3JSVWZdxoFvChjRfoKHg3jd7LgFw38Bgq2VuDwForMUjb681kzsvZhVyD0QhEPwzSn0Mxsv4MtrUrcBtgNq0RqE2xnEVL+GAB6HKU2YNttOGjpgZtSuagCZDVKONRH+F5VBkvpq24illezDhk6qvHzz2ybE4PdjfYPYXHEOTTOPYFjl2xRNl9aKnN+GVLcwkfW5onuIrPvc7+BjyGs1jbS0pBudfg4Nq6pYYovmm5vp2n6nrL746854hJOhChLlpCBBXEMgMAVoHH0BXUvwk8FAUM6wDf0jqErnjGjH804hV1RPnkvJlOkN16c14FAadZtiYj0AMb729WthzbBKm9KARpawRatlj24f8DppFTEkdpX14Hz07ZYVHIkxvBru2gNHXaIcHXTVDB9ePmIi/x76Gl4iMvNnoGV9476vrI8V0IuKfsdiC0ns8/BqBwDUrhtKVpPV4D4L+ftdS19wWBme6mDmlDd8gF74u7eyheI6fWFFcZZTI2uVl7EQs0OrZLOXhNsQ0oK8O8BK094etE7cB5DezFqMcwkBRzlxTVXqBQTNbxBgN4d4qwtYF/UVybQzxH/x8Fs2ghXEyLy83ah4LUNr0LcXNEVLcIWGLFFNJRTeGAMi9LiW/7OK+Wks4QvjBH59izNFDUx2UvILZfhPX3uHEbx65batg5Z2mkubc/WyCM4RlASE9VejbAc/lLtJZNS/MNHI/okKvPA1YGFne2ZWIPp+Si+RBRyXgEBBcZdN6CFF6RCUEaScvpbMqBEJIifKyNwswzMBj/2BXgk5uGah3Cvpl1S4tHelngtlgmNWiZz9T1icYu10F+PwdATluDgoIRPtF2jxaAlk3mHpuAP2BBRsKCVOlQABt+Tvqy9wgR59SP99SfJffQh2N6vt8be/ZhlVcIkd4kwfKx3v7v72Hh3TINcI7HEPT3CMj6mVz7GVh973Z0AK+gstQstCFBdyzglXgni2Q1D8SaDiQkq2Sjc/y9J57ZjI133eWuzn163yaeVT8AhqN33lhcG2N0/h69+754hS60+2JgeqLEClKarPAaKGxWKCWFIbuyr+fdA7geuNVRMUTkvuaOzaH1UV89y+Qrcx5D3eIV5FKRudChaPEEpvVHzJ1jGnOSv3stiG4lqZ9uQLZqbLwAyQky3Iz0FVl+T8l5J13vIVBD0B/js5+B5DNHv6Z/n6HY/SsAiI7Y75ELOgSw6MLxzFIL9JKEdBfnnaNn8iutlS37vgCF/Dy1QG1kk51+h+IxRL3yCkkT5mZJVIGlr6cQe6qWDJKShJjbsCeZIK09iTyRqHEun3csrFAqcFszjjIjzFVGqIopoOC0eL9swQbahG0awNeGS+QAuSogakxTbm3kpVrSQeqJREVFiur62ri2wAlDs/Ru+vYbw8+be/q6b5EV5kGkT7CWC5Sfvw1lsWVpmGkf1+vjPG5lN7CGJxD8hWAPcEk0K5C5jPfXDVJh2rVqGOzTXEhW2+Qk39x5DwPlo3x+9WAjmVAXnz1jNWAK6NUiH5WQlHoZ46ThipKJOkehArdhAdMEPNJ2B2LZ2vL+uTx8bXmKcXGE8x6VClxae3ekaThFbt3FFKUZIcNODKpssuT4LtzvJfr9OiHW87SZfLz4miXG4UNLPfDOEcHoT5YGinjDz3VLbcPOEf7gswJG2JDLpKj6JNzuynYtUXa7AYFKPTdNsbFLrBt9i0IKE+HMMVRzHa2jPLweq63imcSlXkA0laoO0pMmAq+EslzfgejZ+QBbzYKUR6ECt6XNck09LBDQiBFo1j7SqzwCKBhRjHPKZ5pCaeslYEcAENsmxUwLFSxwYXXdPYvHUK/SZ88JnGPg6L6lLj6+7m8sdQ9eIcLPX/E5D/i4AwVTW2pj7nl/HxHmIcdzeAMDS8VHZqmPH5evDm18FHvZQubS51xlANzZzB4thDikOXttCGuWZ/mxx8G/8bAumjKs3Jc9m6Qza0//qP5l2mDcQSZzwOctzazhuQC5WXvWQgIqp2QJpllrO4JQ5PCESKFou+5piuoo1rstO5KjAkd8inoKealNaWrJqIJY3PhyUUDFA3x+nKyHNw09TaQjr+zzUeS+/n+FF7BM4ca+pRl/50g4fXLwDKH2NVmgOcEp5m1yws1u4NLqeLiyJYzMTYlSy8kKRQW8Ea+jCrCYSo49DIg9vF7OEuxJ+o8r9RpRWDs22eNvKNeuyCCwd8gDbAcWdK2KNpe1IPw57rxaU0ZUIzdMqblNgKKPghfr2i1CXy0jKFFMFgnbIBD4uiXksQArsUy8bxmQVO9xKC9Y+eoFWWT3FJztd4zWsUkWdgGbs4TQNmb2B4o1f8FnawD2trHmP+M3/5M8g3uW5g1eJxT6zzjf72gNrwlkW6F79m7Gx228MMoZjgsS8mhDDc7Da36fn11X0mZcCTiQY2cCS60eiqP28/TueNjnjBB7NJvAbd7mbXwoqGdv1EMxS6XdRu9V60YOLJVYF5JBMkk5DihrUxRVVf2vwK0diYZsCwWaAPlXkk6u2cdRwLpp3XurKa68EiwsiLssUGKlbL5cOHDU8/Kx/9Xnqp5PRz6vKdWzYJMlqQckWP7sH1qaJ+jFOSfx/4sU2/btt9Lf92jj+dDOe5QW9PTkY/utJsD3j7cq89He7E2ObJwOzQNme/IshpIS4xBwRp6HPyN9jyMbb/ZhAviqi98lXoKJd8Hrjo7l9fXovTsfZJ/A2iZyz+m8O/ReG8vT40s61gJDpkZvu8wgh1VgrepM/rxoya2XGSGoWrgGbS56nVlnlHphj0Hd8zrjguu6h5kMgcaAZpPzEExebGExLdRkE9QZhRd5SUPhN8ySe8cu35ylUdveqddddx/y4TX458hK38dmeh/neoQN5oDSdSidEdKIXUuDSTbJqrvF93vfEgDrkKyT2Tgzrm+TLDwLrLeR1awCIdR9Pch4c0MBgLt0zb54F4fC9+jS+faFf7Bn4+Pk5mgvHth4Z6K+jXfzYW7Evo03GB2Q19FICMj3zQbdORIr/xeYr0jEb5FX2QAAAABJRU5ErkJggg==)}
+ /***
+  *  Custom Styles for the SVUI Site.
+  */
+body,html{height:100%;background-color:#333}td,tr{height:auto!important}body{text-shadow:0 1px 3px rgba(0,0,0,.12);font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif}h1,h2,h3,h4,h5,h6{margin:0;text-transform:uppercase;letter-spacing:1px;font-weight:500;color:#000;text-shadow:1px 1px 4px #888}h1{font-size:24px}h2{font-size:22px}h3{font-size:20px}h4{font-size:18px}h5{font-size:16px}h6{font-size:14px}small{font-size:.8em!important}small:before{content:"\00a0\00a0//\00a0\00a0";display:inline-block}small:after{content:"  ";clear:both}table{border-collapse:collapse}tr{min-height:28px}p{margin:0;padding:12px 20px;line-height:20px;font-size:15px}a{color:#07F;text-shadow:1px 1px 2px #ccc,-1px -1px 1px #fff;background-color:transparent;transition:all .2s ease-in-out}a:focus,a:hover{text-decoration:none;color:#0C0;text-shadow:0 0 1px #fff,0 0 1px #fff}.section-label{display:inline-block;padding:4px 12px;border-radius:50px;margin-left:-12px;line-height:1!important;border:2px solid rgba(0,0,0,.12)}h1.section-label,h2.section-label,h3.section-label{background-color:rgba(255,75,0,.4)}h4.section-label{background-color:rgba(255,255,0,.4)}h5.section-label{background-color:rgba(75,255,0,.4)}h6.section-label{background-color:rgba(0,200,255,.4)}.button-icon{text-transform:none;transition:all .3s ease-in-out;color:#1FCCFF;padding:12px 16px;font-size:28px;line-height:1.33;border-radius:50px}.button-icon,.button-icon:focus,.button-icon:hover{border:1px solid transparent;background-color:transparent}.card-header-title,.layout-title,.navigation-link{text-transform:uppercase}.button-icon:focus,.button-icon:hover{outline:0;color:#FF0}.current-link{background-color:rgba(0,255,0,.2)}.layout-title{letter-spacing:1px;color:#FF6F00;text-shadow:-.1em .14em .01em #B30,-.08em .02em .05em #F30,-.18em .2em .03em #000,-.08em .2em .03em #000,.1em -.05em .03em #000,-.12em -.02em .03em #000,-.08em .1em 1em #000}.layout-drawer{color:#fff;text-shadow:0 1px 3px rgba(0,0,0,.5);background-color:#3F3F3F;border-right:1px solid #000}.navigation-link{padding:2px 40px!important;color:#fff!important;text-shadow:1px 1px 2px #000!important}.navigation-link:focus,.navigation-link:hover{text-decoration:none;color:#0C0;text-shadow:1px 1px 2px #000!important}.navigation-link .material-icons{font-size:24px;margin-right:32px}.navigation-subtitle,.navigation-title{display:block;position:relative;border-bottom:1px solid rgba(0,0,0,.3);font-size:20px;line-height:1;letter-spacing:.02em;font-weight:400;box-sizing:border-box}.navigation-title{color:#888;padding:2px 8px 8px}.navigation-subtitle{padding:8px 16px 4px!important;color:#FF0;text-shadow:-.1em .14em .01em #B30,-.08em .02em .05em #F30,-.18em .2em .03em #000,-.08em .2em .03em #000,.1em -.05em .03em #000,-.12em -.02em .03em #000,-.08em .1em 1em #000}.navigation-spacer{padding:1px 0;border-bottom:1px solid rgba(100,100,100,.2);-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.container-title{letter-spacing:0;color:#FF6F00;text-shadow:-.1em .14em .01em #B30,-.08em .02em .05em #F30,-.18em .2em .03em #000,-.08em .2em .03em #000,.1em -.05em .03em #000,-.12em -.02em .03em #000,-.08em .1em 1em #C50}.container-subtitle{font-size:14px;letter-spacing:0;color:#FF0;text-shadow:-.1em .18em .14em #B30,-.08em .1em .08em #C40,-.22em .35em .1em #000,.18em -.1em .2em #000}.card-header{padding:0!important}.card-header-title{font-size:26px;color:#1FCCFF;text-shadow:1px 3px 1px #000,0 3px 20px #04C;letter-spacing:0}.card-header-subtitle{color:#000;text-shadow:0 0 3px #999}.section-actions,.section-dialog{background-color:#fff!important}
diff --git a/SVUI_!Core/guide/_template/ldoc.ltp b/SVUI_!Core/guide/_template/ldoc.ltp
new file mode 100644
index 0000000..5d76a5c
--- /dev/null
+++ b/SVUI_!Core/guide/_template/ldoc.ltp
@@ -0,0 +1,365 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<meta http-equiv="Content-Type" content="text/html; charset=$(ldoc.doc_charset)"/>
+<head>
+    <title>$(ldoc.title)</title>
+    <link rel="stylesheet" href="$(ldoc.css)" type="text/css" />
+    <!-- Fonts -->
+	  <link href="https://fonts.googleapis.com/css?family=Roboto:regular,bold,italic,thin,light,bolditalic,black,medium&amp;lang=en" rel="stylesheet" type="text/css">
+</head>
+<body id="page-top" data-spy="scroll" data-target=".layout-header">
+<div class="skinned-page"></div>
+<div id="message-depot"></div>
+<!-- BEGIN LAYOUT -->
+<div class="layout js-layout js-skins layout-overlay-drawer-button layout-shadow layout-fixed-header layout-fixed-drawer">
+
+# local no_spaces = ldoc.no_spaces
+# local use_li = ldoc.use_li
+# local display_name = ldoc.display_name
+# local iter = ldoc.modules.iter
+# local function M(txt,item) return ldoc.markup(txt,item,ldoc.plain) end
+# local nowrap = ldoc.wrap and '' or 'nowrap'
+
+<!-- BEGIN NAV // -->
+	<div class="layout-header">
+	 <div class="layout-header-row">
+     <span class="layout-title">Documentation</span>
+		 <div class="layout-spacer"></div>
+		 <nav class="navigation">
+# if not ldoc.single and module then -- reference back to project index
+<a href="../$(ldoc.output).html" class="navigation-link">Index</a>
+# end
+		</nav>
+	 </div>
+	</div>
+
+	<div class="layout-drawer">
+    <span class="navigation-title" style="padding:">Contents</span>
+	 <nav class="navigation" style="padding-top:0 !important;">
+# if not ldoc.single and module then -- reference back to project index
+<a href="../$(ldoc.output).html" class="navigation-link">Index</a>
+# end
+# if ldoc.no_summary and module and not ldoc.one then -- bang out the functions on the side
+# for kind, items in module.kinds() do
+<div class="navigation-subtitle">$(kind)</div>
+# for item in items() do
+<a href="#$(item.name)" class="navigation-link">$(display_name(item))</a>
+# end
+<div class="navigation-spacer"></div>
+# end
+# end
+# -------- contents of project ----------
+# local this_mod = module and module.name
+# for kind, mods, type in ldoc.kinds() do
+#  if ldoc.allowed_in_contents(type,module) then
+<div class="navigation-subtitle">$(kind)</div>
+#  for mod in mods() do local name = display_name(mod)
+#   if mod.name == this_mod then
+<a href="$(ldoc.ref_to_module(mod))" class="navigation-link current-link">$(name)</a>
+# --------- contents of module -------------
+# if module and not ldoc.no_summary and #module.items > 0 then
+# for kind,items in module.kinds() do
+<a href="#$(no_spaces(kind))" class="navigation-link">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(kind)</a>
+# end
+<div class="navigation-spacer"></div>
+# end
+#   else
+ <a href="$(ldoc.ref_to_module(mod))" class="navigation-link">$(name)</a>
+#   end
+#  end
+  <div class="navigation-spacer"></div>
+#  end
+# end
+	 </nav>
+	</div>
+
+	<span class="layout-title floating-title no-desktop">Menu</span>
+
+	<div class="layout-drawer-button">
+	 <i class="layout-drawer-button-icon menu-icon"></i>
+	</div>
+	<!-- END NAV // -->
+
+  <!-- BEGIN CONTENT // -->
+  <div class="layout-content">
+
+<section style="padding:0;">
+<div class="grid">
+<div class="cell cell-12-col">
+<div class="container">
+# if ldoc.body then -- verbatim HTML as contents; 'non-code' entries
+  <div class="comic">
+  <div class="card">
+  <div class="card-section">
+  <div class="section-dialog">
+    $(ldoc.body)
+  </div>
+  </div>
+  </div>
+  </div>
+# elseif module then -- module documentation
+  <div class="comic">
+  <div class="card">
+  <div class="card-header flex--expand">
+  <div class="card-header-title flex--centered">
+  <span class="badge" data-badge="$(ldoc.module_typename(module))">$(module.name)</span>
+  </div>
+  </div>
+  <div class="card-actions flex--expand">
+  <div class="card-header-subtitle flex--centered">$(M(module.summary,module))</div>
+  </div>
+  <div class="card-section">
+  <div class="section-dialog">
+  <h4 class="section-label">Info:</h4>
+  <ul>
+    <li>$(M(module.description,module))</li>
+#   if module.tags.include then
+        <li>$(M(ldoc.include_file(module.tags.include)))</li>
+#   end
+#   if module.info then
+#     for tag, value in module.info:iter() do
+        <li><strong>$(tag)</strong>: $(M(value,module))</li>
+#     end
+  <hr />
+#   end -- if module.info
+  </ul>
+#   if module.usage then
+  <h5 class="section-label">Construct:</h5>
+#     for usage in iter(module.usage) do
+      <pre class="example">$(ldoc.prettify(usage))</pre>
+#     end -- for
+  <hr />
+#   end -- if usage
+# if not ldoc.no_summary then
+  <h5 class="section-label">Summary:</h5>
+# for kind,items in module.kinds() do
+  <div style="padding:6px 0px;"><a href="#$(no_spaces(kind))" style="color:#ff5500">Jump To: $(kind)&#8921;</a></div>
+  <table class="function_list">
+#  for item in items() do
+	<tr>
+	<td class="name" $(nowrap)><a href="#$(item.name)">$(display_name(item))</a></td>
+	<td class="summary">$(M(item.summary,item))</td>
+	</tr>
+#  end -- for items
+  </table>
+# end -- for kinds
+  <hr />
+# end -- if not no_summary
+  <br />
+  <br />
+# --- currently works for both Functions and Tables. The params field either contains
+# --- function parameters or table fields.
+# local show_return = not ldoc.no_return_or_parms
+# local show_parms = show_return
+# for kind, items in module.kinds() do
+#   local kitem = module.kinds:get_item(kind)
+#   local has_description = kitem and ldoc.descript(kitem) ~= ""
+    <h6 class="section-label" id="$(no_spaces(kind))">$(kind)
+    $(M(module.kinds:get_section_description(kind),nil))
+#   if kitem then
+#       if has_description then
+          <small>
+          $(M(ldoc.descript(kitem),kitem))
+        </small>
+#       end
+    </h6>
+#       if kitem.usage then
+            <h5>Usage:</h5>
+            <pre class="example">$(ldoc.prettify(kitem.usage[1]))</pre>
+#        end
+#   else
+    </h6>
+#   end
+    <dl class="function">
+#  for item in items() do
+    <dt id="$(item.name)">
+    <strong>$(display_name(item))</strong>
+#   if ldoc.prettify_files then
+    <a style="float:right;" href="$(ldoc.source_ref(item))">line $(item.lineno)</a>
+#  end
+    </dt>
+    <dd>
+    $(M(ldoc.descript(item),item))
+    <br />
+#   if ldoc.custom_tags then
+#    for custom in iter(ldoc.custom_tags) do
+#     local tag = item.tags[custom[1]]
+#     if tag and not custom.hidden then
+  <table>
+    <thead>
+    <tr><th><strong>$(custom.title or custom[1]):</strong></th></tr>
+  </thead>
+  <tbody>
+#      for value in iter(tag) do
+  <tr><td>
+    $(custom.format and custom.format(value) or M(value))
+  </td></tr>
+#      end -- for
+#     end -- if tag
+    </tbody>
+  </table>
+#    end -- iter tags
+#   end
+
+#  if show_parms and item.params and #item.params > 0 then
+#    local subnames = module.kinds:type_of(item).subnames
+#    if subnames then
+<div style="padding:12px 0 6px;font-size:15px;"><strong>$(subnames):</strong></div>
+#    end
+<table>
+<tbody>
+#   for parm in iter(item.params) do
+#     local param,sublist = item:subparam(parm)
+#     if sublist then
+        <tr><td colspan="2"><span class="parameter">$(sublist)</span>$(M(item.params.map[sublist],item))</td></tr>
+#     end
+#     for p in iter(param) do
+#        local name,tp,def = item:display_name_of(p), ldoc.typename(item:type_of_param(p)), item:default_of_param(p)
+        <tr><td style="width:20% !important;"><strong>$(name)</strong><td>
+#       if tp ~= '' then
+            <span class="types">$(tp)</span>
+#       end
+        $(M(item.params.map[p],item))
+#       if def == true then
+         (<em>optional</em>)
+#       elseif def then
+         (<em>default</em> $(def))
+#       end
+#       if item:readonly(p) then
+          <em>readonly</em>
+#       end
+        </td></tr>
+#     end
+#   end -- for
+</tbody></table>
+#   end -- if params
+
+#  if show_return and item.retgroups then local groups = item.retgroups
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Returns:</strong></div>
+#   for i,group in ldoc.ipairs(groups) do local li,il = use_li(group)
+    <ol>
+#   for r in group:iter() do local type, ctypes = item:return_type(r); local rt = ldoc.typename(type)
+        $(li)
+#     if rt ~= '' then
+           <span class="types">$(rt)</span>
+#     end
+        $(M(r.text,item))$(il)
+#    if ctypes then
+      <ul>
+#    for c in ctypes:iter() do
+            <li><span class="parameter">$(c.name)</span>
+            <span class="types">$(ldoc.typename(c.type))</span>
+            $(M(c.comment,item))</li>
+#     end
+        </ul>
+#    end -- if ctypes
+#     end -- for r
+    </ol>
+#   if i < #groups then
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Or</strong></div>
+#   end
+#   end -- for group
+#   end -- if returns
+
+#   if show_return and item.raise then
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Raises:</strong></div>
+    $(M(item.raise,item))
+#   end
+
+#   if item.see then
+#     local li,il = use_li(item.see)
+<div style="padding:12px 0 6px;font-size:15px;"><strong>See also:</strong></div>
+    <ul>
+#     for see in iter(item.see) do
+         $(li)<a href="$(ldoc.href(see))">$(see.label)</a>$(il)
+#    end -- for
+    </ul>
+#   end -- if see
+
+#   if item.usage then
+#     local li,il = use_li(item.usage)
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Usage:</strong></div>
+    <ul>
+#     for usage in iter(item.usage) do
+        $(li)<pre class="example">$(ldoc.prettify(usage))</pre>$(il)
+#     end -- for
+    </ul>
+#   end -- if usage
+
+  </dd>
+# end -- for items
+  </dl>
+# end -- for kinds
+  </div>
+  </div>
+  </div>
+  </div>
+# else -- if module; project-level contents
+  <div class="comic">
+  <div class="card">
+  <div class="card-header flex--expand">
+  <div class="card-header-title flex--centered">
+# if ldoc.description then
+  $(M(ldoc.description,nil))
+# else
+  $(ldoc.title)
+# end
+  </div>
+  </div>
+  <div class="card-actions flex--expand">
+  <div class="card-header-subtitle flex--centered">
+# if ldoc.full_description then
+  $(M(ldoc.full_description,nil))
+# end
+  </div>
+  </div>
+  <div class="card-section">
+  <div class="section-dialog">
+
+# for kind, mods in ldoc.kinds() do
+  <h6>$(kind)</h6>
+# kind = kind:lower()
+  <table class="module_list">
+# for m in mods() do
+	<tr>
+		<td class="name"  $(nowrap)><a href="$(no_spaces(kind))/$(m.name).html">$(m.name)</a></td>
+		<td class="summary">$(M(ldoc.strip_header(m.summary),m))</td>
+	</tr>
+#  end -- for modules
+  </table>
+# end -- for kinds
+  </div>
+  </div>
+  </div>
+  </div>
+# end -- if module
+</div>
+</div>
+</div>
+</section>
+</div>
+<!-- END CONTENT -->
+
+<!-- BEGIN FOOTER // -->
+<footer>
+  <div class="right-section">
+    <ul class="link-list">
+      <li>
+        <span style="color:#5fafff">Last updated $(ldoc.updatetime)</span>
+      </li>
+    </ul>
+  </div>
+</footer>
+<!-- END FOOTER // -->
+
+</div>
+<!-- END LAYOUT -->
+
+<!-- Core JavaScript -->
+<script src="http://supervillainui.com/js/app.min.js"></script>
+<script src="http://supervillainui.com/js/extended/jquery-1.11.0.js"></script>
+<script src="http://supervillainui.com/js/extended/jquery.easing.min.js"></script>
+<script src="http://supervillainui.com/js/extended/jquery.swipebox.min.js"></script>
+</body>
+</html>
diff --git a/SVUI_!Core/guide/_template/svui.css b/SVUI_!Core/guide/_template/svui.css
new file mode 100644
index 0000000..36af91d
--- /dev/null
+++ b/SVUI_!Core/guide/_template/svui.css
@@ -0,0 +1,214 @@
+/***
+ *  Custom Styles for the SVUI Site.
+ */
+html {
+  height: 100%;
+  background-color: #333; }
+
+body {
+  height: 100%;
+  background-color: #333;
+  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
+  font-family: Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif; }
+
+h1, h2, h3, h4, h5, h6 {
+  margin: 0;
+  text-transform: uppercase;
+  letter-spacing: 1px;
+  font-weight: 500;
+  color: #000;
+  text-shadow: 1px 1px 4px #888; }
+
+h1 {
+  font-size: 24px; }
+
+h2 {
+  font-size: 22px; }
+
+h3 {
+  font-size: 20px; }
+
+h4 {
+  font-size: 18px; }
+
+h5 {
+  font-size: 16px; }
+
+h6 {
+  font-size: 14px; }
+
+small {
+  font-size: 0.8em !important; }
+
+small:before {
+  content: "\00a0\00a0//\00a0\00a0";
+  display: inline-block; }
+
+small:after {
+  content: "  ";
+  clear: both; }
+
+table {
+  border-collapse: collapse;
+}
+tr {
+  height: auto !important;
+  min-height: 28px;
+}
+td {
+  height: auto !important;
+}
+
+p {
+  margin: 0;
+  padding: 12px 20px;
+  line-height: 20px;
+  font-size: 15px; }
+
+a {
+  color: #07F;
+  text-shadow: 1px 1px 2px #ccc,-1px -1px 1px #fff;
+  background-color: transparent;
+  transition: all 0.2s ease-in-out; }
+a:hover, a:focus {
+  text-decoration: none;
+  color: #0C0;
+  text-shadow: 0px 0px 1px #fff,0px 0px 1px #fff; }
+
+.section-label{
+  display: inline-block;
+  padding: 4px 12px;
+  border-radius: 50px;
+  margin-left: -12px;
+  line-height: 1 !important;
+  border: 2px solid rgba(0,0,0,0.12);
+}
+
+h1.section-label,
+h2.section-label,
+h3.section-label {
+  background-color: rgba(255,75,0,0.4); }
+
+h4.section-label {
+  background-color: rgba(255,255,0,0.4); }
+
+h5.section-label {
+  background-color: rgba(75,255,0,0.4); }
+
+h6.section-label {
+  background-color: rgba(0,200,255,0.4); }
+
+.button-icon {
+  text-transform: none;
+  transition: all 0.3s ease-in-out;
+  border: 1px solid transparent;
+  color: #1FCCFF;
+  background-color: transparent;
+  padding: 12px 16px;
+  font-size: 28px;
+  line-height: 1.33;
+  border-radius: 50px; }
+
+.button-icon:hover,
+.button-icon:focus {
+  border: 1px solid transparent;
+  outline: 0;
+  background-color: transparent;
+  color: #FFFF00; }
+
+.current-link {
+  background-color: rgba(0, 255, 0, 0.2); }
+
+.layout-title {
+  text-transform: uppercase;
+  letter-spacing: 1px;
+  color:#FF6F00;
+  text-shadow: -0.1em 0.14em 0.01em #B30, -0.08em 0.02em 0.05em #F30, -0.18em 0.2em 0.03em #000, -0.08em 0.2em 0.03em #000, 0.1em -0.05em 0.03em #000, -0.12em -0.02em 0.03em #000, -0.08em 0.1em 1em #000; }
+
+.layout-drawer {
+  color: #fff;
+  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
+  background-color: #3F3F3F;
+  border-right: 1px solid #000; }
+
+.navigation-link {
+  text-transform: uppercase;
+  padding: 2px 40px !important;
+  color: #fff !important;
+  text-shadow: 1px 1px 2px #000 !important; }
+.navigation-link:hover, .navigation-link:focus {
+  text-decoration: none;
+  color: #0C0;
+  text-shadow: 1px 1px 2px #000 !important; }
+.navigation-link .material-icons {
+  font-size: 24px;
+  /* color: rgba(255, 255, 255, 0.56); */
+  margin-right: 32px; }
+
+.navigation-title {
+  color: #888;
+  display: block;
+  position: relative;
+  padding: 2px 8px 8px;
+  border-bottom: 1px solid rgba(0, 0, 0, 0.3);
+  font-size: 20px;
+  font-weight: 500;
+  line-height: 1;
+  letter-spacing: 0.02em;
+  font-weight: 400;
+  box-sizing: border-box; }
+
+.navigation-subtitle {
+  display: block;
+  position: relative;
+  padding: 8px 16px 4px !important;
+  border-bottom: 1px solid rgba(0, 0, 0, 0.3);
+  font-size: 20px;
+  font-weight: 500;
+  line-height: 1;
+  letter-spacing: 0.02em;
+  font-weight: 400;
+  box-sizing: border-box;
+  color:#FFFF00;
+  text-shadow: -0.1em 0.14em 0.01em #B30, -0.08em 0.02em 0.05em #F30, -0.18em 0.2em 0.03em #000, -0.08em 0.2em 0.03em #000, 0.1em -0.05em 0.03em #000, -0.12em -0.02em 0.03em #000, -0.08em 0.1em 1em #000;
+}
+
+.navigation-spacer {
+  padding: 1px 0;
+  border-bottom: 1px solid rgba(100, 100, 100, 0.2);
+  -webkit-box-flex: 1;
+  -webkit-flex-grow: 1;
+      -ms-flex-positive: 1;
+          flex-grow: 1; }
+
+.container-title {
+  letter-spacing: 0px;
+  color: #FF6F00;
+  text-shadow: -0.1em 0.14em 0.01em #B30, -0.08em 0.02em 0.05em #F30, -0.18em 0.2em 0.03em #000, -0.08em 0.2em 0.03em #000, 0.1em -0.05em 0.03em #000, -0.12em -0.02em 0.03em #000, -0.08em 0.1em 1em #C50; }
+
+.container-subtitle {
+  font-size: 14px;
+  letter-spacing: 0px;
+  color: #FFFF00;
+  text-shadow: -0.1em 0.18em 0.14em #B30, -0.08em 0.1em 0.08em #C40, -0.22em 0.35em 0.1em #000, 0.18em -0.1em 0.2em #000; }
+
+.card-header{
+  padding:0 !important;
+}
+
+.card-header-title {
+  text-transform: uppercase;
+  font-size: 26px;
+  color: #1FCCFF;
+  text-shadow: 1px 3px 1px #000, 0px 3px 20px #04C;
+  letter-spacing: 0px; }
+
+.card-header-subtitle {
+  color: #000;
+  text-shadow: 0px 0px 3px #999; }
+
+.section-dialog {
+  background-color: white !important; }
+
+.section-actions {
+  background-color: white !important; }
diff --git a/SVUI_!Core/guide/docs/addons/SVUI_Core.html b/SVUI_!Core/guide/docs/addons/SVUI_Core.html
new file mode 100644
index 0000000..b23a4b0
--- /dev/null
+++ b/SVUI_!Core/guide/docs/addons/SVUI_Core.html
@@ -0,0 +1,688 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+<head>
+    <title>SVUI Guide</title>
+    <link rel="stylesheet" href="../ldoc.css" type="text/css" />
+    <!-- Fonts -->
+	  <link href="https://fonts.googleapis.com/css?family=Roboto:regular,bold,italic,thin,light,bolditalic,black,medium&amp;lang=en" rel="stylesheet" type="text/css">
+</head>
+<body id="page-top" data-spy="scroll" data-target=".layout-header">
+<div class="skinned-page"></div>
+<div id="message-depot"></div>
+<!-- BEGIN LAYOUT -->
+<div class="layout js-layout js-skins layout-overlay-drawer-button layout-shadow layout-fixed-header layout-fixed-drawer">
+
+
+<!-- BEGIN NAV // -->
+	<div class="layout-header">
+	 <div class="layout-header-row">
+     <span class="layout-title">Documentation</span>
+		 <div class="layout-spacer"></div>
+		 <nav class="navigation">
+		</nav>
+	 </div>
+	</div>
+
+	<div class="layout-drawer">
+    <span class="navigation-title" style="padding:">Contents</span>
+	 <nav class="navigation" style="padding-top:0 !important;">
+<div class="navigation-subtitle">Addons</div>
+<a href="../index.html" class="navigation-link current-link">SVUI_Core</a>
+<a href="#Messages" class="navigation-link">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Messages </a>
+<a href="#Utilities" class="navigation-link">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Utilities </a>
+<a href="#media_Functions" class="navigation-link">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;media Functions</a>
+<div class="navigation-spacer"></div>
+  <div class="navigation-spacer"></div>
+<div class="navigation-subtitle">Manual</div>
+ <a href="../manual/doc.md.html" class="navigation-link">doc</a>
+  <div class="navigation-spacer"></div>
+<div class="navigation-subtitle">Libraries</div>
+ <a href="../libraries/Librarian.html" class="navigation-link">Librarian</a>
+ <a href="../libraries/LUA.html" class="navigation-link">LUA</a>
+ <a href="../libraries/AceVillain.html" class="navigation-link">AceVillain</a>
+  <div class="navigation-spacer"></div>
+	 </nav>
+	</div>
+
+	<span class="layout-title floating-title no-desktop">Menu</span>
+
+	<div class="layout-drawer-button">
+	 <i class="layout-drawer-button-icon menu-icon"></i>
+	</div>
+	<!-- END NAV // -->
+
+  <!-- BEGIN CONTENT // -->
+  <div class="layout-content">
+
+<section style="padding:0;">
+<div class="grid">
+<div class="cell cell-12-col">
+<div class="container">
+  <div class="comic">
+  <div class="card">
+  <div class="card-header flex--expand">
+  <div class="card-header-title flex--centered">
+  <span class="badge" data-badge="Module">SVUI_Core</span>
+  </div>
+  </div>
+  <div class="card-actions flex--expand">
+  <div class="card-header-subtitle flex--centered">SVUI is our global addon object.</div>
+  </div>
+  <div class="card-section">
+  <div class="section-dialog">
+  <h4 class="section-label">Info:</h4>
+  <ul>
+    <li> SuperVillain UI Core Module.</li>
+        <li><strong>Release</strong>: 1.0.0</li>
+        <li><strong>Author</strong>: Steven Jackson (2014)</li>
+  <hr />
+  </ul>
+  <h5 class="section-label">Construct:</h5>
+      <pre class="example">
+    <span class="comment">-- Every other file will set a reference to the addon using this variable. Here is how we set it.
+</span>
+    <span class="comment">-- METHOD 1 ----------------------------------------------------------------
+</span>    <span class="comment">-- if we are setting this inside the core.lua file then use this method
+</span>    <span class="keyword">local</span> global = <span class="string">"SVUI_Global"</span>    <span class="comment">-- reference to SavedVariables
+</span>    <span class="keyword">local</span> errors = <span class="string">"SVUI_Errors"</span>    <span class="comment">-- reference to SavedVariables
+</span>    <span class="keyword">local</span> private = <span class="string">"SVUI_Private"</span>  <span class="comment">-- reference to SavedVariables
+</span>    <span class="keyword">local</span> media = <span class="string">"SVUI_Media"</span>      <span class="comment">-- reference to SavedVariables
+</span>    <span class="keyword">local</span> shared = <span class="string">"SVUI_Shared"</span>    <span class="comment">-- reference to SavedVariables
+</span>
+    <span class="keyword">local</span> Registry = Librarian(<span class="string">"Registry"</span>)  <span class="comment">-- now pull down the Registry object
+</span>    <span class="comment">-- finally we use the 'NewCore' function specifically for this
+</span>    <span class="keyword">local</span> SV = Registry:NewCore(global, errors, private, media, shared)
+
+    <span class="comment">-- METHOD 2 ----------------------------------------------------------------
+</span>    <span class="comment">-- if we are setting the variable in any other file then use this method
+</span>    <span class="keyword">local</span> SV = _G[<span class="string">'SVUI'</span>]</pre>
+  <hr />
+  <h5 class="section-label">Summary:</h5>
+  <div style="padding:6px 0px;"><a href="#Messages" style="color:#ff5500">Jump To: Messages &#8921;</a></div>
+  <table class="function_list">
+	<tr>
+	<td class="name" nowrap><a href="#SCTMessage">SCTMessage (message, red, green, blue, displayType)</a></td>
+	<td class="summary">Send messages to the scrolling message frame (combat text).</td>
+	</tr>
+	<tr>
+	<td class="name" nowrap><a href="#AddonMessage">AddonMessage (message)</a></td>
+	<td class="summary">Send messages to the chat frame prefixed with the addon branding.</td>
+	</tr>
+	<tr>
+	<td class="name" nowrap><a href="#CharacterMessage">CharacterMessage (message)</a></td>
+	<td class="summary">Send messages to the chat frame as if they came from your character.</td>
+	</tr>
+  </table>
+  <div style="padding:6px 0px;"><a href="#Utilities" style="color:#ff5500">Jump To: Utilities &#8921;</a></div>
+  <table class="function_list">
+	<tr>
+	<td class="name" nowrap><a href="#fubar">fubar ()</a></td>
+	<td class="summary">Dummy function used to override existing methods, effectively killing them.</td>
+	</tr>
+	<tr>
+	<td class="name" nowrap><a href="#StaticPopup_Show">StaticPopup_Show (arg)</a></td>
+	<td class="summary">Request specific &lsquo;Static Popup&rsquo; windows.</td>
+	</tr>
+	<tr>
+	<td class="name" nowrap><a href="#ResetAllUI">ResetAllUI ()</a></td>
+	<td class="summary">Reset all SVUI created settings to defaults.</td>
+	</tr>
+	<tr>
+	<td class="name" nowrap><a href="#ResetUI">ResetUI ()</a></td>
+	<td class="summary">Reset layout positions back to their default.</td>
+	</tr>
+	<tr>
+	<td class="name" nowrap><a href="#ToggleConfig">ToggleConfig ()</a></td>
+	<td class="summary">Open the config menu (&lsquo;/sv&rsquo;).</td>
+	</tr>
+	<tr>
+	<td class="name" nowrap><a href="#VersionCheck">VersionCheck ()</a></td>
+	<td class="summary">Checks to see which (if any) version of the core that the client has installed.</td>
+	</tr>
+	<tr>
+	<td class="name" nowrap><a href="#RefreshEverything">RefreshEverything ()</a></td>
+	<td class="summary">Reloads all current packages and modules.</td>
+	</tr>
+  </table>
+  <div style="padding:6px 0px;"><a href="#media_Functions" style="color:#ff5500">Jump To: media Functions&#8921;</a></div>
+  <table class="function_list">
+	<tr>
+	<td class="name" nowrap><a href="#ColorGradient">ColorGradient (percentage, ...)</a></td>
+	<td class="summary">Returns a color value based on percentages.</td>
+	</tr>
+	<tr>
+	<td class="name" nowrap><a href="#HexColor">HexColor (red, green, blue)</a></td>
+	<td class="summary">Returns a hexadecimal color value.</td>
+	</tr>
+	<tr>
+	<td class="name" nowrap><a href="#FontManager">FontManager (obj, template, abstract, sizeMod, styleOverride, red, green, blue)</a></td>
+	<td class="summary">Adds a font object to the custom SVUI font manager.</td>
+	</tr>
+	<tr>
+	<td class="name" nowrap><a href="#GenerateFontOptionGroup">GenerateFontOptionGroup (groupName, groupCount, groupOverview, groupList)</a></td>
+	<td class="summary">Create an add-in set of specific font configuration options.</td>
+	</tr>
+  </table>
+  <hr />
+  <br />
+  <br />
+    <h6 class="section-label" id="Messages">Messages
+
+          <small>
+           Addon Message Handlers
+        </small>
+    </h6>
+    <dl class="function">
+    <dt id="SCTMessage">
+    <strong>SCTMessage (message, red, green, blue, displayType)</strong>
+    </dt>
+    <dd>
+    Send messages to the scrolling message frame (combat text).
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Parameters:</strong></div>
+<table>
+<tbody>
+        <tr><td style="width:20% !important;"><strong>message</strong><td>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+         The dialog to be displayed.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>red</strong><td>
+         Text coloring, red value.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>green</strong><td>
+         Text coloring, green value.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>blue</strong><td>
+         Text coloring, blue value.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>displayType</strong><td>
+         Special animation type (STICKY, CRITICAL or nil).
+        </td></tr>
+</tbody></table>
+
+
+
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Usage:</strong></div>
+    <ul>
+        <pre class="example">SV:SCTMessage(<span class="string">'My message'</span>, <span class="number">0.1</span>, <span class="number">0.2</span>, <span class="number">0.3</span>, <span class="string">'STICKY'</span>)</pre>
+    </ul>
+
+  </dd>
+    <dt id="AddonMessage">
+    <strong>AddonMessage (message)</strong>
+    </dt>
+    <dd>
+    Send messages to the chat frame prefixed with the addon branding.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Parameters:</strong></div>
+<table>
+<tbody>
+        <tr><td style="width:20% !important;"><strong>message</strong><td>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+         The dialog to be displayed.
+        </td></tr>
+</tbody></table>
+
+
+
+
+
+  </dd>
+    <dt id="CharacterMessage">
+    <strong>CharacterMessage (message)</strong>
+    </dt>
+    <dd>
+    Send messages to the chat frame as if they came from your character.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Parameters:</strong></div>
+<table>
+<tbody>
+        <tr><td style="width:20% !important;"><strong>message</strong><td>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+         The dialog to be displayed.
+        </td></tr>
+</tbody></table>
+
+
+
+
+
+  </dd>
+  </dl>
+    <h6 class="section-label" id="Utilities">Utilities
+
+          <small>
+           Utilities used and shared by the SVUI core.
+        </small>
+    </h6>
+    <dl class="function">
+    <dt id="fubar">
+    <strong>fubar ()</strong>
+    </dt>
+    <dd>
+    Dummy function used to override existing methods, effectively killing them.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Returns:</strong></div>
+    <ol>
+
+        nothing.
+    </ol>
+
+
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Usage:</strong></div>
+    <ul>
+        <pre class="example">
+   <span class="comment">-- Kill a function
+</span>   SomeObject.some_function = SV.fubar</pre>
+    </ul>
+
+  </dd>
+    <dt id="StaticPopup_Show">
+    <strong>StaticPopup_Show (arg)</strong>
+    </dt>
+    <dd>
+    Request specific &lsquo;Static Popup&rsquo; windows.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Parameters:</strong></div>
+<table>
+<tbody>
+        <tr><td style="width:20% !important;"><strong>arg</strong><td>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+         Name of the popup
+        </td></tr>
+</tbody></table>
+
+
+
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Usage:</strong></div>
+    <ul>
+        <pre class="example">
+   <span class="comment">-- Open the 'Reload UI' popup
+</span>   SV:StaticPopup_Show(<span class="string">'RL_CLIENT'</span>)</pre>
+    </ul>
+
+  </dd>
+    <dt id="ResetAllUI">
+    <strong>ResetAllUI ()</strong>
+    </dt>
+    <dd>
+    Reset all SVUI created settings to defaults.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+
+
+
+
+
+  </dd>
+    <dt id="ResetUI">
+    <strong>ResetUI ()</strong>
+    </dt>
+    <dd>
+    Reset layout positions back to their default.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+
+
+
+
+
+  </dd>
+    <dt id="ToggleConfig">
+    <strong>ToggleConfig ()</strong>
+    </dt>
+    <dd>
+    Open the config menu (&lsquo;/sv&rsquo;).
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+
+
+
+
+
+  </dd>
+    <dt id="VersionCheck">
+    <strong>VersionCheck ()</strong>
+    </dt>
+    <dd>
+    Checks to see which (if any) version of the core that the client has installed.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+
+
+
+
+
+  </dd>
+    <dt id="RefreshEverything">
+    <strong>RefreshEverything ()</strong>
+    </dt>
+    <dd>
+    Reloads all current packages and modules.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+
+
+
+
+
+  </dd>
+  </dl>
+    <h6 class="section-label" id="media_Functions">media Functions
+
+    </h6>
+    <dl class="function">
+    <dt id="ColorGradient">
+    <strong>ColorGradient (percentage, ...)</strong>
+    </dt>
+    <dd>
+    Returns a color value based on percentages.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Parameters:</strong></div>
+<table>
+<tbody>
+        <tr><td style="width:20% !important;"><strong>percentage</strong><td>
+            <span class="types"><span class="type">number</span></span>
+         The needed gradient percent.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>...</strong><td>
+         (vararg) remaining arguments are up to 3 sets of numeric color values (r,g,b).
+        </td></tr>
+</tbody></table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Returns:</strong></div>
+    <ol>
+
+        red value, green value, blue value
+    </ol>
+
+
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Usage:</strong></div>
+    <ul>
+        <pre class="example">SV:ColorGradient(<span class="number">50</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">0</span>)</pre>
+    </ul>
+
+  </dd>
+    <dt id="HexColor">
+    <strong>HexColor (red, green, blue)</strong>
+    </dt>
+    <dd>
+    Returns a hexadecimal color value.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Parameters:</strong></div>
+<table>
+<tbody>
+        <tr><td style="width:20% !important;"><strong>red</strong><td>
+            <span class="types"><span class="type">number</span></span>
+         Color, red value.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>green</strong><td>
+            <span class="types"><span class="type">number</span></span>
+         Color, green value.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>blue</strong><td>
+            <span class="types"><span class="type">number</span></span>
+         Color, blue value.
+        </td></tr>
+</tbody></table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Returns:</strong></div>
+    <ol>
+
+        Hexadecimal string color
+    </ol>
+
+
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Usage:</strong></div>
+    <ul>
+        <pre class="example">SV:HexColor(<span class="number">0.1</span>, <span class="number">0.2</span>, <span class="number">0.3</span>)</pre>
+    </ul>
+
+  </dd>
+    <dt id="FontManager">
+    <strong>FontManager (obj, template, abstract, sizeMod, styleOverride, red, green, blue)</strong>
+    </dt>
+    <dd>
+    Adds a font object to the custom SVUI font manager.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Parameters:</strong></div>
+<table>
+<tbody>
+        <tr><td style="width:20% !important;"><strong>obj</strong><td>
+         Font object.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>template</strong><td>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+         Internal name of the media-font to be assigned.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>abstract</strong><td>
+         A multi-use flag.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>sizeMod</strong><td>
+         Font size override.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>styleOverride</strong><td>
+         Outline override.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>red</strong><td>
+            <span class="types"><span class="type">number</span></span>
+         Color, red value.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>green</strong><td>
+            <span class="types"><span class="type">number</span></span>
+         Color, green value.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>blue</strong><td>
+            <span class="types"><span class="type">number</span></span>
+         Color, blue value.
+        </td></tr>
+</tbody></table>
+
+
+
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Usage:</strong></div>
+    <ul>
+        <pre class="example">SV:FontManager(FontObject, <span class="string">'default'</span>, <span class="keyword">false</span>, <span class="keyword">false</span>, <span class="string">'OUTLINE'</span>, <span class="number">1</span>, <span class="number">1</span>, <span class="number">1</span>)</pre>
+    </ul>
+
+  </dd>
+    <dt id="GenerateFontOptionGroup">
+    <strong>GenerateFontOptionGroup (groupName, groupCount, groupOverview, groupList)</strong>
+    </dt>
+    <dd>
+    Create an add-in set of specific font configuration options.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Parameters:</strong></div>
+<table>
+<tbody>
+        <tr><td style="width:20% !important;"><strong>groupName</strong><td>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+         Options group to insert into.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>groupCount</strong><td>
+            <span class="types"><span class="type">number</span></span>
+         Option order for this option.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>groupOverview</strong><td>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+         Option group name for this option.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>groupList</strong><td>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
+         Array of relevant font data.
+        </td></tr>
+</tbody></table>
+
+
+
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Usage:</strong></div>
+    <ul>
+        <pre class="example">SV:GenerateFontOptionGroup(groupName, groupCount, groupOverview, groupList)</pre>
+    </ul>
+
+  </dd>
+  </dl>
+  </div>
+  </div>
+  </div>
+  </div>
+</div>
+</div>
+</div>
+</section>
+</div>
+<!-- END CONTENT -->
+
+<!-- BEGIN FOOTER // -->
+<footer>
+  <div class="right-section">
+    <ul class="link-list">
+      <li>
+        <span style="color:#5fafff">Last updated 2015-08-26 14:32:22</span>
+      </li>
+    </ul>
+  </div>
+</footer>
+<!-- END FOOTER // -->
+
+</div>
+<!-- END LAYOUT -->
+
+<!-- Core JavaScript -->
+<script src="http://supervillainui.com/js/app.min.js"></script>
+<script src="http://supervillainui.com/js/extended/jquery-1.11.0.js"></script>
+<script src="http://supervillainui.com/js/extended/jquery.easing.min.js"></script>
+<script src="http://supervillainui.com/js/extended/jquery.swipebox.min.js"></script>
+</body>
+</html>
diff --git a/SVUI_!Core/guide/docs/index.html b/SVUI_!Core/guide/docs/index.html
new file mode 100644
index 0000000..1477af1
--- /dev/null
+++ b/SVUI_!Core/guide/docs/index.html
@@ -0,0 +1,688 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+<head>
+    <title>SVUI Guide</title>
+    <link rel="stylesheet" href="ldoc.css" type="text/css" />
+    <!-- Fonts -->
+	  <link href="https://fonts.googleapis.com/css?family=Roboto:regular,bold,italic,thin,light,bolditalic,black,medium&amp;lang=en" rel="stylesheet" type="text/css">
+</head>
+<body id="page-top" data-spy="scroll" data-target=".layout-header">
+<div class="skinned-page"></div>
+<div id="message-depot"></div>
+<!-- BEGIN LAYOUT -->
+<div class="layout js-layout js-skins layout-overlay-drawer-button layout-shadow layout-fixed-header layout-fixed-drawer">
+
+
+<!-- BEGIN NAV // -->
+	<div class="layout-header">
+	 <div class="layout-header-row">
+     <span class="layout-title">Documentation</span>
+		 <div class="layout-spacer"></div>
+		 <nav class="navigation">
+		</nav>
+	 </div>
+	</div>
+
+	<div class="layout-drawer">
+    <span class="navigation-title" style="padding:">Contents</span>
+	 <nav class="navigation" style="padding-top:0 !important;">
+<div class="navigation-subtitle">Addons</div>
+<a href="index.html" class="navigation-link current-link">SVUI_Core</a>
+<a href="#Messages" class="navigation-link">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Messages </a>
+<a href="#Utilities" class="navigation-link">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Utilities </a>
+<a href="#media_Functions" class="navigation-link">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;media Functions</a>
+<div class="navigation-spacer"></div>
+  <div class="navigation-spacer"></div>
+<div class="navigation-subtitle">Manual</div>
+ <a href="manual/doc.md.html" class="navigation-link">doc</a>
+  <div class="navigation-spacer"></div>
+<div class="navigation-subtitle">Libraries</div>
+ <a href="libraries/Librarian.html" class="navigation-link">Librarian</a>
+ <a href="libraries/LUA.html" class="navigation-link">LUA</a>
+ <a href="libraries/AceVillain.html" class="navigation-link">AceVillain</a>
+  <div class="navigation-spacer"></div>
+	 </nav>
+	</div>
+
+	<span class="layout-title floating-title no-desktop">Menu</span>
+
+	<div class="layout-drawer-button">
+	 <i class="layout-drawer-button-icon menu-icon"></i>
+	</div>
+	<!-- END NAV // -->
+
+  <!-- BEGIN CONTENT // -->
+  <div class="layout-content">
+
+<section style="padding:0;">
+<div class="grid">
+<div class="cell cell-12-col">
+<div class="container">
+  <div class="comic">
+  <div class="card">
+  <div class="card-header flex--expand">
+  <div class="card-header-title flex--centered">
+  <span class="badge" data-badge="Module">SVUI_Core</span>
+  </div>
+  </div>
+  <div class="card-actions flex--expand">
+  <div class="card-header-subtitle flex--centered">SVUI is our global addon object.</div>
+  </div>
+  <div class="card-section">
+  <div class="section-dialog">
+  <h4 class="section-label">Info:</h4>
+  <ul>
+    <li> SuperVillain UI Core Module.</li>
+        <li><strong>Release</strong>: 1.0.0</li>
+        <li><strong>Author</strong>: Steven Jackson (2014)</li>
+  <hr />
+  </ul>
+  <h5 class="section-label">Construct:</h5>
+      <pre class="example">
+    <span class="comment">-- Every other file will set a reference to the addon using this variable. Here is how we set it.
+</span>
+    <span class="comment">-- METHOD 1 ----------------------------------------------------------------
+</span>    <span class="comment">-- if we are setting this inside the core.lua file then use this method
+</span>    <span class="keyword">local</span> global = <span class="string">"SVUI_Global"</span>    <span class="comment">-- reference to SavedVariables
+</span>    <span class="keyword">local</span> errors = <span class="string">"SVUI_Errors"</span>    <span class="comment">-- reference to SavedVariables
+</span>    <span class="keyword">local</span> private = <span class="string">"SVUI_Private"</span>  <span class="comment">-- reference to SavedVariables
+</span>    <span class="keyword">local</span> media = <span class="string">"SVUI_Media"</span>      <span class="comment">-- reference to SavedVariables
+</span>    <span class="keyword">local</span> shared = <span class="string">"SVUI_Shared"</span>    <span class="comment">-- reference to SavedVariables
+</span>
+    <span class="keyword">local</span> Registry = Librarian(<span class="string">"Registry"</span>)  <span class="comment">-- now pull down the Registry object
+</span>    <span class="comment">-- finally we use the 'NewCore' function specifically for this
+</span>    <span class="keyword">local</span> SV = Registry:NewCore(global, errors, private, media, shared)
+
+    <span class="comment">-- METHOD 2 ----------------------------------------------------------------
+</span>    <span class="comment">-- if we are setting the variable in any other file then use this method
+</span>    <span class="keyword">local</span> SV = _G[<span class="string">'SVUI'</span>]</pre>
+  <hr />
+  <h5 class="section-label">Summary:</h5>
+  <div style="padding:6px 0px;"><a href="#Messages" style="color:#ff5500">Jump To: Messages &#8921;</a></div>
+  <table class="function_list">
+	<tr>
+	<td class="name" nowrap><a href="#SCTMessage">SCTMessage (message, red, green, blue, displayType)</a></td>
+	<td class="summary">Send messages to the scrolling message frame (combat text).</td>
+	</tr>
+	<tr>
+	<td class="name" nowrap><a href="#AddonMessage">AddonMessage (message)</a></td>
+	<td class="summary">Send messages to the chat frame prefixed with the addon branding.</td>
+	</tr>
+	<tr>
+	<td class="name" nowrap><a href="#CharacterMessage">CharacterMessage (message)</a></td>
+	<td class="summary">Send messages to the chat frame as if they came from your character.</td>
+	</tr>
+  </table>
+  <div style="padding:6px 0px;"><a href="#Utilities" style="color:#ff5500">Jump To: Utilities &#8921;</a></div>
+  <table class="function_list">
+	<tr>
+	<td class="name" nowrap><a href="#fubar">fubar ()</a></td>
+	<td class="summary">Dummy function used to override existing methods, effectively killing them.</td>
+	</tr>
+	<tr>
+	<td class="name" nowrap><a href="#StaticPopup_Show">StaticPopup_Show (arg)</a></td>
+	<td class="summary">Request specific &lsquo;Static Popup&rsquo; windows.</td>
+	</tr>
+	<tr>
+	<td class="name" nowrap><a href="#ResetAllUI">ResetAllUI ()</a></td>
+	<td class="summary">Reset all SVUI created settings to defaults.</td>
+	</tr>
+	<tr>
+	<td class="name" nowrap><a href="#ResetUI">ResetUI ()</a></td>
+	<td class="summary">Reset layout positions back to their default.</td>
+	</tr>
+	<tr>
+	<td class="name" nowrap><a href="#ToggleConfig">ToggleConfig ()</a></td>
+	<td class="summary">Open the config menu (&lsquo;/sv&rsquo;).</td>
+	</tr>
+	<tr>
+	<td class="name" nowrap><a href="#VersionCheck">VersionCheck ()</a></td>
+	<td class="summary">Checks to see which (if any) version of the core that the client has installed.</td>
+	</tr>
+	<tr>
+	<td class="name" nowrap><a href="#RefreshEverything">RefreshEverything ()</a></td>
+	<td class="summary">Reloads all current packages and modules.</td>
+	</tr>
+  </table>
+  <div style="padding:6px 0px;"><a href="#media_Functions" style="color:#ff5500">Jump To: media Functions&#8921;</a></div>
+  <table class="function_list">
+	<tr>
+	<td class="name" nowrap><a href="#ColorGradient">ColorGradient (percentage, ...)</a></td>
+	<td class="summary">Returns a color value based on percentages.</td>
+	</tr>
+	<tr>
+	<td class="name" nowrap><a href="#HexColor">HexColor (red, green, blue)</a></td>
+	<td class="summary">Returns a hexadecimal color value.</td>
+	</tr>
+	<tr>
+	<td class="name" nowrap><a href="#FontManager">FontManager (obj, template, abstract, sizeMod, styleOverride, red, green, blue)</a></td>
+	<td class="summary">Adds a font object to the custom SVUI font manager.</td>
+	</tr>
+	<tr>
+	<td class="name" nowrap><a href="#GenerateFontOptionGroup">GenerateFontOptionGroup (groupName, groupCount, groupOverview, groupList)</a></td>
+	<td class="summary">Create an add-in set of specific font configuration options.</td>
+	</tr>
+  </table>
+  <hr />
+  <br />
+  <br />
+    <h6 class="section-label" id="Messages">Messages
+
+          <small>
+           Addon Message Handlers
+        </small>
+    </h6>
+    <dl class="function">
+    <dt id="SCTMessage">
+    <strong>SCTMessage (message, red, green, blue, displayType)</strong>
+    </dt>
+    <dd>
+    Send messages to the scrolling message frame (combat text).
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Parameters:</strong></div>
+<table>
+<tbody>
+        <tr><td style="width:20% !important;"><strong>message</strong><td>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+         The dialog to be displayed.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>red</strong><td>
+         Text coloring, red value.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>green</strong><td>
+         Text coloring, green value.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>blue</strong><td>
+         Text coloring, blue value.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>displayType</strong><td>
+         Special animation type (STICKY, CRITICAL or nil).
+        </td></tr>
+</tbody></table>
+
+
+
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Usage:</strong></div>
+    <ul>
+        <pre class="example">SV:SCTMessage(<span class="string">'My message'</span>, <span class="number">0.1</span>, <span class="number">0.2</span>, <span class="number">0.3</span>, <span class="string">'STICKY'</span>)</pre>
+    </ul>
+
+  </dd>
+    <dt id="AddonMessage">
+    <strong>AddonMessage (message)</strong>
+    </dt>
+    <dd>
+    Send messages to the chat frame prefixed with the addon branding.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Parameters:</strong></div>
+<table>
+<tbody>
+        <tr><td style="width:20% !important;"><strong>message</strong><td>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+         The dialog to be displayed.
+        </td></tr>
+</tbody></table>
+
+
+
+
+
+  </dd>
+    <dt id="CharacterMessage">
+    <strong>CharacterMessage (message)</strong>
+    </dt>
+    <dd>
+    Send messages to the chat frame as if they came from your character.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Parameters:</strong></div>
+<table>
+<tbody>
+        <tr><td style="width:20% !important;"><strong>message</strong><td>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+         The dialog to be displayed.
+        </td></tr>
+</tbody></table>
+
+
+
+
+
+  </dd>
+  </dl>
+    <h6 class="section-label" id="Utilities">Utilities
+
+          <small>
+           Utilities used and shared by the SVUI core.
+        </small>
+    </h6>
+    <dl class="function">
+    <dt id="fubar">
+    <strong>fubar ()</strong>
+    </dt>
+    <dd>
+    Dummy function used to override existing methods, effectively killing them.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Returns:</strong></div>
+    <ol>
+
+        nothing.
+    </ol>
+
+
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Usage:</strong></div>
+    <ul>
+        <pre class="example">
+   <span class="comment">-- Kill a function
+</span>   SomeObject.some_function = SV.fubar</pre>
+    </ul>
+
+  </dd>
+    <dt id="StaticPopup_Show">
+    <strong>StaticPopup_Show (arg)</strong>
+    </dt>
+    <dd>
+    Request specific &lsquo;Static Popup&rsquo; windows.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Parameters:</strong></div>
+<table>
+<tbody>
+        <tr><td style="width:20% !important;"><strong>arg</strong><td>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+         Name of the popup
+        </td></tr>
+</tbody></table>
+
+
+
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Usage:</strong></div>
+    <ul>
+        <pre class="example">
+   <span class="comment">-- Open the 'Reload UI' popup
+</span>   SV:StaticPopup_Show(<span class="string">'RL_CLIENT'</span>)</pre>
+    </ul>
+
+  </dd>
+    <dt id="ResetAllUI">
+    <strong>ResetAllUI ()</strong>
+    </dt>
+    <dd>
+    Reset all SVUI created settings to defaults.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+
+
+
+
+
+  </dd>
+    <dt id="ResetUI">
+    <strong>ResetUI ()</strong>
+    </dt>
+    <dd>
+    Reset layout positions back to their default.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+
+
+
+
+
+  </dd>
+    <dt id="ToggleConfig">
+    <strong>ToggleConfig ()</strong>
+    </dt>
+    <dd>
+    Open the config menu (&lsquo;/sv&rsquo;).
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+
+
+
+
+
+  </dd>
+    <dt id="VersionCheck">
+    <strong>VersionCheck ()</strong>
+    </dt>
+    <dd>
+    Checks to see which (if any) version of the core that the client has installed.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+
+
+
+
+
+  </dd>
+    <dt id="RefreshEverything">
+    <strong>RefreshEverything ()</strong>
+    </dt>
+    <dd>
+    Reloads all current packages and modules.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+
+
+
+
+
+  </dd>
+  </dl>
+    <h6 class="section-label" id="media_Functions">media Functions
+
+    </h6>
+    <dl class="function">
+    <dt id="ColorGradient">
+    <strong>ColorGradient (percentage, ...)</strong>
+    </dt>
+    <dd>
+    Returns a color value based on percentages.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Parameters:</strong></div>
+<table>
+<tbody>
+        <tr><td style="width:20% !important;"><strong>percentage</strong><td>
+            <span class="types"><span class="type">number</span></span>
+         The needed gradient percent.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>...</strong><td>
+         (vararg) remaining arguments are up to 3 sets of numeric color values (r,g,b).
+        </td></tr>
+</tbody></table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Returns:</strong></div>
+    <ol>
+
+        red value, green value, blue value
+    </ol>
+
+
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Usage:</strong></div>
+    <ul>
+        <pre class="example">SV:ColorGradient(<span class="number">50</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">0</span>)</pre>
+    </ul>
+
+  </dd>
+    <dt id="HexColor">
+    <strong>HexColor (red, green, blue)</strong>
+    </dt>
+    <dd>
+    Returns a hexadecimal color value.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Parameters:</strong></div>
+<table>
+<tbody>
+        <tr><td style="width:20% !important;"><strong>red</strong><td>
+            <span class="types"><span class="type">number</span></span>
+         Color, red value.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>green</strong><td>
+            <span class="types"><span class="type">number</span></span>
+         Color, green value.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>blue</strong><td>
+            <span class="types"><span class="type">number</span></span>
+         Color, blue value.
+        </td></tr>
+</tbody></table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Returns:</strong></div>
+    <ol>
+
+        Hexadecimal string color
+    </ol>
+
+
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Usage:</strong></div>
+    <ul>
+        <pre class="example">SV:HexColor(<span class="number">0.1</span>, <span class="number">0.2</span>, <span class="number">0.3</span>)</pre>
+    </ul>
+
+  </dd>
+    <dt id="FontManager">
+    <strong>FontManager (obj, template, abstract, sizeMod, styleOverride, red, green, blue)</strong>
+    </dt>
+    <dd>
+    Adds a font object to the custom SVUI font manager.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Parameters:</strong></div>
+<table>
+<tbody>
+        <tr><td style="width:20% !important;"><strong>obj</strong><td>
+         Font object.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>template</strong><td>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+         Internal name of the media-font to be assigned.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>abstract</strong><td>
+         A multi-use flag.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>sizeMod</strong><td>
+         Font size override.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>styleOverride</strong><td>
+         Outline override.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>red</strong><td>
+            <span class="types"><span class="type">number</span></span>
+         Color, red value.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>green</strong><td>
+            <span class="types"><span class="type">number</span></span>
+         Color, green value.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>blue</strong><td>
+            <span class="types"><span class="type">number</span></span>
+         Color, blue value.
+        </td></tr>
+</tbody></table>
+
+
+
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Usage:</strong></div>
+    <ul>
+        <pre class="example">SV:FontManager(FontObject, <span class="string">'default'</span>, <span class="keyword">false</span>, <span class="keyword">false</span>, <span class="string">'OUTLINE'</span>, <span class="number">1</span>, <span class="number">1</span>, <span class="number">1</span>)</pre>
+    </ul>
+
+  </dd>
+    <dt id="GenerateFontOptionGroup">
+    <strong>GenerateFontOptionGroup (groupName, groupCount, groupOverview, groupList)</strong>
+    </dt>
+    <dd>
+    Create an add-in set of specific font configuration options.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Parameters:</strong></div>
+<table>
+<tbody>
+        <tr><td style="width:20% !important;"><strong>groupName</strong><td>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+         Options group to insert into.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>groupCount</strong><td>
+            <span class="types"><span class="type">number</span></span>
+         Option order for this option.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>groupOverview</strong><td>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+         Option group name for this option.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>groupList</strong><td>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
+         Array of relevant font data.
+        </td></tr>
+</tbody></table>
+
+
+
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Usage:</strong></div>
+    <ul>
+        <pre class="example">SV:GenerateFontOptionGroup(groupName, groupCount, groupOverview, groupList)</pre>
+    </ul>
+
+  </dd>
+  </dl>
+  </div>
+  </div>
+  </div>
+  </div>
+</div>
+</div>
+</div>
+</section>
+</div>
+<!-- END CONTENT -->
+
+<!-- BEGIN FOOTER // -->
+<footer>
+  <div class="right-section">
+    <ul class="link-list">
+      <li>
+        <span style="color:#5fafff">Last updated 2015-08-26 14:32:22</span>
+      </li>
+    </ul>
+  </div>
+</footer>
+<!-- END FOOTER // -->
+
+</div>
+<!-- END LAYOUT -->
+
+<!-- Core JavaScript -->
+<script src="http://supervillainui.com/js/app.min.js"></script>
+<script src="http://supervillainui.com/js/extended/jquery-1.11.0.js"></script>
+<script src="http://supervillainui.com/js/extended/jquery.easing.min.js"></script>
+<script src="http://supervillainui.com/js/extended/jquery.swipebox.min.js"></script>
+</body>
+</html>
diff --git a/SVUI_!Core/guide/docs/ldoc.css b/SVUI_!Core/guide/docs/ldoc.css
new file mode 100644
index 0000000..2a8d337
--- /dev/null
+++ b/SVUI_!Core/guide/docs/ldoc.css
@@ -0,0 +1,9 @@
+@charset "UTF-8";body,html{width:100%}hr,main{display:block}.button,.checkbox,audio,canvas,img,svg,table td,video{vertical-align:middle}body,fieldset{margin:0}fieldset,hr{border:0;padding:0}blockquote,h1{line-height:1.35}.button,.fab,.icon,.ripple{overflow:hidden}.badge,.typography--text-nowrap{white-space:nowrap}.bigfoot-link-list a,.button,.layout-tab,.link-list a,.menu-item,.navigation-link,.tabs__tab,a{text-decoration:none}.card-section>.section-dialog>ul>li,.link-list,.menu{list-style:none}table,table.function_list,table.module_list{border-collapse:collapse}html{color:rgba(0,0,0,.87);height:100%;-ms-touch-action:manipulation;touch-action:manipulation}body{min-height:100%}hr{height:1px;border-top:1px solid #ccc;margin:1em 0}.fab,.fab .button-ripple,.icon,.icon .button-ripple,.ripple{border-radius:50%}textarea{resize:vertical}.browsehappy{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.accordion,.button,.card,.checkbox,.dropdown-menu,.icon,.item,.radio,.slider,.switch,.tabs__tab,a{-webkit-tap-highlight-color:transparent;-webkit-tap-highlight-color:rgba(255,255,255,0)}[hidden]{display:none!important}::-moz-selection{background:#b3d4fc;text-shadow:none}::selection{background:#b3d4fc;text-shadow:none}body,html{font-family:Helvetica,Arial,sans-serif;font-size:14px;font-weight:400;line-height:20px}h1,h2,h3,h4,h5,h6,p{margin:0;padding:0}h1,h2,h3,h4,h5,h6{margin-top:24px}h4,h5,h6,p{margin-bottom:16px}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-family:Roboto,Helvetica,Arial,sans-serif;font-weight:400;line-height:1.35;letter-spacing:-.02em;opacity:.54;font-size:.6em}blockquote,h4{font-family:Roboto,Helvetica,Arial,sans-serif;font-size:24px}ol,p,ul{font-size:14px}address,ol,p,ul{letter-spacing:0}address,h5{line-height:1}h6,ol,p,ul{font-weight:400;line-height:24px}a,h5{font-weight:500}h1{font-family:Roboto,Helvetica,Arial,sans-serif;font-size:56px;font-weight:400;letter-spacing:-.02em;margin-bottom:24px}h2{font-family:Roboto,Helvetica,Arial,sans-serif;font-size:45px;font-weight:400;line-height:48px;margin-bottom:24px}h3{font-family:Roboto,Helvetica,Arial,sans-serif;font-size:34px;font-weight:400;line-height:40px;margin-bottom:24px}h4{font-weight:400;line-height:32px;-moz-osx-font-smoothing:grayscale}h5{font-family:Roboto,Helvetica,Arial,sans-serif;font-size:20px;letter-spacing:.02em}h6{font-family:Roboto,Helvetica,Arial,sans-serif;font-size:16px;letter-spacing:.04em}p.preface{border-bottom:1px solid rgba(0,0,0,.12)}p.preface:last-child{margin-bottom:0}a{color:#ff4081}blockquote{position:relative;font-weight:300;font-style:italic;letter-spacing:.08em}blockquote:before{position:absolute;left:-.5em;content:'“'}blockquote:after{content:'”';margin-left:-.05em}mark{background-color:#f4ff81}dt{font-weight:700}address{font-size:12px;font-weight:400;font-style:normal}.typography--display-4,.typography--display-4-color-contrast{font-family:Roboto,Helvetica,Arial,sans-serif;font-size:112px;font-weight:300;line-height:1;letter-spacing:-.04em}.typography--display-4-color-contrast{opacity:.54}.typography--display-3,.typography--display-3-color-contrast{font-size:56px;font-weight:400;line-height:1.35;letter-spacing:-.02em}.typography--display-3{font-family:Roboto,Helvetica,Arial,sans-serif}.typography--display-3-color-contrast{font-family:Roboto,Helvetica,Arial,sans-serif;opacity:.54}.typography--display-2,.typography--display-2-color-contrast{font-family:Roboto,Helvetica,Arial,sans-serif;font-weight:400;font-size:45px;line-height:48px}.typography--display-2-color-contrast{opacity:.54}.typography--display-1{font-family:Roboto,Helvetica,Arial,sans-serif;font-size:34px;font-weight:400;line-height:40px}.typography--display-1-color-contrast{font-family:Roboto,Helvetica,Arial,sans-serif;font-size:34px;font-weight:400;line-height:40px;opacity:.54}.typography--headline,.typography--headline-color-contrast{font-family:Roboto,Helvetica,Arial,sans-serif;font-weight:400;line-height:32px;-moz-osx-font-smoothing:grayscale}.typography--headline{font-size:24px}.typography--headline-color-contrast{font-size:24px;opacity:.87}.typography--title,.typography--title-color-contrast{font-size:20px;font-weight:500;line-height:1;letter-spacing:.02em}.typography--title{font-family:Roboto,Helvetica,Arial,sans-serif}.typography--title-color-contrast{font-family:Roboto,Helvetica,Arial,sans-serif;opacity:.87}.typography--subhead,.typography--subhead-color-contrast{font-family:Roboto,Helvetica,Arial,sans-serif;line-height:24px;font-size:16px;font-weight:400;letter-spacing:.04em}.typography--subhead-color-contrast{opacity:.87}.typography--body-2{font-size:14px;font-weight:700;line-height:24px;letter-spacing:0}.typography--body-2-color-contrast{font-size:14px;font-weight:700;line-height:24px;letter-spacing:0;opacity:.87}.typography--body-1,.typography--body-1-color-contrast{line-height:24px;letter-spacing:0;font-size:14px;font-weight:400}.typography--body-1-color-contrast{opacity:.87}.typography--body-2-force-preferred-font{font-family:Roboto,Helvetica,Arial,sans-serif;font-size:14px;font-weight:500;line-height:24px;letter-spacing:0}.typography--body-2-force-preferred-font-color-contrast{font-family:Roboto,Helvetica,Arial,sans-serif;font-size:14px;font-weight:500;line-height:24px;letter-spacing:0;opacity:.87}.typography--body-1-force-preferred-font,.typography--body-1-force-preferred-font-color-contrast{font-family:Roboto,Helvetica,Arial,sans-serif;font-size:14px;font-weight:400;line-height:24px;letter-spacing:0}.typography--body-1-force-preferred-font-color-contrast{opacity:.87}.typography--caption,.typography--caption-color-contrast,.typography--caption-force-preferred-font,.typography--caption-force-preferred-font-color-contrast{font-size:12px;font-weight:400;line-height:1;letter-spacing:0}.typography--caption-force-preferred-font{font-family:Roboto,Helvetica,Arial,sans-serif}.typography--caption-color-contrast{opacity:.54}.typography--caption-force-preferred-font-color-contrast{font-family:Roboto,Helvetica,Arial,sans-serif;opacity:.54}.typography--button,.typography--button-color-contrast,.typography--menu,.typography--menu-color-contrast{letter-spacing:0;font-family:Roboto,Helvetica,Arial,sans-serif;font-size:14px;font-weight:500;line-height:1}.typography--menu-color-contrast{opacity:.87}.typography--button{text-transform:uppercase}.typography--button-color-contrast{text-transform:uppercase;opacity:.87}.typography--text-left{text-align:left}.typography--text-right{text-align:right}.typography--text-center{text-align:center}.typography--text-justify{text-align:justify}.typography--text-lowercase{text-transform:lowercase}.button,.layout-tab,.tabs__tab,.typography--text-uppercase{text-transform:uppercase}.typography--text-capitalize{text-transform:capitalize}.typography--font-thin{font-weight:200!important}.typography--font-light{font-weight:300!important}.typography--font-regular{font-weight:400!important}.typography--font-medium{font-weight:500!important}.typography--font-bold{font-weight:700!important}.typography--font-black{font-weight:900!important}.color-text--red{color:#f44336!important}.color--red{background-color:#f44336!important}.color-text--red-50{color:#ffebee!important}.color--red-50{background-color:#ffebee!important}.color-text--red-100{color:#ffcdd2!important}.color--red-100{background-color:#ffcdd2!important}.color-text--red-200{color:#ef9a9a!important}.color--red-200{background-color:#ef9a9a!important}.color-text--red-300{color:#e57373!important}.color--red-300{background-color:#e57373!important}.color-text--red-400{color:#ef5350!important}.color--red-400{background-color:#ef5350!important}.color-text--red-500{color:#f44336!important}.color--red-500{background-color:#f44336!important}.color-text--red-600{color:#e53935!important}.color--red-600{background-color:#e53935!important}.color-text--red-700{color:#d32f2f!important}.color--red-700{background-color:#d32f2f!important}.color-text--red-800{color:#c62828!important}.color--red-800{background-color:#c62828!important}.color-text--red-900{color:#b71c1c!important}.color--red-900{background-color:#b71c1c!important}.color-text--red-A100{color:#ff8a80!important}.color--red-A100{background-color:#ff8a80!important}.color-text--red-A200{color:#ff5252!important}.color--red-A200{background-color:#ff5252!important}.color-text--red-A400{color:#ff1744!important}.color--red-A400{background-color:#ff1744!important}.color-text--red-A700{color:#d50000!important}.color--red-A700{background-color:#d50000!important}.color-text--pink{color:#e91e63!important}.color--pink{background-color:#e91e63!important}.color-text--pink-50{color:#fce4ec!important}.color--pink-50{background-color:#fce4ec!important}.color-text--pink-100{color:#f8bbd0!important}.color--pink-100{background-color:#f8bbd0!important}.color-text--pink-200{color:#f48fb1!important}.color--pink-200{background-color:#f48fb1!important}.color-text--pink-300{color:#f06292!important}.color--pink-300{background-color:#f06292!important}.color-text--pink-400{color:#ec407a!important}.color--pink-400{background-color:#ec407a!important}.color-text--pink-500{color:#e91e63!important}.color--pink-500{background-color:#e91e63!important}.color-text--pink-600{color:#d81b60!important}.color--pink-600{background-color:#d81b60!important}.color-text--pink-700{color:#c2185b!important}.color--pink-700{background-color:#c2185b!important}.color-text--pink-800{color:#ad1457!important}.color--pink-800{background-color:#ad1457!important}.color-text--pink-900{color:#880e4f!important}.color--pink-900{background-color:#880e4f!important}.color-text--pink-A100{color:#ff80ab!important}.color--pink-A100{background-color:#ff80ab!important}.color-text--pink-A200{color:#ff4081!important}.color--pink-A200{background-color:#ff4081!important}.color-text--pink-A400{color:#f50057!important}.color--pink-A400{background-color:#f50057!important}.color-text--pink-A700{color:#c51162!important}.color--pink-A700{background-color:#c51162!important}.color-text--purple{color:#9c27b0!important}.color--purple{background-color:#9c27b0!important}.color-text--purple-50{color:#f3e5f5!important}.color--purple-50{background-color:#f3e5f5!important}.color-text--purple-100{color:#e1bee7!important}.color--purple-100{background-color:#e1bee7!important}.color-text--purple-200{color:#ce93d8!important}.color--purple-200{background-color:#ce93d8!important}.color-text--purple-300{color:#ba68c8!important}.color--purple-300{background-color:#ba68c8!important}.color-text--purple-400{color:#ab47bc!important}.color--purple-400{background-color:#ab47bc!important}.color-text--purple-500{color:#9c27b0!important}.color--purple-500{background-color:#9c27b0!important}.color-text--purple-600{color:#8e24aa!important}.color--purple-600{background-color:#8e24aa!important}.color-text--purple-700{color:#7b1fa2!important}.color--purple-700{background-color:#7b1fa2!important}.color-text--purple-800{color:#6a1b9a!important}.color--purple-800{background-color:#6a1b9a!important}.color-text--purple-900{color:#4a148c!important}.color--purple-900{background-color:#4a148c!important}.color-text--purple-A100{color:#ea80fc!important}.color--purple-A100{background-color:#ea80fc!important}.color-text--purple-A200{color:#e040fb!important}.color--purple-A200{background-color:#e040fb!important}.color-text--purple-A400{color:#d500f9!important}.color--purple-A400{background-color:#d500f9!important}.color-text--purple-A700{color:#a0f!important}.color--purple-A700{background-color:#a0f!important}.color-text--deep-purple{color:#673ab7!important}.color--deep-purple{background-color:#673ab7!important}.color-text--deep-purple-50{color:#ede7f6!important}.color--deep-purple-50{background-color:#ede7f6!important}.color-text--deep-purple-100{color:#d1c4e9!important}.color--deep-purple-100{background-color:#d1c4e9!important}.color-text--deep-purple-200{color:#b39ddb!important}.color--deep-purple-200{background-color:#b39ddb!important}.color-text--deep-purple-300{color:#9575cd!important}.color--deep-purple-300{background-color:#9575cd!important}.color-text--deep-purple-400{color:#7e57c2!important}.color--deep-purple-400{background-color:#7e57c2!important}.color-text--deep-purple-500{color:#673ab7!important}.color--deep-purple-500{background-color:#673ab7!important}.color-text--deep-purple-600{color:#5e35b1!important}.color--deep-purple-600{background-color:#5e35b1!important}.color-text--deep-purple-700{color:#512da8!important}.color--deep-purple-700{background-color:#512da8!important}.color-text--deep-purple-800{color:#4527a0!important}.color--deep-purple-800{background-color:#4527a0!important}.color-text--deep-purple-900{color:#311b92!important}.color--deep-purple-900{background-color:#311b92!important}.color-text--deep-purple-A100{color:#b388ff!important}.color--deep-purple-A100{background-color:#b388ff!important}.color-text--deep-purple-A200{color:#7c4dff!important}.color--deep-purple-A200{background-color:#7c4dff!important}.color-text--deep-purple-A400{color:#651fff!important}.color--deep-purple-A400{background-color:#651fff!important}.color-text--deep-purple-A700{color:#6200ea!important}.color--deep-purple-A700{background-color:#6200ea!important}.color-text--indigo{color:#3f51b5!important}.color--indigo{background-color:#3f51b5!important}.color-text--indigo-50{color:#e8eaf6!important}.color--indigo-50{background-color:#e8eaf6!important}.color-text--indigo-100{color:#c5cae9!important}.color--indigo-100{background-color:#c5cae9!important}.color-text--indigo-200{color:#9fa8da!important}.color--indigo-200{background-color:#9fa8da!important}.color-text--indigo-300{color:#7986cb!important}.color--indigo-300{background-color:#7986cb!important}.color-text--indigo-400{color:#5c6bc0!important}.color--indigo-400{background-color:#5c6bc0!important}.color-text--indigo-500{color:#3f51b5!important}.color--indigo-500{background-color:#3f51b5!important}.color-text--indigo-600{color:#3949ab!important}.color--indigo-600{background-color:#3949ab!important}.color-text--indigo-700{color:#303f9f!important}.color--indigo-700{background-color:#303f9f!important}.color-text--indigo-800{color:#283593!important}.color--indigo-800{background-color:#283593!important}.color-text--indigo-900{color:#1a237e!important}.color--indigo-900{background-color:#1a237e!important}.color-text--indigo-A100{color:#8c9eff!important}.color--indigo-A100{background-color:#8c9eff!important}.color-text--indigo-A200{color:#536dfe!important}.color--indigo-A200{background-color:#536dfe!important}.color-text--indigo-A400{color:#3d5afe!important}.color--indigo-A400{background-color:#3d5afe!important}.color-text--indigo-A700{color:#304ffe!important}.color--indigo-A700{background-color:#304ffe!important}.color-text--blue{color:#2196f3!important}.color--blue{background-color:#2196f3!important}.color-text--blue-50{color:#e3f2fd!important}.color--blue-50{background-color:#e3f2fd!important}.color-text--blue-100{color:#bbdefb!important}.color--blue-100{background-color:#bbdefb!important}.color-text--blue-200{color:#90caf9!important}.color--blue-200{background-color:#90caf9!important}.color-text--blue-300{color:#64b5f6!important}.color--blue-300{background-color:#64b5f6!important}.color-text--blue-400{color:#42a5f5!important}.color--blue-400{background-color:#42a5f5!important}.color-text--blue-500{color:#2196f3!important}.color--blue-500{background-color:#2196f3!important}.color-text--blue-600{color:#1e88e5!important}.color--blue-600{background-color:#1e88e5!important}.color-text--blue-700{color:#1976d2!important}.color--blue-700{background-color:#1976d2!important}.color-text--blue-800{color:#1565c0!important}.color--blue-800{background-color:#1565c0!important}.color-text--blue-900{color:#0d47a1!important}.color--blue-900{background-color:#0d47a1!important}.color-text--blue-A100{color:#82b1ff!important}.color--blue-A100{background-color:#82b1ff!important}.color-text--blue-A200{color:#448aff!important}.color--blue-A200{background-color:#448aff!important}.color-text--blue-A400{color:#2979ff!important}.color--blue-A400{background-color:#2979ff!important}.color-text--blue-A700{color:#2962ff!important}.color--blue-A700{background-color:#2962ff!important}.color-text--light-blue{color:#03a9f4!important}.color--light-blue{background-color:#03a9f4!important}.color-text--light-blue-50{color:#e1f5fe!important}.color--light-blue-50{background-color:#e1f5fe!important}.color-text--light-blue-100{color:#b3e5fc!important}.color--light-blue-100{background-color:#b3e5fc!important}.color-text--light-blue-200{color:#81d4fa!important}.color--light-blue-200{background-color:#81d4fa!important}.color-text--light-blue-300{color:#4fc3f7!important}.color--light-blue-300{background-color:#4fc3f7!important}.color-text--light-blue-400{color:#29b6f6!important}.color--light-blue-400{background-color:#29b6f6!important}.color-text--light-blue-500{color:#03a9f4!important}.color--light-blue-500{background-color:#03a9f4!important}.color-text--light-blue-600{color:#039be5!important}.color--light-blue-600{background-color:#039be5!important}.color-text--light-blue-700{color:#0288d1!important}.color--light-blue-700{background-color:#0288d1!important}.color-text--light-blue-800{color:#0277bd!important}.color--light-blue-800{background-color:#0277bd!important}.color-text--light-blue-900{color:#01579b!important}.color--light-blue-900{background-color:#01579b!important}.color-text--light-blue-A100{color:#80d8ff!important}.color--light-blue-A100{background-color:#80d8ff!important}.color-text--light-blue-A200{color:#40c4ff!important}.color--light-blue-A200{background-color:#40c4ff!important}.color-text--light-blue-A400{color:#00b0ff!important}.color--light-blue-A400{background-color:#00b0ff!important}.color-text--light-blue-A700{color:#0091ea!important}.color--light-blue-A700{background-color:#0091ea!important}.color-text--cyan{color:#00bcd4!important}.color--cyan{background-color:#00bcd4!important}.color-text--cyan-50{color:#e0f7fa!important}.color--cyan-50{background-color:#e0f7fa!important}.color-text--cyan-100{color:#b2ebf2!important}.color--cyan-100{background-color:#b2ebf2!important}.color-text--cyan-200{color:#80deea!important}.color--cyan-200{background-color:#80deea!important}.color-text--cyan-300{color:#4dd0e1!important}.color--cyan-300{background-color:#4dd0e1!important}.color-text--cyan-400{color:#26c6da!important}.color--cyan-400{background-color:#26c6da!important}.color-text--cyan-500{color:#00bcd4!important}.color--cyan-500{background-color:#00bcd4!important}.color-text--cyan-600{color:#00acc1!important}.color--cyan-600{background-color:#00acc1!important}.color-text--cyan-700{color:#0097a7!important}.color--cyan-700{background-color:#0097a7!important}.color-text--cyan-800{color:#00838f!important}.color--cyan-800{background-color:#00838f!important}.color-text--cyan-900{color:#006064!important}.color--cyan-900{background-color:#006064!important}.color-text--cyan-A100{color:#84ffff!important}.color--cyan-A100{background-color:#84ffff!important}.color-text--cyan-A200{color:#18ffff!important}.color--cyan-A200{background-color:#18ffff!important}.color-text--cyan-A400{color:#00e5ff!important}.color--cyan-A400{background-color:#00e5ff!important}.color-text--cyan-A700{color:#00b8d4!important}.color--cyan-A700{background-color:#00b8d4!important}.color-text--teal{color:#009688!important}.color--teal{background-color:#009688!important}.color-text--teal-50{color:#e0f2f1!important}.color--teal-50{background-color:#e0f2f1!important}.color-text--teal-100{color:#b2dfdb!important}.color--teal-100{background-color:#b2dfdb!important}.color-text--teal-200{color:#80cbc4!important}.color--teal-200{background-color:#80cbc4!important}.color-text--teal-300{color:#4db6ac!important}.color--teal-300{background-color:#4db6ac!important}.color-text--teal-400{color:#26a69a!important}.color--teal-400{background-color:#26a69a!important}.color-text--teal-500{color:#009688!important}.color--teal-500{background-color:#009688!important}.color-text--teal-600{color:#00897b!important}.color--teal-600{background-color:#00897b!important}.color-text--teal-700{color:#00796b!important}.color--teal-700{background-color:#00796b!important}.color-text--teal-800{color:#00695c!important}.color--teal-800{background-color:#00695c!important}.color-text--teal-900{color:#004d40!important}.color--teal-900{background-color:#004d40!important}.color-text--teal-A100{color:#a7ffeb!important}.color--teal-A100{background-color:#a7ffeb!important}.color-text--teal-A200{color:#64ffda!important}.color--teal-A200{background-color:#64ffda!important}.color-text--teal-A400{color:#1de9b6!important}.color--teal-A400{background-color:#1de9b6!important}.color-text--teal-A700{color:#00bfa5!important}.color--teal-A700{background-color:#00bfa5!important}.color-text--green{color:#4caf50!important}.color--green{background-color:#4caf50!important}.color-text--green-50{color:#e8f5e9!important}.color--green-50{background-color:#e8f5e9!important}.color-text--green-100{color:#c8e6c9!important}.color--green-100{background-color:#c8e6c9!important}.color-text--green-200{color:#a5d6a7!important}.color--green-200{background-color:#a5d6a7!important}.color-text--green-300{color:#81c784!important}.color--green-300{background-color:#81c784!important}.color-text--green-400{color:#66bb6a!important}.color--green-400{background-color:#66bb6a!important}.color-text--green-500{color:#4caf50!important}.color--green-500{background-color:#4caf50!important}.color-text--green-600{color:#43a047!important}.color--green-600{background-color:#43a047!important}.color-text--green-700{color:#388e3c!important}.color--green-700{background-color:#388e3c!important}.color-text--green-800{color:#2e7d32!important}.color--green-800{background-color:#2e7d32!important}.color-text--green-900{color:#1b5e20!important}.color--green-900{background-color:#1b5e20!important}.color-text--green-A100{color:#b9f6ca!important}.color--green-A100{background-color:#b9f6ca!important}.color-text--green-A200{color:#69f0ae!important}.color--green-A200{background-color:#69f0ae!important}.color-text--green-A400{color:#00e676!important}.color--green-A400{background-color:#00e676!important}.color-text--green-A700{color:#00c853!important}.color--green-A700{background-color:#00c853!important}.color-text--light-green{color:#8bc34a!important}.color--light-green{background-color:#8bc34a!important}.color-text--light-green-50{color:#f1f8e9!important}.color--light-green-50{background-color:#f1f8e9!important}.color-text--light-green-100{color:#dcedc8!important}.color--light-green-100{background-color:#dcedc8!important}.color-text--light-green-200{color:#c5e1a5!important}.color--light-green-200{background-color:#c5e1a5!important}.color-text--light-green-300{color:#aed581!important}.color--light-green-300{background-color:#aed581!important}.color-text--light-green-400{color:#9ccc65!important}.color--light-green-400{background-color:#9ccc65!important}.color-text--light-green-500{color:#8bc34a!important}.color--light-green-500{background-color:#8bc34a!important}.color-text--light-green-600{color:#7cb342!important}.color--light-green-600{background-color:#7cb342!important}.color-text--light-green-700{color:#689f38!important}.color--light-green-700{background-color:#689f38!important}.color-text--light-green-800{color:#558b2f!important}.color--light-green-800{background-color:#558b2f!important}.color-text--light-green-900{color:#33691e!important}.color--light-green-900{background-color:#33691e!important}.color-text--light-green-A100{color:#ccff90!important}.color--light-green-A100{background-color:#ccff90!important}.color-text--light-green-A200{color:#b2ff59!important}.color--light-green-A200{background-color:#b2ff59!important}.color-text--light-green-A400{color:#76ff03!important}.color--light-green-A400{background-color:#76ff03!important}.color-text--light-green-A700{color:#64dd17!important}.color--light-green-A700{background-color:#64dd17!important}.color-text--lime{color:#cddc39!important}.color--lime{background-color:#cddc39!important}.color-text--lime-50{color:#f9fbe7!important}.color--lime-50{background-color:#f9fbe7!important}.color-text--lime-100{color:#f0f4c3!important}.color--lime-100{background-color:#f0f4c3!important}.color-text--lime-200{color:#e6ee9c!important}.color--lime-200{background-color:#e6ee9c!important}.color-text--lime-300{color:#dce775!important}.color--lime-300{background-color:#dce775!important}.color-text--lime-400{color:#d4e157!important}.color--lime-400{background-color:#d4e157!important}.color-text--lime-500{color:#cddc39!important}.color--lime-500{background-color:#cddc39!important}.color-text--lime-600{color:#c0ca33!important}.color--lime-600{background-color:#c0ca33!important}.color-text--lime-700{color:#afb42b!important}.color--lime-700{background-color:#afb42b!important}.color-text--lime-800{color:#9e9d24!important}.color--lime-800{background-color:#9e9d24!important}.color-text--lime-900{color:#827717!important}.color--lime-900{background-color:#827717!important}.color-text--lime-A100{color:#f4ff81!important}.color--lime-A100{background-color:#f4ff81!important}.color-text--lime-A200{color:#eeff41!important}.color--lime-A200{background-color:#eeff41!important}.color-text--lime-A400{color:#c6ff00!important}.color--lime-A400{background-color:#c6ff00!important}.color-text--lime-A700{color:#aeea00!important}.color--lime-A700{background-color:#aeea00!important}.color-text--yellow{color:#ffeb3b!important}.color--yellow{background-color:#ffeb3b!important}.color-text--yellow-50{color:#fffde7!important}.color--yellow-50{background-color:#fffde7!important}.color-text--yellow-100{color:#fff9c4!important}.color--yellow-100{background-color:#fff9c4!important}.color-text--yellow-200{color:#fff59d!important}.color--yellow-200{background-color:#fff59d!important}.color-text--yellow-300{color:#fff176!important}.color--yellow-300{background-color:#fff176!important}.color-text--yellow-400{color:#ffee58!important}.color--yellow-400{background-color:#ffee58!important}.color-text--yellow-500{color:#ffeb3b!important}.color--yellow-500{background-color:#ffeb3b!important}.color-text--yellow-600{color:#fdd835!important}.color--yellow-600{background-color:#fdd835!important}.color-text--yellow-700{color:#fbc02d!important}.color--yellow-700{background-color:#fbc02d!important}.color-text--yellow-800{color:#f9a825!important}.color--yellow-800{background-color:#f9a825!important}.color-text--yellow-900{color:#f57f17!important}.color--yellow-900{background-color:#f57f17!important}.color-text--yellow-A100{color:#ffff8d!important}.color--yellow-A100{background-color:#ffff8d!important}.color-text--yellow-A200{color:#ff0!important}.color--yellow-A200{background-color:#ff0!important}.color-text--yellow-A400{color:#ffea00!important}.color--yellow-A400{background-color:#ffea00!important}.color-text--yellow-A700{color:#ffd600!important}.color--yellow-A700{background-color:#ffd600!important}.color-text--amber{color:#ffc107!important}.color--amber{background-color:#ffc107!important}.color-text--amber-50{color:#fff8e1!important}.color--amber-50{background-color:#fff8e1!important}.color-text--amber-100{color:#ffecb3!important}.color--amber-100{background-color:#ffecb3!important}.color-text--amber-200{color:#ffe082!important}.color--amber-200{background-color:#ffe082!important}.color-text--amber-300{color:#ffd54f!important}.color--amber-300{background-color:#ffd54f!important}.color-text--amber-400{color:#ffca28!important}.color--amber-400{background-color:#ffca28!important}.color-text--amber-500{color:#ffc107!important}.color--amber-500{background-color:#ffc107!important}.color-text--amber-600{color:#ffb300!important}.color--amber-600{background-color:#ffb300!important}.color-text--amber-700{color:#ffa000!important}.color--amber-700{background-color:#ffa000!important}.color-text--amber-800{color:#ff8f00!important}.color--amber-800{background-color:#ff8f00!important}.color-text--amber-900{color:#ff6f00!important}.color--amber-900{background-color:#ff6f00!important}.color-text--amber-A100{color:#ffe57f!important}.color--amber-A100{background-color:#ffe57f!important}.color-text--amber-A200{color:#ffd740!important}.color--amber-A200{background-color:#ffd740!important}.color-text--amber-A400{color:#ffc400!important}.color--amber-A400{background-color:#ffc400!important}.color-text--amber-A700{color:#ffab00!important}.color--amber-A700{background-color:#ffab00!important}.color-text--orange{color:#ff9800!important}.color--orange{background-color:#ff9800!important}.color-text--orange-50{color:#fff3e0!important}.color--orange-50{background-color:#fff3e0!important}.color-text--orange-100{color:#ffe0b2!important}.color--orange-100{background-color:#ffe0b2!important}.color-text--orange-200{color:#ffcc80!important}.color--orange-200{background-color:#ffcc80!important}.color-text--orange-300{color:#ffb74d!important}.color--orange-300{background-color:#ffb74d!important}.color-text--orange-400{color:#ffa726!important}.color--orange-400{background-color:#ffa726!important}.color-text--orange-500{color:#ff9800!important}.color--orange-500{background-color:#ff9800!important}.color-text--orange-600{color:#fb8c00!important}.color--orange-600{background-color:#fb8c00!important}.color-text--orange-700{color:#f57c00!important}.color--orange-700{background-color:#f57c00!important}.color-text--orange-800{color:#ef6c00!important}.color--orange-800{background-color:#ef6c00!important}.color-text--orange-900{color:#e65100!important}.color--orange-900{background-color:#e65100!important}.color-text--orange-A100{color:#ffd180!important}.color--orange-A100{background-color:#ffd180!important}.color-text--orange-A200{color:#ffab40!important}.color--orange-A200{background-color:#ffab40!important}.color-text--orange-A400{color:#ff9100!important}.color--orange-A400{background-color:#ff9100!important}.color-text--orange-A700{color:#ff6d00!important}.color--orange-A700{background-color:#ff6d00!important}.color-text--deep-orange{color:#ff5722!important}.color--deep-orange{background-color:#ff5722!important}.color-text--deep-orange-50{color:#fbe9e7!important}.color--deep-orange-50{background-color:#fbe9e7!important}.color-text--deep-orange-100{color:#ffccbc!important}.color--deep-orange-100{background-color:#ffccbc!important}.color-text--deep-orange-200{color:#ffab91!important}.color--deep-orange-200{background-color:#ffab91!important}.color-text--deep-orange-300{color:#ff8a65!important}.color--deep-orange-300{background-color:#ff8a65!important}.color-text--deep-orange-400{color:#ff7043!important}.color--deep-orange-400{background-color:#ff7043!important}.color-text--deep-orange-500{color:#ff5722!important}.color--deep-orange-500{background-color:#ff5722!important}.color-text--deep-orange-600{color:#f4511e!important}.color--deep-orange-600{background-color:#f4511e!important}.color-text--deep-orange-700{color:#e64a19!important}.color--deep-orange-700{background-color:#e64a19!important}.color-text--deep-orange-800{color:#d84315!important}.color--deep-orange-800{background-color:#d84315!important}.color-text--deep-orange-900{color:#bf360c!important}.color--deep-orange-900{background-color:#bf360c!important}.color-text--deep-orange-A100{color:#ff9e80!important}.color--deep-orange-A100{background-color:#ff9e80!important}.color-text--deep-orange-A200{color:#ff6e40!important}.color--deep-orange-A200{background-color:#ff6e40!important}.color-text--deep-orange-A400{color:#ff3d00!important}.color--deep-orange-A400{background-color:#ff3d00!important}.color-text--deep-orange-A700{color:#dd2c00!important}.color--deep-orange-A700{background-color:#dd2c00!important}.color-text--brown{color:#795548!important}.color--brown{background-color:#795548!important}.color-text--brown-50{color:#efebe9!important}.color--brown-50{background-color:#efebe9!important}.color-text--brown-100{color:#d7ccc8!important}.color--brown-100{background-color:#d7ccc8!important}.color-text--brown-200{color:#bcaaa4!important}.color--brown-200{background-color:#bcaaa4!important}.color-text--brown-300{color:#a1887f!important}.color--brown-300{background-color:#a1887f!important}.color-text--brown-400{color:#8d6e63!important}.color--brown-400{background-color:#8d6e63!important}.color-text--brown-500{color:#795548!important}.color--brown-500{background-color:#795548!important}.color-text--brown-600{color:#6d4c41!important}.color--brown-600{background-color:#6d4c41!important}.color-text--brown-700{color:#5d4037!important}.color--brown-700{background-color:#5d4037!important}.color-text--brown-800{color:#4e342e!important}.color--brown-800{background-color:#4e342e!important}.color-text--brown-900{color:#3e2723!important}.color--brown-900{background-color:#3e2723!important}.color-text--grey{color:#9e9e9e!important}.color--grey{background-color:#9e9e9e!important}.color-text--grey-50{color:#fafafa!important}.color--grey-50{background-color:#fafafa!important}.color-text--grey-100{color:#f5f5f5!important}.color--grey-100{background-color:#f5f5f5!important}.color-text--grey-200{color:#eee!important}.color--grey-200{background-color:#eee!important}.color-text--grey-300{color:#e0e0e0!important}.color--grey-300{background-color:#e0e0e0!important}.color-text--grey-400{color:#bdbdbd!important}.color--grey-400{background-color:#bdbdbd!important}.color-text--grey-500{color:#9e9e9e!important}.color--grey-500{background-color:#9e9e9e!important}.color-text--grey-600{color:#757575!important}.color--grey-600{background-color:#757575!important}.color-text--grey-700{color:#616161!important}.color--grey-700{background-color:#616161!important}.color-text--grey-800{color:#424242!important}.color--grey-800{background-color:#424242!important}.color-text--grey-900{color:#212121!important}.color--grey-900{background-color:#212121!important}.color-text--blue-grey{color:#607d8b!important}.color--blue-grey{background-color:#607d8b!important}.color-text--blue-grey-50{color:#eceff1!important}.color--blue-grey-50{background-color:#eceff1!important}.color-text--blue-grey-100{color:#cfd8dc!important}.color--blue-grey-100{background-color:#cfd8dc!important}.color-text--blue-grey-200{color:#b0bec5!important}.color--blue-grey-200{background-color:#b0bec5!important}.color-text--blue-grey-300{color:#90a4ae!important}.color--blue-grey-300{background-color:#90a4ae!important}.color-text--blue-grey-400{color:#78909c!important}.color--blue-grey-400{background-color:#78909c!important}.color-text--blue-grey-500{color:#607d8b!important}.color--blue-grey-500{background-color:#607d8b!important}.color-text--blue-grey-600{color:#546e7a!important}.color--blue-grey-600{background-color:#546e7a!important}.color-text--blue-grey-700{color:#455a64!important}.color--blue-grey-700{background-color:#455a64!important}.color-text--blue-grey-800{color:#37474f!important}.color--blue-grey-800{background-color:#37474f!important}.color-text--blue-grey-900{color:#263238!important}.color--blue-grey-900{background-color:#263238!important}.color--black{background-color:#000!important}.color-text--black{color:#000!important}.color--white{background-color:#fff!important}.color-text--white{color:#fff!important}.color--primary{background-color:#3f51b5!important}.color--primary-contrast{background-color:#fff!important}.color--primary-dark{background-color:#303f9f!important}.color--accent{background-color:#ff4081!important}.color--accent-contrast{background-color:#fff!important}.color-text--primary{color:#3f51b5!important}.color-text--primary-contrast{color:#fff!important}.color-text--primary-dark{color:#303f9f!important}.color-text--accent{color:#ff4081!important}.color-text--accent-contrast{color:#fff!important}.ripple{background:#000;height:50px;left:0;opacity:0;pointer-events:none;position:absolute;top:0;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);width:50px}.ripple.is-animating{-webkit-transition:-webkit-transform .3s cubic-bezier(0,0,.2,1),width .3s cubic-bezier(0,0,.2,1),height .3s cubic-bezier(0,0,.2,1),opacity .6s cubic-bezier(0,0,.2,1);transition:transform .3s cubic-bezier(0,0,.2,1),width .3s cubic-bezier(0,0,.2,1),height .3s cubic-bezier(0,0,.2,1),opacity .6s cubic-bezier(0,0,.2,1)}.ripple.is-visible{opacity:.3}.animate-default,.animate-fast-out-slow-in{-webkit-transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(.4,0,.2,1)}.animate-linear-out-slow-in{-webkit-transition-timing-function:cubic-bezier(0,0,.2,1);transition-timing-function:cubic-bezier(0,0,.2,1)}.animate-fast-out-linear-in{-webkit-transition-timing-function:cubic-bezier(.4,0,1,1);transition-timing-function:cubic-bezier(.4,0,1,1)}.badge{position:relative;margin-right:24px}.badge:not([data-badge]){margin-right:auto}.badge[data-badge]:after{content:attr(data-badge);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-align-content:center;-ms-flex-line-pack:center;align-content:center;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;position:absolute;top:-11px;right:-24px;font-family:Roboto,Helvetica,Arial,sans-serif;font-weight:600;font-size:12px;width:22px;height:22px;border-radius:50%;background:#ff7700;color:#fff}.button,.fab{position:relative}.card,.layout{-webkit-box-direction:normal;-webkit-box-orient:vertical}.button .badge[data-badge]:after{top:-10px;right:-5px}.badge.no-background[data-badge]:after{color:#ff4081;background:rgba(255,255,255,.2);box-shadow:0 0 1px gray}.button{background:0 0;border:none;border-radius:2px;color:#000;height:36px;min-width:64px;padding:0 8px;display:inline-block;font-family:Roboto,Helvetica,Arial,sans-serif;font-size:14px;font-weight:500;letter-spacing:0;will-change:box-shadow,transform;-webkit-transition:box-shadow .2s cubic-bezier(.4,0,1,1),background-color .2s cubic-bezier(.4,0,.2,1),color .2s cubic-bezier(.4,0,.2,1);transition:box-shadow .2s cubic-bezier(.4,0,1,1),background-color .2s cubic-bezier(.4,0,.2,1),color .2s cubic-bezier(.4,0,.2,1);outline:0;cursor:pointer;text-align:center;line-height:36px}.button::-moz-focus-inner{border:0}.button:hover{background-color:rgba(158,158,158,.2)}.button:focus:not(:active){background-color:rgba(0,0,0,.12)}.button:active{background-color:rgba(158,158,158,.4)}.button.colored{color:#3f51b5}.button.colored:focus:not(:active){background-color:rgba(0,0,0,.12)}input.button[type=submit]{-webkit-appearance:none}.raised{background:rgba(158,158,158,.2);box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)}.raised:active{box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.2);background-color:rgba(158,158,158,.4)}.raised:focus:not(:active){box-shadow:0 0 8px rgba(0,0,0,.18),0 8px 16px rgba(0,0,0,.36);background-color:rgba(158,158,158,.4)}.raised.colored{background:#3f51b5;color:#fff}.raised.colored:active,.raised.colored:focus:not(:active),.raised.colored:hover{background-color:#3f51b5}.raised.colored .ripple{background:#fff}.fab{font-size:24px;height:56px;margin:auto;min-width:56px;width:56px;padding:0;background:rgba(158,158,158,.2);box-shadow:0 1px 1.5px 0 rgba(0,0,0,.12),0 1px 1px 0 rgba(0,0,0,.24);line-height:normal}.fab:active,.fab:focus:not(:active){background-color:rgba(158,158,158,.4)}.fab .material-icons{transform:translate(-12px,-12px);line-height:24px;width:24px}.fab .material-icons,.icon .material-icons{position:absolute;top:50%;left:50%;-webkit-transform:translate(-12px,-12px);-ms-transform:translate(-12px,-12px)}.fab.mini-fab{height:40px;min-width:40px;width:40px}.fab .button-ripple{-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000)}.fab:active{box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.2)}.fab:focus:not(:active){box-shadow:0 0 8px rgba(0,0,0,.18),0 8px 16px rgba(0,0,0,.36)}.fab.colored{background:#ff4081;color:#fff}.fab.colored:active,.fab.colored:focus:not(:active),.fab.colored:hover{background-color:#ff4081}.fab.colored .ripple{background:#fff}.icon{font-size:24px;margin-left:0;margin-right:0;min-width:32px;width:32px;color:inherit;line-height:normal}.icon .material-icons{transform:translate(-12px,-12px);line-height:24px;width:24px}.icon.mini-icon{height:24px;min-width:24px;width:24px}.button-ripple,.card{overflow:hidden;width:100%;height:100%}.icon.mini-icon .material-icons{top:0;left:0}.icon .button-ripple{-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000)}.button-ripple{display:block;left:0;position:absolute;top:0;z-index:0}.button[disabled] .button-ripple .ripple{background-color:transparent}.primary.primary{color:#3f51b5}.primary.primary .ripple{background:#fff}.primary.primary.fab,.primary.primary.raised{color:#fff;background-color:#3f51b5}.accent.accent{color:#ff4081}.accent.accent .ripple{background:#fff}.accent.accent.fab,.accent.accent.raised{color:#fff;background-color:#ff4081}.button[disabled][disabled]{color:rgba(0,0,0,.26);cursor:auto;background-color:transparent}.button--fab[disabled][disabled],.button--raised[disabled][disabled]{background-color:rgba(0,0,0,.12);color:rgba(0,0,0,.26);box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)}.button--colored[disabled][disabled]{color:rgba(0,0,0,.26)}.card{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;font-size:16px;letter-spacing:0;font-weight:400;z-index:1;position:relative;background:#fff;border-radius:2px;box-sizing:border-box}.card-media{background-color:#ff4081;background-repeat:repeat;background-position:50% 50%;background-size:cover;background-origin:padding-box;background-attachment:scroll;box-sizing:border-box}.card-header{color:#000;display:block;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-align-content:stretch;-ms-flex-line-pack:stretch;align-content:stretch;line-height:normal;padding:60px 0 0;-webkit-perspective-origin:165px 56px;perspective-origin:165px 56px;-webkit-transform-origin:165px 56px;-ms-transform-origin:165px 56px;transform-origin:165px 56px;box-sizing:border-box}.card-section{color:#000;background-color:#fff;font-size:13px;line-height:18px}.card-section>.section-dialog{overflow:hidden;width:96%;background-color:transparent;padding:.5% 2%;margin:0;text-align:left}.card-actions,.card-section>.section-actions,.checkbox{box-sizing:border-box;width:100%}.card-section>.section-dialog>ul{padding-top:4px}.card-section>.section-actions{color:rgba(0,0,0,.54);font-size:16px;background-color:transparent;padding:8px}.card-actions{font-size:16px;background-color:rgba(0,255,255,.1)}.card-menu{position:absolute;right:16px;top:16px}.card-header-title{-webkit-align-self:flex-end;-ms-flex-item-align:end;align-self:flex-end;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;font-size:24px;font-weight:300;letter-spacing:1px;background-color:rgba(0,0,0,.5);transform-origin:149px 48px;margin:0;padding:12px 0}.card-header-subtitle,.card-header-title{overflow:hidden;display:block;line-height:normal;-webkit-transform-origin:149px 48px;-ms-transform-origin:149px 48px}.card-header-subtitle{-webkit-align-self:flex-end;-ms-flex-item-align:end;align-self:flex-end;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;background-color:transparent;transform-origin:149px 48px;margin:0;padding:8px 0}.checkbox-input,.checkbox-label{line-height:24px}.checkbox{position:relative;z-index:1;display:inline-block;height:24px;margin:0;padding:0}.checkbox.is-upgraded{padding-left:24px}.checkbox.is-upgraded .checkbox-input{position:absolute;width:0;height:0;margin:0;padding:0;opacity:0;-ms-appearance:none;-moz-appearance:none;-webkit-appearance:none;appearance:none;border:none}.checkbox-box-outline,.checkbox-focus-helper{position:absolute;left:0;top:3px;display:inline-block;box-sizing:border-box;width:16px;height:16px}.checkbox-box-outline{margin:0;cursor:pointer;overflow:hidden;border:2px solid rgba(0,0,0,.54);border-radius:2px;z-index:2}.checkbox.is-checked .checkbox-box-outline{border:2px solid #3f51b5}.checkbox.is-disabled .checkbox-box-outline{border:2px solid rgba(0,0,0,.26);cursor:auto}.checkbox-focus-helper{border-radius:50%;background-color:transparent}.checkbox.is-focused .checkbox-focus-helper{box-shadow:0 0 0 8px rgba(0,0,0,.1);background-color:rgba(0,0,0,.1)}.checkbox.is-focused.is-checked .checkbox-focus-helper{box-shadow:0 0 0 8px rgba(63,81,181,.26);background-color:rgba(63,81,181,.26)}.checkbox-tick-outline{position:absolute;top:0;left:0;height:100%;width:100%;-webkit-mask:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnDQogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iDQogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIg0KICAgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIg0KICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyINCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyINCiAgIHZlcnNpb249IjEuMSINCiAgIHZpZXdCb3g9IjAgMCAxIDEiDQogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4NCiAgPGRlZnM+DQogICAgPGNsaXBQYXRoIGlkPSJjbGlwIj4NCiAgICAgIDxwYXRoDQogICAgICAgICBkPSJNIDAsMCAwLDEgMSwxIDEsMCAwLDAgeiBNIDAuODUzNDM3NSwwLjE2NzE4NzUgMC45NTk2ODc1LDAuMjczMTI1IDAuNDI5Mzc1LDAuODAzNDM3NSAwLjMyMzEyNSwwLjkwOTY4NzUgMC4yMTcxODc1LDAuODAzNDM3NSAwLjA0MDMxMjUsMC42MjY4NzUgMC4xNDY1NjI1LDAuNTIwNjI1IDAuMzIzMTI1LDAuNjk3NSAwLjg1MzQzNzUsMC4xNjcxODc1IHoiDQogICAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lIiAvPg0KICAgIDwvY2xpcFBhdGg+DQogICAgPG1hc2sgaWQ9Im1hc2siIG1hc2tVbml0cz0ib2JqZWN0Qm91bmRpbmdCb3giIG1hc2tDb250ZW50VW5pdHM9Im9iamVjdEJvdW5kaW5nQm94Ij4NCiAgICAgIDxwYXRoDQogICAgICAgICBkPSJNIDAsMCAwLDEgMSwxIDEsMCAwLDAgeiBNIDAuODUzNDM3NSwwLjE2NzE4NzUgMC45NTk2ODc1LDAuMjczMTI1IDAuNDI5Mzc1LDAuODAzNDM3NSAwLjMyMzEyNSwwLjkwOTY4NzUgMC4yMTcxODc1LDAuODAzNDM3NSAwLjA0MDMxMjUsMC42MjY4NzUgMC4xNDY1NjI1LDAuNTIwNjI1IDAuMzIzMTI1LDAuNjk3NSAwLjg1MzQzNzUsMC4xNjcxODc1IHoiDQogICAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lIiAvPg0KICAgIDwvbWFzaz4NCiAgPC9kZWZzPg0KICA8cmVjdA0KICAgICB3aWR0aD0iMSINCiAgICAgaGVpZ2h0PSIxIg0KICAgICB4PSIwIg0KICAgICB5PSIwIg0KICAgICBjbGlwLXBhdGg9InVybCgjY2xpcCkiDQogICAgIHN0eWxlPSJmaWxsOiMwMDAwMDA7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmUiIC8+DQo8L3N2Zz4NCg==);mask:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnDQogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iDQogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIg0KICAgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIg0KICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyINCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyINCiAgIHZlcnNpb249IjEuMSINCiAgIHZpZXdCb3g9IjAgMCAxIDEiDQogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4NCiAgPGRlZnM+DQogICAgPGNsaXBQYXRoIGlkPSJjbGlwIj4NCiAgICAgIDxwYXRoDQogICAgICAgICBkPSJNIDAsMCAwLDEgMSwxIDEsMCAwLDAgeiBNIDAuODUzNDM3NSwwLjE2NzE4NzUgMC45NTk2ODc1LDAuMjczMTI1IDAuNDI5Mzc1LDAuODAzNDM3NSAwLjMyMzEyNSwwLjkwOTY4NzUgMC4yMTcxODc1LDAuODAzNDM3NSAwLjA0MDMxMjUsMC42MjY4NzUgMC4xNDY1NjI1LDAuNTIwNjI1IDAuMzIzMTI1LDAuNjk3NSAwLjg1MzQzNzUsMC4xNjcxODc1IHoiDQogICAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lIiAvPg0KICAgIDwvY2xpcFBhdGg+DQogICAgPG1hc2sgaWQ9Im1hc2siIG1hc2tVbml0cz0ib2JqZWN0Qm91bmRpbmdCb3giIG1hc2tDb250ZW50VW5pdHM9Im9iamVjdEJvdW5kaW5nQm94Ij4NCiAgICAgIDxwYXRoDQogICAgICAgICBkPSJNIDAsMCAwLDEgMSwxIDEsMCAwLDAgeiBNIDAuODUzNDM3NSwwLjE2NzE4NzUgMC45NTk2ODc1LDAuMjczMTI1IDAuNDI5Mzc1LDAuODAzNDM3NSAwLjMyMzEyNSwwLjkwOTY4NzUgMC4yMTcxODc1LDAuODAzNDM3NSAwLjA0MDMxMjUsMC42MjY4NzUgMC4xNDY1NjI1LDAuNTIwNjI1IDAuMzIzMTI1LDAuNjk3NSAwLjg1MzQzNzUsMC4xNjcxODc1IHoiDQogICAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lIiAvPg0KICAgIDwvbWFzaz4NCiAgPC9kZWZzPg0KICA8cmVjdA0KICAgICB3aWR0aD0iMSINCiAgICAgaGVpZ2h0PSIxIg0KICAgICB4PSIwIg0KICAgICB5PSIwIg0KICAgICBjbGlwLXBhdGg9InVybCgjY2xpcCkiDQogICAgIHN0eWxlPSJmaWxsOiMwMDAwMDA7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmUiIC8+DQo8L3N2Zz4NCg==);background:0 0;-webkit-transition-duration:.28s;transition-duration:.28s;transition-timing-function:cubic-bezier(.4,0,.2,1);-webkit-transition-property:background;transition-property:background}.checkbox-tick-outline,table tbody tr{-webkit-transition-timing-function:cubic-bezier(.4,0,.2,1)}.checkbox-ripple,.icon-ripple{box-sizing:border-box;overflow:hidden;-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000)}.checkbox.is-checked .checkbox-tick-outline{background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnDQogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iDQogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIg0KICAgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIg0KICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyINCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyINCiAgIHZlcnNpb249IjEuMSINCiAgIHZpZXdCb3g9IjAgMCAxIDEiDQogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4NCiAgPHBhdGgNCiAgICAgZD0iTSAwLjA0MDM4MDU5LDAuNjI2Nzc2NyAwLjE0NjQ0NjYxLDAuNTIwNzEwNjggMC40MjkyODkzMiwwLjgwMzU1MzM5IDAuMzIzMjIzMywwLjkwOTYxOTQxIHogTSAwLjIxNzE1NzI5LDAuODAzNTUzMzkgMC44NTM1NTMzOSwwLjE2NzE1NzI5IDAuOTU5NjE5NDEsMC4yNzMyMjMzIDAuMzIzMjIzMywwLjkwOTYxOTQxIHoiDQogICAgIGlkPSJyZWN0Mzc4MCINCiAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZSIgLz4NCjwvc3ZnPg0K) #3f51b5}.checkbox.is-checked.is-disabled .checkbox-tick-outline{background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnDQogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iDQogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIg0KICAgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIg0KICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyINCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyINCiAgIHZlcnNpb249IjEuMSINCiAgIHZpZXdCb3g9IjAgMCAxIDEiDQogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4NCiAgPHBhdGgNCiAgICAgZD0iTSAwLjA0MDM4MDU5LDAuNjI2Nzc2NyAwLjE0NjQ0NjYxLDAuNTIwNzEwNjggMC40MjkyODkzMiwwLjgwMzU1MzM5IDAuMzIzMjIzMywwLjkwOTYxOTQxIHogTSAwLjIxNzE1NzI5LDAuODAzNTUzMzkgMC44NTM1NTMzOSwwLjE2NzE1NzI5IDAuOTU5NjE5NDEsMC4yNzMyMjMzIDAuMzIzMjIzMywwLjkwOTYxOTQxIHoiDQogICAgIGlkPSJyZWN0Mzc4MCINCiAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZSIgLz4NCjwvc3ZnPg0K) rgba(0,0,0,.26)}.checkbox-label{position:relative;cursor:pointer;font-size:16px;margin:0}.checkbox.is-disabled .checkbox-label{color:rgba(0,0,0,.26);cursor:auto}.checkbox-ripple{position:absolute;z-index:2;top:-6px;left:-10px;width:36px;height:36px;border-radius:50%;cursor:pointer}.datatable,table,table td,table th{border:1px solid rgba(0,0,0,.12)}.datatable td,table,table tbody tr,table td,table th{position:relative}.checkbox-ripple .ripple{background:#3f51b5}.checkbox.is-disabled .checkbox-ripple{cursor:auto}.checkbox.is-disabled .checkbox-ripple .ripple{background:0 0}table{width:100%;max-width:100%;white-space:wrap;font-size:12px;line-height:16px;background-color:#fff;color:#000;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}.bigfoot-heading,.datatable,.link-list a,.menu-item,.textfield__label,ul.nowrap{white-space:nowrap}table thead{padding-bottom:3px}table tbody tr{height:48px;-webkit-transition-duration:.28s;transition-duration:.28s;transition-timing-function:cubic-bezier(.4,0,.2,1);-webkit-transition-property:background-color;transition-property:background-color}table tbody tr:hover{background-color:#eee}table td,table th{padding:6px;margin:0;height:32px;box-sizing:border-box}table td{text-align:left}table th{vertical-align:bottom;text-align:center;text-overflow:ellipsis;font-size:14px;line-height:24px;letter-spacing:0;font-weight:700;color:rgba(0,0,0,.54)}.datatable td,.icon,.layout-title.floating-title,.switch{vertical-align:middle}@media (min-width:40em){table{font-size:13px}th{font-size:15px}}.datatable thead .datatable-select{margin-top:0}.datatable tbody tr.is-selected{background-color:#e0e0e0}.datatable td,.datatable th{padding:0 18px;text-align:right}.datatable td:first-of-type,.datatable th:first-of-type{padding-left:24px}.datatable td:last-of-type,.datatable th:last-of-type{padding-right:24px}.datatable td{height:48px;border-top:1px solid rgba(0,0,0,.12);border-bottom:1px solid rgba(0,0,0,.12);padding-top:12px;box-sizing:border-box}.datatable td .datatable-select{vertical-align:middle;position:absolute;left:24px}.datatable th .datatable-select{position:relative}.datatable-select{width:16px}.datatable-cell.non-numeric{text-align:left}.datatable-cell.justified,.icon-label{text-align:center}footer{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:row wrap;-ms-flex-flow:row wrap;flex-flow:row wrap;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;padding:4px 2px;color:#9e9e9e;background-color:#424242}footer:after{content:'';display:block}footer>.left-section{display:inline-block;-webkit-box-ordinal-group:1;-webkit-order:0;-ms-flex-order:0;order:0}footer>.right-section{display:inline-block;-webkit-box-ordinal-group:2;-webkit-order:1;-ms-flex-order:1;order:1}footer>.social-btn{width:9px;height:9px;padding:0;margin:0;background-color:#9e9e9e;border:none}.link-list{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:row nowrap;-ms-flex-flow:row nowrap;flex-flow:row nowrap;margin:0;padding:0}.link-list li{margin-bottom:0;margin-right:16px}.link-list a{color:inherit}.bigfoot{padding:16px 40px;color:#9e9e9e;background-color:#424242}.bigfoot-bottom-section:after,.bigfoot-middle-section:after,.bigfoot-top-section:after{content:'';display:block;clear:both}.bigfoot-left-section,.bigfoot-right-section{margin-bottom:16px}.bigfoot-right-section a{display:block;margin-bottom:16px;color:inherit;text-decoration:none}@media screen and (min-width:760px){.link-list li{line-height:9px}.bigfoot-left-section{float:left}.bigfoot-right-section{float:right}.bigfoot-right-section a{display:inline-block;margin-left:16px;line-height:36px;vertical-align:middle}}.bigfoot-social-btn{width:36px;height:36px;padding:0;margin:0;background-color:#9e9e9e;border:none}.bigfoot-drop-down-section{display:block;position:relative}@media screen and (min-width:760px){.bigfoot-drop-down-section{width:33%}.bigfoot-drop-down-section:nth-child(1),.bigfoot-drop-down-section:nth-child(2){float:left}.bigfoot-drop-down-section:nth-child(3){float:right}.bigfoot-drop-down-section:nth-child(3):after{clear:right}.bigfoot-drop-down-section:nth-child(4){clear:right;float:right}.bigfoot-middle-section:after{content:'';display:block;clear:both}.bigfoot-bottom-section{padding-top:0}}#about,.bigfoot-link-list:after,.container:after{clear:both}@media screen and (min-width:1024px){.bigfoot-drop-down-section,.bigfoot-drop-down-section:nth-child(3),.bigfoot-drop-down-section:nth-child(4){width:24%;float:left}}.bigfoot-heading-checkbox{position:absolute;width:100%;height:68px;padding:32px;margin:-16px 0 0;cursor:pointer;z-index:1;opacity:0}.bigfoot-heading-checkbox~.bigfoot-heading:after{font-family:'ff Icons';content:'\E5CE'}.bigfoot-heading-checkbox:checked~ul{display:none}.bigfoot-heading-checkbox:checked~.bigfoot-heading:after{font-family:'ff Icons';content:'\E5CF'}.bigfoot-heading:after,.bigfoot-link-list:after{display:block;content:''}.bigfoot-heading{position:relative;width:100%;padding-right:52px;margin-bottom:16px;box-sizing:border-box;font-size:24px;line-height:36px;font-weight:500;text-overflow:ellipsis;overflow:hidden;color:#e0e0e0}.bigfoot-link-list li,.menu-item{font-weight:400;letter-spacing:0}.bigfoot-heading:after{position:absolute;top:0;right:0;width:36px;height:36px;background-size:cover}.bigfoot-link-list{list-style:none;margin:0 0 32px;padding:0}.bigfoot-link-list li{font-size:14px;line-height:20px}.bigfoot-link-list a{color:inherit;white-space:nowrap}@media screen and (min-width:760px){.bigfoot-heading-checkbox{display:none}.bigfoot-heading-checkbox~.bigfoot-heading:after{background-image:none}.bigfoot-heading-checkbox:checked~ul{display:block}.bigfoot-heading-checkbox:checked~.bigfoot-heading:after{content:''}}.icon,.icon-label{display:inline-block}.bigfoot-bottom-section{padding-top:16px;margin-bottom:16px}.logo{margin-bottom:16px;color:#fff}.bigfoot-bottom-section .bigfoot-link-list li{float:left;margin-bottom:0;margin-right:16px}@media screen and (min-width:760px){.logo{float:left;margin-bottom:0;margin-right:16px}}.icon{position:relative;z-index:1;height:32px;margin:0;padding:0}.icon-input{line-height:32px}.icon.is-upgraded .icon-input{position:absolute;width:0;height:0;margin:0;padding:0;opacity:0;-ms-appearance:none;-moz-appearance:none;-webkit-appearance:none;appearance:none;border:none}.icon-label{position:relative;cursor:pointer;height:32px;width:32px;min-width:32px;color:#616161;border-radius:50%;padding:0;margin-left:0;margin-right:0;background-color:transparent;will-change:background-color;-webkit-transition:background-color .2s cubic-bezier(.4,0,.2,1),color .2s cubic-bezier(.4,0,.2,1);transition:background-color .2s cubic-bezier(.4,0,.2,1),color .2s cubic-bezier(.4,0,.2,1)}.layout-drawer,.menu-outline,.tooltip{will-change:transform}.icon-label.material-icons{line-height:32px;font-size:24px}.icon.is-checked .icon-label{color:#3f51b5}.icon.is-disabled .icon-label{color:rgba(0,0,0,.26);cursor:auto;-webkit-transition:none;transition:none}.icon.is-focused .icon-label{background-color:rgba(0,0,0,.12)}.icon.is-focused.is-checked .icon-label{background-color:rgba(63,81,181,.26)}.icon-ripple{position:absolute;z-index:2;top:-2px;left:-2px;width:36px;height:36px;border-radius:50%;cursor:pointer}.menu,.menu-outline{position:absolute;top:0;left:0}.icon-ripple .ripple{background:#616161}.icon.is-disabled .icon-ripple{cursor:auto}.icon.is-disabled .icon-ripple .ripple{background:0 0}.menu-container{display:block;margin:0;padding:0;border:none;position:absolute;overflow:visible;height:0;width:0;z-index:-1}.menu-container.is-visible{z-index:999}.menu-outline{background:#fff;padding:0;border-radius:2px;overflow:hidden;opacity:0;-webkit-transform:scale(0);-ms-transform:scale(0);transform:scale(0);-webkit-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);-webkit-transition:-webkit-transform .3s cubic-bezier(.4,0,.2,1),opacity .2s cubic-bezier(.4,0,.2,1);transition:transform .3s cubic-bezier(.4,0,.2,1),opacity .2s cubic-bezier(.4,0,.2,1);z-index:-1}.menu-item,.menu-outline{margin:0;display:block;border:none}.menu-item,.menu-item[disabled],.menu-item[disabled]:focus,.menu-item[disabled]:hover{background-color:transparent}.menu-container.is-visible .menu-outline{opacity:1;-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);z-index:999}.menu-outline.menu--bottom-right{-webkit-transform-origin:100% 0;-ms-transform-origin:100% 0;transform-origin:100% 0}.menu-outline.menu--top-left{-webkit-transform-origin:0 100%;-ms-transform-origin:0 100%;transform-origin:0 100%}.menu-outline.menu--top-right{-webkit-transform-origin:100% 100%;-ms-transform-origin:100% 100%;transform-origin:100% 100%}.menu{height:auto;width:auto;min-width:124px;padding:8px 0;margin:0;opacity:0;clip:rect(0 0 0 0);z-index:-1}.menu-container.is-visible .menu{opacity:1;z-index:999}.menu.is-animating{-webkit-transition:opacity .2s cubic-bezier(.4,0,.2,1),clip .3s cubic-bezier(.4,0,.2,1);transition:opacity .2s cubic-bezier(.4,0,.2,1),clip .3s cubic-bezier(.4,0,.2,1)}.menu.menu--bottom-right{left:auto;right:0}.menu.menu--top-left{top:auto;bottom:0}.menu.menu--top-right{top:auto;left:auto;bottom:0;right:0}.menu.menu--unaligned{top:auto;left:auto}.menu-item{color:rgba(0,0,0,.87);text-align:left;padding:0 16px;outline-color:#bdbdbd;position:relative;overflow:hidden;font-size:14px;cursor:pointer;height:48px;line-height:48px;opacity:0;-webkit-transition:opacity .2s cubic-bezier(.4,0,.2,1);transition:opacity .2s cubic-bezier(.4,0,.2,1);user-select:none}.layout-tab-bar-button,.menu-item{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.menu-item:focus,.textfield.is-focused .textfield__input{outline:0}.menu-container.is-visible .menu-item{opacity:1}.menu-item::-moz-focus-inner{border:0}.menu-item[disabled]{color:#bdbdbd;cursor:auto}.menu-item[disabled] .ripple{background:0 0}.menu-item:focus,.menu-item:hover{background-color:#eee}.menu-item:active{background-color:#e0e0e0}.menu-item-ripple-container{display:block;height:100%;left:0;position:absolute;top:0;width:100%;z-index:0;overflow:hidden}.progress{display:block;position:relative;height:4px;width:500px}.progress>.bar{display:block;position:absolute;top:0;bottom:0;width:0;-webkit-transition:width .2s cubic-bezier(.4,0,.2,1);transition:width .2s cubic-bezier(.4,0,.2,1)}.layout,.navigation{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox}.progress>.progressbar{background-color:#3f51b5;z-index:1;left:0}.progress>.bufferbar{background-image:-webkit-linear-gradient(left,rgba(255,255,255,.7),rgba(255,255,255,.7)),-webkit-linear-gradient(left,#3f51b5,#3f51b5);background-image:linear-gradient(to right,rgba(255,255,255,.7),rgba(255,255,255,.7)),linear-gradient(to right,#3f51b5,#3f51b5);z-index:0;left:0}.progress>.auxbar{right:0}@supports (-webkit-appearance:none){.progress:not(.progress-indeterminate):not(.progress-indeterminate)>.auxbar{background-image:-webkit-linear-gradient(left,rgba(255,255,255,.7),rgba(255,255,255,.7)),-webkit-linear-gradient(left,#3f51b5,#3f51b5);background-image:linear-gradient(to right,rgba(255,255,255,.7),rgba(255,255,255,.7)),linear-gradient(to right,#3f51b5,#3f51b5);-webkit-mask:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8c3ZnIHdpZHRoPSIxMiIgaGVpZ2h0PSI0IiB2aWV3UG9ydD0iMCAwIDEyIDQiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCiAgPGVsbGlwc2UgY3g9IjIiIGN5PSIyIiByeD0iMiIgcnk9IjIiPg0KICAgIDxhbmltYXRlIGF0dHJpYnV0ZU5hbWU9ImN4IiBmcm9tPSIyIiB0bz0iLTEwIiBkdXI9IjAuNnMiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPg0KICA8L2VsbGlwc2U+DQogIDxlbGxpcHNlIGN4PSIxNCIgY3k9IjIiIHJ4PSIyIiByeT0iMiIgY2xhc3M9ImxvYWRlciI+DQogICAgPGFuaW1hdGUgYXR0cmlidXRlTmFtZT0iY3giIGZyb209IjE0IiB0bz0iMiIgZHVyPSIwLjZzIiByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4NCiAgPC9lbGxpcHNlPg0KPC9zdmc+DQo=);mask:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8c3ZnIHdpZHRoPSIxMiIgaGVpZ2h0PSI0IiB2aWV3UG9ydD0iMCAwIDEyIDQiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCiAgPGVsbGlwc2UgY3g9IjIiIGN5PSIyIiByeD0iMiIgcnk9IjIiPg0KICAgIDxhbmltYXRlIGF0dHJpYnV0ZU5hbWU9ImN4IiBmcm9tPSIyIiB0bz0iLTEwIiBkdXI9IjAuNnMiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPg0KICA8L2VsbGlwc2U+DQogIDxlbGxpcHNlIGN4PSIxNCIgY3k9IjIiIHJ4PSIyIiByeT0iMiIgY2xhc3M9ImxvYWRlciI+DQogICAgPGFuaW1hdGUgYXR0cmlidXRlTmFtZT0iY3giIGZyb209IjE0IiB0bz0iMiIgZHVyPSIwLjZzIiByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4NCiAgPC9lbGxpcHNlPg0KPC9zdmc+DQo=)}}.progress:not(.progress-indeterminate)>.auxbar{background-image:-webkit-linear-gradient(left,rgba(255,255,255,.9),rgba(255,255,255,.9)),-webkit-linear-gradient(left,#3f51b5,#3f51b5);background-image:linear-gradient(to right,rgba(255,255,255,.9),rgba(255,255,255,.9)),linear-gradient(to right,#3f51b5,#3f51b5)}.progress.progress-indeterminate>.bar1{background-color:#3f51b5;-webkit-animation-name:indeterminate1;animation-name:indeterminate1;animation-duration:2s;animation-iteration-count:infinite;animation-timing-function:linear}.progress.progress-indeterminate>.bar1,.progress.progress-indeterminate>.bar3{-webkit-animation-duration:2s;-webkit-animation-iteration-count:infinite;-webkit-animation-timing-function:linear}.progress.progress-indeterminate>.bar3{background-image:none;background-color:#3f51b5;-webkit-animation-name:indeterminate2;animation-name:indeterminate2;animation-duration:2s;animation-iteration-count:infinite;animation-timing-function:linear}@-webkit-keyframes indeterminate1{0%{left:0;width:0}50%{left:25%;width:75%}75%{left:100%;width:0}}@keyframes indeterminate1{0%{left:0;width:0}50%{left:25%;width:75%}75%{left:100%;width:0}}@-webkit-keyframes indeterminate2{0%,50%{left:0;width:0}75%{left:0;width:25%}100%{left:100%;width:0}}@keyframes indeterminate2{0%,50%{left:0;width:0}75%{left:0;width:25%}100%{left:100%;width:0}}.navigation{display:flex;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;box-sizing:border-box}.navigation-link{color:#424242;font-weight:500;font-size:13px;margin:0}.layout{width:100%;height:100%;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;overflow-y:auto;overflow-x:hidden;position:relative;-webkit-overflow-scrolling:touch}.layout-transparent>.layout-header,.layout-transparent>.littlefoot{color:#fff;background-color:rgba(0,0,0,.35);box-shadow:none}.layout-transparent>.layout-drawer{color:#fff;text-shadow:0 1px 3px rgba(0,0,0,.5);background-color:rgba(0,0,0,.35);border-right:1px solid #000}.layout-transparent>.layout-drawer-button{color:#fff;background-color:transparent;box-shadow:none}.layout-shadow{box-shadow:inset 0 0 100px rgba(0,0,0,.5)}.layout-drawer,.layout-header{box-sizing:border-box;-webkit-box-orient:vertical;box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)}.layout.is-small-screen .layout-large-screen-only,.layout:not(.is-small-screen) .layout-small-screen-only{display:none}.layout-container{position:absolute;width:100%;height:100%}.layout-title{display:block;position:relative;font-family:Roboto,Helvetica,Arial,sans-serif;font-size:20px;line-height:1;letter-spacing:.02em;font-weight:400;box-sizing:border-box}.layout-tab,.tabs__tab,.tooltip{text-align:center;font-weight:500}.layout-title.floating-title{position:absolute;top:0;left:52px;height:48px;line-height:44px;z-index:2}.layout-spacer{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.layout-drawer{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;width:240px;height:100%;max-height:100%;position:absolute;top:0;left:0;border-right:1px solid #e0e0e0;background:#fafafa;-webkit-transform:translateX(-250px);-ms-transform:translateX(-250px);transform:translateX(-250px);-webkit-transform-style:preserve-3d;transform-style:preserve-3d;-webkit-transition-duration:.2s;transition-duration:.2s;-webkit-transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(.4,0,.2,1);-webkit-transition-property:-webkit-transform;transition-property:transform;color:#424242;overflow:visible;overflow-y:auto;z-index:5}.layout-drawer.is-visible{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}.layout-drawer>*{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0}.layout-drawer>.layout-title{line-height:64px;padding-left:40px}@media screen and (max-width:1024px){.layout-drawer>.layout-title{line-height:56px;padding-left:16px}}.layout-drawer .navigation{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:stretch;-webkit-align-items:stretch;-ms-flex-align:stretch;align-items:stretch;padding-top:16px}.layout-drawer .navigation .navigation-link{display:block;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;padding:16px 40px;margin:0;color:#757575}.layout-drawer .navigation .navigation-link:hover{background-color:#e0e0e0}.layout-drawer .navigation .navigation-link--current{background-color:#000;color:#3f51b5}.layout-drawer-button{display:block;position:absolute;height:48px;width:48px;border:0;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;overflow:hidden;text-align:center;cursor:pointer;font-size:26px;line-height:50px;font-family:Helvetica,Arial,sans-serif;margin:10px 12px;top:0;left:0;color:#fff;z-index:4}.layout-header .layout-drawer-button{position:absolute;color:#fff;background-color:inherit}@media screen and (max-width:1024px){.layout-drawer .navigation .navigation-link{padding:16px}.layout-header .layout-drawer-button{margin:4px}.layout-drawer-button{margin:4px;color:rgba(0,0,0,.5)}}@media screen and (min-width:1025px){.layout-fixed-drawer>.layout-drawer{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}.layout-fixed-drawer>.layout-drawer-button{display:none}}.layout-header{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-pack:start;-webkit-justify-content:flex-start;-ms-flex-pack:start;justify-content:flex-start;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;width:100%;margin:0;padding:0;border:none;min-height:64px;max-height:1000px;z-index:3;background-color:#3f51b5;color:#fff;-webkit-transition-duration:.2s;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1);-webkit-transition-property:max-height,box-shadow;transition-property:max-height,box-shadow}.layout-header,.layout-obfuscator{-webkit-transition-timing-function:cubic-bezier(.4,0,.2,1)}.layout-fixed-drawer:not(.is-small-screen)>.layout-header{margin-left:240px;width:calc(100% - 240px)}.layout-header-row,.layout-header-row .navigation{-webkit-box-orient:horizontal;-webkit-box-direction:normal;margin:0}.layout-fixed-drawer>.layout-header .layout-header-row{padding-left:40px}.layout-header>.layout-icon{position:absolute;left:40px;top:16px;height:32px;width:32px;overflow:hidden;z-index:3;display:block}.layout.has-drawer .layout-header>.layout-icon{display:none}.layout-header.is-compact{max-height:64px}.layout-header.is-compact.has-tabs{height:112px}@media screen and (max-width:1024px){.layout-header{min-height:56px;display:none}.layout-header>.layout-icon{left:16px;top:12px}.layout-header.is-compact{max-height:56px}.layout-header.is-compact.has-tabs{min-height:104px}.layout-fixed-header>.layout-header{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}}.layout-header--transparent.layout-header--transparent{background-color:transparent;box-shadow:none}.layout-header--scroll,.layout-header--seamed{box-shadow:none}.layout-header--waterfall{box-shadow:none;overflow:hidden}.layout-header--waterfall.is-casting-shadow,.switch__thumb{box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)}.layout-header-row{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;box-sizing:border-box;-webkit-align-self:stretch;-ms-flex-item-align:stretch;align-self:stretch;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;height:64px;padding:0 40px 0 80px}@media screen and (max-width:1024px){.layout-header-row{height:56px;padding:0 16px 0 72px}}.layout-header-row>*{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0}.layout-header--scroll .layout-header-row{width:100%}.layout-header-row .navigation{padding:0;height:64px;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.layout-header-row .navigation-link{display:block;color:#fff;line-height:64px;padding:0 24px}@media screen and (max-width:1024px){.layout-header-row .navigation{height:56px}.layout-header-row .navigation-link{line-height:56px;padding:0 16px}}.layout-tab,.layout-tab-bar-button .material-icons{line-height:48px}.layout-obfuscator{background-color:transparent;position:absolute;top:0;left:0;height:100%;width:100%;z-index:4;visibility:hidden;-webkit-transition-property:background-color;transition-property:background-color;-webkit-transition-duration:.2s;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.layout-drawer.is-visible~.layout-obfuscator{background-color:rgba(0,0,0,.5);visibility:visible}.layout-content{-ms-flex:0 1 auto;display:inline-block;overflow-y:auto;overflow-x:hidden;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;z-index:1;-webkit-overflow-scrolling:touch}.layout-fixed-drawer>.layout-content{margin-left:240px}.layout-container.has-scrolling-header .layout-content{overflow:visible}@media screen and (max-width:1024px){.layout-fixed-drawer>.layout-content{margin-left:0}.layout-container.has-scrolling-header .layout-content{overflow-y:auto;overflow-x:hidden}}.layout-tab-bar{height:96px;margin:0;width:calc(100% - 112px);padding:0 0 0 56px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;background-color:#3f51b5;overflow-y:hidden;overflow-x:scroll}.layout-tab-bar::-webkit-scrollbar{display:none}@media screen and (max-width:1024px){.layout-tab-bar{width:calc(100% - 60px);padding:0 0 0 60px}}.layout-fixed-tabs .layout-tab-bar{padding:0;overflow:hidden;width:100%}.layout-tab-bar-container{position:relative;height:48px;width:100%;border:none;margin:0;z-index:2;-webkit-box-flex:0;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;overflow:hidden}.layout-container>.layout-tab-bar-container{position:absolute;top:0;left:0}.layout-tab-bar-button{display:inline-block;position:absolute;top:0;height:48px;width:56px;z-index:4;text-align:center;background-color:#3f51b5;color:transparent;cursor:pointer;user-select:none}@media screen and (max-width:1024px){.layout-tab-bar-button{display:none;width:60px}}.layout-fixed-tabs .layout-tab-bar-button{display:none}.layout-tab-bar-button.is-active{color:#fff}.layout-tab-bar-left-button{left:0}.layout-tab-bar-right-button{right:0}.layout-tab{margin:0;border:none;padding:0 24px;float:left;position:relative;display:block;-webkit-box-flex:0;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;height:48px;font-size:14px;color:rgba(255,255,255,.6);overflow:hidden}.radio,.radio__button,.switch__input,.switch__label{line-height:24px}@media screen and (max-width:1024px){.layout-tab{padding:0 12px}}.layout-fixed-tabs .layout-tab{float:none;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;padding:0}.layout.is-upgraded .layout-tab.is-active{color:#fff}.layout.is-upgraded .layout-tab.is-active::after{height:2px;width:100%;display:block;content:" ";bottom:0;left:0;position:absolute;background:#ff4081;-webkit-animation:border-expand .2s cubic-bezier(.4,0,.4,1) .01s alternate forwards;animation:border-expand .2s cubic-bezier(.4,0,.4,1) .01s alternate forwards;-webkit-transition:all 1s cubic-bezier(.4,0,1,1);transition:all 1s cubic-bezier(.4,0,1,1)}.layout-tab .layout-tab-ripple-container{display:block;position:absolute;height:100%;width:100%;left:0;top:0;z-index:1;overflow:hidden}.layout-tab .layout-tab-ripple-container .ripple{background-color:#fff}.layout-tab-panel{display:block}.layout.is-upgraded .layout-tab-panel{display:none}.layout.is-upgraded .layout-tab-panel.is-active{display:block}.radio,.radio__outer-circle{margin:0;box-sizing:border-box;display:inline-block}.radio{position:relative;font-size:16px;padding-left:0}.radio.is-upgraded{padding-left:24px}.radio.is-upgraded .radio__button{position:absolute;width:0;height:0;margin:0;padding:0;opacity:0;-ms-appearance:none;-moz-appearance:none;-webkit-appearance:none;appearance:none;border:none}.radio__outer-circle{position:absolute;top:2px;left:0;width:16px;height:16px;cursor:pointer;border:2px solid rgba(0,0,0,.54);border-radius:50%;z-index:2}.radio.is-checked .radio__outer-circle{border:2px solid #3f51b5}.radio.is-disabled .radio__outer-circle{border:2px solid rgba(0,0,0,.26);cursor:auto}.radio-ripple,.radio__inner-circle{position:absolute;border-radius:50%}.radio__inner-circle{z-index:1;margin:0;top:6px;left:4px;box-sizing:border-box;width:8px;height:8px;cursor:pointer;-webkit-transition-duration:.28s;transition-duration:.28s;-webkit-transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(.4,0,.2,1);-webkit-transition-property:-webkit-transform;transition-property:transform;-webkit-transform:scale3d(0,0,0);transform:scale3d(0,0,0);background:#3f51b5}.radio-ripple,.switch-ripple{box-sizing:border-box;z-index:2;-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000)}.radio.is-checked .radio__inner-circle{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}.radio.is-disabled .radio__inner-circle{background:rgba(0,0,0,.26);cursor:auto}.radio.is-focused .radio__inner-circle{box-shadow:0 0 0 10px rgba(0,0,0,.1)}.radio__label{cursor:pointer}.radio.is-disabled .radio__label{color:rgba(0,0,0,.26);cursor:auto}.radio-ripple{top:-9px;left:-13px;width:42px;height:42px;cursor:pointer;overflow:hidden}.radio-ripple .ripple{background:#3f51b5}.radio.is-disabled .radio-ripple{cursor:auto}.radio.is-disabled .radio-ripple .ripple{background:0 0}:root .slider.slider.is-upgraded,_:-ms-input-placeholder{-ms-appearance:none;height:32px;margin:0}.slider{width:calc(100% - 40px);margin:0 20px}.slider.is-upgraded{-webkit-appearance:none;-moz-appearance:none;appearance:none;height:2px;background:0 0;user-select:none;outline:0;padding:0;color:#3f51b5;-webkit-align-self:center;-ms-flex-item-align:center;align-self:center;z-index:1}.slider.is-upgraded,.switch{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.slider.is-upgraded::-moz-focus-outer{border:0}.slider.is-upgraded::-ms-tooltip{display:none}.slider.is-upgraded::-webkit-slider-runnable-track{background:0 0}.slider.is-upgraded::-moz-range-track{background:0 0;border:none}.slider.is-upgraded::-ms-track{background:0 0;color:transparent;height:2px;width:100%;border:none}.slider.is-upgraded::-ms-fill-lower{padding:0;background:linear-gradient(to right,transparent,transparent 16px,#3f51b5 16px,#3f51b5 0)}.slider.is-upgraded::-ms-fill-upper{padding:0;background:linear-gradient(to left,transparent,transparent 16px,rgba(0,0,0,.26) 16px,rgba(0,0,0,.26) 0)}.slider.is-upgraded::-webkit-slider-thumb{-webkit-appearance:none;width:12px;height:12px;box-sizing:border-box;border-radius:50%;background:#3f51b5;border:none;-webkit-transition:-webkit-transform .18s cubic-bezier(.4,0,.2,1),border .18s cubic-bezier(.4,0,.2,1),box-shadow .18s cubic-bezier(.4,0,.2,1),background .28s cubic-bezier(.4,0,.2,1);transition:transform .18s cubic-bezier(.4,0,.2,1),border .18s cubic-bezier(.4,0,.2,1),box-shadow .18s cubic-bezier(.4,0,.2,1),background .28s cubic-bezier(.4,0,.2,1)}.slider.is-upgraded::-moz-range-thumb{-moz-appearance:none;width:12px;height:12px;box-sizing:border-box;border-radius:50%;background:#3f51b5;border:none}.slider.is-upgraded:focus:not(:active)::-webkit-slider-thumb{box-shadow:0 0 0 10px rgba(63,81,181,.26)}.slider.is-upgraded:focus:not(:active)::-moz-range-thumb{box-shadow:0 0 0 10px rgba(63,81,181,.26)}.slider.is-upgraded:active::-webkit-slider-thumb{background:#3f51b5;-webkit-transform:scale(1.5);transform:scale(1.5)}.slider.is-upgraded:active::-moz-range-thumb{background:#3f51b5;transform:scale(1.5)}.slider.is-upgraded::-ms-thumb{width:32px;height:32px;border:none;border-radius:50%;background:#3f51b5;-ms-transform:scale(.375);transform:scale(.375);transition:transform .18s cubic-bezier(.4,0,.2,1),background .28s cubic-bezier(.4,0,.2,1)}.slider.is-upgraded:focus:not(:active)::-ms-thumb{background:radial-gradient(circle closest-side,#3f51b5 0,#3f51b5 37.5%,rgba(63,81,181,.26) 37.5%,rgba(63,81,181,.26) 100%);-ms-transform:scale(1);transform:scale(1)}.slider.is-upgraded:active::-ms-thumb{background:#3f51b5;-ms-transform:scale(.5625);transform:scale(.5625)}.slider.is-upgraded.is-lowest-value::-webkit-slider-thumb{border:2px solid rgba(0,0,0,.26);background:0 0}.slider.is-upgraded.is-lowest-value::-moz-range-thumb{border:2px solid rgba(0,0,0,.26);background:0 0}.slider.is-upgraded.is-lowest-value~.slider__background-flex>.slider__background-upper{left:6px}.slider.is-upgraded.is-lowest-value:focus:not(:active)::-webkit-slider-thumb{box-shadow:0 0 0 10px rgba(0,0,0,.12);background:rgba(0,0,0,.12)}.slider.is-upgraded.is-lowest-value:focus:not(:active)::-moz-range-thumb{box-shadow:0 0 0 10px rgba(0,0,0,.12);background:rgba(0,0,0,.12)}.slider.is-upgraded.is-lowest-value:active::-webkit-slider-thumb{border:1.6px solid rgba(0,0,0,.26);-webkit-transform:scale(1.5);transform:scale(1.5)}.slider.is-upgraded.is-lowest-value:active~.slider__background-flex>.slider__background-upper{left:9px}.slider.is-upgraded.is-lowest-value:active::-moz-range-thumb{border:1.5px solid rgba(0,0,0,.26);transform:scale(1.5)}.slider.is-upgraded.is-lowest-value::-ms-thumb{background:radial-gradient(circle closest-side,transparent 0,transparent 66.67%,rgba(0,0,0,.26) 66.67%,rgba(0,0,0,.26) 100%)}.slider.is-upgraded.is-lowest-value:focus:not(:active)::-ms-thumb{background:radial-gradient(circle closest-side,rgba(0,0,0,.12) 0,rgba(0,0,0,.12) 25%,rgba(0,0,0,.26) 25%,rgba(0,0,0,.26) 37.5%,rgba(0,0,0,.12) 37.5%,rgba(0,0,0,.12) 100%);-ms-transform:scale(1);transform:scale(1)}.slider.is-upgraded.is-lowest-value:active::-ms-thumb{-ms-transform:scale(.5625);transform:scale(.5625);background:radial-gradient(circle closest-side,transparent 0,transparent 77.78%,rgba(0,0,0,.26) 77.78%,rgba(0,0,0,.26) 100%)}.slider.is-upgraded.is-lowest-value::-ms-fill-lower{background:0 0}.slider.is-upgraded.is-lowest-value::-ms-fill-upper{margin-left:6px}.slider.is-upgraded.is-lowest-value:active::-ms-fill-upper{margin-left:9px}.slider.is-upgraded:disabled::-webkit-slider-thumb,.slider.is-upgraded:disabled:active::-webkit-slider-thumb,.slider.is-upgraded:disabled:focus::-webkit-slider-thumb{-webkit-transform:scale(.667);transform:scale(.667);background:rgba(0,0,0,.26)}.slider.is-upgraded:disabled::-moz-range-thumb,.slider.is-upgraded:disabled:active::-moz-range-thumb,.slider.is-upgraded:disabled:focus::-moz-range-thumb{transform:scale(.667);background:rgba(0,0,0,.26)}.slider.is-upgraded:disabled~.slider__background-flex>.slider__background-lower{background-color:rgba(0,0,0,.26);left:-6px}.slider.is-upgraded.is-lowest-value:disabled:active~.slider__background-flex>.slider__background-upper,.slider.is-upgraded:disabled~.slider__background-flex>.slider__background-upper{left:6px}.slider.is-upgraded.is-lowest-value:disabled::-webkit-slider-thumb,.slider.is-upgraded.is-lowest-value:disabled:active::-webkit-slider-thumb,.slider.is-upgraded.is-lowest-value:disabled:focus::-webkit-slider-thumb{border:3px solid rgba(0,0,0,.26);background:0 0;-webkit-transform:scale(.667);transform:scale(.667)}.slider.is-upgraded.is-lowest-value:disabled::-moz-range-thumb,.slider.is-upgraded.is-lowest-value:disabled:active::-moz-range-thumb,.slider.is-upgraded.is-lowest-value:disabled:focus::-moz-range-thumb{border:3px solid rgba(0,0,0,.26);background:0 0;transform:scale(.667)}.slider.is-upgraded:disabled::-ms-thumb,.slider.is-upgraded:disabled:active::-ms-thumb,.slider.is-upgraded:disabled:focus::-ms-thumb{-ms-transform:scale(.25);transform:scale(.25);background:rgba(0,0,0,.26)}.slider.is-upgraded.is-lowest-value:disabled::-ms-thumb,.slider.is-upgraded.is-lowest-value:disabled:active::-ms-thumb,.slider.is-upgraded.is-lowest-value:disabled:focus::-ms-thumb{-ms-transform:scale(.25);transform:scale(.25);background:radial-gradient(circle closest-side,transparent 0,transparent 50%,rgba(0,0,0,.26) 50%,rgba(0,0,0,.26) 100%)}.slider.is-upgraded:disabled::-ms-fill-lower{margin-right:6px;background:linear-gradient(to right,transparent,transparent 25px,rgba(0,0,0,.26) 25px,rgba(0,0,0,.26) 0)}.slider__background-flex,.slider__container{background:0 0;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox}.slider.is-upgraded:disabled::-ms-fill-upper{margin-left:6px}.slider.is-upgraded.is-lowest-value:disabled:active::-ms-fill-upper{margin-left:6px}.slider__ie-container{height:18px;overflow:visible;border:none;margin:none;padding:none}.slider__container{height:18px;position:relative;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row}.slider__background-flex{position:absolute;height:2px;width:calc(100% - 52px);top:50%;left:0;margin:0 26px;display:flex;overflow:hidden;border:0;padding:0;-webkit-transform:translate(0,-1px);-ms-transform:translate(0,-1px);transform:translate(0,-1px)}.spinner,.switch,.switch__focus-helper{display:inline-block}.slider__background-lower{background:#3f51b5;-webkit-box-flex:0;-webkit-flex:0;-ms-flex:0;flex:0;position:relative;border:0;padding:0}.slider__background-upper{background:rgba(0,0,0,.26);-webkit-box-flex:0;-webkit-flex:0;-ms-flex:0;flex:0;position:relative;border:0;padding:0;-webkit-transition:left .18s cubic-bezier(.4,0,.2,1);transition:left .18s cubic-bezier(.4,0,.2,1)}.spinner{position:relative;width:28px;height:28px}.spinner:not(.is-upgraded).is-active:after{content:"Loading..."}.spinner.is-upgraded.is-active{-webkit-animation:spinner__container-rotate 1568.23529412ms linear infinite;animation:spinner__container-rotate 1568.23529412ms linear infinite}@-webkit-keyframes spinner__container-rotate{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spinner__container-rotate{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.spinner__layer{position:absolute;width:100%;height:100%;opacity:0}.spinner__layer-1{border-color:#42a5f5}.spinner--single-color .spinner__layer-1{border-color:#3f51b5}.spinner.is-active .spinner__layer-1{-webkit-animation:spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1) infinite both,spinner__layer-1-fade-in-out 5332ms cubic-bezier(.4,0,.2,1) infinite both;animation:spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1) infinite both,spinner__layer-1-fade-in-out 5332ms cubic-bezier(.4,0,.2,1) infinite both}.spinner__layer-2{border-color:#f44336}.spinner--single-color .spinner__layer-2{border-color:#3f51b5}.spinner.is-active .spinner__layer-2{-webkit-animation:spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1) infinite both,spinner__layer-2-fade-in-out 5332ms cubic-bezier(.4,0,.2,1) infinite both;animation:spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1) infinite both,spinner__layer-2-fade-in-out 5332ms cubic-bezier(.4,0,.2,1) infinite both}.spinner__layer-3{border-color:#fdd835}.spinner--single-color .spinner__layer-3{border-color:#3f51b5}.spinner.is-active .spinner__layer-3{-webkit-animation:spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1) infinite both,spinner__layer-3-fade-in-out 5332ms cubic-bezier(.4,0,.2,1) infinite both;animation:spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1) infinite both,spinner__layer-3-fade-in-out 5332ms cubic-bezier(.4,0,.2,1) infinite both}.spinner__layer-4{border-color:#4caf50}.spinner--single-color .spinner__layer-4{border-color:#3f51b5}.spinner__circle,.spinner__circle-clipper,.spinner__gap-patch{height:100%;border-color:inherit}.spinner.is-active .spinner__layer-4{-webkit-animation:spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1) infinite both,spinner__layer-4-fade-in-out 5332ms cubic-bezier(.4,0,.2,1) infinite both;animation:spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1) infinite both,spinner__layer-4-fade-in-out 5332ms cubic-bezier(.4,0,.2,1) infinite both}@-webkit-keyframes spinner__fill-unfill-rotate{12.5%{-webkit-transform:rotate(135deg);transform:rotate(135deg)}25%{-webkit-transform:rotate(270deg);transform:rotate(270deg)}37.5%{-webkit-transform:rotate(405deg);transform:rotate(405deg)}50%{-webkit-transform:rotate(540deg);transform:rotate(540deg)}62.5%{-webkit-transform:rotate(675deg);transform:rotate(675deg)}75%{-webkit-transform:rotate(810deg);transform:rotate(810deg)}87.5%{-webkit-transform:rotate(945deg);transform:rotate(945deg)}to{-webkit-transform:rotate(1080deg);transform:rotate(1080deg)}}@keyframes spinner__fill-unfill-rotate{12.5%{-webkit-transform:rotate(135deg);transform:rotate(135deg)}25%{-webkit-transform:rotate(270deg);transform:rotate(270deg)}37.5%{-webkit-transform:rotate(405deg);transform:rotate(405deg)}50%{-webkit-transform:rotate(540deg);transform:rotate(540deg)}62.5%{-webkit-transform:rotate(675deg);transform:rotate(675deg)}75%{-webkit-transform:rotate(810deg);transform:rotate(810deg)}87.5%{-webkit-transform:rotate(945deg);transform:rotate(945deg)}to{-webkit-transform:rotate(1080deg);transform:rotate(1080deg)}}@-webkit-keyframes spinner__layer-1-fade-in-out{100%,25%,90%,from{opacity:.99}26%,89%{opacity:0}}@keyframes spinner__layer-1-fade-in-out{100%,25%,90%,from{opacity:.99}26%,89%{opacity:0}}@-webkit-keyframes spinner__layer-2-fade-in-out{15%,51%,from{opacity:0}25%,50%{opacity:.99}}@keyframes spinner__layer-2-fade-in-out{15%,51%,from{opacity:0}25%,50%{opacity:.99}}@-webkit-keyframes spinner__layer-3-fade-in-out{40%,76%,from{opacity:0}50%,75%{opacity:.99}}@keyframes spinner__layer-3-fade-in-out{40%,76%,from{opacity:0}50%,75%{opacity:.99}}@-webkit-keyframes spinner__layer-4-fade-in-out{100%,65%,from{opacity:0}75%,90%{opacity:.99}}@keyframes spinner__layer-4-fade-in-out{100%,65%,from{opacity:0}75%,90%{opacity:.99}}.spinner__gap-patch{position:absolute;box-sizing:border-box;top:0;left:45%;width:10%;overflow:hidden}.spinner__gap-patch .spinner__circle{width:1000%;left:-450%}.spinner__circle-clipper{display:inline-block;position:relative;width:50%;overflow:hidden}.spinner__circle-clipper .spinner__circle{width:200%}.spinner__circle{box-sizing:border-box;border-width:3px;border-style:solid;border-bottom-color:transparent!important;border-radius:50%;-webkit-animation:none;animation:none;position:absolute;top:0;right:0;bottom:0;left:0}.spinner__left .spinner__circle{border-right-color:transparent!important;-webkit-transform:rotate(129deg);-ms-transform:rotate(129deg);transform:rotate(129deg)}.spinner.is-active .spinner__left .spinner__circle{-webkit-animation:spinner__left-spin 1333ms cubic-bezier(.4,0,.2,1) infinite both;animation:spinner__left-spin 1333ms cubic-bezier(.4,0,.2,1) infinite both}.spinner__right .spinner__circle{left:-100%;border-left-color:transparent!important;-webkit-transform:rotate(-129deg);-ms-transform:rotate(-129deg);transform:rotate(-129deg)}.spinner.is-active .spinner__right .spinner__circle{-webkit-animation:spinner__right-spin 1333ms cubic-bezier(.4,0,.2,1) infinite both;animation:spinner__right-spin 1333ms cubic-bezier(.4,0,.2,1) infinite both}@-webkit-keyframes spinner__left-spin{from,to{-webkit-transform:rotate(130deg);transform:rotate(130deg)}50%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}}@keyframes spinner__left-spin{from,to{-webkit-transform:rotate(130deg);transform:rotate(130deg)}50%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}}@-webkit-keyframes spinner__right-spin{from,to{-webkit-transform:rotate(-130deg);transform:rotate(-130deg)}50%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}}@keyframes spinner__right-spin{from,to{-webkit-transform:rotate(-130deg);transform:rotate(-130deg)}50%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}}.switch{position:relative;z-index:1;box-sizing:border-box;width:100%;height:24px;margin:0;padding:0;overflow:visible;-webkit-touch-callout:none;user-select:none}.switch.is-upgraded{padding-left:28px}.switch.is-upgraded .switch__input{position:absolute;width:0;height:0;margin:0;padding:0;opacity:0;-ms-appearance:none;-moz-appearance:none;-webkit-appearance:none;appearance:none;border:none}.switch__track{background:rgba(0,0,0,.26);position:absolute;left:0;top:5px;height:14px;width:36px;border-radius:14px;cursor:pointer}.switch.is-checked .switch__track{background:rgba(63,81,181,.5)}.switch.is-disabled .switch__track{background:rgba(0,0,0,.12);cursor:auto}.switch__thumb{background:#fafafa;position:absolute;left:0;top:2px;height:20px;width:20px;cursor:pointer;-webkit-transition-duration:.28s;transition-duration:.28s;-webkit-transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(.4,0,.2,1);transition-property:left}.switch-ripple,.switch__thumb{border-radius:50%;-webkit-transition-property:left}.switch.is-checked .switch__thumb{background:#3f51b5;left:16px;box-shadow:0 3px 4px 0 rgba(0,0,0,.14),0 3px 3px -2px rgba(0,0,0,.2),0 1px 8px 0 rgba(0,0,0,.12)}.switch.is-disabled .switch__thumb{background:#bdbdbd;cursor:auto}.switch__focus-helper{position:absolute;top:50%;left:50%;-webkit-transform:translate(-4px,-4px);-ms-transform:translate(-4px,-4px);transform:translate(-4px,-4px);box-sizing:border-box;width:8px;height:8px;border-radius:50%;background-color:transparent}.switch.is-focused .switch__focus-helper{box-shadow:0 0 0 20px rgba(0,0,0,.1);background-color:rgba(0,0,0,.1)}.switch.is-focused.is-checked .switch__focus-helper{box-shadow:0 0 0 20px rgba(63,81,181,.26);background-color:rgba(63,81,181,.26)}.switch__label{position:relative;cursor:pointer;font-size:16px;margin:0;left:24px}.switch.is-disabled .switch__label{color:#bdbdbd;cursor:auto}.switch-ripple{position:absolute;top:-12px;left:-14px;width:48px;height:48px;cursor:pointer;overflow:hidden;-webkit-transition-duration:.4s;transition-duration:.4s;-webkit-transition-timing-function:step-end;transition-timing-function:step-end;transition-property:left}.switch-ripple .ripple{background:#3f51b5}.switch.is-disabled .switch-ripple{cursor:auto}.switch.is-disabled .switch-ripple .ripple{background:0 0}.switch.is-checked .switch-ripple{cursor:auto;left:2px}.tabs{display:block;width:100%}.tabs__tab-bar{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-align-content:space-between;-ms-flex-line-pack:justify;align-content:space-between;-webkit-box-align:start;-webkit-align-items:flex-start;-ms-flex-align:start;align-items:flex-start;height:48px;padding:0;margin:0;border-bottom:1px solid #e0e0e0}.tabs__tab{margin:0;border:none;padding:0 24px;float:left;position:relative;display:block;color:red;height:48px;line-height:48px;font-size:14px;color:rgba(0,0,0,.54);overflow:hidden}.tabs.is-upgraded .tabs__tab.is-active{color:rgba(0,0,0,.87)}.tabs.is-upgraded .tabs__tab.is-active:after{height:2px;width:100%;display:block;content:" ";bottom:0;left:0;position:absolute;background:#3f51b5;-webkit-animation:border-expand .2s cubic-bezier(.4,0,.4,1) .01s alternate forwards;animation:border-expand .2s cubic-bezier(.4,0,.4,1) .01s alternate forwards;-webkit-transition:all 1s cubic-bezier(.4,0,1,1);transition:all 1s cubic-bezier(.4,0,1,1)}.tabs__tab .tabs-ripple{display:block;position:absolute;height:100%;width:100%;left:0;top:0;z-index:1;overflow:hidden}.tabs__tab .tabs-ripple .ripple{background:#3f51b5}.tabs__panel{display:block}.tabs.is-upgraded .tabs__panel{display:none}.tabs.is-upgraded .tabs__panel.is-active{display:block}@-webkit-keyframes border-expand{0%{opacity:0;width:0}100%{opacity:1;width:100%}}@keyframes border-expand{0%{opacity:0;width:0}100%{opacity:1;width:100%}}.textfield{position:relative;font-size:16px;display:inline-block;box-sizing:border-box;width:300px;max-width:100%;margin:0;padding:20px 0}.textfield .button{position:absolute;bottom:20px}.textfield--align-right{text-align:right}.textfield--full-width{width:100%}.textfield--expandable{min-width:32px;width:auto;min-height:32px}.textfield__input,.textfield__label{display:block;font-size:16px;width:100%;text-align:left}.textfield__input{border:none;border-bottom:1px solid rgba(0,0,0,.12);margin:0;padding:4px 0;background:16px;color:inherit}.textfield.is-invalid .textfield__input{border-color:#de3226;box-shadow:none}.textfield.is-disabled .textfield__input{background-color:transparent;border-bottom:1px dotted rgba(0,0,0,.12)}.textfield textarea.textfield__input{display:block}.textfield__label{bottom:0;color:rgba(0,0,0,.26);left:0;right:0;pointer-events:none;position:absolute;top:24px;overflow:hidden}.textfield.is-dirty .textfield__label{visibility:hidden}.textfield--floating-label .textfield__label{-webkit-transition-duration:.2s;transition-duration:.2s;-webkit-transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(.4,0,.2,1)}.textfield--floating-label.is-dirty .textfield__label,.textfield--floating-label.is-focused .textfield__label{color:#3f51b5;font-size:12px;top:4px;visibility:visible}.textfield--floating-label.is-invalid .textfield__label,.textfield__error{color:#de3226;font-size:12px}.textfield--floating-label.is-dirty .textfield__expandable-holder .textfield__label,.textfield--floating-label.is-focused .textfield__expandable-holder .textfield__label{top:-16px}.textfield__label:after{background-color:#3f51b5;bottom:20px;content:'';height:2px;left:45%;position:absolute;-webkit-transition-duration:.2s;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1);visibility:hidden;width:10px}.textfield__expandable-holder,.textfield__label:after{-webkit-transition-timing-function:cubic-bezier(.4,0,.2,1)}.textfield.is-focused .textfield__label:after{left:0;visibility:visible;width:100%}.textfield.is-invalid .textfield__label:after{background-color:#de3226}.textfield__error{position:absolute;margin-top:3px;visibility:hidden;display:block}.textfield.is-invalid .textfield__error{visibility:visible}.textfield__expandable-holder{position:relative;margin-left:32px;-webkit-transition-duration:.2s;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1);display:inline-block;max-width:.1px}.textfield.is-dirty .textfield__expandable-holder,.textfield.is-focused .textfield__expandable-holder{max-width:600px}.textfield__expandable-holder .textfield__label:after{bottom:0}.tooltip{-webkit-transform:scale(0);-ms-transform:scale(0);transform:scale(0);-webkit-transform-origin:top center;-ms-transform-origin:top center;transform-origin:top center;z-index:999;background:rgba(97,97,97,.9);border-radius:2px;color:#fff;display:inline-block;font-size:10px;line-height:14px;max-width:170px;position:fixed;top:-500px;left:-500px;padding:8px}.skinned-content,.skinned-page{background-color:transparent;background-repeat:no-repeat;background-attachment:scroll}.tooltip.is-active{-webkit-animation:pulse 200ms cubic-bezier(0,0,.2,1) forwards;animation:pulse 200ms cubic-bezier(0,0,.2,1) forwards}.tooltip--large{line-height:14px;font-size:14px;padding:16px}@-webkit-keyframes pulse{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0}50%{-webkit-transform:scale(.99);transform:scale(.99)}100%{-webkit-transform:scale(1);transform:scale(1);opacity:1;visibility:visible}}@keyframes pulse{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0}50%{-webkit-transform:scale(.99);transform:scale(.99)}100%{-webkit-transform:scale(1);transform:scale(1);opacity:1;visibility:visible}}.glow--inset{box-shadow:inset 0 0 12px #000,inset 0 0 2px #999,inset 0 4px 20px -5px #555}.glow--2dp{box-shadow:0 2px 2px 0 rgba(255,255,255,.24),0 3px 1px -2px rgba(255,255,255,.3),0 1px 5px 0 rgba(255,255,255,.22)}.shadow--2dp{box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)}.shadow--3dp{box-shadow:0 3px 4px 0 rgba(0,0,0,.14),0 3px 3px -2px rgba(0,0,0,.2),0 1px 8px 0 rgba(0,0,0,.12)}.shadow--4dp{box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.2)}.shadow--6dp{box-shadow:0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12),0 3px 5px -1px rgba(0,0,0,.2)}.shadow--8dp{box-shadow:0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12),0 5px 5px -3px rgba(0,0,0,.2)}.shadow--16dp{box-shadow:0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12),0 8px 10px -5px rgba(0,0,0,.2)}.grid{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:row wrap;-ms-flex-flow:row wrap;flex-flow:row wrap;margin:0 auto;-webkit-box-align:stretch;-webkit-align-items:stretch;-ms-flex-align:stretch;align-items:stretch}.grid.no-spacing{padding:0}.cell{box-sizing:border-box}.cell-top{-webkit-align-self:flex-start;-ms-flex-item-align:start;align-self:flex-start}.cell-middle{-webkit-align-self:center;-ms-flex-item-align:center;align-self:center}.cell-bottom{-webkit-align-self:flex-end;-ms-flex-item-align:end;align-self:flex-end}.cell-stretch{-webkit-align-self:stretch;-ms-flex-item-align:stretch;align-self:stretch}.grid.no-spacing>.cell{margin:0}@media (max-width:479px){.grid{padding:8px}.cell{margin:8px;width:calc(100% - 16px)}.no-spacing>.cell{width:100%}.cell-hide-phone{display:none!important}.cell-1-col{width:calc(25% - 16px)}.no-spacing>.cell-1-col{width:25%}.cell-1-col-phone.cell-1-col-phone{width:calc(25% - 16px)}.no-spacing>.cell-1-col-phone.cell-1-col-phone{width:25%}.cell-2-col{width:calc(50% - 16px)}.no-spacing>.cell-2-col{width:50%}.cell-2-col-phone.cell-2-col-phone{width:calc(50% - 16px)}.no-spacing>.cell-2-col-phone.cell-2-col-phone{width:50%}.cell-3-col{width:calc(75% - 16px)}.no-spacing>.cell-3-col{width:75%}.cell-3-col-phone.cell-3-col-phone{width:calc(75% - 16px)}.no-spacing>.cell-3-col-phone.cell-3-col-phone{width:75%}.cell-4-col{width:calc(100% - 16px)}.no-spacing>.cell-4-col{width:100%}.cell-4-col-phone.cell-4-col-phone{width:calc(100% - 16px)}.no-spacing>.cell-4-col-phone.cell-4-col-phone{width:100%}.cell-5-col{width:calc(100% - 16px)}.no-spacing>.cell-5-col{width:100%}.cell-5-col-phone.cell-5-col-phone{width:calc(100% - 16px)}.no-spacing>.cell-5-col-phone.cell-5-col-phone{width:100%}.cell-6-col{width:calc(100% - 16px)}.no-spacing>.cell-6-col{width:100%}.cell-6-col-phone.cell-6-col-phone{width:calc(100% - 16px)}.no-spacing>.cell-6-col-phone.cell-6-col-phone{width:100%}.cell-7-col{width:calc(100% - 16px)}.no-spacing>.cell-7-col{width:100%}.cell-7-col-phone.cell-7-col-phone{width:calc(100% - 16px)}.no-spacing>.cell-7-col-phone.cell-7-col-phone{width:100%}.cell-8-col{width:calc(100% - 16px)}.no-spacing>.cell-8-col{width:100%}.cell-8-col-phone.cell-8-col-phone{width:calc(100% - 16px)}.no-spacing>.cell-8-col-phone.cell-8-col-phone{width:100%}.cell-9-col{width:calc(100% - 16px)}.no-spacing>.cell-9-col{width:100%}.cell-9-col-phone.cell-9-col-phone{width:calc(100% - 16px)}.no-spacing>.cell-9-col-phone.cell-9-col-phone{width:100%}.cell-10-col{width:calc(100% - 16px)}.no-spacing>.cell-10-col{width:100%}.cell-10-col-phone.cell-10-col-phone{width:calc(100% - 16px)}.no-spacing>.cell-10-col-phone.cell-10-col-phone{width:100%}.cell-11-col{width:calc(100% - 16px)}.no-spacing>.cell-11-col{width:100%}.cell-11-col-phone.cell-11-col-phone{width:calc(100% - 16px)}.no-spacing>.cell-11-col-phone.cell-11-col-phone{width:100%}.cell-12-col{width:calc(100% - 16px)}.no-spacing>.cell-12-col{width:100%}.cell-12-col-phone.cell-12-col-phone{width:calc(100% - 16px)}.no-spacing>.cell-12-col-phone.cell-12-col-phone{width:100%}}@media (min-width:480px) and (max-width:839px){.grid{padding:8px}.cell{margin:8px;width:calc(50% - 16px)}.no-spacing>.cell{width:50%}.cell-hide-tablet{display:none!important}.cell-1-col{width:calc(12.5% - 16px)}.no-spacing>.cell-1-col{width:12.5%}.cell-1-col-tablet.cell-1-col-tablet{width:calc(12.5% - 16px)}.no-spacing>.cell-1-col-tablet.cell-1-col-tablet{width:12.5%}.cell-2-col{width:calc(25% - 16px)}.no-spacing>.cell-2-col{width:25%}.cell-2-col-tablet.cell-2-col-tablet{width:calc(25% - 16px)}.no-spacing>.cell-2-col-tablet.cell-2-col-tablet{width:25%}.cell-3-col{width:calc(37.5% - 16px)}.no-spacing>.cell-3-col{width:37.5%}.cell-3-col-tablet.cell-3-col-tablet{width:calc(37.5% - 16px)}.no-spacing>.cell-3-col-tablet.cell-3-col-tablet{width:37.5%}.cell-4-col{width:calc(50% - 16px)}.no-spacing>.cell-4-col{width:50%}.cell-4-col-tablet.cell-4-col-tablet{width:calc(50% - 16px)}.no-spacing>.cell-4-col-tablet.cell-4-col-tablet{width:50%}.cell-5-col{width:calc(62.5% - 16px)}.no-spacing>.cell-5-col{width:62.5%}.cell-5-col-tablet.cell-5-col-tablet{width:calc(62.5% - 16px)}.no-spacing>.cell-5-col-tablet.cell-5-col-tablet{width:62.5%}.cell-6-col{width:calc(75% - 16px)}.no-spacing>.cell-6-col{width:75%}.cell-6-col-tablet.cell-6-col-tablet{width:calc(75% - 16px)}.no-spacing>.cell-6-col-tablet.cell-6-col-tablet{width:75%}.cell-7-col{width:calc(87.5% - 16px)}.no-spacing>.cell-7-col{width:87.5%}.cell-7-col-tablet.cell-7-col-tablet{width:calc(87.5% - 16px)}.no-spacing>.cell-7-col-tablet.cell-7-col-tablet{width:87.5%}.cell-8-col{width:calc(100% - 16px)}.no-spacing>.cell-8-col{width:100%}.cell-8-col-tablet.cell-8-col-tablet{width:calc(100% - 16px)}.no-spacing>.cell-8-col-tablet.cell-8-col-tablet{width:100%}.cell-9-col{width:calc(100% - 16px)}.no-spacing>.cell-9-col{width:100%}.cell-9-col-tablet.cell-9-col-tablet{width:calc(100% - 16px)}.no-spacing>.cell-9-col-tablet.cell-9-col-tablet{width:100%}.cell-10-col{width:calc(100% - 16px)}.no-spacing>.cell-10-col{width:100%}.cell-10-col-tablet.cell-10-col-tablet{width:calc(100% - 16px)}.no-spacing>.cell-10-col-tablet.cell-10-col-tablet{width:100%}.cell-11-col{width:calc(100% - 16px)}.no-spacing>.cell-11-col{width:100%}.cell-11-col-tablet.cell-11-col-tablet{width:calc(100% - 16px)}.no-spacing>.cell-11-col-tablet.cell-11-col-tablet{width:100%}.cell-12-col{width:calc(100% - 16px)}.no-spacing>.cell-12-col{width:100%}.cell-12-col-tablet.cell-12-col-tablet{width:calc(100% - 16px)}.no-spacing>.cell-12-col-tablet.cell-12-col-tablet{width:100%}}@media (min-width:840px){.grid{padding:8px}.cell{margin:8px;width:calc(33.3333333333% - 16px)}.no-spacing>.cell{width:33.3333333333%}.cell-hide-desktop{display:none!important}.cell-1-col{width:calc(8.3333333333% - 16px)}.no-spacing>.cell-1-col{width:8.3333333333%}.cell-1-col-desktop.cell-1-col-desktop{width:calc(8.3333333333% - 16px)}.no-spacing>.cell-1-col-desktop.cell-1-col-desktop{width:8.3333333333%}.cell-2-col{width:calc(16.6666666667% - 16px)}.no-spacing>.cell-2-col{width:16.6666666667%}.cell-2-col-desktop.cell-2-col-desktop{width:calc(16.6666666667% - 16px)}.no-spacing>.cell-2-col-desktop.cell-2-col-desktop{width:16.6666666667%}.cell-3-col{width:calc(25% - 16px)}.no-spacing>.cell-3-col{width:25%}.cell-3-col-desktop.cell-3-col-desktop{width:calc(25% - 16px)}.no-spacing>.cell-3-col-desktop.cell-3-col-desktop{width:25%}.cell-4-col{width:calc(33.3333333333% - 16px)}.no-spacing>.cell-4-col{width:33.3333333333%}.cell-4-col-desktop.cell-4-col-desktop{width:calc(33.3333333333% - 16px)}.no-spacing>.cell-4-col-desktop.cell-4-col-desktop{width:33.3333333333%}.cell-5-col{width:calc(41.6666666667% - 16px)}.no-spacing>.cell-5-col{width:41.6666666667%}.cell-5-col-desktop.cell-5-col-desktop{width:calc(41.6666666667% - 16px)}.no-spacing>.cell-5-col-desktop.cell-5-col-desktop{width:41.6666666667%}.cell-6-col{width:calc(50% - 16px)}.no-spacing>.cell-6-col{width:50%}.cell-6-col-desktop.cell-6-col-desktop{width:calc(50% - 16px)}.no-spacing>.cell-6-col-desktop.cell-6-col-desktop{width:50%}.cell-7-col{width:calc(58.3333333333% - 16px)}.no-spacing>.cell-7-col{width:58.3333333333%}.cell-7-col-desktop.cell-7-col-desktop{width:calc(58.3333333333% - 16px)}.no-spacing>.cell-7-col-desktop.cell-7-col-desktop{width:58.3333333333%}.cell-8-col{width:calc(66.6666666667% - 16px)}.no-spacing>.cell-8-col{width:66.6666666667%}.cell-8-col-desktop.cell-8-col-desktop{width:calc(66.6666666667% - 16px)}.no-spacing>.cell-8-col-desktop.cell-8-col-desktop{width:66.6666666667%}.cell-9-col{width:calc(75% - 16px)}.no-spacing>.cell-9-col{width:75%}.cell-9-col-desktop.cell-9-col-desktop{width:calc(75% - 16px)}.no-spacing>.cell-9-col-desktop.cell-9-col-desktop{width:75%}.cell-10-col{width:calc(83.3333333333% - 16px)}.no-spacing>.cell-10-col{width:83.3333333333%}.cell-10-col-desktop.cell-10-col-desktop{width:calc(83.3333333333% - 16px)}.no-spacing>.cell-10-col-desktop.cell-10-col-desktop{width:83.3333333333%}.cell-11-col{width:calc(91.6666666667% - 16px)}.no-spacing>.cell-11-col{width:91.6666666667%}.cell-11-col-desktop.cell-11-col-desktop{width:calc(91.6666666667% - 16px)}.no-spacing>.cell-11-col-desktop.cell-11-col-desktop{width:91.6666666667%}.cell-12-col{width:calc(100% - 16px)}.no-spacing>.cell-12-col{width:100%}.cell-12-col-desktop.cell-12-col-desktop{width:calc(100% - 16px)}.no-spacing>.cell-12-col-desktop.cell-12-col-desktop{width:100%}}.skinned-page{width:100%;height:100%;position:fixed;background-size:cover;background-position:center center;z-index:0}.skinned-content{background-size:100%;background-position:top center;z-index:2}header,section{position:relative;width:100%;height:auto;text-align:center;padding:0}@media (min-width:40em){header{padding:100px 0 50px}section{padding:50px 0}}.border--top{border-top:1px solid rgba(0,0,0,.1)}.border--bottom{border-bottom:1px solid rgba(0,0,0,.1)}.flex--expand{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.flex--centered{width:100%;-webkit-align-self:center;-ms-flex-item-align:center;align-self:center;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center}.absolute--overlay{position:absolute;top:0;left:0;width:100%;height:100%}.container>a>img,.container>img{display:inline-block;height:auto}.container,.media-viewer{position:relative;margin-right:auto;margin-left:auto}.container{padding:0}.container:after,.container:before{content:" ";display:table}.container>a{display:inline-block;max-width:600px;padding:4px;line-height:1.428571429;margin-right:auto;margin-left:auto;border:1px solid rgba(0,0,0,.75);border-radius:4px;transition:all .2s ease-in-out}.container>a,.media-viewer>a,.media-viewer>embed,.media-viewer>iframe,.media-viewer>object{min-height:80%;background-color:rgba(255,255,255,.65);box-shadow:0 0 35px rgba(0,0,0,.5);-webkit-transition:all .2s ease-in-out}.container-subtitle,.container-title{font-family:Roboto,Helvetica,Arial,sans-serif;text-align:center;margin-top:24px;line-height:1}.container>a>img{width:100%}.container>img{width:100%;max-width:600px}@media (min-width:40em){.container{padding:16px;max-width:80%}}.container-title{font-size:45px;font-weight:400;margin-bottom:24px}.container-subtitle{font-size:20px;font-weight:500;letter-spacing:.02em;margin-bottom:16px}.type,pre .keyword,pre .marker,pre .operator{font-weight:700}code,span.parameter,tt{font-family:monospace}.media-viewer{width:100%;max-width:600px;height:0;padding-bottom:56.25%;padding-top:25px}.media-viewer>a,.media-viewer>embed,.media-viewer>iframe,.media-viewer>object{display:block;position:absolute;top:0;left:0;width:100%;height:auto;padding:4px;line-height:1.428571429;border:1px solid rgba(0,0,0,.75);border-radius:4px;transition:all .2s ease-in-out}.media-viewer>a>img,.media-viewer>embed>img,.media-viewer>iframe>img,.media-viewer>object>img{display:inline-block;width:100%;height:100%!important}.no-phone{display:none}.no-desktop{display:block}@media (min-width:40em){.no-phone{display:block}.no-desktop{display:none}}code,tt{font-size:1.1em}p.name,pre{font-family:"Andale Mono",monospace}span.parameter:after{content:":"}span.types:before{content:"("}span.types:after{content:")"}.type{font-style:italic}blockquote{margin-left:3em}p.name{padding-top:1em}pre{background-color:#f5f5f5;border:1px solid silver;padding:10px;margin:10px 0;overflow:auto}pre.example{font-size:.85em}table.index{border:1px #00007f}#content,#main{border-left:2px solid #ccc}table.index td{text-align:left;vertical-align:top}#container{margin-left:1em;margin-right:1em;background-color:#f0f0f0}#product{text-align:center;border-bottom:1px solid #ccc;background-color:#fff}#main,#navigation{background-color:#f0f0f0}#product big{font-size:2em}#navigation{float:left;width:14em;vertical-align:top;overflow:visible}#navigation h2{background-color:#e7e7e7;font-size:1.1em;color:#000;text-align:left;padding:.2em;border-top:1px solid #ddd;border-bottom:1px solid #ddd}#about,#content{background-color:#fff}#navigation ul{font-size:1em;list-style-type:none;margin:1px 1px 10px}#navigation li{text-indent:-1em;display:block;margin:3px 0 0 22px}#navigation li li a{margin:0 3px 0 -1em}#content{margin-left:14em;padding:1em;width:700px;border-right:2px solid #ccc}table.function_list td.summary,table.module_list td.summary{width:100%}#about{padding:5px;border-top:2px solid #ccc}@media print{#container,#content,#main{background-color:#fff}#main{border-left:0}#container{margin-left:2%;margin-right:2%}#content{padding:1em}#navigation{display:none}pre.example{font-family:"Andale Mono",monospace;font-size:10pt;page-break-inside:avoid}}table.function_list td,table.module_list td{border-width:1px;padding:3px;border-style:solid;border-color:#ccc}table.function_list td.name,table.module_list td.name{background-color:#f0f0f0;min-width:200px}table.module_list{border-width:1px;border-style:solid;border-color:#ccc}table.function_list{border-width:1px;border-style:solid;border-color:#ccc}ul.nowrap{overflow:auto}dl.function dt,dl.table dt{border-top:1px solid #ccc;padding-top:1em}dl.function dd,dl.table dd{padding-bottom:1em;margin:10px 0 0 20px}dl.function h3,dl.table h3{font-size:.95em}ol ol,ol ul,ul ol,ul ul{margin-top:0}a:target+*{background-color:#FF9}pre .comment{color:#558817}pre .constant{color:#a8660d}pre .escape{color:#844631}pre .keyword{color:#aa5050}pre .library{color:#0e7c6b}pre .marker{color:#512b1e;background:#fedc56}pre .string{color:#8080ff}pre .number{color:#f8660d}pre .operator{color:#2239a8}pre .prepro,pre .preprocessor{color:#a33243}pre .global,pre .user-keyword{color:purple}pre .prompt{color:#558817}pre .url{color:#272fc2;text-decoration:underline}
+/***
+* BASE64 IMAGES
+*/
+.card-header,.comic,.menu-icon{background-size:cover;background-repeat:no-repeat;background-position:center}.menu-icon{display:inline-block;width:32px;height:32px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAA20SURBVHhe7ZoNVFRlGscV0/zY0nXTzpqZ9kG6YhtBCDknYjbrZFnJirrsup4sE53CsQmTSIqyb3MPNasrspEuak1iHjpoYri2BVmEYuzaKT8S3JzyizqyseTC3f//5X0u74yDgtk3D+d3Lg6Xuff/e5/73vcyduqojuqojuqojuqojjptdUYQx1fnINpXJ3//77haTq6zQpdjlOMMEh0V3dXEcRVe1+hdw/Q2dLW8f/MxTlXkaajQB5fgYNDgQd108O6asxC6twmCnw16COHDw7vFJcQxHkWQwGO0vH8YGTN2TBe8KvueWN5pKvtgSUlJ5sF5kmHJv0vuooI7ENiBcKMcPwf9wQBwAUJfaILQQ8BAzbkI3wf0AkpGfHy8KUOF5jHw3mfwOBBwJomMiuwGuhr7fjMVGR3ZNYDLA4mLjutpMMKZ4BxmcD2k/cYEr90IuF8zDmcU6CsMGzqsG0lMSlTbYPA7PzOJuyquB05Tuqalc75ujYwa2RX0DBaQcF1CX9AL4RUSXMBJXZ/1UNYbmr0+n2+XSdaDWdXY53EwA9yI0ElagiJmZMzFoN+1113bj1sJnhCfMBBE4XcuM6CAvpRgiPha3aAMSnjQD6HDhcyHMlPiRsX90uACCZ42O21D4ZrCXZv/vtkirdYxy9pcgn2aqZ4ze85usFGLSEJoJxARF+vgwtySt0uaXHe7FokEBL8InCcinKOdcgm1uxvUNa6D9wHnARV8YvJEH8IfXrFyxWGEHgHCNdH4upXBgVV7sFanPEFBgMmenXsUvpU+izIw8m4EH6dxctQ9d3tWcku8Od4mSgA7IWAcQl8NIgBF9I24LKInkLmhfRJiYmN6xMXCZDNRpLS01A8sjR+vXSlk3J9Rk/dCXl19fb0lUEIARwNpreqO1ikRldsrGz1pnsPgX+CTkuISy5vtJfMQ2AEera3Fe2nQeXvBHRiI0SA8/ur4wZkPZMrE2DYJDK6xg4P7CgsL9elZSkDiuMQX8Po4gvClJa+X2MHLy8styLAK1xaSYzbrArC2vLNFv2PrBQk2FKAliIBfFRUV2QIoGd23F+GVBAoIkkABrUoIM8ODi3X4JXIAqaeffpoCknX4GoZnmeHZDQi9PW1O2os26WmrDLZnP5e9jxLaKkKP/l91+IEUkJGRsdcUoCWwG5YjPL9sCRHDI7ohZ0gJnXFf7mqGB/EcdfvNtQCOPgT4tYBUCc8ywu9By74a54ibAEYYDDdJnpycAApERKiS0V/2t2WNGP1NrhmuP+jwSgBouQzkUtMg9A4tQYnAvr1DSsAihMvRHtjhHHAlKS4utmq/CLxO64/WW8Ubiq3MBzO3YYadmJGeUVmxrcKqP4bWB2xH8Cl+Pw1MwTjdAIbbBK4LhmGhE6NJLNlUUhM8RxStK7IW/mmhsNo92z0Ni6CBoA+BxEHg6vWvrVfdZ1ZDQ4NV9EqRlTE3g7fam8CvIyIizkdcc06wiwLOwk5KQOa8TPsNKUEQAQj/OAXk5+cfNgVwFNCSFLAApCH0dC2hmQSn00TCaxZseReXg2bZsmUiYEtKSspqkIzQQ08kwO4Ewd+MSKAAkTD/sfnNAmT0QX/spEaeb6be0AgfJGCW7oDjBBB2AkRYrumufyD4o9gqUu9KXWmSmZn5IkH4WQTvVwa+BPvBDoRm+GycVzKIP1UB7ARQjfCxQV0QIGAwRn53sAD/Qf+JBPhDCRDQ1gGUvVkWQPDPMfJfYuRtMPr7EJwCeEmxA64B0VrCwLYKEAkY9c3HCWDFXBPzi8TbEp8o24YTMzBlyAE4ujiZWWAi5oLHKcUG+1TXVCv4/UlLL4Aa6huawXVrFo+3ft16q+r9qv/l5uT6cUwum/n80Lzyc8SRG7kPj2/OH5XvV1pFxRh5gwJfwSEwBZGPvxNQgnexd+zUKVPdwAt2UkBARwQJQBdMQkf4TQEmwbNy7aEgZKQM6urqbIJ/pidZHl89OzB8KAG8e3mf9arQC7MXbkiZkeIhntmeKeByxD1eACtyKB4rmxlGeBAIqLYD6ZPA9b1NSRjtzEMX+CmBl4aMvGzrvkCINgjgyk8RInQo9DmsCCWA4TUHEJrPCfK02QsRJfhJBSgJ+CW2GiUEC2A7zmJowtsiRcB4Y/nWcvsyoABWw3/R3qD+PxBpIK0fHLAt8DwQfgYJIaAOHbBOB1fhCSK2KkBeCMNjbTfQE/TFCIeD0VlZWepaLSvH3ABy83Jrx9wwJrvwlULLv89vcYt/vzX/4fl7wOflW8q/AlbFuxUBBE96q15eFUDRerS4wY6qHQFsr9xu0uS5x7MXi7E/+/1+i2wt36rIez5vJ847CXJiwfnjJ4zvQpjPyNpqiQRbwOZNeKQ1BBAEfsEUwC1DQwD5ijJwlzhgcDBjns0BxcMZnwkQ8BlCH8l4IOMItxSQvzy/VQEbN2y0ClYXWIiYH0JAIxZNfwkh4ITBpZQABKQAO3wrAo4yuBBwvQO2ZRs6oAk0EIS3KADt+hSBgA/AQRFhCiAUAGqDBUgXnLIAhGMH9KcACU8REh6XgOW518PLoEBGXzpAEAEmJyuZxeUSwIz9JkTcyy0lMKSMPmhieEpoRUDjgqcWPHEqArogfA+E6w9ulpPnY2jFVoykpmBNQZPb494G/Fu34aAh2LENrWtw3D5VgXAClUmUk27Z22VWztKcKgxESqo7tWrH+3gfUFQIQcC3yldXWVHZyPPD1n5fdlfu87kNuAy9ePjpj0xh+F6u/5NWF3aAFnAh3rypFQFW3rI89VxAEfw+IBzgY6nQHgEiQQv4TAt4kechEjDLH0OoBgYX5H1Xr1lNAR9OmjBpZpCANhU7QM0BFPBI1iMhBdAyD0YBYBYk5Lnd7k/y8vA4DPgzUwDhrSuAoJWaKYBQAKCAeRCwiefBkUf4RvAFQ/O1UALABoTnlxKgaVtpAb1NAcQUsOfjPaoDdBeoZwNcrzdAwjzBdbfrMc1iUJ67NPdjsBfUYET2zX+qhdzlubUI3WSKMDuAIqT9Eb4BW9X6oQSw/YHvlAXwExfQKzIicljaPWluoCYpUwCR29Pc9Lnbsf9tmHBuAVEChIzU/JaMGT3m95p7CF7jkrqF0c7709PTD61ds9Yivpd8X3rSPKV4KNrNh6fSd0o5AdfhtQP8nhNv1fYqG3Zl9rPZ3BZPmz5tvCPeMQD0Sp6c3KUT/z7cjuqsPnGJwHqgWYJV/FqxGvVgAatW4lYGsP9CLcCWgFB2eODGc3kl8Av5K/I/Jx6PRwEBz1ACwn8IDiF4BdgPEerpEaEZvhrbJt4tzPD887sIAMU4/hUI3xecifDtF8CPmgwBXgqQ4DwQkQ4QCVjcvIED36Ul3ILQLyFgzY4PsB+gQBN5XZDbKbsAIl5F8CMMTyDiCMJvlfDsAPncQdCjvwujPwfH7xMw+u0UwOqsBdgS8OZNFMA7AJHghoBjOPAT3GLfY2Y4iLBWv4zJycD8GZHWFxEcdQSX8BVofxWecC0i58Hw3DI8JKjwZNCQQS2jfyoCUu5I6Rp9RXRP0A9cgollA1C3LG75JysT+Qvvvn/vU1tZOOU8n6OgwCDsbiJqAbMUdxC9mFmyeIm1pXTLp64Zrn/ie3vSK3+7XE2G+i5h5SzO4XZ3bk7u0uio6AjAia8TP9xRSb5OIbgtIS46bsTMGTNtCfkr8wMEyIgwPLYNCL0fbBWys7M3m2A2Jx8jPLGDUwJBaIb/NFR4bhlcwqdOT73PDK+rTQufk5ZIgAD14SckLKIE2mdwGQkd3JaQOjt1P67l+eAuMB4r89GaS4nT4bwEXEtc013LEPo9we1yv4fwi9kFZniBEnT4jQzvjHX2DQp/eosStACR4PEu8paBxtYEsP0hgeuEEwkQKGIsuFNTKMFxGSgkOGgCNRCwBOGTGJ7oU/3GqrP+zwlngrPBANwpwqfeOTXVm+P9SH1QGXRNi5iFzyzkg82HuCvwfp8IYhQOZ6TBzbdPu/12sNPr9X4l4UvfLFXgNWuFb0WTZh3EznKOcl4KzgV9QHd9zbd9wdPuap5N+b9AKIF/YQmjBFuE1/t6KAHE5/OpJTJWiDW2CITWuNLnpL/F4AxrBg8SwODPjYwdOZRI8CHnD+mOc+H1fnqu+VZLbieQwG7Ad7LEVCIQaqRrpiudJxssgMhSlSgRDueTCF69di1ufyDUqOvv9+L75Qh/kw7flTA8jv0tBJdqEdCMIYBAAD9c6Q8Jk8DrGPW61gSwGyQ4P3sgZnDAblDBcVnwS426hCc45rcYPnTJCYRhBpbbZW8wAFySMi3FvXjR4vUigE+UJrJOENg1DI/tLmwXocv+6BjlGKr/k9VZeLDpCfjhpkj/TsObpSTohZMtAneLoZqbIOKEArgSlPDoolvBCAku4DX23fcqeMjSEnjbFJQIb7a32hRQ9BrWEDo8aGR4XDoqPOglwfXbsqTjfhhlCFASECoKEt4SAVgF2uEho1IHN/+O/4OvzslJyV1AN0eso3d0bHQ4yfXlfgRkUUPWT54w2Y155CJwDujJOQW///1v9zaUaltKwDZMJKTMTvnIDM9PooLC/6hKrl01e2sBYxDe++T8J8cyPD+O+7GGl7IFMDwI059B2qTcmfKjDR9QCBqLZ/fBvKcTTHg/jNvb6SoI6A4BXMaqjgByifzk6icZuqM6qqM66ntQnTr9HxzJ0mIqNkzFAAAAAElFTkSuQmCC)}.comic{background-image:url(data:image/png;base64,/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAICAgICAgICAgIDAgICAwQDAgIDBAUEBAQEBAUGBQUFBQUFBgYHBwgHBwYJCQoKCQkMDAwMDAwMDAwMDAwMDAz/2wBDAQMDAwUEBQkGBgkNCwkLDQ8ODg4ODw8MDAwMDA8PDAwMDAwMDwwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wgARCACGAMgDAREAAhEBAxEB/8QAGgABAQEBAQEBAAAAAAAAAAAAAQACAwQFCP/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAfwwBAQAIEREIGwAjIEZET3mTBgyAEBEBEQkZACAhE+sYORk5gZMkQEREAERkBAhPsGDBgyYMmTICRGSECMkQCRH1DIGQMgYMkAERAZIgAiEj6BkCIjIGTJEZIDJEQGSISPYACRGjJABkAAyQAAgQkeowAkJo0IAZMgZICAAIQA7mQA0Jo2JERgDIEAgQAAGyMkJojoaESIDIGRICMgAEQARsTRo6GyNABkAAyZMARo5kREaI0Js6HQ2AnMyYMmTIERGCEiASNGzodDZEYMHMyBEAmzkIEQEImzRo2IGTBgyRohNCcBICICETRo2RGTIEImyNEeQhIgAiE0aNEIAQmjRoRMniECEAMkJo0JoiIhNGzZER//EABwQAQACAgMBAAAAAAAAAAAAABEAUBBAATBBcP/aAAgBAQABBQIhsEIfBC2ND3D0GuWbcllxGOP/xAAUEQEAAAAAAAAAAAAAAAAAAACA/9oACAEDAQE/AVT/AP/EABQRAQAAAAAAAAAAAAAAAAAAAID/2gAIAQIBAT8BVP8A/8QAIRAAAQMDBAMAAAAAAAAAAAAAEQCB8BAhYDAxUHFhcJH/2gAIAQEABj8Cy+/pib4XIebkNJBrOKMV0nFD4KcfU4TFdXThf//EACcQAAECBAUFAQEBAAAAAAAAAAABESExUWFBcYGR8BChscHR8eEg/9oACAEBAAE/IXy5+9Dfo2E2Gv2Mp9dOk8OmnR6nYcdsR80HIDjmSDi82+XF454FZ5FGtuQk3TfpDraX+Xc8kciJxyFej2FhSCPGWMZyogqVwg2OsZ0FS1oT/aipiLkdukvhxB/E+kTsa6j1UzOQ6Ls4y9XXW/Vc1SlXjFmnYlpBMYQtK4vKcuR9ux5GWgy6nYivSOA1+nEMp0QZby5gK7xga9MzLcYyj1fB7Qm+86qfsJaWHSevLDfL/pOUchucwGqK3cVunmpmGI5GxroSx0G45jOJIaN6DE+lR8MKLSkpXH3eOd7jrlHOJzSmRnI1/RapgNmNQzmYzIoJdejvI0dTFITFhiqUJwMYFGh4MKlYEU16PjhO34PHLDmI/JcUdE5AfHDkzz7+m6qmJ4mMWOcQb9MnuR2GqQG1JQWA1iVrngdxEoVgR/g6zi6eRx0k246/R2i5xh+SI8r9GxQakjimEJ9y4oqPLo2OxSEsTNW6QJRWAvYjoWHHtDAWEZWQcdrjrgh6mJxFE3NpPp8M8J6ycVF9a/RU1XAXcWpMbcnlkNpiMMv8GpAUiqxXJBlrOf8AD2KqYyHX6Rex2IBHEVpFWEuKd6/0fOuv2wjOnbWbexoaNp8uNvj/AH0NzmIzLlLWhdlyw3PozVeev0ZNpEJTeHLExe+/VHX3n0ewq7lXHwgt+j/g4iz7uOvK/biZzl7b2STR5YVysZ64zk8dqGp5bJZ3Gk0sGtP+jd0eNPlhm9+niR190zuZStIjp2b4Ouor7+SbDapNRt6XInHJjEKGUHJYiLmOzdv4J2ZuWH1f1X0Iv3X7Y4mtIbjI2Em0+XF49qw2qb1u+07C0pKkaexdJNODfLiq/PJd4zv+ji8c5y56KbQ5Lp46MaxOOZqcQQRs/nwRa6+hJStrTO4iyvJrTaML1HRrM+lWeVhfKOsnjtQe0ZJm0s7ir9h6FXx2rlYfeng82qXwPA0e2tBlvZMSeMGd2wrlYQ99NurdMySJ75MTvh/PY+Ums3wf+vavofy+tfgdLYs3dvYssGZrN8FXi2r6HvflziDc5gc5c46T/RvkJfg2TXlrahvVXm/2nTsd6f7/AD+Cb0wEXw72rlYdp6+n9E/E8aZ3HWDYy5buLmjM72rlYV8YVI/y9M7l53ETJmdcq/wZZY450zUdSKwbF6Z3G+ouDVysN9VbYQ9DLRaNi8ITnc5y5zljik+cj/nI256H4o/OYj/xvXs2k2nw4r+/Rq0e/wBKN29ezakZfhyPu9BNa3/aiaUhLS1RktJoyaM7UPrxm8Jw0IYwrhPGUJ1MMGZoSaFtSjsmj7lbKxPdthI6o4sIjZdHHEX4ez45WzSuJPg/wRXZsXbSY8ODfRVZVuRNxJtj3E9CK7LVFXYeFCI0L7uSVUohWbG0sKdURJqpFHR3xlYYyLFlWirI153FY6xZCKaiu2tVFgqpiiLXWzysf//aAAwDAQACAAMAAAAQEAAgkAAgkEgkgAAEEEkAAkgEAAAAEgAgggEgkEkggEggkEkEkgAEEAgggAkgggAgEgggEAkgkkAggEEEggkAkEkAEgEAAgAAgEgkEEgEkgAkAAAkkAgEEkEAEkggEgAgAkAAEgAEAEAgAEAEgkkkAEkkEkgAAgEkgkAAAEEAkAAEggAkEgAEkEgkAggAkAAEkkgEAEkAgEEgAgggkgkAH//EABQRAQAAAAAAAAAAAAAAAAAAAID/2gAIAQMBAT8QVP8A/8QAFBEBAAAAAAAAAAAAAAAAAAAAgP/aAAgBAgEBPxBU/wD/xAAlEAEBAAIDAAEEAgMBAAAAAAABEQAhMUFRYXGBkbGhwdHh8PH/2gAIAQEAAT8Q3UKqkOWdG/uchibHZONcpejvEbsALWydP08x5VsnNnxNbwQPL/nOQqU8rLv64m6yvVJPsZQ/t615hQu3c+v0Lgzc4eLv70zUV1dHK/a5IGic3f8AOEvDXK9XBR9TnbrAK9uzX8/1g+L6hy/X35zo03Zr9eHp3kDVDu9T6eeGR3Dx2/d98xeza/H+fcq3ddeT6TvGlkfrrKUH45q/+4edm00/Mf3ny152Q/GsVEQRARUIsLNDrti7WqoqiKkinSddsAeTSc15Z2vZ1+omhQ0FU+z2fObV0X+H5/rEW0PRreR3tDv/ANH8ZHmI7UnHbjyDdcF98PnKoJs4sS/Gn85e+b/Me9f+4q6vOx7dc/X4ywEEfxvrNui8bHj/AL5yaER/7fOb7Fps5/O8qcRXSd/kzZNqeJzilkDp79KOJwSknPX0P6xF3s5ZOfjNFJHiG/vN4Cfmj/eNsi/E5MeygO2c/bADaAEwgdEdv1DGrCKEk2ZBGy7HGbIbV2FJaFeHbvO0jq0Jo8vB6YABoO+JHj89Yw6U9T95LF2fO3+sTbro2f1gxDfKRr8V/OVC65Csn36+MtXUObz38v43rIB1p0FHc473854gJdTRz1vXziHCBlUEOqb4xHPIzf6/xjFDk9UvHH1y9lm9wfGr/OWhUh7GfKUwcEhb5fOd/jEOTXAD35TvGxTVda6PrqYfUvZ/5myX5eMFsvNZf+1lSVPig/vEiIwagoRQ5F30x4QgICgWwPJPPTNyIRIiogsFmg67Yitq8khpIpNJ0d4m4Cqxl28/f06xKQXggsPL584iq300+mRCL9fF++cnfuyw/OHddG3fDOfrkiqnUv3ie95BSGnMQ44Xs+cd1dpst99nXV5xYVZ39U54d/GsRsBtDcfT5/rEibaUmnXErR7kRFLWk/PkweAVtXlL2B3kSt+kUo9bwJyFdQ4fizj5xEarWo5ZOobMKVXZORv49yIxQdyn0ub4qC6T/ebbtR4b/WNMKqmghaHA/MyjESJHBBNi69HeIciBS8Rspd+DrIiLsgFGmQVfsesQ4LFLFpyDYPq8408CxdcTtn8jEygIXZNfO9/HmISoWHtr1oxAKu3h9PcbA3OzR+x3k2ha4i93kgfOIAIb0HP4GaxGixVlW/e/7zXoDwCb16JvNShEqh0fJv65IVAJqlp67NfGG2015T48e8RwFOwG2aOecDgDshCe9/nJFkHdjDnmajksKvXS9fPeIbFthrnkn+5mlTc4Jb17+s3dj3DZ+85BJzERv2xoV0BSE2VGnXbFqqqqSRiRE0OjvAFaoTrarUO17OsocEok5BShl25esXS9AO4IcCzg6e8qqqXmJvwx4fDvAOzaYgu3mHb75kHEWFNk+E6+XEyrYR611kv4Ihbz85B0q9QPzmgKAROOf7xsBNaqcfjFCemuSbwUIDe42+ccYgvNOG/G2d4hK3pufgdvznQ2kZUnZvr5xiiaZZEL8aEwqitcb3sTgO/MbpA4H5TjnzH0w8uvePxm3ag64n8ayUvK6N8cvmCvI36d/wCcRwQjZ2hspfsOssVeUUii8C3a6esrgocGxU5j/J7wkSRKJ0nk49LvN3wi3idRqnh1lbui1wLp6z6HjJTjQeqPBvT695SamihJo5Q5l6lx5aKJe4PFLd9eZWgBNIy3yjz8423leFJrn/rglObKxB/cPrvJKAJ1Xv4jiKuk8C6/GPLYV7YccRwBsFe2cH1MU2aHeh58ZMNHpd874vXeeRCTb/28V5Ca0N/zveLGa9S7+nH4xSCKBDW/pnBG3/vpzgTSEiu1+7h660hu/md5yJCUm2rde+nBioACbE5J2FOPXrHoQ0LoIPHwfvBARgO7ap3AzcCo3ir7DK60BEBxOxPPnDVNVlHTXG+jz3KqxW1ALob3+BjsB7qlrzNb+fM0CLEpwH36+ceVdQg0a6vnx7i6Iiaicu9e/GAohPibPn/eUHMHbJs9uJQmcqDfd5/PnI/oN4W3bA6R78usenycQvvO8V58CyP03c5YTW7N/oz4Chxzv7+YQaB8HAfP3wRqp45f6y132rz88YUAHUTkT79fOVIl3qc0N75vrf8AYmcI2APnW9HxiEJXxya4wbNcvK/zgq2Btmj+PnOFSLzwff4wZGw4Xh+368ynldwOQeea7+cZQE2QmqjuefPudO4Ej9p+mKCqhEO58jm9ed51Ha6UunFP5YSEKLRo079nz7g7eOSxdWU26vWIjrHgdp5048JSpF3e9zIoJBsNL7J/NyA6HZ3r3g18Yot6ghBV4Gd+Nx4g7QDG9/f1w0J4XiCdz4wcC8Ax8eNfrJ5BnYfHIXFFCNtEKn1c+3EXhsXjUv69M0BVBxuHXfGUkbXbf4mVLSLpYb36uOnQoeOH+J/GGzV9CP8ArHCkC8zv6YHZ8pPuh+9Zw0NKR6/p64NUiGArNcVNfHuCipTzhYPMAIQBdYpV2G/0xIIBs96AVKn91x2Ztd9aHWhrX3ZfPFapzU8l+jIAPUzXrhU98/jFGo0VWa+vP1ZatKO9m6ccCPnuO4vola899GBSR2I2R6EGnr1iKaICKydb/g9/q7OxfQN9UmnzBdlKohQvMN79MgNocyUD6a4+ca1dDBqg/fcPnvFwEeag9NnvhlHTt4sOOvtgpG/Gv+82T+EQ6xZVKeR8mAeFN1t84JjBL3oVS4RKgOgKOv5wAKT210e8OvjHdjiPJpdXi/HmFAGVi7HTgcEqSl6Clj6an5fzgiGpycCel7YiXYBAOxX1FwRsCj8Oza/f9mfUJeoRcN6nrnERnpQpdjF7fZjSqiQC1F+4U4eseWqlANOra6/kxdBdVGqDlAujs7/nEBqQWu9HM/gdft3jQMRa14F1tOHrFQWKmpfRfTt7/atDWrqghyzz47zktEBWJH30ejHYoiQfC2Hl8esWZH2H5+N+5oKB9Xf3scEqNDgt57w02rTet+5eH3GifHeAwoHT/wAxTgFOW6305o27cXe/Z7kIJE5Quzf+WCTZHB0ef5YCx0hbo2pU1+2Q5orKcscyf1d4IRgxQBYLdcr+GCxIL7hpZZ/dclY9peFUTSDBQsNHcLQahp88IKIFQTRbqbPXWI44IXgsHX2cnF2jyLedcQEHw7x6ocCHJNs/kZBr7QaTuPnr1iFW64uhDiocePeNYwFaqA09n4HeAiO9qTbXmEa+nWEoJojpHnr7nrCESW8HN8+uDJrhTrjufGJaro2XfPDsxJaGmQLPl53gpoVMvWufc7olnyvz1ivrDhZby5uh9lrT8T95pY8ugZZ4P84O10tn5T9JiTaAj8K8i7vXmXBQ3k717Xr/AM4xVjdPMWvsGHNpy2M1f+n7kFo6ENUUbOS4K0CQwu91q/f24wdIqNGwIO4ug7O8BOgaqUrhHrrCqrQIKqi8F2K9PWa8aYCL6PqdveUTRULZpA2ngdneBuroVUoDww5Ho6yjY3RC7rhPa9PX6ESFVCYk5BXSdvf7CL2OATLp07XOC9nm3XPp144nKaqpI/F+fPc/91z9j30yFAERAq99PZ7hUTnrevzA157jp455rP8AnINzZsgd/NyFAB1JZ+PjCLKnCL+/69w5Crz036c/Zk6REKxNXnbl/hhpKE+AeL+/vebWtVFacqcNT8so2qJHW9J0n9H5xJE0GCEBfHY/hkKJQMZo64Ppfc5LaxURvCJpPyxVYraTbft+RkOOAoB1HkPT16yHTEQGuofP8HvJekVtSN6v6HeB4tFTZTbCb9HWHGSAi+DzGP1vWBREoA8ILKmvTvJd8rqQCApH6XeETUCDXeumefHWP5DEax6F7Xp6x3BKqA1XwfTt7z6bJSEEO/gOzIzaznZdPD8j0dYyw02Itb59fnNKUvgTnudE7e8o1EKXuT36fGF4oBNPQ/u9eYLeKCfK/K8/OdNNcDlHcbqdveaKMNDNadL/AMcYUXSJtuK+m7+GK9FbQbadxMuZttpQY7h16wmXsCNCOn/hiiDRAO0WQW7Xp6ycAash2j1477ZFgg3AaQ5Qug7O8CViSIJVkePXTAlhAhW0UibvoesKAJRA0gNDdDvtgUEREQCISguh32yxroAQKCtNbHrpkqINElQiG8n11zRxRG6218v5GH8yANI+fs9ZstB1K0Q6XzxxTQ20ahRO39MNWbjabb8XV9xAIF1CbJ9usfmHT59/jzKW1d3em+/X4wVkSV0VL5/eCcIGR315/lgDo3Lws4vk69wY6Vjfm+8fjeMIjQliIXnhu/hlEljsYfC/v7i8/KdKx1w0/wAs72k0Tbpt4+88zREas5ALuuz11k6kBppHln2uAu21aoipJAa8O8DRBIoQELahPtdYOAgBArDKKb9uspbohGsNBTR7d5Kq1UJAS0RwH3MBA0IkSNOyOT69ZJAAMCGxQPL7gcUz0D5Th9/XDpBguivGvPjvLQAFUdXlrs8OsQBjEF8Gb+fHNDvAHncf799yq8Jo12/HR8ZV95d87OecQTXyP0f385taccz58weK6dNS/wCPjBsnoKdnvvGvMG63rX8cQffnB3Wnm03wnnz7iVBzTvGl4/TNoklp2x8t7+PMRtuB5RrQX+TkCyoITe5PD33FYzZuUhvX8DrIAUAbtj3Xt1p6yB7UAKOyA3Xrti1GssIbEF167Yi4KsLyROXjpghXZJXlheWmumEWYMSNRDdfkZSaUkEiIn5HbP/Z);background-color:#000;background-attachment:scroll;border:1px solid #333;box-shadow:5px 7px 20px #000;padding:16px;margin-bottom:16px}.card-header{color:#fff;background-image:url(data:image/png;base64,/9j/4AAQSkZJRgABAQEASABIAAD//gATQ3JlYXRlZCB3aXRoIEdJTVD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wgARCABGAZADAREAAhEBAxEB/8QAHAAAAgMBAQEBAAAAAAAAAAAAAAECAwQFBgcI/8QAGQEBAQEBAQEAAAAAAAAAAAAAAAECAwQF/9oADAMBAAIQAxAAAAH8qAM3y5LJylhATlsSS1kRUhJGkdTN5llNAAAAAAAAAAAAAAAEhEhEisAPRZvEssKKCyNONvWLChWQFQgsE70vIswUCAAAAAYABYdLluNM3Y3KXL0xPOqrmJn3msjYoq1KwA9Xm8CyNRJw6UrgIVogqpEQqB6zNwp5zRgIkXxoLzVLoM5cnXlZWc/O7eXbfz6YOmNeNVWQri9uG7HTDrGHpzFzXEaQAeuzeJZRRDlmSK7CK6QyIzcWR6GXRLgsuLAJGcy1QU1TZmKbAhLWdTO/X+L6GbWPO9/N2efasz6wly6xnucu8VpXZVYgA9fm85d0nLavyNS9La1Zal1FkSKayplrPZnrOZ7KKFkBYiGIRWsUmMmX46e5535z0jJx1eeoVj3zkuTU1GUx2XRoNkvoI1yxq+KjIZ6qjYTPJ9MRoJkgBK1itiAArRolCI6plBlqMrPpXDp8065pltXq89X516qTNqcHUoueNqY9To5t8uqWnUtlvw3Z6cbpjKTXXG+46B5LrgIE0YBQIJYEFhDsZEsJ0hRYMQCPccd+R3OVUpeljV0uHebBpzdSqxm3GtMuqa0RozbZqjU4nTmpoSNlzPTPO9MgpWkqAQXPLEYhgSRKE0azRDJ0DOpjUZXjea5jVNZrmFMgjIU4ZIkrCFVaCiAFhTQAAAAIAAAGAAIYwAAJQDUABJEjQAH/xAAoEAABBAICAgICAgMBAAAAAAABAAIDBBESBRMQIRQgIjIVIyQwMUD/2gAIAQEAAQUC86egsLXwPa0TY8rpRZharCwseCmR5bKNZP8A0YPjVYWv0jbln/HZ8tOD2pp8OOD6Cysr2sFOaQKo2gvN1m/3CNzlUpdstiiYZJOOkiNWgx8dihE2GOr/AGsqN3cIy5keCQdsez+zvQ2P0qDaGQYmWqx9XFZYi72ZCt34y5FcV+VbmI9XfQNJQrSlDj53IcVOU3hnpvCq1Siqqlxn4iCpEvlVYkeVrtT7gt2AySS/eYX1rr/i154C+vBCYYv1rVo8yY9yODEz83Ywic/Xjvde03W15awuXW5Y8ORcUJEXIRlyFKVwbxdkrjqr6rblL5jRwkSbxMAX8dCxf48aN+s1O5WsEeZjCPLvKPKWCjetFOlnctCV1BPaGpvs1z12JdYhUe58PIOdJavSSRwlx/joX7wRxCnDBM0tEu7WlrDn8n/XiDmHkABcpy0GPmliMzLD1DFaDm0Ljj/C2ChwBQ4CFDhqrUKtOFfJpRKTlagR5yunc2Mu5iXL+VskfPtPBlmKLNj1haAJo+uUZAF3BZEgazXw61KrFJr1vkl+VF+zsFz6bSvgzODqMjAa7sx1zGrH/UIHFCo4pnHZVOsK4kqwzObDVjXyqbE7mKrUedjCfzjkeXtOVG7ObXNyPZG7L11NXWFgfRwymtDCfY+5WowIxktDkW4Z4k/SpJ2Vp2ddhRnWTP8Aa6XLYbLXxyESL45zM4BTHPgSuTXSla2CA2w9NqPehxuQ3jImGcNZJ7e3X2D6jwL3OY+GFlF2PvlbtRlauwoSrtXat8howiV+yxhYWPB9jh5A6hyrCy/vlBb5Y5zcSPxI+w96ktSNa6Qv8h6bKhOmzoWcL5aks7GZ20ucLfK3Xb+V6fsrB3o+1khbrZbLZbIu95WVlYWVlZKGWrsKDgtlssrZbrZcdY647020xkDkWRk66o7J5ytlt4Jz4ytl2FdpXcV3OXc5bEnYrYrYrYoykjKysrPjKz/uysrKyspry1OeXLsK7CuwrsK3Wfr/AP/EACURAAICAQIGAgMAAAAAAAAAAAABAhEhEBIDIDAxQFATIkJDcf/aAAgBAwEBPwHo17K/LhHcyUadDg0RhayOCoirFEx2EivR1zQ74Nrc8k19Sf1Q42qIx2rJ+NkVkoeBefZZfPB/ZDxk4b3ROJmVHEbij9dkXcaEtiyRkXeGdtH0LVFl6UUUVyXpfhOcnhibXY/o9XEoorrZ0fn3yvWjbpRtPjXKx+Uh9Wyyyxu/UX0LLL0v0F9L/8QAJBEAAwABBAIBBQEAAAAAAAAAAAERAhASICEwQDEiMkFCUHH/2gAIAQIBAT8B8N/pT288tq6Mctyos1kZZx9GObpk4PM7+RsvsMXgpS6XSEMvgsw6MPuMPqdE5lTJ7mftDJ9aLv1qUelKXSEIQhCcc1cRV9GajMOlTBJs/cajo3ufQ0SfHgejv4IbdOkbjcbisrOyMhDaQhPPtSP91em4pS8qPXsjIQiIYk9l6s/BOK4VFKPI3Plj7T+RfHFEJxhNIQSnJe09e/JCEJ/ChCE5/wD/xAA0EAACAQIDBQYEBgMBAAAAAAAAAQIRIQMSMRAgIlFxMDIzQWGBBBORoUBCUFJiciOCweH/2gAIAQEABj8C/BpjX6Ch7um5qWvt89kTqu3tFsy4qlC1USUeJKjI5mqN0qiTle9mOStRDWWsdLknThWhkUatE63JRjstvRJr17Lhjb1NEj/w1+5qdJGHLdsqlsOf0PDPJdWcWJFdC+I/ZEVTEnKWnIk8eNOVzTD9zvRXRHm+iMNYSdaPUj8xUSjmJKOrap9TLHSmVDhHX1ON1lq2Z/45ivoSHYY95E9yyqabnIvRlanDCT9hZfh8T1qeGl1ZNTpe6oRWbLR6l5TZo31Z4a9y/wAqP0PFXsfmfRHDhyfU4cGnUtGKO/T2L4sn7l5M8zQ0MJ/yJYr8kca402pV51MjehHK6TbM1avLqfKk1GSVL8hubuTcnR5q0KT8/Mkqj5Ft1r1L6UP88XJehL5cXkrYllwaqXoVjgv3NFE4pxRfG+xec2d2vVl44a/sWnhL+p4leiZ3cR+xw4DfucGDGPV1PyR6I8b6Ivjzf+xdt7NDRdnHNNyhVVTJYkHKE+cXqSzXdRXdtLlPsNPiVdBZeFlsNv1OK2yrFt1LyHR1qZsRVZ3YGsEWv0RbDkzhwfqy2HFCw8al45jCcJOKrehxTlLq9+nZURQ57KbmHLnFGLHlLZF+pF+TLCuq0Gnu2iWid5I77HmlL6jLkormcxVWpc+DnzhT/gqfu7PXZ5FzQ0LbeS3WYfNWJtJ8V1tgxU0E06WFxsST9y/Yq9kSLGuz4aX7XT7kl+G13Jx9amFPkcSUv7XNKdC0q9Tn+Dp+jf/EACkQAQACAQMDAwUBAAMAAAAAAAEAESExQVEQYXEggZGhscHR8OEwQPH/2gAIAQEAAT8h6Gsz9sOvWoJSLcQBO2X69HadDjSph7U/7SV2zKgn1duraaXvNM3hhgC01EJhwK1g95Yy82fiIvYniS1ofBL9svaXFMS564qbDVD0r/hv0fT5LlzxaVeTmPDSya5aCYgC4Fwic0G1g3JYK77u7haKtuDRL2slF+sci1CYqUqlENJWKjHtAgHaHRFKfSewOnCprlJUrqlwqG89rmVe9i4DFw4MxxNoSloVsw3nIfaBuCJ/fPWumongTX175pT90JrJMf8AQCw9XHFEO0MZBbzUF1WoNPLCyx8xfrDRf2No9hkFyEdl6P4laBSDORa+q/E0Dp8qxNK/k+IvxcAfKUIUU0HSfsq4OuauvdiPA0/BLEvzEpZqCM/TomtyqPWli9Mu0u3xphwyoF0lEyU7ygQI5uZwBdKrSfThtKFDuxvxZNZ7kI/bsWbh51swuGMt2o/EGy/ufiGfh933jvm9kwD7BZor/LvGPlQfuaYeS59qP9sHyfATRY4vFdqZdqqci8sxykI0DA+cfmMp52BjAxs2IYAmJWhc03ZxxTGBNd7d/wDYFvC+XIgjVZU+gQUiKzjEJazZsSVMo6McYz2Snh6eyUK3BQRoN53RAZo02mHcVVGxsrCX8b3YNu+8x1fT/wBwpnPJCMvvWDe5I/ME5Pw/Eypfx+lNj4B/cVg3ekdb+ScTDzuf6TtHsfqN4rymUc5WHHKW6cgePTu7Tunidh6KXesSypgTDUM03E0eXhirc0l2tZKu8ShU0HAiE5ZfBgDDIsXirmni7ukPbBGIQA+UNQphDq9ZsU1wE/VYHJ3JVABWsyaPmAWqnBNZKgX8liK2WBHyBNm/K7ln0j4c7Oofv0Q4J2YcR8ehjTBuzVGWDQ9B6FbufaWcENbRHkMJuSyEGsdDamStVftFrdY+su524Epd2fiqhBg8eIEFAKEFFLM2gmusMiN9N4TRw8wVfGJsFCrJ2i6ZeLZuSlY5mCWlmtIuSoNrhlNq7k3jMfc19h/CFWLov0YhCUurlgw1zBHrfSy5QI8SAMNy/QjNRp7RW3zljWa8iUe+8PmiF/ZbwAolGYdBS5IcXlX8v+QfAohvjMFqB8kdvEoBqWMA9imj5itypkg9gTciFENeUOpX0Klcple8Igwd0bSMmusFnLcBWFU3HM8rlyxrfc/MC64ZjRGqcy/MPb6fuuYZnrmIvBG+xCxjWCHOsekuWVHcJqLzPOpltfdllz7DpOjsz/X4ikOqrJ9GFb51hTR7/wB3K41bvCo+NDhlI5IU3i3eXDBiul4MgED6spvG49FWIOG4+WjLS0tLS2Wlpa+u5bLZfS5eXl5eXijW8FB9Pha15jbb0//aAAwDAQACAAMAAAAQkEoif8aCcCckkkkkkkkkkkgAgkj7E79X8UeoEkkkgAgeZohYpYkg4iE2mJ4lcAk1qOpu30fRus8kk86+rfvR53JN9UItWByNsurUkhWf7rx5HTOZAyy6FpypO4roA5XUExe3A2T8X+bWREDUxcaU9ce4FV7DyW/ZNzCptE2Sf5a7JIgZBdJNTpIYBCkkjE+bYkgjIevY/wDAr8/nJIJBJJIABAJJNpAG5JP/xAAiEQADAAIDAAICAwAAAAAAAAAAAREQISAxQTBRQFBhcbH/2gAIAQMBAT8Qz5iZSK4wnF/o7lOMg6LweWIf4CIM0QU1iqBakfSE1vwaqERqY9oiDX0OJcn8dLlD5whMGoJGhtFKchIH4RZkv4/06aHxGgHX9Apjs8GzZIN3ih4WGobKUpSlxCC0MiIiJGiouSisvGTiVb+DENjurwUY9jfY/BFr2JY2ENNsSoCjNUuyLrihRvYpdnQgp6Q2ZWyskERoqRBVhSlZed5LQlpUdiha2GuqL6InpnohsbDEg8QhBEIjRUUr+sNrsYrKUvBZ7y8XN4PCEdPCLujRrEHwLZRQk/RUJ2QVbFISok7x4yhPgXBIhBixc6x0KpSiekNrwb2PY6NvNE8IEosQn4aXRW+yjGTMJmfLMzCZeipjSOuhtjdKMXNKUuFFFKKyv86ispSl4//EACERAAMAAgIDAQADAAAAAAAAAAABERAhIDEwQVFAUGFx/9oACAECAQE/EONy3hS5pS8F/BzLVRricFhiGLr8DKDeBxEOgG4ZNpjIl7E0VMrGhaVlohOvi+xZvPRome3NUVEEYp0fwbZRYqTtjVi9mPEbE3hdBtEd/wCgwXSEYeliTi+xdYeKLbiGpiEIQqIIGonCyijZRWWScITNBCsSiXwVRex7q0JLRIdGMUg9NJDtQ60iaFyLrQrL6Km2O42yL2J7Box/0K+ZiMfYsv6ISQQQnhp3lPVIe9JSRKEOgm1tCfpiQjCixSrBqVlZMrH0gNGtCfSETk/HCcWJGJ1YSpnshDaYmJiy6G0eoj0OBykYmezZ0X4Q9M7c4MeKilKUvjnTExI2JMTUZKEgklmDDEY2GVBkpJhLsSMuaUpcXw0pS4pSiUS7RGuhMW9igiEx1iEIQQQQQiIiEJ+uEEEEEJx//8QAKRABAAICAQMEAgMBAAMAAAAAAQARITFBUWFxgZGhsRDBINHw4TBA8f/aAAgBAQABPxD8aIJkN2l9K0wa6lDaR5hAwF28RLNql8vMbMZE3LNtY8xJ5ngE8gmFoPS4gVWWIpFqX4mOKp/9ELjh/lUNBvSX7Qayk7MvdWXLfk2StrXNtBpko6VFtRELkg6EQCO8y2D5nQv6xhOb5ZvEuhr7luB4FM/ESLj7N/3NiyuRf1LVobW2JceJq7HMQEwWnRSWrwBXk/UCPREr/wAFAlkxKLnzHf0jl8vc0Dh3lVVRoZdTlsrHxLdLFVGgLwYtj6sZBYmzlHfaCGuroqXk71xW4zD4tFuk67UnVM29bPUGw8Md6FZNeTdRRoAqMlWfcxsO3GFtebgo1T2lVALMpx3n0Y7yzk9vyRl7ukuw0vxBlAtEpMeYUdZbd3mCKt+YdxaggCdYZVoC+gzFg8zQ6s5jUxsA2PTNXMpfnQ53zMwHQyr61LCpo/ZfuAYpf6In2hKes8vw3T3cYCIjyVe9TXH/AGZZvC6f0DAb/wAI5qYqlwV7q/UGGg7mlPJrFQV+zqKUwNVdVni9JDKj/wDpix2qv1/ZKkac4PlIPxwkswmNbzCUSQQTfWxF7QxHCEYAzxUC71fbBb6wr5YaNLujoPEeOTJRVu7e1QQIsvE2rfdWOcgb+VufZlJKUfJZ+4zQVtBhYO2GrenaIRsdpaH0P4G5cIsIibEtyqlMMgFJi/10bxBlDuXXTLFdD0HErKjqKZoiyxCZAwhvWsJKFgLHMepXtOTPV1vYlJGvU6VQK53d41Aasf8AeKw8cYSmEbsO0YWBRmERKs7PpNNTlZe1pT9OW8PsiLjFpaPkwLYJwC/tNOJ0D0oYoh/Wj7EoBX+GoqLzqo+Anuul09yKAR6F+CBIsS0hvGJY2uVV+5a+UgZSvpgqau84vEO6CUKos2DvDuMoWh5ta8ymAQlUK/QVFJOMatDl5wnvKM7+0yEd60QczlyLWUvmkyGIbNFHVoT2jQrtsIcjf/Zap0GRAPOq9I2QFWxY09GFWrd/eH3im4sOVQFLW86/gQKDP64nqQr6QVvIsumCo1+2ymeoFEYldDs1iXELdcNes3ELIldZndGW0/UCS54/dB95hQH1KusHXvZCHmn2h9mLgx1uD2k3kvnD5lItD/WzLIGqk37AyvGrTL4hxh82lPdEFRz8jfcDKck2NPtcNO86YHk+Vlkh7Ku/eLlzOAalTTKuJiAUG9o3V3OIEckRoC0EUcQhBsZa4hsrrs1DBuRqgZNW65l2l9QVCy1ozV94UwvI2dqOJohJBHsN16Q4VAaKINlhh1DH2kQUAl9j5lxplWK3xx7+kqGSxcgLB249IbNXTdQ4w1DpPsfitoHljsbogeiWtxbB2qxdSDU06xZywdrX6mCPRRVN4QQs3arTftM9922fuPEq65dBoxtcPmYi1rGT1lHhev8AaAMp8rFSse4wDgvAlTTK7y+gm36hwElWXc3wzSJ5iVKxBYIlTcItt1r0TIh6s5Ynsg4ExAYNgMeIXIeercqFMBBueAgwlrWnQ1v5uXFBVGaClwGjc3vkY8xN1qCmxIPmUYG9OA3/AFGDFCLFB16wmgpi4oopvB3l6Cd4HjLh/DkteYl6koYAhfJOK3bHpMsUyMK5uC7oC3d3lgumcG2Y59CUfM+ACaDF9IlMUVOWrPYuUpFkXkrat3zOAbesYSAvoX9I3WK7pgiFey43KL6QiKLYzUIERlks6ynWKJU0rFPiOWQIbbeMxUo+gM+rluGLoBG5dy11VQz8XZlM5LFdGAl5WV3lJvqXlehBivojb+ocAAiDcYVUDrIEbhL1dOL4YTC1t47Fd7mDp8uB9Uz8wwaUN7sguEEAcCpXv8QxcAYG7XG0+xabMfqJhpQ1X5gOY6qv6l5dG8y8ZlneWBvU6iMK+0C0SopCGGsbGyBSFSjguy1ahL8C+Su1QFKAquF7r4l7FxZiSbL4X9JylOAvkSMHeiL2Mmkww1K+m3vKGm13l3mX6y/WPfGZnqEyWb9VlZRR23LuQOxAvVRSBhzMvV7S7ABxmYUT3leqetcw4K2uTXiXC0Hq5Zd2JnLR7SktAzoljm5kzA9oN3QzPRCEejcamrOfFzNgJVinq/aMAmQy/wDTxiN4eA/Yv9QoCAPN/wBi2RyHiMK+UJynEC7gACnSG9wCctNMwbDF+Z3Pwi8XOIsbgHMWKWLXsUfOP6iMWFMAKGd6d6KbzAtNTvTvRJli3/AU0xVljWJ3p3mWeYtwYwAq/wCFXfiK+6PDgbJ3J3J353YDgLtcv5B4l9Mfw//Z)}.skinned-page{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAC4CAYAAAAMnDLKAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAB3RJTUUH3wgZDwkyIJT6egAAIABJREFUeNrsvXeTLNmR5XdvRKQWpZ9+ryW60Q05wGCwuyR3zcgPxs+2Ri5nhzuDgWy0wtOydGVV6oy4+0cff/UrR9RrkEajGTkZZrCHyr4ZGXHD/bj7cRExhPC/hvWxPtbHv8kjW2/B+lgfawBYH+tjfawBYH2sj/WxBoD1sT7WxxoA1sf6WB9rAFgf62N9rAFgfayP9bEGgPWxPtbHGgDWx/pYH2sAWB/rY32sAWB9rI/1sQaA9bE+1scaANbH+lgfawBYH+tjfawBYH2sj/WxBoD1sT7WxxoA1sf6WB9rAFgf62N9rAFgfayP9bEGgPWxPtbHGgDWx/pYH2sAWB/rY32sAWB9rI/1sQaA9bE+1scaANbH+lgfawBYH+tjfawBYH2sj/WxBoD1sT7WxxoA1sf6WB9rAFgf62N9rAFgfayP9bEGgPWxPtbHGgDWx/pYH2sAWB/rY32sAWB9rI/1sQaA9bE+1scaANbH+lgDwPpYH+tjDQDrY32sjzUArI/1sT7WALA+1sf6+LcMAGm9Netjffz//yjeoewJ/8b/j9xPdPcT33F/dWuvA8Drzhv/H1r7t1z3u9b65xZr/r7u8/XxbxwAKnkCXriSPqfwVBCa6z7/PiW4bm2CV3LdtYSaz/x5uba6Zm3Cf/tb1ianbBV+87r7CO663rU21exR3V6mGmBI71hbBwKp5trqwCa4telvBM3/qyDztwJRugbw/u8Yhnet+VsA/P+NtX/L/vwta9+5vwUWeeX2wpu5kyacnBdeYm38nrVeae066sCgqgGDyikkryF+z9pwzXljzTmza9bav6X7/czdR3jHWgoAr82fI70DSDN3bXWCkb5nrX8G1629DsT4e9XfoPD8vb9FeP3+f58sVfg3XgPK/hquWxuuMUrX7cffujbUgHDdnqZ3eHPV96y9zhiEEELIQwj/k1NwKlBVwxMkxyFUTvGvEwRudOmE14NK7pQ5vGPtdQqTueug0ER8lmrOW9UouF9bB5yZO69/0O9SWr9PdUoba/a0esfa5K67qvmMClRdo5hVjWEIbp+uA5S6/Yg1zy/W7Eedx1anbO/ygN7lWYV3eJ91BscrXHLPq7rmHH/L2rr9SDX7HGv2+vu89OCe39t7yUMI/wkflm7jeBOlU0yvsOGaC85qPudFlPhuDoGp3AVHp4iFAxReM5W2umatnYPCX+FeolPa3AEH7zEPIaycYvmHHQG65TUP0IcihVvrBbdubZ2VrbvvygFTVgM+fCa2p9yPUAOkHlA8cFc1FrgOYKM7f8C1hBr5SDXGoqpRxOA8TRqcUAN2qcYrSk4W6u4xfc9aD5rXgY/3iryHXV3jvaQaz/ivDLB5AKUT3CiBDlCgiE2mq2trTUGLa246Ohd4hY3PncBEtyErp2yVeyhU2pUT9OTOneMhLLFhXgjq7rHCfvCBVFhLRalqFKis2Y9Us9Zb5KxGgcI1+/EuQKmuseqhBmCra6xNcNfXcF4jBT1ec97rPLbrALbOOCUHYFzrQSJBfrOaeyy/xzgRYEsnG8HJWOH2g3sRvwdg3+XtZs6zCjXebnL7+04DnIcQ/gcn0EsnXB7Vcvz3JW7oXdaUysbPg3so0T3A0l1b5R5qXvMA+bAoYAW+66+7qgGJVAMoDexF6byf6LyAphPm5O5x5RTI7zO9mVWNN0OgCTV7x/Atd2tDzd5Fp8zVNbxB6fajvMbaB1x3dCBROmufub1ruN/j3tXtR+XANNZwMdd5d9ftXR3A2nXkNdbUe2z0lFKNh53X7Gnu9i7UeLvXATd1yxvgurCzCiHk5gGYMufO2vDEDVzEEhuRXyMYdizw8Aq3EV6gV26DvMtd4L95QKHVW+G6CicwuUPilRP+CvceXbqU19fAPftzJF2fX0tACdinpQPYBNBM13gzyQEeAaVwrqsX6JWzQHSNV/i7UeOhhBr5CE74yxoFWtYAh/cOGgDXqga460Ciusaart4RAtaBcbpGgaoa8GFITMXyMkP5yGr2vwI40jhlDsDCNYCyuub3qndwaQTNkIcQ/gN+zB7QAl+m27iqiYcX+G7jHWvtvBGAUjlAYWy5dGtLPIDo1nJDuXbpAIVeRIl78x5D7ly1FSxME8pWOquScC9VCKHlQofMPUQqRcspUHBrGZI13X4QJEKNopRO8IID48oJvweU3FlTeltN7HPlAKVyMWvDgV3mPC4KdMudN9bsB72t0hmiOuD2IcjS7VOoMTgejKsa41S6e1k6Q/R9+8FzZDWhJQ0Zz8vsVB3oUo9iTZYnGAm4wuKixtWygxu9hBDZxZXO5UsOUKJzue2m6V14QCmdFSugHHMIZrNGgQoXgkQoceniLsbwK5ynAWFYOeHN3drCgUR5jQKt8JBs7eoaF5PhigeU6GLR6wAlOdc/XAMosSYUymq8iwouc4nPs2usqZePokaBcqcUfu9SDUh4MM5cCFK3d3UKG2CcfPhWun3OagxOclwY9650slQXEhcuTCudbi2ct5vjnGWNt0sPpagJtd+uNQ7Au4Klc7kLh1SFI8f8A7SHssLaHIKeOUCpHPjYjdAz4EOZO0BZ1bjnFR5s7rwOupgNbOzcWbbKudENh/KVs0DR3bedf4FztLBfpbtHWkgCSRP7Ed1aKhC9jiWAzXtxmQNCxur0aOoAparxlDLdY3L3SFnKIAe87pYLB1ZYWzgFb0Iul1C4rEbuGjUAG3DeEl5Ygee4cmFC7gxZ5q6lvIYUXDiD4wGd+zGHLjVr9j/iuhd4jk3c08KtJaDQE8nJL+QhhP/RucaVU4oZhCJ3VoKoVmhtxOcZLnaJC27opnkOcglLfRadAi2x1jZsgWto6e8SG0RmngrUwgYvHNhVeIABSpUBJAgedDGp4HMoS8vtMb0LWr3gBMaupQlXdYnfbF4DKAHueeksfYH9pIX0IF9dAz70tlaQiVbNfjRdfGsg0b4GULx82NrKWT1vIUt3DZkzOJnbZyqmN065A5+V2/+yBny8Iatw73XGKXMGpwH5Lx1HlAEk7LzRhYYF7nOOczXw3BY4X2Yk4C/hxhQ1lpOpuplzISoofu5QhnFQCwAydXEN0ZyoVmgtY1Yq3ALnNZBYQvALt7YB4V3A0hYu/pvBIrQdoBTOnSdItHHOlfNQknPjOlAouv6eFCwBPjmEN2KfVri+NvbQ7wfTYEsIbUdrCSgEHwp02ylm4bIMBJ8Wrs17iJ4Parv4NuAclXOXW3BlF/BQ2lhLMEgAlBLnJWdTOuM0c+cgM7+EAtI4rfB7ZnAW13gXq+8xOHxec7fPoYZQtd+cOv2M2H8Cx9u1xgF4kqNwzOQUClTH9vq1+TWueHRgM62xCAY0FSx4oY2wB9DGOebwVgp9Z45N7cDKzoHyTWch5xAMrrX7aODvKdC9DeHye5ccynedAkVnIed48F0IeIl7oMtdubUMyQpYhQUEoQOlXkJpDdy4tg13eonf8NzACoDSBqBUuIbKKUWJ6y6h1MzSzCHoHezPqqamYw5Z6sFdX0A+GpBF7keJc3BtBvlYYW2BZ57huZRY23JyR0+QpOAca5sA4qV73gmGtnRrF84DiPDG6YUFGPG3HsCvIRA5FNNO0nLEUZ1LRZDInEVIcLlX8AIKBxKlQ2jb6ImzFAkbVAEt7borPCyuXQEBm1i7lCAmuElLbKitLQE+EcIxxz23tGfpGrd9ge/6EKSBe1y6vaOFpNXrOovHUCOvUYqVC0N8DFm680Y888LFofabXVw/ASVzYEwPpYX94NrShXornH/pYvjKxeX0rFY1BHMG4S+1H8sa4xQhSwF7Vzo3muHlDDLcgSFbOBDMXTjbcRmJEvfH9PXceTOl4ylIuM9qdIteKZ/5JA8h/EfcyNSlsFiBtdADzFz8ssRaWr0mNmqG77RcwQMtZBsPdIp4P8ODSrAIdlMTKFYTAr2CkFZYa2jYwT1UEDjb6AmEoOu4BAMDA6wpBK9bY/XMsnVwDSvnllXYj6jzzFzcSy9sDne9hzhx6fiLCoIX4InksLIBXhgJTu4z3eius3glvt90HlTHZY/oAredy912efiFC8nmAHUfly/gPdArImncwHkT7mXpdCDCEJFU7cBjm+D3OtiPZY3cMZxtu1x+CVniM1m5EKR0MlPguggSuQNBz9u89WDzEMK/x003oXAzp+AZ3F+ykiQd5tqICK8gYOMbENIZLthAgmkRphxnQLkOUHjhYvjoztODJZ3jOgo87AoWocQ9BiBm7ryLHjyhGQSijbUreBdGxkzxENrO5aZAmyexwt+FE7AGrPUMYNdwNQ+MLXtO2TJX5s0QpI99WDrCK+C+UwhhgP1dOK8vOTDuwzuaw7K24d6XLkPQwtoEZamwzy1Y4JmLe7OauhWGThW8mMKBcQRILCAfDVjqqmbvlgCJDDJd4R4rACzBJ6upOi0d+Mwc0Uoif4lQI3OAQnI+WQjQxgZdAHEbLlYJAIMYQhgDfVtwTedOyDOtzeD6cC0Ft4GNmONhM94PcKMJKG1cy8IV67RcuFIAUEqXJSCSToC+fTw8uo28R3toQ+fCJQiMhTb2uwNYoDmuuQFPpC4OXYCNbrh4k0phlnOJ58qUI4m+rlubuxhyDsDow9KTnCSgBIAEwS4g7IwAlAqAktfE8NFlkPoARA8oWY3LvYLBIUjQXZ4BjL3X0biGNA5u7VzruB8z5zHQeufOk+Y+t51xygFAyXFF9KCm4GwarkhsGUJomQcQJLxNCHTpynvptpw7gi65WJQKfoEfJ8qvsNaQ6hxZh7ZLC64APoXOG50rXjkSzH5zAsHpQLB9zNqG0M6ArG1kEwKs6dI9lAogMXehRuWAsARI0LWmKzjGHgxqXO4GrMUEe9t3aboVhKDpQhC6qUuAYAOhTQlAqQCwcyhyG1Zp7jyUOTyD3HlxM1gkU/w5LB2Z9QmUwgNKctmmsQPuJfaDBodk9AL7UbjrIMcT4MEyzGVvB9OqU1jktuMMCshXpXtsYC3BJ3eyPoG318azI6BEJ6NMVcc8hPAr50avEMOTEadStMB6+rSZ3cgY6biGu+ASGx0AEgWEbOoImwogUUBhg7MIXTzgC3g2HceS0z1va21AHMoahjnAq1NDCrIKawrhH0DZ5s7FL13apo/7mGPPLNyYOBdzgRAkAHxKCDRJqQY8lARAIWlGgZ4ARPqOTGLtRVfnXeH3kiNJzUPqOW+mDYVZORe4h7CLnJKBB8PLHhRlBkHv4RoSvk/uKEdY5wGWxNsY4VAXBm7p0tctyNJca5nVWCHs6uBZzcAdFQjrAvRiDt1qI2yfOVKwg+9eOPJ7ydJ0IwHniKlJMEzC1TZLVo5N4eIXQH+7wQ4E5sIp0BwkVoGbqUIII+R0yXLPYMHsms4BPoz3JwCeBjbChLLvMhLRcSA+3rf4fOwIM5KNc2x8V9ewcKFQCQVtwd2dwlUl0UqLUIUQNrQPC8RzAS76GN8bwNIwP9/GeYMLQZg+MkAJAB9yJTkE2oAquBCkg3ua4B57jtRiTUfPAUrPgfEM920Au4RikiSdwBMcAHwWznuqnIX0pGDTecEzhHr0oC5cRoLE6QqecRNrDQhZsbiEHLSw1mSshfsgsd52gNKCsV64attWCGFuHADdSVOWHJasCfdrCYE2HoBNPy0IxlQPsHDkmBUNUcHP8bDN1ZrDpesCuUZ42B2gvCFxF+7YCFa6B+VZAqjs+keIhfsuhi+wmU2tTXDlFwDCEg+lpb0zQd9EfcIUFqvpyL8Z3Ny+/p5if5oOHI2kMpCYwdtgldkU97iBfa5cFoUgsdJ1z10FYQGDQZDYcEQteZhCMmMAu4HYeop9bAN0be+G8PLG4GG62DuThR7c/zE8pQ4Ac6nf7ACYps4DKJyn2oHiz5yHkju9KJx3EZ2L33CeGVPShXSiAS+kCX5mAY+hobXsSG1jL+Zurf3e214A5vgjkCoLIZy5irsc1ruCy9dwCtQG2kzgHkagWsLFNUBczAEyhmr2sLrO65ghJOhBCMb6O0I4xvhuD8J57hR2CS8ggxdg+5HDbV8CVAIedgOuYJLwknRbam3CfqygbAvEoTMQtR0I/wrgY8LB9GkPFnKB0MHCjQn2g/n2OQRoA+clGK9gOQ2MNhHvVy5MYwZpFULYwu8tIUsGQucAuC1XhLWAfLW01kB9yxWUmYVsY5+XAMsSIL3EOZsA46l7VlOAYBOciPFjXVcktkS83wKvMIJX3YUbP8M+BOhW5uQmwutrwmhPEB724FGeu6raVh5C+KkjRJa4uI4jEsYuZ29u6AkUqMCPrxwCNkMIp84NyQAoC8SbbSkbXa0CXMQULmrHCUHfVX0RDMzFLHGOJty1c1xXHw9wDG+mgc9sbzbgJY3B9jNmTVg7B7FlhycFaSGb8CTsHHQZ5+AAzELOAT4l9mMGXmWAtfb3CoAygZUfAKCXAIIeADbD2hmebRvhxgL3nRCCBAhvJUApa/gI89jOwWlswC1ewPobmXYCD3IL/3+KsM08mjOkBocA/AlCGzMWY2QDevCMZvAMGgCJ5OSxgMGJjhQMzoNlTcfKpU9z6VYDhHkObzKDEcl1jwULgRaIFdoOqc500w2knyKEg/nJcygqc5wXLt7PEGqsoPj2YDNsHtNmcwlMBUtROrdxAeHdAHKPatxGs0LnOm8EKUhAYZHMCK7aABbZhKMNr+ocYLSp77L0uAGloRu3Dc5hBnKoBXfUOIUduJZTF95kENwV3P6Oc6N7AEGzkAP8e4HUVNfF8FOEYptYW+IaLN4dI+7eci5+21X6XSC7sgWXm260ycI5jMUmWHNavT4M2RLnpSGzax1AH2bwhkxJT13KN+K5zvQZ5S5BljhRa6LPMngX0YXPERxPA5mUGe6RBjjWVIFaUdApyd48hPDzcLV3uAFChIrPwp4A12cO17iHC5y4yqUOGOETIFcX1mAKl9uU+gS1BgMAyhgsdAByJzwsIyRHsIwWVowgTJtI/VxAIJrwLkwgN5EKG4GNb+NeTNAHALcLxKEtuOdkas1aj2HFGM+RaDLF59roSpUvIAR7yEgsXbVnDpKuDCHsQtimiNGbSLGVCFemCNVmAKqGi8sHUA7uR9M1y0wRkmy6ayOnkRB2rgSaNBQ5MlFB8mEhyC54kguAYAF5NpDbhNydIRSzkPYCxmHLufgBIVbuZH0Dz/jcedes8htLhhK8juAIxBLeRRse9sL1r7Dd+MJGghUu3p+7E69cPFGgFmDiiJUVYtYCimJxzMCRUjOgag+CdwoeoBGudnoxD2xA1QQgJNfwMQQYnCJtNsB1LBCCpBpXcANWzNb2gMZnIIS2XeEMeyr62ocVlCK5GN72eAghIlnlU2GFrm8Mi18AUOZQ/qjPZk4gg4R3DkKV7rkx1+Y677j8Oes/GJcbUM1gURc1nMbqHZxGAU5jitz6wDU4zRAz9/Gb59i7ITxEA9UhAPQUgDHEdRlfsoFQ7gSk3wD3O8H3c3jRAdfAEMTClRwgH+AxsA7C9pnG2rzxAVz8qSsoa8HbM54iWBbgHPFPFq5O25njB5NuhCkUFkxMHUicIpRo46EmuD4RFjkDu9lyNQUtuJ/nsEQtV5fAKr8BFOoC1qOFawhgxOfwGAqXJZgBKEjSnTqiL3N8xCb4D2YOtrDPZK4tpTmCVdlwfQhThBlDPZMVQpDM7YcJoQ9BqLBLl+bcgltNorULD8dAbgchHnmRTVyvAcomrNEFzrGJe1gCDJZ45qycZN/JAunNPjw2hosZQKKAm38By9mFK76AhxBdFuQEBo6FTuYlbMB6n8AL6Tui1cA44LwNRzBXjp8xWTsNV7sqkyPnu5CDC3hjXTyfeR5C+AcIk+XW2+Fqb3hEPNZ1efimS0lUUGbGuCOAxQAXcYbww9afAfE2gOpn4Wr/Pav8zoGWHlCacCmTS+cM4AJaoVMbrvMIxMoGrC45jQLWgy7m1NUgcP8YruxAIC6QgekhPWmexxaq8s4haAMg/xIeykr/7RyWeuBKZ+ldbGjtHHn4AgI2hoXcxnmXjomusK9BIcjIAUoObuUCSr0LkL+AVesBuEu4/QSUBAViLLyA9e+BG1hBHpPbD8vqXDhXvAlAGbvw7QK60Q1X287HAOMNpLlPwR014HEEeBf2nI+hJ22n9CVAIoCcj+6abe/6eQjh7yF4bSgsO+9iuNpeewrWlJNT5rjgCFSj61qBOCL5FEIIR3Bvh444yvGbDa1tIJZKeEgBqNuGGz0B4lJgItzGC6wdwCLTWjWQRqzgYpYg72bgEvpg4U/Baezqd+Yg7tg/cYo9uIEioDmuo4O1Bii7rkdiif2z8KpEaLOoyTIMnNcyA1FrWYYplIRdjhPsh5GCE4BzGx7BBTyyXQDKArxKcvF+EmieI+SkAYlu77ZgKCbYu4bLoS/g9vPzgHNPcY99/LcRipU6kGMDty726hxhTBuFUUvIUtT5JwC9FgjDJQjmiIxVhJfeg376Kty3Od2/c27xFBbGFGUKl7uN+G0Bq8minCTF76OYwiNgH4h/gNCh41A+QcFjCOENLAFZ3RVcKlPoN+AmhgC2GZDfCLwDWIwh2OcJ3FBz+Y4Ql2+6Yqkx0kQbEgy79w24thMQP7mE9MIVOtHCnYPcGyKeO0Na0kDiAoDTx7M+g6UgoCydYDBttgKgBLi7phBdKdsS3swSNfYTeFUDrTWl3UCcO4an1NJ/O3OEaoI3M0H4OEBIMkIefttlJBrhaifnCcKfTbj8U4Cx6cAJQtgh+Kexawpj+prGqQni2TJcfXx25uTxDF55E+XOpa5lgJBs5BrA+jDKR/q7QJbBwvWGzQScufLNBjaIgxg5rGLqapfP4Fa2sHkLXWCvxpqam9RB59cp3C+Ws57Aglkp5JlLKZm7dwTPoofvRxBYRoIdOIIuwrU2BbTqx324ihsoFZ3DmprSHYMU2nLdYwYGJqSnAN4tMPRT7Z2B8a7ueeEsch9714A1vQD6t3E/cxdObbkcNbMMSzwv1iW0ACiWZVgCXBcQ0o72fwnwYRnwFCTYpp6feQG7CIkmKKNu6LqP8Ls7YL/HyK60dN5TlKZvgDSeIbTJQJJmeo4915cxBzHHUvEjeD4DeGRzyL55wkeQnyEI9zHqEnLsXUT9QBte+wr600PoZFm5LjiwJUK0TtBAkF8iBjfrfARLnzlyZ4kCIR+T5DUo08ePnoar/c59CMBID4lE3xwE4gCM7AEU0FJvMxBbAzyg1/h7AxbPSJ8+XO43iJk2HZHTAQDZwzYh3oNVPEEz0gDFTyYIt8CZnMJ9HWLvTCBv6DtbWnsBwoxDQc5BmBlIjOGCc2z4GbyLW9r3KbycDMTWCGBwE+k4TvKx8OYUMfSeK4pKAJrKkZa7rkjMLOsOXGsr/LoBDuMIRUPb2LuJ9mkXHuEhwpMdEMyUOyMFj10dRBPe7ilIxQE8uDNwMA2Q5S0QtZYJOoKhYWk0y8oTDE4bgNBE7YB5sBYSH+K+WgidLlCsVbhivEkeQvh3IEOmQAdzVfYRdxRwjUdwiY2kOcJFdhGvjWCpcqQEmQ/N8PkKfEQXN3EG4bc03RQuZh+lokc6r3kuY8R/TShMqXscurhrCqUewqV6Aw9lG+vGcOUDvIsABZqCIAoglAxQTCnuwEMZgTht6bdPAXi34CKfo7y04+oPpsiT72rdCJ5PF0BwDsLTQOICeegOYtYLsOZ39PcUcXQLSnSMQrI7CPPGUAgLBY/AU9xBPvsMRmFD3zl0+2FFYod4hptI11pa9AZCniPUnmwgpDMPdgcG7thlJDgXkiDRg6c1geGsnGFJ4WpH4whZs+CKlFaOpzgIV7tuWetvnFeBPSUp2M5DCD8CmddEfHQAwQggggJcEytBfAUBzYGYJAWtX+A1vtt1BR1msQLQsoG4q4G1SxB6XSD3VEpYIDQZAaH7iAvPtLaJmJWbT1b3COBj2YczANo2BP8YsbdVsJ2jEcrccHuAllW5iZBihopAa1k+hODdwe/NUGBjluwE//0WuJoJMiYZvAvjOvaQY79ACNLQ/Z87QJkhG3CO/RggNLpAXv6GfmuEppcBiL4TEGg3AK6Wot1E3cg+lOIWUnHnaEpq63yvALA3EP4cw/K2AShGau/CwB2jsMtYe4YVuzBkJygF7sJTNZDYBN8xDldHsHWRZj5wcj5H/QwtfUP70YUHwUwbK0Mto9awQqDoLE4HREoJpWggVs/xsPqwdGfhanuixR372IgMjRMJ+eEllKIAH8HRWQsU2pjlZF63gJs6EXInoHwC0DQRqpy5EOQUXtEmOI2Z1vZB9J0hrNhy9RGnsIA3wC+MUEBlodAJUjhmeaNLlW7h+0aS3oIlPkVRyw1Y6SViauMPzgA0e4hvZ7hvK2w6BiO9hyKTKRTcXOwTKD85jRlkKcETWSHFxmKgU8jKHkJLWs4teIcl1s4hdxbi7cLjsJDgBojYV8hIbaGnxVzuHTyH10jZ7SD9e4GwzQzJATiMHZQ6j1E704R7bmHFECz/DMVs5uFNHUhEEJULGJwuvJs3yDo08hDCT5BvbCCOMJdtAC6APfUt1PqT9W/ClW+AgOJQiUOkCvtwzUcuhk9wWxLKZ3O4k2S5TwEWRmw1tDaHC1ZA2SYgu1oAiSZQ3kKQkYRo5YgtyzJ0XLiyDYb5BMC0gdJo8xiGIMiOwY304LZVALwqhHAbVomhUIHnZ9+7AzJp6kpUMwCeeRcWSozB6vdhJMzDu4E+ihEKyDbxW3YvuwDJU3A8m+AabJ8tBNlzHAqzPBXCzpU8qAt4AT2QgLbWUmG3kDI+gPU39/0UxPgewPYNPMYh5LbEWlPUVzAGG8gMzHFvCRmrRk2dxgqkce7i/Qnko3K8m2UTzmHxe+AlViGEqb0cNANCNVzdcEQs1MVFnAOxekD1i3B1BHEbFYGHetgtVMxxjHcf3MK+c7nH4Wr76SZKXg8AUj1U/42bDjVvAAAgAElEQVRdFVcDgLKCNQ2whEPHaRRgmFdgyldQCEsNWtrwFsi9CVxBIzMPUSC0h36Jc5SvdsBcW9gzRP39CJxCB/yHEVBtEHIjuJ9txJsNuIerEMJdKPEC91aXRryPa5uGq+28LQeO95CxucB1dCBDyXEaBry8jq4rtLHMz4ZL97URgiTE5QuAEJuYNqDgB5DPLed1NAXqNjjk0BVFGU90DD7I4vhDZK+2IUvHWrMBfTtDY9aGq5PJsW+sVRhLLlhDwklAbZfpGdhD/RWqmfhiAb6ss4uLOHVthQ3XAzBwSNVx5b0LIOAAPQBvUBc+hADPUL1lZZbHIAGHiFEnEOyoB3AGj6Efrg7e4NuLtpEKOoIw+8GX7CDLQMIkgMQFioS20MSyj/LqG0iD+W6zAQjEqSwbB1bO3H4cwqXcxu9NcU8NXd8RlLaP+HcGYraltaeucpKdhyNkO1gKfOY8lDGMQoaqxyYEOmk/xq6mfxuE8DHk8QYyABOw5Pa86N1tw7ujfGTgNIyQ2wRZzY7BBsq/V/BgWTy2Ak+xA+9hH0T5hiuWaiLUWIFwD/CYS8jwBrI/h+Fqi3WA5xKR+4/wxqdo2AshhDOrBGwiNl6Ev36HXA5XguTCHEU+7EI7QBqxQClw7sgqS9M1kS9u4KEQ1XKBRBvFIx1YlAs9bCNL9mG9hwhXFq5seIi46xyWJiGut/h/Q4JiIUQP6DrDPSbE8EY0taGwJYSUrmuhB5tBASoQZgsU8BgbnUCCVdiPKfoQhsitW+qNI7XPIXg7YM8XWFuAEbcw6gbWzuA9tcF/WMx8B6A2gsJugIOx1O1tsOcnqI7cAoNv8f4NeKMMj3ZQYblEjYWBxSHAeAthsHk/HRCJxwh9tsLVyTpTcF4DpF+P4O1apyRDr014bK9BovMdEysAlWUOXqJuoI3n5EOvoPP2wtXhIiWyBANrB+ZYbY40YlagAzdpEq5Or12is6xwXXbHUDae4wQpNvMu9qGobHw4AOfQhHfRABudIZ5rIp1p7HlEvG9C+gYA1UEqbYWHbdVnb3BPPTQaLUEgBhBmnCXQg/U6RkHJbaT0ZgCUDtKTTZezX6FfI8c+HSDXfwd8zRm8uV0AkrHcN1G8dYaKv13wKitkV1Yo1pmCt+AQmAvwOLvIwy+1P5yyfIr9uSuhnaNApoNGFta230Tq7sIx8wtwRBFhUMQ5mijMOcfz2URhzyGMYy/89VyKDaT7DlA1O8Bzm8LltrqEYxScDQCcE5QNs7DHvNIu0noThMO56xd4o7970E9OEH47UYiFQM1w9b0AHAM2RcEC85MTgEAA8meOQIxAO0sdMrf+UsKVh6utnQvER1YN9gx/9xC/j0C2mMv7DF1V2yAIj0HiWEjwHJu1jVhqH1WJVmZ5gPTUHu59H+5mD0UoSwn6TRQkHeHh9tGEYzUMu0hZncId79UURZlXdFdKfIH89wCe2RtY8veg8DOXgjL23IitB3Bdrc+hg1DtDVzg24itz+Dq7ujc3LtbIFAP4UHt6jNLZZ5in3f1exMQiBsA44Nw2Wm5p/uwa9t0ZbL7qFbcQoHMKaroTA4OUeOyhbTqATwiA5ZjeMjbKJ577crmOyBJR04H9iGPbSg4a1ya4FsKhGpDeJcncPsbqHA8CSF08xjjr2OMyxDCIsaYxxjbUUcIYT/G2I8xhhhjpv9WhhBmMcYqxtjV53kI4STG2AkhTLSuF2M0QJnqPHmMsRVjPIsxNkIIRzHGjRBCO8ZoefjzGGMvhJDFGAcxxkmMMYUQXsUYt0IIzRhjC2mzIoQQYoy7McaprvtZjHFT52ApsD34myGEpOt+bFY0xrip75+hBPkW3NgnxrjGGHfhMp6iZt5Q/ike2J1w2Yt/gtjUSKUXUIp7qOY6Q5VZU2BwgFy+hQNm4Y7Ah9wAqXiOVONtPZMTALyVRpcgbA0kRqjcCwizMleX8B6s0gyZGKu9eAmr/wCE1BnSkl0p6XO4zPdhZI4h5Bs6/ytwErdgGA6QVepp7aGu4UgyEFG2PUcV5BAE8mu4/T2EWDMArBmqV8jhszT9Ah6HGYvXqCfZdMVjDVeVeQxvbAMe7j4K9BroCzAA3whXu08L1F70QwiLPMb4CymKuUshpbQvBe7iYb+d9xZjNLcjpJRexhiH+ixKOacppYWAYqjP8pTSa62rpPR9xFxnUtqWwOEkxpillKa6lmEIoYwxzlNKx1rb0DWe6fPzGOOGQCXGGJcppRf6OxOAjAVir6Xw/RhjEWPMU0qvdK1ZjHEnxriMMWYhhCcxxi0BXldr3+h6yhjjvRjjQt99FmNsxBibAiUrChkLZB+EEOa6n2cWPsUYb+k6rPFnGmO8q9/YlgJdhBCWMcb3Bcrm/p5amWyM8ZYe/pl+744+t8lGx8bsxxjvSRmsWnBXa61ZycKsqLVnKFPuhhBWMcbbWmvkYtJ1T0GuRa29j7TnTJ/d1b8D3WOFaytQ3TiPMd6REdkSGC/0+QM09Ryh2rGjZ/8sXA46uSMZs+zAOISwrec1QM7evI42MiAjKOAQ3My+fq+N9N05itE20CT2DJxDB1zTEkSfpTlfhMvhIW2EhsfwoiO8iz66KHvIKKwQDjQASId5jPFXFmunlC5kod/GCFK2Log4W3ymteZuxJTSYYyxLSHoSPiDlLArhbdChuOUUpDHsBVCKARCL6WAbT2odghhklKqQginUsw2CLNKlnygBzhLKc3lvezpvF0J4kxKM5BglCGEZUrpuQAl1zXOYoxT3WNP1xdDCKuU0lP9Togx7qWUZjHGRUrpCEDV0n5YWLGSkNrvH0rZ+wKsIqX0yoQ0xvihPKGW3N2lrnkrxthNKZkXMNHasX73AKz/rRhjK6VkfQHnVj0opT0A+bmrPZ1rrVWqzWKM72mfz3QfO9pTE/RDa4iJMb4v4RzDqre0/xXy4osY4we6xxKeXFNgl0sOFlr7nn47Tym9tBy3rqWpPRrb9QqUuwKJpc57U/doHs1IwJ1rn55K5qsY47a+P9H/TgXQ5n2aKz/R2h7y9UeW/pMsWdPPqWSsp3su0fhmcmfFXC/1PJuS7aTnlmkfNvVvI4TwQmsLM2RIXa4kk7k+f63fqbS2k8cYf2zMpKxzktK+gReQwEIvZXnbWGuhQgtlrWVKaSJraGRJnlJ6FmMcppSihRBWpGHors8KWeR2SmkupYvyCg5gqQo9QCNWRrK8LdQ/r2QBO3pYp/JQjgQSLd37iZSp0NqhubQCsV0pfj/GeA6l6EoY57pvhiA7EvSRBLSt3ywFEs+0l0sJ+gReQC7Ay7UPz8xiQIESWkc3JDRDWY+pAOUHEkADQuvOHAA4zAt4T+fd1lqr7OwKCM9AVt0MIVwIUI7B+g8VvpnVPbH0oSz7qZGtEsj+d5FXWEmZuxL499BbcK5ntCFFbKSUnljlm9bOY4xJ8tjQ2n6MsaO9C3oGD/QcM4D0UGDcTilZWvVcHlXDrW3ivFZ5eRZjvKH/1hCANfQ7wxhjL6Vk8xtPJAMNyallJGaSpYEMi+nAhhS4oT1s2vOEQpuxHsg7bEo2spTSiYXluO/zGGMzjzH+GrX7mbyAphazvLEJxnElZT4USPThylh+tgGrwhvpSzFWUqxKPIIV5WQppSda24G7Zkx5JQW31JS53MYZpBBCpc2exBhv6jttIWAhq7KnB5VijBNtyK4sS1v3FrQfN7S2gGcwSCk1dN2n8iQOZWlyAchED6Wl8xqhVykc2tb1bNhaS7nFGO/GGC/kmb1GaHJba61zzlzusa7xtdWVyyJPdJ6ZwombApAevItVjPEjCTzrGLZMgME9LHReA8pzdCNG7eG+pet0bRMB+AUINrP2xp+can8WAk8j/zJ5mrsKB6Nkqa/r3kPn4lRyYM88SPE7uo8bAogL3WuUZc/lXTw28lvPJqaUlvA0b0iRMnkihX5zV3tRaZ8qhZddKbF1mZ7rek059/WcelrbSimNwI9tmvctJc50bU3zjKUvb2Q4Wbhnk7pMD0uEBD2dK89jjD8Jl6O8cp3EQoKxCS9OXODEPRSonKLU0BjJXDfUtRgeJExPgm6xaUNudB8u9xztq1FIutB5X2rjBkj9nKWUcoubY4zW3/BCIUkHddEXKaUo1N0CoLySwEUppqVElwKDXT28ppQtmWssxZ+LAzmV9V/FGLckBEspjnEDWQhhDE4jSHjfxBgrPfQdPZOGwMdY/0qW7EBKeyJPKxcQLvWbGcBgX/dzyrZn/dYBgMPOywKcKAJxibbdt9WDer6HAKU7uvcp6ulvy2PYEfiU4BHmujZT5m09x52Ukt3jhUCignE5EbimGOMd7aV5AZsChA1xRKfa40prDVCeWSim7yxSSiPdRxKoV9KJR5LDXN+pUkoTydFSgGJc2kMr6NHaLKU0FSCuZISMH3uq57eQXLdCCAsZpkr/rZDn80oexZmut4N05tJ1745CCC3JEsuGJyGESA4gwrIbF1Cg2iohZ547j4GzAzgplUhlhTybGGBwhJxmX6g+AmG4jfTFsW7EAMUm6ARtyDaY/CN5Hcda+7b0Umu7eribMcbjEEIzpXSkDbbcf2YejtVtxxgntlYC0JNFKCRwliq9J6vbUrxvqD3QwzqU+3+kONTyxAcCl5XF+1YurbU3JSDbsjRz+1vXOZFAHlq7s4i3faSbBkbE6rcsc2Bhxb5Adqbn0RSoWIFXru9+JKBK8D6aOn8QoJRS4o91b02Qgg2BW9D1JnAOJ/rtA7NUWmuua5TwG6Bs6VmvdB87suhVjLE0gJXS7Yp/quS2D80rFcifIrtl5F2Uld2w2Nw8Pkuf67wLPatnOseu9GiVUjK9WAjEVjrvUxmnofbE6mxiSmkJTiTB6LUQaozFTZnn1EQtgFUTNiV3K2RoBiGEzLIAC9Q0WwowQ7VYC7nkGcp/jVzIwA9Y5ZFZ9I5rHkqoKbda+r5ibOtQ20AGwmKsrn5vaGSjHuyO1lqsE0Cs7GpNJgXdlhD27HMDNp1nLsGwh51p7YXOO9P+7IhDSFo7lPDtyXIYmVfEGLeTCA+BT1Ocxl258jMpUJQ3kyu2fGkFWVo7QyooCVA62o831i8gpnwqQDjDnIIhXPlKa/cAKJZyjAKqDe2Rka9D3ZNlDk6l3BbfTiQLb1tSRVC+5RckvBaCmBttCvQBPIix7m9HIYCtbWmf76CR51Qh4MAySNqPQoB4SyDRkzwGhW6dGGNfz6sKIZgsZSGErryOTErY1h5ZyfZxCGELIHEqIzDReXfMkApQN/R8N+TFJRmGroAjDyHM9ZuWKuyKLDTZbRlRLZ7pDK79AF7HvvShC2M9gudug0VSSumlAUABZU/IF+Zo+5ygsymifzkLV1+PnAlFjVgzJatQH23FF4z3rTqvIddsjqKLQp8/lXAuFMd0tHEW/1k/dhuZh/MQwo42di5lnplLFUIYam1bQrCNuOtUa21I4zbIxtdw5buyTBOkAG8I9aPCih0p9xZSW0kgcVv3YOHKQF6ADc2wbrhKCmTvbXhu5axy26fIw1v6MCG3XsHKWn3F2LrN9Ly2RGAZiN0VSFgt/Yn4jXaM8aYUs5KS7el3jRc5AmF2W17BVPHttvbDuh9PtB/9GONd7XOpvTOX+6Y+N3KzKQWfgVAdIh1qbdAzfX9X+9qUNW3pPAaEhZ55AlfVEXBEGZg9S++ZwQE/ZDMPzWPYA6Cfar+DZMQajUrJnxmyhmQ0SQ8aUvwKa+1ZWSbGuCoj3C2GP5bsFtDbZLxUjHEjjzH+DMpcuF79NspIm2hOWFLhUQgxdhmCZbg6IbaBFt1D5GkDBhe0hfJDAMoTCYHdTCa0NJfKkDtTjNbXQ2lLOY/khk31UII+fySrZNOJ+3qoBhS7VmChtW1Z1y097LlCkjMUBu2IeDKl2LXCJim9gUweY7wlBXrLIoNzGcua9qQY91HIcmj7BtfTetlL5OwzVJRVApQFmoeWWmslpfuIy99HEdEc1rSKMW7quqdIcZaYI3Cm3HqU4j+23LjAx9KIZwKJoQTynvZuqv24bdkbKf6RAb9ieONV3mif27KGZ0p/ZgLYWwgXn8MTtOacsaWTBdQLGJyh5KMv72gh2SiNt5F8vBCJN4OsWphRIgXeEzhYq655ZhYSJpNzyc2FwOYNa1xQNVoIZHog0a02p432fTPAGdL84W0hULj6AlBOCY5oyUyuHoAv7EgoxrCGj74rG87RKvy2dlnx/lZNueJIIGEddVZTYKlCe4XYQoAwQIxWpJQeS8FLCaSRm/ZgbeBCW5vWVFXkrsClSCn9xWJ9gMTLGONMVv+BtSxrbTKOQu75ERT/ga5hU0oxM+JPWQUbrvFG3ECUhXyBQqI7shTW8PPShFZutOXEx0YQIf57Yc1bMcZPwuUoLXtxRBtC/dzKSZFGDGjzbSsGDwIf4w0+EFj0U0qv7bnrfvqqdxjrfPfNq0kp/cXKe7V2IBd6JC7gnizcTZFrU/3ebVjTC4VZewLr3ZTSC7j4u0aUqrbkLXsuUDuFd7AtkG8I6I/lzRQ6x1yc1CPtc1N7koUQzmVszAsrBWKPUEPSQem81TtsQHYtZ7/Q7w5A3o3d7I1TEn2ozbG5FB2EA0uU6vcMACrU+zedRearwiOagf7qPWMAgAa8hxPUSfPVz4Vi+Q3bFJRkch7gWGvtofTRrPT2fXGI0UJK6VsJgZWhzhUzzbR2F97Fl2aRrVRTKL6vjb9tzUMppa8EHPMQwm25dAs9rEznHcgifCnLcR5j/BAx2nNVDe7pXJsppUfa/5Hi5kpu43MpU0/XuC3LO5Yb/ZEEx+rjzeXelqdzLIb6QEAyRVxuXkDP+A/tpw2inMUYf6h1xvq3dO4MIJEJUH6ICr+xuINN5MsfmUcYY/wUMmT1Cn3tyZYU3KpDP9S5+gLNhRRtD/txIa/ofV3bpgBlZmGGQPJUWZfn4lVaOu8T82xlROylpfa8bggk+jI0Hf27KcC0ephnUPBtyO5zWO+AdG0LTU9BBLMRiB3XdZi7ASAFCG0jVeteh9aGMW1CP3shhMoKgXL0CAfEUvQCpgCCBkDiBA1CCSizQC1zJhfHqpYqXPAcTSnWKWZluR252D2kEcdCOhsW0lVM0xBI7FlGQOzogb6b6/ORruWRHuzb15BZWCE238ZpRSm+uec9Xd+BlKaQJZvpWv4kq5JUjZfJHT2WRfhQ+9RPKf1Zn8UY4wcS3qn4BSMKmyGErZTSt1bbH2P8TGGStVOfyhK2FVY8tUYaKeZUwneg/3VFMj2w70tp71jJrcDEyLSG1p6iUtCq/z6U4u/bdBvxBlaU89LStMoGTEBOmrUPIh2/tU67GONHIuwW8ojmFhIINL8GSPxACmPe3UzpuD4AZaK1H5iLLYA9BxjbsBZLM9/SZxZyllJeC11PZBieyIvrSYlHAq2l9vntDEgZp5swinzZTluyanr0At2yOUL0E+hPRHs6R39xuEgDfxccVpPHGP8ecf5UJ/6ruBw9+8l93kHdwAjFCPQO3gjhB663IKG9tAXF7MvltjTiFGWqW2D9n0kgSlkyCytm8i529MBaSvdZY8YOSoEX8C7sDTcjpXMsc2BucSkBM97gBmoEniFN1NH1PZVnERX7Gln1EDUMe/rspZR7JaU1F/NbgVJTwtuQa30mjsHAYANudBZj/Fi/baWvZ1LWpRT0uT5fmrKFy5HdxzbUQi79S5sqJLBLegZjpJvepvvgzdyyrAl4iras4AcWVgjsB0b0iXCztuBVjPFDZU662o+2zntHcbdVLFppdA6Pzaos77t+iJk+a2OfzSU399+MwkQela19qSzUieRjQzJwprVddFbuK+5/KXncwDSoKepmzN0vJEtbqOe31nIzxm8VHWXsDTfIx4ClDT08x99vC4F+iricln3sXHnLEMzQhmiafwClDSAczjAPMCEPP0ALckDe0vL7OXrc+yhuaMAtayFmsi4qq0vYtkIbrbUMQxdtqlHXfUOCYW6ZbaLlh8cCiRdY2wmXQzLnWmu1BnNZhD0B060Y44lizhMJ+g6aqf6iz0pTCgHNS6w1QHkoz2IZY/yRFCjTtWWyYjdRJjuTUnwuS9dBvN5WTGyx+oW8gB8qD39T+3EmL8cIORsnbvzHhf59Aybf1s7g0dzS+c3rsBj+JrJFJYTf+ASbpXiEcLGl+34qb21pWRB9/ghu9Ibi+jfySOwakhToW+TWNzBYJEOtQUNewTfW1SqD1oEM2J5ZN+bTcPnSEfMubLTeGdqjTXaN8OvA253D7WdNjrUhmxGxArsJivYi9PoMw0YShv/keYzxlxjImGEQSBMnKUEiFPj7Ak0PAaOzIgZyrLSZr+BmRQyTsOmtm1j7WArVQZrRUlZmUawB6QkKOYZSEJu1lvRQmrDIb9s1BQzsfd+Ga7YfLoeE3pSgNRRXW5FMX678gSzZazWj8PVO9lLVjuLwMyn+E5Q02zvxznXuttzwmTyRxxL+oFbakxijue0dCan1FvxFwryU4lv78THapq1/wroRFwoFT0SCnmEaTkPu+XMQfZ9pbQtxfw/1A9bYdCGeYoLGGBPyTa09UPHSsaU99XxPQJIOZeUmCFF35HXcEOs/s3y/rHWFDJJlUvbEA1X63YaeSQ5jYaO/rA7EiGcjo9s0WCL7rAAn6ll1MKrOBos05CHvgg97Ea6+sdrGtkc0ZLXC1XHpCfyYcWAj/F4IV9/V0MQ5Sjf4J+QSkgyTfxpwIThxJEC5Zy6GKeEZNMLVd9SPwWIG5KrbuLiJNsjSF1vIHIwxcqmD3oJnJkQYWmIEiL140zIHD61gJVzOp+frvm/CIj8WAmeYGFOhkm7HSoFNuCRUN60SDVNg9pD6eS6BOgsh3JEy26i1MxtyovTWK1WwvZE1rURsncQYT6V4RYzxfYHOEux3VNXimfLuVjT0oYhN6y0Yoq5/hNLcQhbySKBno9XmIu9G4XLsd9Ra6414YcZEa0+1N+dom15J8R/rWmcKHUYou55a+KZMygt5NSPxIksBzinApyHW38D4jWL4SmB/gpZ2U/wxwHjHpWDfvgJM3ksJg2P1Jh09c8t6BQDKSnJnstxHFupQsmCVrjnGd9kr99owZBkK7PimbXtVmKUcbWReCzM7jUCcAmSsdL9pWYCINGBkfhE1+Rlih8JlBFrORcmAVE0UAp2Eqy8Q2cc8PXN9lqjx3kRG4ADuex/FEda3voGhkKdC5+cCCRvSaM05GyiQsTn1T3XebWyuZUGsV34m8HmCTskeqsPsJZ3WHdfDWptpl1CTPpZFvwghDHS9hZTijgpTRlKoYxF8Y+XWn0oozwUSTVm2qVj/HSntB0aMKW15R6FJSzntV5b9UPz8TM/fQqloNeqyWNbh9omKlpK8gYG5/9onq2SMMcYfSiEtfOsqRLNqSGugWYm7ONPePZQ3lLR2hsk/Y/UhTMR/PNXaiUqxSyjxOFwObN1Bzv7IGP5wOSF5gkI16/nPkH7eROHNCsZxw7IOAJShDMW5itcy3afJYwRIcJz7EgNT7Fps9sYAHnaBdHCFwSUBHkPAwJAKg0561gvwM8QKFQDAXmFdwSvIMLjAPIYW5qlVjm2cA30amI46wuQWc5dtVtsIs+CiYtZmuPoCz0PMSdvC3LhncNEa2uiRlO6FhL8NF7+NQqVdK2zRRlvo0BNi27W19N9KNf28Qvx/U8RhpfiRjU0W129I0K1xpUQTlPWAG8HZjDGOZelPpTSWqcitW0xKbEUn76kPYUNlqKUUc9vKYdF9d1cAclPW40Jgc1tEnL1uax99CO8LCI4VZtzEjL8S05hKhRWPbWKPlG3XWniV1hsKUD5VYc9YKb0tnHshTsOmTFmhU+WawvoYsmlgfEv30AWBm8vFbyukSwIOe2NQVx6KjV7rAgSthmEXsyStQWuka9zFeL0RalyMhLTQsotwdorZjBFj3goUzQ1QhTtBuX4Him+l2PQCFuDmWqjpOc5jjD/Hl5eODMxQCrxyRUAlQKNCL0GG9uEAtyUDSLTx2QHYzgJs5hhWOg9X3y7EufLm+thctwYeoE383UII8ixcjt62CSwHmMO2B07htSyYAYwNw0xS0HvG+AoIllYaLLfxSIr/WOCTqZzY0loreR23rOFKFuGW3MVbajiZYKzaTVSqPVRYM1OxziGqCiOGd/SkbJV4g0/D5ajpUytCkWXeRF78QpZ+pD2xkl2rYd/EOLNjDO64JQ/gQEC8qyo/m+X33PZDIcRTawtWGHPPQEN7d0su/l3t3UyAuCXewAa7PES9/C0Bd8KEKxsIa913bCm2eRUvkHYuMHqrcKPcCvALLeTWz9Hxuoe1Vnq8wigxvs16C5k2i+HnyBCQWO/g2kxnT0C4B/TRsI8nIDXYCiF0rB14BVchAJEKpB4ylPcGoEgEVzAHu5+QusgBEiU6ATuw2CuEGlW4OnX4Faa+EtX4+m2Ly79k+g/exQRTcK36708SZL5MYhou3/Br4UAHwnWqSkFjal9LqW7p97ZTSl+rG+1AqaYhiNCRBLERQrgtITLv4IGuu6fvHksYexL+fZU0P5P1jqilf2XTj2KMD8QXRACh5eFPQLAlS0+KKbeBIwsRfWc2ngxViEGZg8cWrmntBYq5rKy5o3DloQD9WDl7q994qc5NG8bxQPu8UKjwoay09TJcWPGO0pHH8sIeIs23I47jTPc3VFhinuA3mA40tNFp4hfarkjsL9aQhJFaNqXaGoQsJDZvxjJWpnjP5DUaoHTgfZ5jyGvAQJUGiuamaK9vQwfOnNHtWt1KuBzdTt0KqAK0z5N5ADk4gHMgWgBBGNEvEOH2F7gQU3DzEJpAngu4inxfGcc6F1BuY0+7cO2YWsyBgA2lfrZRBGQDHbvwDkqBxJ9kaTZxnjeIv3bRc/BHndcIlAFSgGMNrTSv44+yVG2RhZu63n0p5Efa26GuYanY8D1Un52ovBNIwrQAACAASURBVPdDXcNeSulLq8uXUnTRVfkMRUDvqeJuImX7wABFz/UJOiV/KOs9E+HXs5JdrX2KUuDPBdgR7nUQoKyknAsQhVMRfd9YBke1BoWKog7kRn9s+fyU0p8kuAtdt5XbvpFCP9Cz3NWzLmXh74O3sbU31RNwQ9dmTTT3tNbmHLyW0g7RwNRJKX0hr2MTYe8Fulo54epbgUYfBnMB8nob3bFfIQQyEr3E/MA2vF2Ojy+gtHMMFs0cwTdxir90Xjjf8zEKIbStDiBcUwo8dQ1Cvl8gx1pa79wpfhOAYhds/3aQTThwLksX8Yu9e7DtKpwu0C9gSPdI7pflWc06Heph3wCofSuFbyKksHNsINaznLG9/OGmgaMVnMhaDAUGX4nVvgghfIzegj8pft/WOYay0hcCiR+iwvGPKhvuKbbfkJUeKbf+mRjxG/I6LqSYD7Qfh6qcfIYioI91bwfWDISKsnNUn5WSjRdSjKniW5tSs5TVs1Lgn2NAijW7WHlvS5V7K3kbnyvdZwU4SRb1rlj/Z9q3oxjjp/rv2yml32s4hlVZbllYIo/hI8vna+8ytejekZt/ISL4qYCup/3/FinNLcmHyflLzLCwF9HYde+C41mAC7A3Ak9lcL7R2k0YmRH0h+X2z8LluPoALi1DQ52R9vuYNBzB8CfweBFEfuG5u1zumy8COgX7HmB952D27TiCexRBUoyRdrALPES8n4GZtFcX9cPVOew95C0tLXKOTSuA5h0rwNEDs/fpjVEEsYkJKX+Wa7iFhzLGTAN73Xc7pfQHWdkhNtmyD0250ZXW/tamyoiltuaQp1L89+x+JNAtKfFHAoyFXFqbxDuUkP5R03VGMcafGwMt9/pUIcieZhV8ba6+FHMhJX9KEFRY8QzNSp9YuawE8Q2Ght6JMY6UwdgXwFq/wKtw+f6DoeLyscKgv1gRjBTfBnccyD23wa1bAse27ueHIvyCLH4hy97Vs/lWw18PBRKFnuuXIll3BOBbAiYr5vrAOvOkxAXCAXtpRyHguxEu3zPxIly+7KOt8y7E5Ft5bx9TeN6+XBfzIqNA8yas/Qrp4Db6AiycGrhmvQzxfs/14nRcyJ7VpPJppMs8xvh3KB9k9Z8p/hxuf4G1M8Q0CWtzxC8JzKS9aIFrLVzo4qafAwEzhCCVG28chc72ogdjSe3VX/YW2h6mzBpYbGLyzwghiAHNqRT0mdz/HdzzMXKtu2Cjv7b6cwtv5I7amOuPzKOS4tvMwxsSoteaXZCkVElu429tXpyBhJj8fYUQP5LwD3XelazkL5QBGEtBxwofWuqo+zOGoP5SgGV5Z5ub3xQYPLR6BTH7M1kz6xcYyjv4QM9vJgV/T/ezo3SfvQG3ofTkgcKChyoiylQjsRIBOBNR+IFVL8o937DqP5tLaAVF8nQyFWgZoMx0Xhug8VJhyn08S7O89iZeM1QH4fJFshYam9E7RPhga/lm6R6acJ5KXjZRkl6BmW8iRrfz91CrEjF/ow1P9RRDPip4thV0tnJNfHaURgKWTmljDRdQXRP3B1QPNhD/s0Owj3PwvA1c6EugcAxX33IbnCdhis8SyVO0Em8CQL4GoPRQoWebt4f05HOtWYjpHgCoDtCs1IR1PAsh3AApOJW1vyXhtCGZ9gakG/aCE1h7m3X4IYaGfivwGep3l7KmDYUFn+uBlgKfgeL4e5ZNkJAv5DGcSYG+VVxfyMratJ2RwOAzDPewFF5pawUa5/JEfqDv3A8h/EVyUIroi5gfeChlrbT2ofbqRKGNycLEjXe7a2XfAuObAkID2CP9XYojOJdX9LVCDyu2sVeDV3q29vKVt3wQQs7c1Q/sgpt6Gi7f7diCR2Dp0i2Exo8lh2ZcBpB/e4luA9bf5mmwv2YO3iGDK28xPAuGZi4NH6HXE1yvFe4lqwP4KdwCVvk1wSAmNhDUeAxN1y9gLkYLVv4cBEVEyaMRfkNc2L5j/RfgExrh8tVgNmt+AGJkiZRhK1y+t65ENmEK1z9HgcsmHvYhPIZtXMsTbKY1fBxi5uEDGyslhbdjU9c5Em/wRASWvcjyTbh8ocS2uIe58uUPFVYkFQ4dCDysvPqWrn8l4e9K8X+qa7tQ+myAApVKYBBlTX+l6TulrHchXuOGMgQPMRjkF5jx91ozENis9Fjpt5FCkDOkIpPOa+24+1LmffETM3lcj8PlCPQ9TBW2Oo1dgYy9HShHavAtH4TZklbxeaRn99I4CniZb1CS3kfM/UyGYQPGaYbM1wDx+htY/wJKa6Xsm1DSl26AZxMDd+aob0nQtRW8dLP4C4TEbO1fwbD7iV+ZAcCPcVMRlr2CIkfEyYxbWgCJCgwmC4amLqxYoie5QL8zXasBFJ7Vhx3clL0AcYCSxwTWlG9U/VZAYC/fnAHscim4xVhPpZCenLFuwht4sH9BPvftK7wlzPbSTJt5+EgWehRCuK9WYms8sVc8WxrrpUDktTIElpl4g2EpfaQGFwIUK5N9H805leLQ+0h5PbRSWBWCvdT/bMbfDXQuPsLLUv5e607C5Svg7qIz7SvMEvg7hSmWZWiKR9kAGdrTc/uhCnFKEYi5PLOhCMeHSOe+pxoJe/GHucR8x4E12NwWSAxQUJbA8dhrvff1/FqoOu1DLrfRcLMv0KkgS3ZtDcTw5nUMUaxj1bHHWBtR9m5z+1qQsZOadt45PIQWQOIEhT4ZDHsF4MgJKBYCBFj1AAUPzqWvHCGRQAzmiJP5xmC6HVNccIRFX4IEDNd0QZ2D9W9hoxnDN9Cp1wZI7KDoaArOYYDw5RVCkAydW+ZKbaIy6wsJqFWf2dtwSutxt0yHsgFbEto9rbsAaN61enYRWEMQiOfhchy5vddvKtb/K3PJxX4bYXmsundLP70nr2ApL+ADxPBnmLlncfljAcq+YnibE3Aqq9xVfv9DNP08l3IncR1Hsppm7T+XJxJEZpr1tvZhayhqKKyYKYz5oyz0Knz3whKbmGRvNHrPeCGtNe/uHp6dvbjUqvyGApSefvcOyDQbnzZESGCZqUPJwBDFO00olNWQGHBvgug7dbF4H4bMXtVWoPmuQClwF6HvGMqewziPUKsQoRdN1N0UyOyZVxCtGSi5wp7K9f4zDZjw3yIuonQeRIHPFuHqG4dH4BEydC5FtDS2wYSy16ADRLMXUhjR90QPogTrb+9wP1BZqKUdn2ImXBuun72Vx2oE2sjJHunh3cS1vZRiWrz/TOTdY7nPN1HdZSmlICF9DZbbiossxWYvmrSZ/keKWR9iKs+uXO03WmevFTtV2uyh1i1ByI1ZJ6B4/65z8T9Gp+ZMlvyezQ7Q3AF7ucZHyuW3lCF4Kg8iizH+RPd2Zrl8KXRfJbiP8V6HH0hZF+I/7uk85vq/hhzYG4MWIgVv6DwWNr2CfN5D/ccf8DqxPuJu85T2kPJlI4+FqHPwR0Mo1gv0ArQgS0eukacJtv4UIWSCVecLPEsw+Y1rwnLf83/hunlzeC8BxjeEEI7zLMt+ig/mNXn/yrn/ES4OBxDw/y9xjuD6CBKAgKhWgWMwYiRD7J1h7RIpwEwPvIWGoDaAY6KHZSnGRyjFLPQAzM06Qc43oqe7heaQcxB6d8FVPLTJQsoy3NX1nkuYPtC6TZBg5yIF7xrpJOG3N+Le1jVYOeuelCIh87ClTrsfKM1VYoCkvaOuUFFOLuv/Y8XubRUdJZTKGjha4dFP5cJvqehoYhOCrFMP9fufy2N4T+SrVePdF09xHkI4FCh8JHD6UKHUmWL4e1ZSHEI4kqdzV8/0lpQtiRy8o/+Wi3z9Fvdwx9qaUf3HvoVHkJ89KN3XKuIaIvQ8RUw9gLW2jFUX9fvnIBG3UNX3DN5DjiYyxvtZTWVtgRi+grecwfDmjo8LqMSNAILgPO+37wacK93SkDAENaHY35n+FzVuyf62tSvluEu3dqnPM5zH1kzt5SM6x8Kds6l/c5FIbazN9O9U/w70e0UI4bEIs0LrWjqnEVvb+rcZQrCBjkZi9fT/X8uCbWNE2CMrBbb5bkpXGat+Q/u1LSHqqlvufdXwNyWgS8tPSyCfy5L9JcuyTxTbd8X4T5Uj35Wgm4X8ykaIqYruiSbRlCGEG1mW3bXhHAor7sQYl1mW/dCNC+thnHhDIFGEEJZZlv1CXMRc91zqGppq/f0qXM7w/4WeUaF7tknNmwofvtaUpv0Y4+e6zl1dm4Vku/IyXgo0v1V+v6sQ7ht0ve3ovCORpH9WNmEoI/Ac3ad7ANiZuIc7IPUsHn+ssGkPg24euqEzAUVim+CqMvSpZK4H30qE2cV3CkNGdv44XL40JyCrxZA6d0pc4bwVem5ygMQSnkBkfU8eY/wxXw1e425EdAVmrhR4AjQKCA3Kmt6ChXNr7ILLcPXlI0bONSyOEVucUPuf4/wruWw26XcD17DEtQyQW/+TFHYDIc0SKZY+XlD6Fd9IjBedHGlM1X2BSSel9Dt78DYqSkM590MIZ1mWfSig2Ugp/VYP+0j5+Y2U0kphzLHWDtTj/mdxAa+zLPvMYnYp8wvF39sqbPpGa59kWfa5rnkzpfRK1roXY9zKsuwH+q2QUnqcZdmdEELIsuyjlNJre5lmjLGZZdlnEs4cLbpVlmU/UqvroVm+LMs+l5HYtboEFSL90ARRgDXPsuwDgeaeVfmllI4FhBbWPRS43MOwjyeSnccCwi09l0fyRHbQOHUg+f5Ca62x6EAEpb1TclfXnYcQ3lb5CWQX4mDGmPgcxGPYvMiuPgu6Z3th7qaMUwyXr5lv6aNcmR2b/9/Bec+1LjdDKB5pagYMxnCmVGqF85phznSPQf8mewVbjLHINVoqQPiptJWrJaYy++rB0nEGHiTogjBdSAAZI3YxbqCOxQzIbdpUIsvPrlRSO0RKz/oQnqO81wDlDPnfBlI/T+TKW/lmUN7Z0i82oaeoqupf5GIObR67JugslS//UILVqqrqvxlhqe9sau0FKuD6IYR2VVX/ZPsjT2JTvfOvQwivsyz7ib2ZuKqq/9Py0SoOGqaULlJK+1K4D2OMrSzL3k8p/Vbx+ijLsk/4ZiXF5Te/w4Lsp6oqnKHuvqFpvBfiDZohhJhl2c8EGladuJllWQejw5+qsGeZZdmPxEFsV1X1W+1lkgfQQq2BTRTKY4zDqqr+RcBg5b1DXdsLne99kZTDlNIXVlOvfbZMz0FVVc8VkvR17/sqvbY+/i0YIqu6a2NmYI4ZkDvQCQtbm3hvpg2V3YXBsaKcIIB+W2CHF+423fgum61QwEMZYfZ/wFxH6q19biBR6jxvJwJ9WqP4I2eRE5hx3wMwRtFNrGkJJkhcOAWPINM6zuuY0MLjN6euEKkBj+EwXL5WLCG2r9DIc66S0YeyJl2XZz0Hn2BcxlPl5vvI61aK67YQlzeqqvpXvMDyptj3UhZoW4LbVF78jzZHXu7uSoDyWwzI3FNI8EdjtVXll0IIuRQoZFm2Kws3VPPQaUrpTZZl/yALvJlS+oOBWJZlP5YiP0spHaeUXsqiz7Mse5BS+hqDOj7IsmwvxniYUpqllJ5mWfZBSmmaZdlnKaVvNMN/EmN8kGXZpu67kpt/Q2HFZ4rhbTzbTSlchbAil6X9RIA4FHm3rWfb09pXlg4WaEZ5Yf+q599G/cChDIOFZD1lTP6IAi5rAbZ39tnLV4yhPw+Xo7mt6jQh7UvW/wJ9/H2ARGnVg9CZFQrK2nhpB2sNMse7jeEZBxQ4tZwnHuHRF85Y5xYC/CRcnQpcoLooQQmiO8kE1XxMH0Y0JiQHKC1cQIlwoIu1p4iDSDguw9VpwwHsfAXG3soscxRHRBQX2UShDfQhJDDMTVzvSwGBIfcpQqG2YsYzMcxf4aUdXZW+jhU7F7JOFyGEUFXV7zE484ZafM+RL/8UgPIvEq6ViLMqpTRFb8En9hp1eRdNKdCvbCiFQoV5lmUfyRJtV1X1G5uQlGXZf0Lt/hN5LdsxxttZlt1TCHKeUjrKsuzv5YYaAXgqV/e+uIdvpeDPZOmtLv8FQHZT592PMeZVVX0l6x9sSAksaldey7nGxH9plZFyvW1K02vt3T1kJb5Rj8G5uf7hcm5iE0Nf3r6+XinXjiyw9dlHV7eyYEcd3mM5gbG0lLT1C7wRwPQgo5mTXXsDsbU9N1xIXTrPO4Wrk4WrmpR9w+lyAYBYWQjAuDy44SCF+3FWFxFRMljpyqFPXW9BgQq9TJapi+Kb0vUWEHxO0J0VXClk5fKhT1F9ZQq+wHCSPkDiADnaJv7/Qucfgjl+or9fobx3KUWxF03G8N1M/1cSSKv+s4KkU1kle431fSPvqqr6kwBlQ5ZvZt12spg/tJSUvI5dhRUf6tVmr6SoZYzxp/ZadSn+QCnDf9C9PVVIsMyy7Cey5DsppT/ovy+zLPt35hLrLTkjxeoNvQfxX8U9jLMs+7mKiqY2HyCE8AEyDX+UMh4p5Whu8Asp/R7e+/dUax8p89BU2HOSUrJX0dlr1g7lLX0pzqBtYExeSCBjA2i/FZDksqoV8vClZCC6Gv0VZDiH4rfx2TmyUGbZLawoXcHODANHaNnnyBpkrjV/7qpwl64JyGflcteunFkI8LkrBV66mH9Vk87zDUEZThzD1QGjqUbx6S0sw+X7ygI67ZjLnMO1aqE4YoX43jiDJfqpOyjfXCGeW6DoiG2VbQCHsaxzV6jxFC6c1RScIe97z+J91OjPxHIPtHaptXcFEpazt5ec3OCseRXr2Biy+zaFR+BxS6FMUy3F9k76eYzxx7LSM8tr24s6Bc5fm7BLwV/JG7EhIlEGYiqlSlr7a5FthT7vSol/pDTko3A5r/DnytZ0BVRDgdjHuvcjFR6dyZtpxRibVVX9QXswg2d1IY9movvOZOG/1nn3sXeliNozzODbgBI/EdBsh6tz9TpQUHPBbbJOB/F+hAy2YcmPsI68F9N90TH5CQbU1q4g//TOWUWbEI42XTqfxjp3pfomy9EGQ+QuDx9gWTPX5htdRiDARclxjtKVBDeAgDwna5Ynruxxik3JXG/BBQqGLC7K4eb0gPpv9PBb4a9nFeZI5yQ0WTDjEVFXsIGNfogehm3Ej1+hRr+pa/wmXM6Ne2AgpLU2Wt1Ck+f6bRvqkavH/Wu4pjbs1N6y8yKE8L4Y4Y/EkM/l2t/AK6vPUkpfZVl2zzoBxZ5zko+VMC9SSn/IsuyWvIn/oLX7WmsKtBdjnEjBt8U5/EKAe4YJznfFpZTyLqzE+BN7/bnCIxvsYi/xfBQuR2bbG5Sa4ko2ZTE3BQKvED480N7ZG5vsGXWUWrQiMWv6ydBu23XDa1YOJIIjmOcunF2B5F657tZxuPr2HvbXlI7zmoerA3pZqr+CZ5tgkIPTZbsW1vjMQghvswAJzGGAgodw9eWgZbg6QZhrs5q1mbvgpSMMF1BIbsgCE4WiA5IlYqYANrWJ0uMZ8q1d1FyfYCMaKNwx978H8nPq9mWAe36mIg8rArLioAu5pO/bfaid93a4HDxqcwIPZO3es/BKwm/DSe8rdrXZ9jleUtERgdXTPX0qq9iQV1BJ2Btyjb+RlX2tCb1HipWfBbxgIsZ4Xx7DSETfp2KaP9Hal/Ia91QK/BJ5+A+lzD8TMB6Gy/HeH9uMiKqq/hnx/g80EuxE+9FTKXAMIZTiP2xe330pToW3R9lshUoVgVt69lZIZc1RG3hpR8capsLl6PaWYu9vMTEohqvv5VtIPhooBWapesP1mHShQ8fh8s0/EYaMSluFqzM4ZzW828IZ6+iMX8PpbHQkekIpcMNCgB+4kt4Ai1zVuDK+QjC6foEM36kcSBSO4c+gvBXiFSLe2HETBRB2AeaVrjzJRauVXkqJLTPxAo08DcR69tLRLjbKhige6fMNNCRNkLPe0ZqWmOu7KjppQdkGignvGRhUVfUbxe67Ov8xGPi2BP3IiD6d1yoFRyjsaQl8xuIefmNvzsUg0InmEi5RCnxfFnKRUhophj+TZT1S1eD7IvQ+U4rtRKTgT3Sdu7K+L8XudxRePlTK8BtlOjZUl/9YLntH+/GZfutclv0jlPceCHySwMr6AmJVVf/F6ii0t7Nw+faiLgC2mVL6R4QTNrdvLIKuayXMaILahm6Y0tqYuR4s7WG4HNzJyj0LHXpoBDLvYu6yZFMXThc1vBu9c8b4zZpq3txl25YAtbdeALsBQ038H4FUlasFWDk+ICLe92XCyREYhSMbmbYILlTwswnJnBqgnIXLMUwBsVKGuMs8jxd6WF1kFZa4pxY29MgROz24Xq9UbtqRwtvkmwO5rlZ9dibG/mP97qaY8j7m1L2v8x5I8N6XQN4WcNgbjz8QoCQrGxZB2MZM/7yqqj8j9z1QSu6RAD+LMf7Upt9KMbvhu8GVH4IUtFd3/VLFNDZ2zKoTP7XpN3q12IEyShP1C/zeypsV79/SPr9RSPAD/e7dEMJX8pbeSJnv69yvtHd35MXdFshbo9B97XNL+/4Evfd71kCWUvpv2ue7IPgOreNT+2Ty942e3wYIuAvI/wBy+toAPVx9MS6H5djaIwzuCKg5Wbl5FwEcmDeqqxo9WcFjyB0RH1xtjm/jfxsCzFzcQQX3hUBLh0YRil2Gq/MAF65ykK8gWzgvINW0JUfEKw1343xhCXsLRqjdD/iNI51jULOW92gxYNP1IfjXK5sg/FlWycKHHXOV5Qq/Z9NjlaM2BN6UxTkQ2fe1LORmuBxM2dLDuoMpuCO53J9J8W+LR7BR2e/LuzgNISyqqvqdPIYYY/xE351J2fakXFWMMYh4G6ii79ci+OzVWNY7by+f+MLIM5GCL0XIfaHf2tL/dkMIj1Un8FJE4SJ8N7b7X7Qfefhuxp+9Im0kIPxU3MiGKgXNJbfy3pkyKV/LmxkKYB/J4ttI8QcmRxjMOQiXMycz9SPsiMthtqldUwr8Gp2gAQN0Csd3WdnwtmvYmcIy+4G8bRfHl9CPvKZfgPpSuXkc0YXaf0XO5xhCGRw6+EGgq5qKQP9Z5sKBvMbSV474WNZ0HK5cF1Rew1MkFw8dwdInl9WIYHdzdG+1XBu0H5sckU1ouyrHY51rD9zD7/X3Quc37uFrdORZCPHncPlGog/tFeayhiNYve0QwpcqXPlSCrSj3PXXMcZz/X1b3/n2u8xg9acY49+JRNuTt/AKqcIPtA+rqqq+0N9BIeEjWciF6hU+sRbrqqp+l2WZvZfvFyIbbaBHF/H+pkKbTBWAn4uUtAIceydAgXucKwvyESb/fKXruAkPyjoDv9He2VDXr1Ffv4V3MUaFZPcFYjbr3zJO/XA5Wt44nk08cyuFt5n8nL2/j87CCCU8QfMXXwHO2pSEmoCmq52ZOxI61lTspnB18k+4JizP4YVX9BwMAEjeNWvmAESn+FMHEgk3njmXfu68i+i+4y194YopUrj68hE/kpxMbYWQhWg5dwNHhuHqaKQM92ggYSPJOw6oEoaFGAv7heLaTXgcY9Qb3LOiKcWht3SOnXA5stvezGOhQlsWsmM97lYQpPj5SMq6pXDin1SC/FL9HVu670eK4T+wl26klP5rjHFWVdVLzQO0zMtLnXtH1vtzeS3zqqqeQDG3tZdPzIUWufhIJbv/KmUr5AEdqz7iXF7Lp7qnnq5lL6W0EjBZJ51NGL6PPv7fqhXb5j120Y47U4hgo+K+1XU+V52GvZH5Zbh8/VcfHXztcDkReQjjsYSL3oYCvdb3ObJ+gVifAzqfhss3WKWazj7qHL2A9I40uhnrFvStcrpM/Sxdy//bNODHNQTD3LkmyeXjC1fYwy4lliAW1wwWyRyZMUI6I7o6geBAZeaUm23GU9QEJKQVEzIHJRj7jjtvA98hoJw7VneMFmDrILPGo+cCAnu77lgu/W/lim8g0/BN+G6Y5yl68Bsppf8isqqv87ekyDbXwKo3Wyml/02Vhl2lAYcoqHkRQviVrrWXUvrfVeiyjDH+e33nsbiHVwKDKsb4nvoQRuIB/p3WnoYQTqqqepxl2cdqOPmsqqr/qmGlrxSa2Bt2V+JG7hohJ0tsE4A/1j021CH4DO26HxlpKnB7EC5f8W7WdKn7vG/lvCmlf9bvZajTsCayA3EONpvioRRzjjy/GYEJKlJzyLPJRw/WdwTLnsGTZC1Kgix1oHMr52nyhbsc7f2uUXwl2P7g9MvX6iTO9GAaMNak7pIDALoSF+Hq6KKVY/wb+N6FS/9Vzs1p1xAgmas58DXNEQhYIlRg5qABkDD3y0CiBdDgdxu4rhm4gIS+B+MWtsLlNJa/iBS0ysI3SCN1FMOf6vtfqhbA8tc2Fv2NGPGPDNSkMDd0nT8wq6RYtq+1G7r+3+laRwKJUuf4rbUOyyL3Qgi/kYK+iTH+LyL3rHbf3r77E5XH/rO8gNcxxv+oyrphVVVfCCB68g5uCNRKKf5P8FLUL9CVdlsEp70e+yspfFNeESf2bEj5rXT2sSz9ShkCy8M/DN+NELsJpbABLDa3r9T+PNXfW5BRI4CnLv08g+x77muC1t8A4rqqkespvAiW2JfwYEO4OtaucKF26TivClkzZsd8/U2AMSMYVBYCrMJfj/rybGNylrnliheyGqX1rxFnpxKJi+BCkORi/uh6n8euDyFhM7hBbDRquIKmGe7DNysFV0E1R8bAzmEDRs8hTGW4fFnGNsqJX+r/P1E4sAHXcIGhI3vh8sWnX8ui2zSaY5Q7F1L8cynxbwQwMXw3LedcLvqpVejZ3lVV9X9YajCE8GtNCDoQEDTknndjjBtKsXUFUP+z/rXy5SgLvhtjHOi8VhPx96oatHkJmaz0lu7l93omrwRqVvf+pf61F6xswSt4EkL4AO75I2RyGuHyjcyFwPgBFM7cdVPQ3XA5aPYAzy5H1yknXCXIaNNxXxnCBMrYEmXCNEYTl55jut1zapXzlDNX+s6KwKXzwLOa8IEVgZEAEJ0y19UEQKkC5QAAIABJREFU1J04uJvxa4saVGO5Y1ET21Q1ww/8VKKmO28Or6N0DH/X9RZkUPwq/PUI9IjzBlfFxT6EJvLD53qwKwmiZQ9+E76bYrOQJepqnb1a7B7cyT9qzaG+Y3nl/XD1TUR7UqqewOYBwoo3IqpsKu4nAplSxNt7mMJzoPM0lQX4me5trIKkPVnrnwpIvrXnKvLvQjUM/6zqwWUI4Zda+1wAs9L3cxFx/1kWei6uo9Be7Gvtx+gd+Sftw4X+tQk69nLXe2gw+1qAa8M9dyydGS6HetorsV+Hy7mRQ+zzETiFyrHmc5cJ4MxM5uzJuHN0Xo4wpOXKg1nc5lPvZPJXjsRr1GTlokuX++ahufNishzvoPNu/soxigwRShdnlDVrK/dv7mL46PKhvmmBBUNVjcfgiyPm4eorzts1sZQB0BzVXbnzZiYudIioImw7t+4Uoc4Q638vK3MLv/ksXE6BuYNqxH8UaNgoMhsnPtX1PTA+Qa64CbNZ04mE1whEm0b8p3D5kpP3BBKWwnopazoLIfxMlnckL+Ajxfs3tPaPUrZZCOHXUqqTqqoei7TbDJcDTH+vew4676FSb7/DO/zsTcjfgEj9zCyVSNL7yKK0ZNGNu3kAg/Gfw3cTkNuo+DxC1+YDKO5v9ds2aHOg67BxXyzxPgHXwOE1U2dJmYevrmmIy5GWq8JfT/fxMbsfvLtw4BBdZqKupia4LNzSpcTfhiDWDEQlTq76r640OLqUR1aDVMldcOXyntw87zHMXeVghrUrh3h1pKBH4+Ka3oJGTZll0zVFLVHUEZDi6aKSa+yKjO7iHF+Gy5HTQ7ihX0npPwQw/KssfNQ5zBL8QcUp98H6fhEu58Z9JADoStBt7PUQnoKRYD/V2l3VBJjLayDxQl7EwxDCL2Qpf6z8/hvtwQPF+3NZ3d9LiechhM+l3GdSrvso7BmHEP5F99wREL7SnvxF3MD9cPlevd/pPhpaazXttk8PID9foDrvBuT3H/XdmwgPX0FGN2EAvwXpGkB8r1wImOAxsEmObeu5y241nW6xzZf6svzvrX1pkxRXluV194jIPRMyWcUmQAhJpS5Nd5u1lY11z7f5OH94umxa3VUqNZJKKwghAaLETookM8k1Fvf5oHN5J07c55E9NjLDBBEe7s/d393OPfde8j4KyQaU4qWb7NUo0zYScH0sK1chltT8fiNCG1l2C/KTSvqpBURs8xgYe4haiVnw8GpBPhkUVIVSU+jA01jUhToUBcgaWxleryhm9Hy2x3jfYeM5T+AXS/0HlonGW5rZXyDEp3DudRz7nJSEj0P/dxzrjS9/tTQefI2UwaqZfYzr1/jce+PfR+HRJdzvebjcHQjuH3DsgrcJB7loEZ7Dl5ZGjv0Trvc2vI59WNNFeCRP8P1NKIlZrOlHAqZO4B438Ky/ADbgodBDHLeB5/E2eYE3oAiOEd/+kIg9b5Nx+Iqe8QxZ9p+x5tUAYC4lm7VBnpof+yuxRFkGnhNNXIHDxuLOWaUwXysReGbWRlm1vhjV1jZ9jgGoJmHhbkToSwEDGznxSLSVBbEOgxyN3JwFoYMCkeqJMNDSCO1xbBKKpXFjPbmfRkslJUNgkvHoEwGki7jXm0wuYfM6nfgFQLA5uO5eh/A9Pr9EAr9uqeHkSUvtwf8TMf0FS3MMfN6hC9ATCivewefetOShpZ4GHzgS3jTNZ0gdzuEc29jQm0jP/SPW/xaEzZ/9f8NzHwGg20PmoYZC+cLSKKxrWEcHVvYVrlXhvD/gvHdx7Fnc40M8v5NY9xox7j7Hc7tAvI1NouueIW/rBjyqM8RC3aGM0HHaV8+l6Mf3tO/duYApOG/jLfXdaC1Ifn9GBLCxuL2egvI66qsI6PGaoh8JZhByc6qyLK+jMKSkbruGfLBJF943jQbps4KObagjsPepr+hYb0rY4JpdOtYbGo6K9J9fcyRr0DV2ZX0V/bvBuXaRL5+hzsPetbiRY705ZEfOw2vx+3oOcos3cJxHsU2JYpeTqEariqJwl3aA1NkZrGsHFusq3PC5oijuYCM/gkBcwGZ5Bet5BQKxBm9jEYL0LgRjgBj+NgRyAd/dwqb50X4bW34a19kkdL4Hy/4TMge3kTk4AWEc4jvffP+Eda5CUflQ1gvE0nSc4gNcY8nMPoFgDyGgJyC0L6DgLhOx5ybu9QWu8xaBvb9AuB1ofUpkoFO4/4LO7cU8PEruIXkuJmm9SoyUG5E5EdrGJtvrPafCIz62Ds67I5mmgjJnWoV7IEqjssnGIGbxaHC/5qgqy/J6QALqBC56RAWuZbGFaJ9OACAqQNEP6MS18J2LltChCVw2C67HacQ9G5/qUkvutAItlnkJjGV0KMuwQC/Ay499hPQseQcdS51uZikX/Qgsv1Uone98xj2UyWpRFL/gd7fAj19Gtd3XUFYzUCZvodttXRTF5+gduILjv8Xn2+gQdKEoimf4/RdFUXxEA0P9vOtFUVxD9949KEBH/Q3EoR9xfW9VfhFKeB7X9G65V4ui2IHi+xz3dQbfzxZF8QDrcyrwPO75S/x9Cf9fKIpiEwrVuf7LOPY+nktD3XuHuP49KONF3OcOzrGF3yyRst/AZx0xcN4qf4aOZSNXkKHYoVbzJr8vYSD82NdI9/aw5wxZFU6t+37sCxXYMh66YgORZ1xWaOtU2GQLMI3fIxdCAb7I3RgFFYZ8/k4L4tmVcKMM0pNDQfK5OUkhaZt94VyrAuMMB/coaKQ4qpB88FPhjnvfg9eE2BsVCHkT0QUKXXwMNQN93+HYbVi4ZWIQ7iOu93DhJpTPz7D0yzjvHSjHUwDCzuBYg8fwB1rHbVjIFbjil8hjuA23vweLegcKr8A536O02+ew3j3czzPiTpxCXL6L636OYzpYnyvcB/j+HCnre/j9AVnwHkKqgrgX3pBzydL4cq+12CZ8qEvp4MomW80N6X12pPhmW1z6RjArre7rkhfQQKDHJmZBwHe96Qt5uQWIWl3ybhuZu8EerHrpDXnG7FkXVVmWV8Ut0Nbe3BW4H1CB9fhGmHu5ar/Iu4ji/Zzgl3Jd7UrEL64R1F9bI5kALqWwsEyyF47qvrI0zNTpxc4zd+qxU45vwW1dJhfugNKSXkQ0C1f8HMWXA3w3gPt5jXCN/4Dg9Ild+BIC8NLMPsSxSwAFZ7B5PyLA8TmE8yMI/1kz+yMxGv+HpXFWj4E1XMVx58zsz3gO95A58ClMz7EGB+jOU/bjMygqd/HXLY2MW4BScTzlc1zPJ+k6DuAU8DVLDWTu4Dlzm6wOPb9F8kC3qUisJL5HI3n4KpABzghws01ORW8K3lQH9F71vJXl16V0OZPb5iXej/Z/Qwq1E5GLKrRqrjOWfWSTcwA1/6kpvahp6GEQDlRB0UIUgtQZT4LjoFpekj94TcVUNt5yiUGYQphZBb2sktbGHIF5YufxCLIGwnCCgCYvYvG5f+eI9PKUwoEVCMo+HevU11VLLctukVV3BPohrv8K6T4Pr74g3oCDbz9gnc/N7J/JO/qUcIC/x9+/tzQ++19wrWWK4Udm9jus/S6OfQSFsoA13bDUhussBPxXXPchPAafr3gT3/8NivEcjtuHAjxDXP9nuO4T3KMr0j0iYA3wnH2WxJawQ7mWfpjJ2Zuk/BSUY+arfz4rYB8D1aMMZZcLdzriqfr/50mYtTfGUDzYGQHnx2TWMQALmHsaT+S6kyhvoAyEtpuhNnaCsKIr57Ug1RE9NPYu5oI0YiWex4F8zp8pTjG0yR6Bu5RGnCVX8jE2/THKO7+wNOlo1dLo8psEmDkF9iW+e4aN75r+vqVOMrP4bo/otlfpHL8SSr0M4fKN/i0Rdz7C9V5b6p583tKQzE/w2YaZ/XdLk41/wFrexrEu4MfJuyiIFLUMq+wg3V3cwwsKV5w56c+DyUiedz9LIN1dHOvh33ES+i381sPCp1ASXjPi053cys6LN1oFe8CC/W1S29LJZLNKMnSH4l1rD44qyLRpyp2VRNUSPhdSKKQkpYErgMImJwOra9zIgpsgl6lNQ8uWsEK9C1UShYQgUbFSLSFFEXgzldQLNDY+t6AICoIswBOMKrF6UhwytNQ09Bgd70JVUO54QOm7c+R2fkNewhp+1wdaP0cbegWf+aSji2Sxf8I9eghyHpvf4Bpfs9Sb0PPzPiD1PSiMA+TLr+Lvfw8hfEYhyu+onuITeBX7OMdrKAEnylyj93WDUp6nyTL+BKG/TDn6b7BOxy8W8ezuWOqT0CG8wLsGe6/GEbywY8TS9PZuHhJw/4gt8hpZGUT0+EMR9jLI0bM8VWSB28JOTu2pvCgdnsFuDVFHYrQ7Nl7N+4aFyyCgZZD8MkDymykkIKZG5qiNUaGRHjvIaONIoQwzCoU7pJQC9NUBI9AkHNDnodOL/Jglela3YRmXaN1bBAat0TU+h6CuElC0ZWlo5QXyjD6mvLcz/baJZvw2gY5/xebfgqLx9TkB5wKe2RV8tgOL/AHxFR5AyXg67wO45esAG9+HsJ1BePAA6yoh+Nt43zcIsFykdJxTti8ToepjrMkZeU7a8rZvb1G87UpzjjIye1C8C1Ac/k7ukXLmvn0blNLT+ZgW0M074iUOMlRdtuaN7Lcm4LiwsasCQ2nCMBwFdPVIXgqhAnOoXXEIoG60EmQi5l5tkz3+RpKvVAGqghSetdCG1ZXKKZ9opLk+6EMb75xaBu6XrncQACtcglmRi+Wb6RSdw/POM1R44kzB0xBO3xyPaDMfp3v+Ahv/Iq3/HinbK/T3f4ervELu9ANL03beh7CfRLzvWZHLWOcWhPkVUP8+hPcrEo4PoXx8TPozM7uOtZ8jYs9TKI+zhNY/gcKYgYX/Fd99TfforvIzQuW9GUqPBP8U7Yl1AstO0Lv8mjgCvld36B3O22Tfvq7s3QOLm3H0RAAtoOXyvmuCY6uAJVtlMK9CvAyL0tc22XSnCgxw5SDglcDS1xnXp84syCQFGAm4xvCd4DwR4aGfObaxuMFoJ9CqB5K9YPeoscnuqRqjKaZR2WSxkrLEvFPsIqWYnGo7D6Hwc34BQfGuxbtY109CZGmAnp/Hhj5uqQT2G5zzHbqvTyEMHSiJLXzuRTsXKHX2GWVv/gGYw1l4KD2Kv9cQf3tV4z9AuZzFOTxzcRLHruN+HiFEcBzgOzyvXSirS3hPuzi/ey1e5Thnqf3WWXpvD8izmCFh/QnXP0Pv/BnVcLDwOllnPkjdqeV0Rh97ggeSMfA9qqlCZdtWwXkLEewykLWh/LaScKAIZCBSEkPPAqjro23AGG1UIK4fWM6cRVfLXgcLbqakBovggeQ0oLVwDcpAoWgsxai/or8jemEVZSTcMszT5ji01ChknlBoxwjcC9ig83jc770P/gQrfY54A7vYZKcgzK/x3R8hbBdwXUfbn8PKvkshxv+BNZ2FFX+MZ+QZid/T+j8hsPP35Frewe+v4TmegOVdwb1eoXTYt7hXBziPIYTxpipvWyrc+RuBvXPwOjxb8TMUoIOte2RtZyH8brBYSXARmzPvFgM2Xlfiem3GoSGBsvQ6cqziTEWGI8BFbEUQVpQBlsYDcaLW/mrI3pzHQ4BhEAvXAnKUGWGrhF1UtcTwyucvA4seued1gIIWmYxEVDhRiOuj17MpYGOT0aqek5618QGqfg4HzfzFbxAC3aMN2cd3a5Se8iYWD2GlmfP+DELmffOdNPMtBOgS1uH1Aj7g9AL+XcBaf2ip1t5j+B4UyocQsnI0Gn1WluVlCNFFeDNPLbW3+jts8DnwEs5CuN0V37HURPVtS12WbhAWsYo1elx+SIrJ+xV6RmKBXPpd/PHjfGT8LPH6j5FQDOjd9khJaM6e+SLqikckoDrIplmQ3fL9HM3jZIDZAgNXtmAPyqytAiqwhvd9VwBlIDA5em+VKVoogsVVQVxeZzIHFrj/wynHMrVxKFhAHaRhNCd71OxFNAlpIAxEnnzEIU/H0nyBGTp/nzwGxwi8W22PNtgi8bvvW+oo5LGwW1mPib3I5Ra8gEVYzlv4zSNY6nM4dtdSpd4yBPRbS511/tFHg+HP97jWEsKNH/B3J/a8ZWk60y8kbBfw2RxCk/NQEF2KvytSBmap2cdJEgymdO9YKshiDKZPSsb/c6+rI4Qet9azInClgHicLWJGH2NQbEReB0oid94DYQ+yQikzhCE1crWEpxYQ91TGq6osy2tCYsgJRTEFKCxEGzWiDAqx/FHFU470Uwe8hDq4ZqQ0uGxySJuosbi6KgcK1nIPFbmSfXIb3bWcsfF+b54GekVsQGcBzuPzijIHnppawsbz2HWWqK9vxl2Rx/AAQuyI903cl6PiK3CtC7juH1rqfvwNva9LUBL3cexNgIIOsn1vqSbiMq75hHL/l3GtNSgdH8h5Al7EgFJ1pyxNZ/IGrM/Jw/ENvkkcCn/+XXhFczY+eJPJPz0idGnn6YiLUk1JVVtgwdV7nBE8oWeTlXq78nnEW1FvV7tsVdZS7Rd4HGOp9aosy3cyZJ1CYt4qEOYoO9BkEPgmUALqnreVP7Zd0wKlZJINKAUsyaX5NKyoA74Dr5uHM+6TV8DsMKedLhBrz5uKuLJcoOfwBIJT2vhU5H1L9fMuBLcsVQq6YulBgPoQZPcuvoY1fQEvwC31fWwaJ/YswD2fwVo+Ik/He++fwRrPIkNwHArlA0vTcu6QIK7ieB+r/rWlisYOvAUHVH12wgHu52dcb5YULAN0C4RTbeC3HVHOg4BoNgiyQkVgcMziOpgiQ1jLkdtqSWHPtHgMWodQBkqikzHWrCQOJKwY0b7sMhXYLD9RRNt6Rej8KAMKajeTtjRdE6Q46ozHoB2Mohi+yOAPZQsoWJLGVPxjT/LDPKK5sfGW5DsEmHGb8W38nluIeZy+TTn4ASye4TvnsfukY88QHCMswuPwLSgF7xL0Vwj3An7bh8vt/RE+pI3yCZTAIT73VOYO1vN7ClH+hDVsWird3cKf10Q8WqZU5ivKEDhzcg/exgx5MSuWmpycwPtftzQjwPeNz99zz8GrMzcIPPT04CF5Xdzn8TDI2bPX2JE9VmX2mZLpuhnSHBexcQs7Bpg7tMdGFtfi1DbZDlyVTy8gDLmRMKUCl5k8vC6Yb069gk6Qy2yL93MMRD2vuued4BwKlqiimoZpjCRFo0qiK8BKZZMjmrmhhANCe+SyLVKo4Ei794n3ibUOVh0nK/ETucM9WERm3TlZZ9FSqfFL/N+Btm0I3EUI/EWKve8iLj9FSuI2/u25fx+y+h0s/ymy4N6o1HsT+r1/CuH2+1yyVB24Z+N05y+J2NPFb/bw5wD370r1GYGoTO/1ZqTLZLC2xCvr2njfy24m1V0GxqkTUIP7QSZA91Qu1R1xAHQMn7UYyo7ISxSa1DZJMS6NagGKgGFnLQtmkKINbawyD6GYArwVGSQ/d15GX9tSjjn3rg5Az2IK8FnJb3YojvXf/0q55S4BWI8gCGzJnpK18uajTGf1kGCOYu3XlC83uOI+Ydhbbz3Ge/EGG+4y36J1eqWesxVvA0AcIoT4G+XoT8KbGODYby31NfQCn8ZS16OrtEHv4vcjSyOzKuAJxy01US0h4D6JZ4G8q3uU0iuJ2OP7YYGs3jP6N7fwdvxHC706AY/FLB7PFbWpi7AqLpIrMgDzyGKafCQDOhqcW4mxl36UeoE3IGCEwg8ylN0oQ6CMwCJIIyogooChuviRgLfRlHOWPgIbG4tHnEdlyG1EJ8YHegEBZJ42iFsn70Dr57lpqU+du3f7RE5Zo/V/QbGwj7j2DrtOpjFy+33qjRfiDAD0LcL6u5L43lLBjbfmXoKS8LHn3gfgF5zzPuL9Ls59B+/Aq//OwT0fwmO4aom/v2XjA2PeIk/qa7rHDinNdcrvGxF45ikedqv3iEhY/n7XCSRkfvwrGx/IySGBWmgXto4IeNmCKVVB2DkKzp9LgefYsi7k3WAtJqSkvngLb0LqqizL92TBo8D1GQZIfo7KWE9REt1AO2pfwIisk2MVRrxqyyifnJKI0p+5uge9RyZbaAlmI3nZHr38R/AATpEycQbgDHkHRvHzWbrmr9i8i/jO7/WPsMgnLNGK18mivotrzJnZvxEC723DtmCpa+T3DYJ7A8f1LXX1LS3NALiG8x+zVNzzGOc9J/G+sw+XiBtxB8roDBFnRvS8FknZeuOOBRsvlnEFy89uncDXQvCcjqQKefpUZAy7QTqunJKz5/MqUK01NCzEw4xCsUBh5JruNAE3Z4xkxA1BSgESzPK9zuvATR8FFjz3eRNYU8ucdxgQI6KH13ZsxEvINSgZBO59nfEY+gLSdFo2k444W6ZjXxIXgM/nfQLeouf2wNJo62OWRk1/Cg/gCj1XZ+M59djX8DHCgUuW6hNuUaz4d7DOK1AoZ2F5zxEouIXn7S3lnAR0moTQ+xdsUuZgCd//QLyFRfx9QKHGEj0/B/jWKWXJz7mSuJeJPQuyDwqJ+3UwDO+lOnDFXxGfwAKjFVWOdsVrjBqBviT2KHsTe0HeX/ddGWTwLGPQxgylZwEiYdU0YI7nH40zyllrFdpoBFlOkyoppzPlWM3ZWwseYcGxkcBbQK9UkJTztV7Uwi4gNzDxzTRPx/Ik5EW6lzuE+lfYMAYlcRJAn6PC/4l/nyHB8fkCF6EkfFLNn2Cl3W13oO9rnOO6JUr0DRLAK5Zaq38Ggb9maWil04N3bLzs+balQiVXHBv4/iWUhiPiz8Ryz9t44dW8jTf16JDQzdKz0wYxundnMnuJ9/tBi8eg+2bPJqf+DgO2KF9vPsDSTABKV1S67wqbLPoZCCYW9el4kwXoTxGgaUh+KWkzRc+1cKcO3PA276LJcAEioC/Xo2B0BJZfTkm08R0i7IKvzR2EvCON/2aWXiJnE3gw6TbFvr45nD04D0HyZqQ+i8BLiB/j2A5Z8Kf49ycA+rxs+RHWt43w4X2EGRWO9dbePovALfuapaGlXrNwwVId/pAAuVlL3Xy8NPm0paGds7TRmSpdkRfgAjNL7DxWuD2ykC4ws5IKi8bYawv4xibb3mu2SbkzEe13R1KOjRCSovoaJRcx6zRSPlGquhJ8rAoA94F2BdY8PC94mHHxixbhqOS4JiD25IC+JhN/W5AyNNqARQbTKAPaZJlRPmUmfxuhsRFbUdfQt/FxznXAQCyI9NOz8VZPJTHhmPr6AhbyNT5foc31kCz7PNDzZYQQFyHIB7C6D+Hme0ut7yy14n4fn3UIS1iCMjhPac9PLQ3zmIF3s0F5++OkAL+EklgjQ9GneHWO3sWGpYrKKIxkBctdpLUnBE/IYY9t3yYHzY5sska/zCgJ3jOdINTryXm5dbhOz1ZD1gQhSKQkzOLeFso01F4Fb7IAFmx0zuUr717LhKO8f5MBLLQLStmS7svRcMvg/J3ghWgIotdsK1bSIpCINszPg1NKmm7hCa61ZAycMBR1Ifac/yGdvwuh7dn4QFNn3Pm0W+92c4+4BwvkljdI712jWPkrsrIuoE8tzQF4B+c6hmOXLPU3PA8BP4SSuQDB93Fji1AexwlL2IMSW7NUNOVj3F8SeOdg6lDy+UMinzEzjrvvjDLWUEPJqNxbDUM3gytFNPaINlzZ+NDOCDRWTr/WC1TBsVEvS/YYRpLif+OVcy1AkUl3lZYvrNEYuWyxkDkBikhAOUUQ4RRtvQSUcVgKizAHCmpLtFxKkPOsjQBBhaRDhzbeFJJBQt8wA1Igc3TeHbKKzuv3eH8TQnWAF+6puHUcu0aWyQdobFpqTT4H4Z6FV+A1B3ctNdt8l9hqNylNeAJC/hjf/QRw8bilcd8uwIsEWjoJ6hR5LU8p7z9L4KS3WztGz+5QhLtL73Vg43X1apxyAsRGIKKm1xb3j8jNwuSwohTLy1a8kfR4KYbyIAgr1BNRhRIVvlWyZ/cNVOD3MmkwC/KKZQtHIHfsMBDYWqiNbfhCrhfaUKxw2ZLfZw1vFnf+iWoLzCb7r0XMrGEA7uwR4McNRTctNaQoxAVUJeE01zmyVlvkBbilb4gZ5xtslWLpu5ZaaXmZ7KylLsWXSCl+DSF2kpGz8Lyf/lVSBt7ObMfSQM4SimaIa3oM/jOE2EefHcd5HuM3y+TV+DPaw2+XiKfAz46nRe8Lkr8rgsPtvvvihfXFc2WsaiSA81CsfhWEGSN5542kujuBUe1lwvCuTXan6kl+nydtRziFH8tyFVKBlfBQZph7nSl5/zp4QIW4xrkH0UZqYCt9lJSeZTISUbyfCwks0OSFxUVTFmjsipD9mvLnnPrpkIs5sjSSap6O9ZSgexhLBAiapanCXvK7AiF2rsEhrud1Aj5G/AnW9CME3i3tHuL403guly315fsGbMBVS5N8N8lLOUd8hi+hCBZIAbn7PyCSUUlKoqRjvbd9Y6mvYUN7tBEkf5/+XYpnxvMhmoziHmYAs4idp30vywAfa1pYhDlmIFc05qjAtfAVdP4mtwlvbLzC8E3GyhWACtC0QYW5z3M856i7T1szxdLaS3+LKSwpa8ER2pRElQlBui3sRP1crQVnSkpBhuclzVSSEPtadGadI+J+Pa4t8LZgiwS+bUBw++TidyGYq3gP3g58Axb6pSV67wJSd+59rELAvVjpBWUdlkmpPaBjHf/YoPBljphs9y01LSnIO/T3xlVy3IyDM1AjsoKlpM3UA+1bvna+DPZNYzEd3AJAWw2NgtGdAOTWfpfa+acRWWgblKMKiu9pVzgJldYCtJF1GExQbbcnCLzeYJkBRMzay3kHAVMqp3z2Je/aVnzRtKTtihaOgGXYVrruqGGkl2Zqfphz1Jya8jbVK3S9JyTwju4OLNGJz9Im+B6/9aKaBTx7b8Zxlth43sRzC/G+u9J/oRTkMXgZj3DNB+AIeAx/E9dw6+sknxppw1XyaDzF6RvyOO2rFxTKMMD1CudybCd7AAAL3UlEQVSdkXfOvfhK+rwjxw7o2TJGo114OFTUkHhXUnoFyUTkCXYzBLsotV5mPNWRxQVIkaEcZnCKQ5ssZqsdBLw+BXhTbnx5RAupVjaiTtZTlE81xZXnB93JHFscwXpbyxqa4NjG2huZ9CQ1aPSctAfCrJxnJJ+z+79k441OvcfAaVqPd8xds/FKsR8hrO+Qkvg3eAVLdPwhKY/rluoObhCI53n+Gp7EvKXagjlkFxbhTZwkQpMXR1WkKHxfbAtzT9lus/TuOXXHQqojsk1SbEUA9EVknTID5vVk31XB8bkWYDmAuQwMZARcK4mutPHmvZqSLm1yaI9iGMZU4KO40VH+v81jMJvsZGItnIJptQUWfN45wnqj2gLtHXhUpqC1cBj0RVYB8Bm1dDoI2GdscZbE2yoIHPR7/gYI/xl6Pi/wrJcgiH7svwLMO29pRPYveE6LBPSVZva/EQ4sWuLwvyBA7h1C3T+GcvDwxnGKV/j+mE32QNgn5p7z+U3y+5zuy02EUjbeDgGGfOwoMC4HFvP6o/Rf1Ai0sMmZAWapzkELfTaF0cehjYYrB4FS89BGsYfDYJ9ranAMc2AqcM7aKeBlUwS0yVhrLioqgxjZLN9v0DJAyTTmXq7hSK6dWY43kKtvKKcAkW3NT4rAOmmfumgaLbe2KimuPkUb3PvoLWMDvsZ5v4KAXiH39yYEc9VSn/7Kfhv4+TYE3GfL/0gMxLfI+3L23yXych6SUK3Q87qD6yzQ89in+16gZ86t1dj75Bp8Bpg7JOA92i/cLp7z8FG//wNR3EoC6mSwgE6Qs58TxVGR8vZ1v5bQxveXZo9YUc1kPNauZKF6krqvNYz3ECDXtCBKDeaqkpqW3HwkiJZJAUbuTGPxqLDI62haFFUbvdeCNGKZueeyxesopijLKmCxabOJjuZrycoOhPU1TxvcZxGcJKXhG3UBcf8ufvsZLP0J/OYRrrmB464QYegvltp3LSPl6JWAq1ASvmm/g2fhyqdPMfw8ra221N2IuRMlpS9n6Hn3JSVWZdxoFvChjRfoKHg3jd7LgFw38Bgq2VuDwForMUjb681kzsvZhVyD0QhEPwzSn0Mxsv4MtrUrcBtgNq0RqE2xnEVL+GAB6HKU2YNttOGjpgZtSuagCZDVKONRH+F5VBkvpq24illezDhk6qvHzz2ybE4PdjfYPYXHEOTTOPYFjl2xRNl9aKnN+GVLcwkfW5onuIrPvc7+BjyGs1jbS0pBudfg4Nq6pYYovmm5vp2n6nrL746854hJOhChLlpCBBXEMgMAVoHH0BXUvwk8FAUM6wDf0jqErnjGjH804hV1RPnkvJlOkN16c14FAadZtiYj0AMb729WthzbBKm9KARpawRatlj24f8DppFTEkdpX14Hz07ZYVHIkxvBru2gNHXaIcHXTVDB9ePmIi/x76Gl4iMvNnoGV9476vrI8V0IuKfsdiC0ns8/BqBwDUrhtKVpPV4D4L+ftdS19wWBme6mDmlDd8gF74u7eyheI6fWFFcZZTI2uVl7EQs0OrZLOXhNsQ0oK8O8BK094etE7cB5DezFqMcwkBRzlxTVXqBQTNbxBgN4d4qwtYF/UVybQzxH/x8Fs2ghXEyLy83ah4LUNr0LcXNEVLcIWGLFFNJRTeGAMi9LiW/7OK+Wks4QvjBH59izNFDUx2UvILZfhPX3uHEbx65batg5Z2mkubc/WyCM4RlASE9VejbAc/lLtJZNS/MNHI/okKvPA1YGFne2ZWIPp+Si+RBRyXgEBBcZdN6CFF6RCUEaScvpbMqBEJIifKyNwswzMBj/2BXgk5uGah3Cvpl1S4tHelngtlgmNWiZz9T1icYu10F+PwdATluDgoIRPtF2jxaAlk3mHpuAP2BBRsKCVOlQABt+Tvqy9wgR59SP99SfJffQh2N6vt8be/ZhlVcIkd4kwfKx3v7v72Hh3TINcI7HEPT3CMj6mVz7GVh973Z0AK+gstQstCFBdyzglXgni2Q1D8SaDiQkq2Sjc/y9J57ZjI133eWuzn163yaeVT8AhqN33lhcG2N0/h69+754hS60+2JgeqLEClKarPAaKGxWKCWFIbuyr+fdA7geuNVRMUTkvuaOzaH1UV89y+Qrcx5D3eIV5FKRudChaPEEpvVHzJ1jGnOSv3stiG4lqZ9uQLZqbLwAyQky3Iz0FVl+T8l5J13vIVBD0B/js5+B5DNHv6Z/n6HY/SsAiI7Y75ELOgSw6MLxzFIL9JKEdBfnnaNn8iutlS37vgCF/Dy1QG1kk51+h+IxRL3yCkkT5mZJVIGlr6cQe6qWDJKShJjbsCeZIK09iTyRqHEun3csrFAqcFszjjIjzFVGqIopoOC0eL9swQbahG0awNeGS+QAuSogakxTbm3kpVrSQeqJREVFiur62ri2wAlDs/Ru+vYbw8+be/q6b5EV5kGkT7CWC5Sfvw1lsWVpmGkf1+vjPG5lN7CGJxD8hWAPcEk0K5C5jPfXDVJh2rVqGOzTXEhW2+Qk39x5DwPlo3x+9WAjmVAXnz1jNWAK6NUiH5WQlHoZ46ThipKJOkehArdhAdMEPNJ2B2LZ2vL+uTx8bXmKcXGE8x6VClxae3ekaThFbt3FFKUZIcNODKpssuT4LtzvJfr9OiHW87SZfLz4miXG4UNLPfDOEcHoT5YGinjDz3VLbcPOEf7gswJG2JDLpKj6JNzuynYtUXa7AYFKPTdNsbFLrBt9i0IKE+HMMVRzHa2jPLweq63imcSlXkA0laoO0pMmAq+EslzfgejZ+QBbzYKUR6ECt6XNck09LBDQiBFo1j7SqzwCKBhRjHPKZ5pCaeslYEcAENsmxUwLFSxwYXXdPYvHUK/SZ88JnGPg6L6lLj6+7m8sdQ9eIcLPX/E5D/i4AwVTW2pj7nl/HxHmIcdzeAMDS8VHZqmPH5evDm18FHvZQubS51xlANzZzB4thDikOXttCGuWZ/mxx8G/8bAumjKs3Jc9m6Qza0//qP5l2mDcQSZzwOctzazhuQC5WXvWQgIqp2QJpllrO4JQ5PCESKFou+5piuoo1rstO5KjAkd8inoKealNaWrJqIJY3PhyUUDFA3x+nKyHNw09TaQjr+zzUeS+/n+FF7BM4ca+pRl/50g4fXLwDKH2NVmgOcEp5m1yws1u4NLqeLiyJYzMTYlSy8kKRQW8Ea+jCrCYSo49DIg9vF7OEuxJ+o8r9RpRWDs22eNvKNeuyCCwd8gDbAcWdK2KNpe1IPw57rxaU0ZUIzdMqblNgKKPghfr2i1CXy0jKFFMFgnbIBD4uiXksQArsUy8bxmQVO9xKC9Y+eoFWWT3FJztd4zWsUkWdgGbs4TQNmb2B4o1f8FnawD2trHmP+M3/5M8g3uW5g1eJxT6zzjf72gNrwlkW6F79m7Gx228MMoZjgsS8mhDDc7Da36fn11X0mZcCTiQY2cCS60eiqP28/TueNjnjBB7NJvAbd7mbXwoqGdv1EMxS6XdRu9V60YOLJVYF5JBMkk5DihrUxRVVf2vwK0diYZsCwWaAPlXkk6u2cdRwLpp3XurKa68EiwsiLssUGKlbL5cOHDU8/Kx/9Xnqp5PRz6vKdWzYJMlqQckWP7sH1qaJ+jFOSfx/4sU2/btt9Lf92jj+dDOe5QW9PTkY/utJsD3j7cq89He7E2ObJwOzQNme/IshpIS4xBwRp6HPyN9jyMbb/ZhAviqi98lXoKJd8Hrjo7l9fXovTsfZJ/A2iZyz+m8O/ReG8vT40s61gJDpkZvu8wgh1VgrepM/rxoya2XGSGoWrgGbS56nVlnlHphj0Hd8zrjguu6h5kMgcaAZpPzEExebGExLdRkE9QZhRd5SUPhN8ySe8cu35ylUdveqddddx/y4TX458hK38dmeh/neoQN5oDSdSidEdKIXUuDSTbJqrvF93vfEgDrkKyT2Tgzrm+TLDwLrLeR1awCIdR9Pch4c0MBgLt0zb54F4fC9+jS+faFf7Bn4+Pk5mgvHth4Z6K+jXfzYW7Evo03GB2Q19FICMj3zQbdORIr/xeYr0jEb5FX2QAAAABJRU5ErkJggg==)}
+ /***
+  *  Custom Styles for the SVUI Site.
+  */
+body,html{height:100%;background-color:#333}td,tr{height:auto!important}body{text-shadow:0 1px 3px rgba(0,0,0,.12);font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif}h1,h2,h3,h4,h5,h6{margin:0;text-transform:uppercase;letter-spacing:1px;font-weight:500;color:#000;text-shadow:1px 1px 4px #888}h1{font-size:24px}h2{font-size:22px}h3{font-size:20px}h4{font-size:18px}h5{font-size:16px}h6{font-size:14px}small{font-size:.8em!important}small:before{content:"\00a0\00a0//\00a0\00a0";display:inline-block}small:after{content:"  ";clear:both}table{border-collapse:collapse}tr{min-height:28px}p{margin:0;padding:12px 20px;line-height:20px;font-size:15px}a{color:#07F;text-shadow:1px 1px 2px #ccc,-1px -1px 1px #fff;background-color:transparent;transition:all .2s ease-in-out}a:focus,a:hover{text-decoration:none;color:#0C0;text-shadow:0 0 1px #fff,0 0 1px #fff}.section-label{display:inline-block;padding:4px 12px;border-radius:50px;margin-left:-12px;line-height:1!important;border:2px solid rgba(0,0,0,.12)}h1.section-label,h2.section-label,h3.section-label{background-color:rgba(255,75,0,.4)}h4.section-label{background-color:rgba(255,255,0,.4)}h5.section-label{background-color:rgba(75,255,0,.4)}h6.section-label{background-color:rgba(0,200,255,.4)}.button-icon{text-transform:none;transition:all .3s ease-in-out;color:#1FCCFF;padding:12px 16px;font-size:28px;line-height:1.33;border-radius:50px}.button-icon,.button-icon:focus,.button-icon:hover{border:1px solid transparent;background-color:transparent}.card-header-title,.layout-title,.navigation-link{text-transform:uppercase}.button-icon:focus,.button-icon:hover{outline:0;color:#FF0}.current-link{background-color:rgba(0,255,0,.2)}.layout-title{letter-spacing:1px;color:#FF6F00;text-shadow:-.1em .14em .01em #B30,-.08em .02em .05em #F30,-.18em .2em .03em #000,-.08em .2em .03em #000,.1em -.05em .03em #000,-.12em -.02em .03em #000,-.08em .1em 1em #000}.layout-drawer{color:#fff;text-shadow:0 1px 3px rgba(0,0,0,.5);background-color:#3F3F3F;border-right:1px solid #000}.navigation-link{padding:2px 40px!important;color:#fff!important;text-shadow:1px 1px 2px #000!important}.navigation-link:focus,.navigation-link:hover{text-decoration:none;color:#0C0;text-shadow:1px 1px 2px #000!important}.navigation-link .material-icons{font-size:24px;margin-right:32px}.navigation-subtitle,.navigation-title{display:block;position:relative;border-bottom:1px solid rgba(0,0,0,.3);font-size:20px;line-height:1;letter-spacing:.02em;font-weight:400;box-sizing:border-box}.navigation-title{color:#888;padding:2px 8px 8px}.navigation-subtitle{padding:8px 16px 4px!important;color:#FF0;text-shadow:-.1em .14em .01em #B30,-.08em .02em .05em #F30,-.18em .2em .03em #000,-.08em .2em .03em #000,.1em -.05em .03em #000,-.12em -.02em .03em #000,-.08em .1em 1em #000}.navigation-spacer{padding:1px 0;border-bottom:1px solid rgba(100,100,100,.2);-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.container-title{letter-spacing:0;color:#FF6F00;text-shadow:-.1em .14em .01em #B30,-.08em .02em .05em #F30,-.18em .2em .03em #000,-.08em .2em .03em #000,.1em -.05em .03em #000,-.12em -.02em .03em #000,-.08em .1em 1em #C50}.container-subtitle{font-size:14px;letter-spacing:0;color:#FF0;text-shadow:-.1em .18em .14em #B30,-.08em .1em .08em #C40,-.22em .35em .1em #000,.18em -.1em .2em #000}.card-header{padding:0!important}.card-header-title{font-size:26px;color:#1FCCFF;text-shadow:1px 3px 1px #000,0 3px 20px #04C;letter-spacing:0}.card-header-subtitle{color:#000;text-shadow:0 0 3px #999}.section-actions,.section-dialog{background-color:#fff!important}
diff --git a/SVUI_!Core/guide/docs/libraries/AceVillain.html b/SVUI_!Core/guide/docs/libraries/AceVillain.html
new file mode 100644
index 0000000..0f7b6f6
--- /dev/null
+++ b/SVUI_!Core/guide/docs/libraries/AceVillain.html
@@ -0,0 +1,115 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+<head>
+    <title>SVUI Guide</title>
+    <link rel="stylesheet" href="../ldoc.css" type="text/css" />
+    <!-- Fonts -->
+	  <link href="https://fonts.googleapis.com/css?family=Roboto:regular,bold,italic,thin,light,bolditalic,black,medium&amp;lang=en" rel="stylesheet" type="text/css">
+</head>
+<body id="page-top" data-spy="scroll" data-target=".layout-header">
+<div class="skinned-page"></div>
+<div id="message-depot"></div>
+<!-- BEGIN LAYOUT -->
+<div class="layout js-layout js-skins layout-overlay-drawer-button layout-shadow layout-fixed-header layout-fixed-drawer">
+
+
+<!-- BEGIN NAV // -->
+	<div class="layout-header">
+	 <div class="layout-header-row">
+     <span class="layout-title">Documentation</span>
+		 <div class="layout-spacer"></div>
+		 <nav class="navigation">
+		</nav>
+	 </div>
+	</div>
+
+	<div class="layout-drawer">
+    <span class="navigation-title" style="padding:">Contents</span>
+	 <nav class="navigation" style="padding-top:0 !important;">
+<div class="navigation-subtitle">Libraries</div>
+ <a href="../libraries/Librarian.html" class="navigation-link">Librarian</a>
+ <a href="../libraries/LUA.html" class="navigation-link">LUA</a>
+<a href="../libraries/AceVillain.html" class="navigation-link current-link">AceVillain</a>
+  <div class="navigation-spacer"></div>
+<div class="navigation-subtitle">Addons</div>
+ <a href="../index.html" class="navigation-link">SVUI_Core</a>
+  <div class="navigation-spacer"></div>
+<div class="navigation-subtitle">Manual</div>
+ <a href="../manual/doc.md.html" class="navigation-link">doc</a>
+  <div class="navigation-spacer"></div>
+	 </nav>
+	</div>
+
+	<span class="layout-title floating-title no-desktop">Menu</span>
+
+	<div class="layout-drawer-button">
+	 <i class="layout-drawer-button-icon menu-icon"></i>
+	</div>
+	<!-- END NAV // -->
+
+  <!-- BEGIN CONTENT // -->
+  <div class="layout-content">
+
+<section style="padding:0;">
+<div class="grid">
+<div class="cell cell-12-col">
+<div class="container">
+  <div class="comic">
+  <div class="card">
+  <div class="card-header flex--expand">
+  <div class="card-header-title flex--centered">
+  <span class="badge" data-badge="File">AceVillain</span>
+  </div>
+  </div>
+  <div class="card-actions flex--expand">
+  <div class="card-header-subtitle flex--centered">Ace3 modification library.</div>
+  </div>
+  <div class="card-section">
+  <div class="section-dialog">
+  <h4 class="section-label">Info:</h4>
+  <ul>
+    <li>
+</li>
+        <li><strong>Release</strong>: 1.0.0</li>
+        <li><strong>Author</strong>: Steven Jackson (2014)</li>
+  <hr />
+  </ul>
+  <h5 class="section-label">Summary:</h5>
+  <hr />
+  <br />
+  <br />
+  </div>
+  </div>
+  </div>
+  </div>
+</div>
+</div>
+</div>
+</section>
+</div>
+<!-- END CONTENT -->
+
+<!-- BEGIN FOOTER // -->
+<footer>
+  <div class="right-section">
+    <ul class="link-list">
+      <li>
+        <span style="color:#5fafff">Last updated 2015-08-26 14:32:22</span>
+      </li>
+    </ul>
+  </div>
+</footer>
+<!-- END FOOTER // -->
+
+</div>
+<!-- END LAYOUT -->
+
+<!-- Core JavaScript -->
+<script src="http://supervillainui.com/js/app.min.js"></script>
+<script src="http://supervillainui.com/js/extended/jquery-1.11.0.js"></script>
+<script src="http://supervillainui.com/js/extended/jquery.easing.min.js"></script>
+<script src="http://supervillainui.com/js/extended/jquery.swipebox.min.js"></script>
+</body>
+</html>
diff --git a/SVUI_!Core/guide/docs/libraries/LUA.html b/SVUI_!Core/guide/docs/libraries/LUA.html
new file mode 100644
index 0000000..773b26a
--- /dev/null
+++ b/SVUI_!Core/guide/docs/libraries/LUA.html
@@ -0,0 +1,533 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+<head>
+    <title>SVUI Guide</title>
+    <link rel="stylesheet" href="../ldoc.css" type="text/css" />
+    <!-- Fonts -->
+	  <link href="https://fonts.googleapis.com/css?family=Roboto:regular,bold,italic,thin,light,bolditalic,black,medium&amp;lang=en" rel="stylesheet" type="text/css">
+</head>
+<body id="page-top" data-spy="scroll" data-target=".layout-header">
+<div class="skinned-page"></div>
+<div id="message-depot"></div>
+<!-- BEGIN LAYOUT -->
+<div class="layout js-layout js-skins layout-overlay-drawer-button layout-shadow layout-fixed-header layout-fixed-drawer">
+
+
+<!-- BEGIN NAV // -->
+	<div class="layout-header">
+	 <div class="layout-header-row">
+     <span class="layout-title">Documentation</span>
+		 <div class="layout-spacer"></div>
+		 <nav class="navigation">
+		</nav>
+	 </div>
+	</div>
+
+	<div class="layout-drawer">
+    <span class="navigation-title" style="padding:">Contents</span>
+	 <nav class="navigation" style="padding-top:0 !important;">
+<div class="navigation-subtitle">Libraries</div>
+ <a href="../libraries/Librarian.html" class="navigation-link">Librarian</a>
+<a href="../libraries/LUA.html" class="navigation-link current-link">LUA</a>
+<a href="#Math" class="navigation-link">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Math </a>
+<a href="#Pickle" class="navigation-link">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Pickle </a>
+<a href="#String" class="navigation-link">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String </a>
+<a href="#Table" class="navigation-link">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Table </a>
+<div class="navigation-spacer"></div>
+ <a href="../libraries/AceVillain.html" class="navigation-link">AceVillain</a>
+  <div class="navigation-spacer"></div>
+<div class="navigation-subtitle">Addons</div>
+ <a href="../index.html" class="navigation-link">SVUI_Core</a>
+  <div class="navigation-spacer"></div>
+<div class="navigation-subtitle">Manual</div>
+ <a href="../manual/doc.md.html" class="navigation-link">doc</a>
+  <div class="navigation-spacer"></div>
+	 </nav>
+	</div>
+
+	<span class="layout-title floating-title no-desktop">Menu</span>
+
+	<div class="layout-drawer-button">
+	 <i class="layout-drawer-button-icon menu-icon"></i>
+	</div>
+	<!-- END NAV // -->
+
+  <!-- BEGIN CONTENT // -->
+  <div class="layout-content">
+
+<section style="padding:0;">
+<div class="grid">
+<div class="cell cell-12-col">
+<div class="container">
+  <div class="comic">
+  <div class="card">
+  <div class="card-header flex--expand">
+  <div class="card-header-title flex--centered">
+  <span class="badge" data-badge="File">LUA</span>
+  </div>
+  </div>
+  <div class="card-actions flex--expand">
+  <div class="card-header-subtitle flex--centered">LUA companion library.</div>
+  </div>
+  <div class="card-section">
+  <div class="section-dialog">
+  <h4 class="section-label">Info:</h4>
+  <ul>
+    <li>
+</li>
+        <li><strong>Release</strong>: 1.0.0</li>
+        <li><strong>Author</strong>: Steven Jackson (2014)</li>
+  <hr />
+  </ul>
+  <h5 class="section-label">Summary:</h5>
+  <div style="padding:6px 0px;"><a href="#Math" style="color:#ff5500">Jump To: Math &#8921;</a></div>
+  <table class="function_list">
+	<tr>
+	<td class="name" nowrap><a href="#math.parsefloat">math.parsefloat (value, decimal)</a></td>
+	<td class="summary">Integer float utility for lua.</td>
+	</tr>
+  </table>
+  <div style="padding:6px 0px;"><a href="#Pickle" style="color:#ff5500">Jump To: Pickle &#8921;</a></div>
+  <table class="function_list">
+	<tr>
+	<td class="name" nowrap><a href="#Pickle">Pickle</a></td>
+	<td class="summary">Global class used by pickle/unpickle functions.</td>
+	</tr>
+	<tr>
+	<td class="name" nowrap><a href="#pickle">pickle (t)</a></td>
+	<td class="summary">A table serialization utility for lua.</td>
+	</tr>
+	<tr>
+	<td class="name" nowrap><a href="#unpickle">unpickle (s)</a></td>
+	<td class="summary">Un-serialization tool (pretty sure thats not a word).</td>
+	</tr>
+  </table>
+  <div style="padding:6px 0px;"><a href="#String" style="color:#ff5500">Jump To: String &#8921;</a></div>
+  <table class="function_list">
+	<tr>
+	<td class="name" nowrap><a href="#string.encode">string.encode (data)</a></td>
+	<td class="summary">Base64 encoding tool.</td>
+	</tr>
+	<tr>
+	<td class="name" nowrap><a href="#string.decode">string.decode (data)</a></td>
+	<td class="summary">Base64 decoding tool.</td>
+	</tr>
+	<tr>
+	<td class="name" nowrap><a href="#string.explode">string.explode (data, delim)</a></td>
+	<td class="summary">String to array utility.</td>
+	</tr>
+	<tr>
+	<td class="name" nowrap><a href="#prettify">prettify</a></td>
+	<td class="summary">PRETTY PRINT FOR TABLES</td>
+	</tr>
+  </table>
+  <div style="padding:6px 0px;"><a href="#Table" style="color:#ff5500">Jump To: Table &#8921;</a></div>
+  <table class="function_list">
+	<tr>
+	<td class="name" nowrap><a href="#table.tostring">table.tostring (tbl, pretty)</a></td>
+	<td class="summary">Dump table contents to string</td>
+	</tr>
+	<tr>
+	<td class="name" nowrap><a href="#table.copy">table.copy (targetTable, deepCopy, mergeTable)</a></td>
+	<td class="summary">Copy all table data from a source to another table</td>
+	</tr>
+  </table>
+  <hr />
+  <br />
+  <br />
+    <h6 class="section-label" id="Math">Math
+
+          <small>
+           UTILITIES
+        </small>
+    </h6>
+    <dl class="function">
+    <dt id="math.parsefloat">
+    <strong>math.parsefloat (value, decimal)</strong>
+    </dt>
+    <dd>
+    Integer float utility for lua.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Parameters:</strong></div>
+<table>
+<tbody>
+        <tr><td style="width:20% !important;"><strong>value</strong><td>
+         The integer amount to be adjusted.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>decimal</strong><td>
+         Number of decimal places allowed.
+        </td></tr>
+</tbody></table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Returns:</strong></div>
+    <ol>
+
+        floating point integer
+    </ol>
+
+
+
+
+  </dd>
+  </dl>
+    <h6 class="section-label" id="Pickle">Pickle
+
+          <small>
+           UTILITIES
+        </small>
+    </h6>
+    <dl class="function">
+    <dt id="Pickle">
+    <strong>Pickle</strong>
+    </dt>
+    <dd>
+    Global class used by pickle/unpickle functions.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Fields:</strong></div>
+<table>
+<tbody>
+        <tr><td style="width:20% !important;"><strong>clone</strong><td>
+
+
+        </td></tr>
+</tbody></table>
+
+
+
+
+
+  </dd>
+    <dt id="pickle">
+    <strong>pickle (t)</strong>
+    </dt>
+    <dd>
+    A table serialization utility for lua.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Parameters:</strong></div>
+<table>
+<tbody>
+        <tr><td style="width:20% !important;"><strong>t</strong><td>
+         A table to be serialized.
+        </td></tr>
+</tbody></table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Returns:</strong></div>
+    <ol>
+
+        serialized table data
+    </ol>
+
+
+
+
+  </dd>
+    <dt id="unpickle">
+    <strong>unpickle (s)</strong>
+    </dt>
+    <dd>
+    Un-serialization tool (pretty sure thats not a word).
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Parameters:</strong></div>
+<table>
+<tbody>
+        <tr><td style="width:20% !important;"><strong>s</strong><td>
+         A serialized table to be reversed.
+        </td></tr>
+</tbody></table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Returns:</strong></div>
+    <ol>
+
+        serialized table data
+    </ol>
+
+
+
+
+  </dd>
+  </dl>
+    <h6 class="section-label" id="String">String
+
+          <small>
+           UTILITIES
+        </small>
+    </h6>
+    <dl class="function">
+    <dt id="string.encode">
+    <strong>string.encode (data)</strong>
+    </dt>
+    <dd>
+    Base64 encoding tool.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Parameters:</strong></div>
+<table>
+<tbody>
+        <tr><td style="width:20% !important;"><strong>data</strong><td>
+         string data to be encoded.
+        </td></tr>
+</tbody></table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Returns:</strong></div>
+    <ol>
+
+        encoded string
+    </ol>
+
+
+
+
+  </dd>
+    <dt id="string.decode">
+    <strong>string.decode (data)</strong>
+    </dt>
+    <dd>
+    Base64 decoding tool.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Parameters:</strong></div>
+<table>
+<tbody>
+        <tr><td style="width:20% !important;"><strong>data</strong><td>
+         encoded string to be decoded.
+        </td></tr>
+</tbody></table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Returns:</strong></div>
+    <ol>
+
+        decoded string
+    </ol>
+
+
+
+
+  </dd>
+    <dt id="string.explode">
+    <strong>string.explode (data, delim)</strong>
+    </dt>
+    <dd>
+    String to array utility.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Parameters:</strong></div>
+<table>
+<tbody>
+        <tr><td style="width:20% !important;"><strong>data</strong><td>
+         string to be converted to table data.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>delim</strong><td>
+         Character delimiter to separate the string by.
+        </td></tr>
+</tbody></table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Returns:</strong></div>
+    <ol>
+
+        table data
+    </ol>
+
+
+
+
+  </dd>
+    <dt id="prettify">
+    <strong>prettify</strong>
+    </dt>
+    <dd>
+    PRETTY PRINT FOR TABLES
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+
+
+
+
+
+  </dd>
+  </dl>
+    <h6 class="section-label" id="Table">Table
+
+          <small>
+           UTILITIES
+        </small>
+    </h6>
+    <dl class="function">
+    <dt id="table.tostring">
+    <strong>table.tostring (tbl, pretty)</strong>
+    </dt>
+    <dd>
+    Dump table contents to string
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Parameters:</strong></div>
+<table>
+<tbody>
+        <tr><td style="width:20% !important;"><strong>tbl</strong><td>
+         A table to be stringified.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>pretty</strong><td>
+         Flag to syntactically format the result.
+        </td></tr>
+</tbody></table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Returns:</strong></div>
+    <ol>
+
+        string value
+    </ol>
+
+
+
+
+  </dd>
+    <dt id="table.copy">
+    <strong>table.copy (targetTable, deepCopy, mergeTable)</strong>
+    </dt>
+    <dd>
+    Copy all table data from a source to another table
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Parameters:</strong></div>
+<table>
+<tbody>
+        <tr><td style="width:20% !important;"><strong>targetTable</strong><td>
+         The recipient of the copied data.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>deepCopy</strong><td>
+         Flag the use of DEEP copying.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>mergeTable</strong><td>
+         The origin of the copied data.
+        </td></tr>
+</tbody></table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Returns:</strong></div>
+    <ol>
+
+        copied data
+    </ol>
+
+
+
+
+  </dd>
+  </dl>
+  </div>
+  </div>
+  </div>
+  </div>
+</div>
+</div>
+</div>
+</section>
+</div>
+<!-- END CONTENT -->
+
+<!-- BEGIN FOOTER // -->
+<footer>
+  <div class="right-section">
+    <ul class="link-list">
+      <li>
+        <span style="color:#5fafff">Last updated 2015-08-26 14:32:22</span>
+      </li>
+    </ul>
+  </div>
+</footer>
+<!-- END FOOTER // -->
+
+</div>
+<!-- END LAYOUT -->
+
+<!-- Core JavaScript -->
+<script src="http://supervillainui.com/js/app.min.js"></script>
+<script src="http://supervillainui.com/js/extended/jquery-1.11.0.js"></script>
+<script src="http://supervillainui.com/js/extended/jquery.easing.min.js"></script>
+<script src="http://supervillainui.com/js/extended/jquery.swipebox.min.js"></script>
+</body>
+</html>
diff --git a/SVUI_!Core/guide/docs/libraries/Librarian.html b/SVUI_!Core/guide/docs/libraries/Librarian.html
new file mode 100644
index 0000000..5c346ac
--- /dev/null
+++ b/SVUI_!Core/guide/docs/libraries/Librarian.html
@@ -0,0 +1,243 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+<head>
+    <title>SVUI Guide</title>
+    <link rel="stylesheet" href="../ldoc.css" type="text/css" />
+    <!-- Fonts -->
+	  <link href="https://fonts.googleapis.com/css?family=Roboto:regular,bold,italic,thin,light,bolditalic,black,medium&amp;lang=en" rel="stylesheet" type="text/css">
+</head>
+<body id="page-top" data-spy="scroll" data-target=".layout-header">
+<div class="skinned-page"></div>
+<div id="message-depot"></div>
+<!-- BEGIN LAYOUT -->
+<div class="layout js-layout js-skins layout-overlay-drawer-button layout-shadow layout-fixed-header layout-fixed-drawer">
+
+
+<!-- BEGIN NAV // -->
+	<div class="layout-header">
+	 <div class="layout-header-row">
+     <span class="layout-title">Documentation</span>
+		 <div class="layout-spacer"></div>
+		 <nav class="navigation">
+		</nav>
+	 </div>
+	</div>
+
+	<div class="layout-drawer">
+    <span class="navigation-title" style="padding:">Contents</span>
+	 <nav class="navigation" style="padding-top:0 !important;">
+<div class="navigation-subtitle">Libraries</div>
+<a href="../libraries/Librarian.html" class="navigation-link current-link">Librarian</a>
+<a href="#Functions" class="navigation-link">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Functions</a>
+<a href="#Tables" class="navigation-link">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Tables</a>
+<div class="navigation-spacer"></div>
+ <a href="../libraries/LUA.html" class="navigation-link">LUA</a>
+ <a href="../libraries/AceVillain.html" class="navigation-link">AceVillain</a>
+  <div class="navigation-spacer"></div>
+<div class="navigation-subtitle">Addons</div>
+ <a href="../index.html" class="navigation-link">SVUI_Core</a>
+  <div class="navigation-spacer"></div>
+<div class="navigation-subtitle">Manual</div>
+ <a href="../manual/doc.md.html" class="navigation-link">doc</a>
+  <div class="navigation-spacer"></div>
+	 </nav>
+	</div>
+
+	<span class="layout-title floating-title no-desktop">Menu</span>
+
+	<div class="layout-drawer-button">
+	 <i class="layout-drawer-button-icon menu-icon"></i>
+	</div>
+	<!-- END NAV // -->
+
+  <!-- BEGIN CONTENT // -->
+  <div class="layout-content">
+
+<section style="padding:0;">
+<div class="grid">
+<div class="cell cell-12-col">
+<div class="container">
+  <div class="comic">
+  <div class="card">
+  <div class="card-header flex--expand">
+  <div class="card-header-title flex--centered">
+  <span class="badge" data-badge="File">Librarian</span>
+  </div>
+  </div>
+  <div class="card-actions flex--expand">
+  <div class="card-header-subtitle flex--centered">Librarian lib management library.</div>
+  </div>
+  <div class="card-section">
+  <div class="section-dialog">
+  <h4 class="section-label">Info:</h4>
+  <ul>
+    <li> Librarian is a versioning manager for use with proprietary SVUI libraries.</li>
+        <li><strong>Release</strong>: 1.0.0</li>
+        <li><strong>Author</strong>: Steven Jackson (2014)</li>
+  <hr />
+  </ul>
+  <h5 class="section-label">Summary:</h5>
+  <div style="padding:6px 0px;"><a href="#Functions" style="color:#ff5500">Jump To: Functions&#8921;</a></div>
+  <table class="function_list">
+	<tr>
+	<td class="name" nowrap><a href="#NewLibrary">NewLibrary (libName)</a></td>
+	<td class="summary">Adds a new lib to saved objects.</td>
+	</tr>
+	<tr>
+	<td class="name" nowrap><a href="#Fetch">Fetch (libName, silent)</a></td>
+	<td class="summary">Retrieve a saved library object.</td>
+	</tr>
+  </table>
+  <div style="padding:6px 0px;"><a href="#Tables" style="color:#ff5500">Jump To: Tables&#8921;</a></div>
+  <table class="function_list">
+	<tr>
+	<td class="name" nowrap><a href="#Librarian">Librarian</a></td>
+	<td class="summary">Global Librarian object.</td>
+	</tr>
+  </table>
+  <hr />
+  <br />
+  <br />
+    <h6 class="section-label" id="Functions">Functions
+
+    </h6>
+    <dl class="function">
+    <dt id="NewLibrary">
+    <strong>NewLibrary (libName)</strong>
+    </dt>
+    <dd>
+    Adds a new lib to saved objects.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Parameters:</strong></div>
+<table>
+<tbody>
+        <tr><td style="width:20% !important;"><strong>libName</strong><td>
+         hashable name of the new library.
+        </td></tr>
+</tbody></table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Returns:</strong></div>
+    <ol>
+
+        Lib class object
+    </ol>
+
+
+
+
+  </dd>
+    <dt id="Fetch">
+    <strong>Fetch (libName, silent)</strong>
+    </dt>
+    <dd>
+    Retrieve a saved library object.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Parameters:</strong></div>
+<table>
+<tbody>
+        <tr><td style="width:20% !important;"><strong>libName</strong><td>
+         Saved name of the library.
+        </td></tr>
+        <tr><td style="width:20% !important;"><strong>silent</strong><td>
+         do not allow errors to propegate.
+        </td></tr>
+</tbody></table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Returns:</strong></div>
+    <ol>
+
+        Lib class object
+    </ol>
+
+
+
+
+  </dd>
+  </dl>
+    <h6 class="section-label" id="Tables">Tables
+
+    </h6>
+    <dl class="function">
+    <dt id="Librarian">
+    <strong>Librarian</strong>
+    </dt>
+    <dd>
+    Global Librarian object.
+    <br />
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+    </tbody>
+  </table>
+
+<div style="padding:12px 0 6px;font-size:15px;"><strong>Fields:</strong></div>
+<table>
+<tbody>
+        <tr><td style="width:20% !important;"><strong>libs</strong><td>
+
+
+        </td></tr>
+</tbody></table>
+
+
+
+
+
+  </dd>
+  </dl>
+  </div>
+  </div>
+  </div>
+  </div>
+</div>
+</div>
+</div>
+</section>
+</div>
+<!-- END CONTENT -->
+
+<!-- BEGIN FOOTER // -->
+<footer>
+  <div class="right-section">
+    <ul class="link-list">
+      <li>
+        <span style="color:#5fafff">Last updated 2015-08-26 14:32:22</span>
+      </li>
+    </ul>
+  </div>
+</footer>
+<!-- END FOOTER // -->
+
+</div>
+<!-- END LAYOUT -->
+
+<!-- Core JavaScript -->
+<script src="http://supervillainui.com/js/app.min.js"></script>
+<script src="http://supervillainui.com/js/extended/jquery-1.11.0.js"></script>
+<script src="http://supervillainui.com/js/extended/jquery.easing.min.js"></script>
+<script src="http://supervillainui.com/js/extended/jquery.swipebox.min.js"></script>
+</body>
+</html>
diff --git a/SVUI_!Core/guide/docs/manual/doc.md.html b/SVUI_!Core/guide/docs/manual/doc.md.html
new file mode 100644
index 0000000..5b11408
--- /dev/null
+++ b/SVUI_!Core/guide/docs/manual/doc.md.html
@@ -0,0 +1,133 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+<head>
+    <title>SVUI Guide</title>
+    <link rel="stylesheet" href="../ldoc.css" type="text/css" />
+    <!-- Fonts -->
+	  <link href="https://fonts.googleapis.com/css?family=Roboto:regular,bold,italic,thin,light,bolditalic,black,medium&amp;lang=en" rel="stylesheet" type="text/css">
+</head>
+<body id="page-top" data-spy="scroll" data-target=".layout-header">
+<div class="skinned-page"></div>
+<div id="message-depot"></div>
+<!-- BEGIN LAYOUT -->
+<div class="layout js-layout js-skins layout-overlay-drawer-button layout-shadow layout-fixed-header layout-fixed-drawer">
+
+
+<!-- BEGIN NAV // -->
+	<div class="layout-header">
+	 <div class="layout-header-row">
+     <span class="layout-title">Documentation</span>
+		 <div class="layout-spacer"></div>
+		 <nav class="navigation">
+		</nav>
+	 </div>
+	</div>
+
+	<div class="layout-drawer">
+    <span class="navigation-title" style="padding:">Contents</span>
+	 <nav class="navigation" style="padding-top:0 !important;">
+<div class="navigation-subtitle">Manual</div>
+<a href="../manual/doc.md.html" class="navigation-link current-link">doc</a>
+<a href="#Introduction" class="navigation-link">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Introduction </a>
+<a href="#Release_Version" class="navigation-link">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Release Version </a>
+<a href="#License" class="navigation-link">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;License </a>
+<div class="navigation-spacer"></div>
+  <div class="navigation-spacer"></div>
+<div class="navigation-subtitle">Addons</div>
+ <a href="../index.html" class="navigation-link">SVUI_Core</a>
+  <div class="navigation-spacer"></div>
+<div class="navigation-subtitle">Libraries</div>
+ <a href="../libraries/Librarian.html" class="navigation-link">Librarian</a>
+ <a href="../libraries/LUA.html" class="navigation-link">LUA</a>
+ <a href="../libraries/AceVillain.html" class="navigation-link">AceVillain</a>
+  <div class="navigation-spacer"></div>
+	 </nav>
+	</div>
+
+	<span class="layout-title floating-title no-desktop">Menu</span>
+
+	<div class="layout-drawer-button">
+	 <i class="layout-drawer-button-icon menu-icon"></i>
+	</div>
+	<!-- END NAV // -->
+
+  <!-- BEGIN CONTENT // -->
+  <div class="layout-content">
+
+<section style="padding:0;">
+<div class="grid">
+<div class="cell cell-12-col">
+<div class="container">
+  <div class="comic">
+  <div class="card">
+  <div class="card-section">
+  <div class="section-dialog">
+    <h1>SuperVillain UI</h1>
+
+<p><a name="Introduction"></a></p>
+
+<h2>Introduction</h2>
+
+<p>Custom World of Warcraft User Interface</p>
+
+<h3>Compatibility</h3>
+
+<p>SuperVillain UI is designed to work with the latest live expansion of World of Warcraft.</p>
+
+<h3>Notes</h3>
+
+<ul>
+<li>This repo will be used exclusively for development versions</li>
+<li>All feature requests will be considered but not guranteed</li>
+<li>Please be thorough when posting issues</li>
+</ul>
+
+
+<p><a name="Release_Version"></a></p>
+
+<h2>Release Version</h2>
+
+<p>If you are looking for the most current release version (non-development) you can find it at <a href="http://www.wowinterface.com/downloads/info23519-SuperVillainUI.html#info">WowInterface</a> or <a href="http://www.curse.com/addons/wow/supervillain-ui">Curse</a></p>
+
+<p><a name="License"></a></p>
+
+<h2>License</h2>
+
+<p>SuperVillain UI is licensed under the The MIT License.
+Copyright &copy; 2010, Failcoder (Steve Jackson). </p>
+
+  </div>
+  </div>
+  </div>
+  </div>
+</div>
+</div>
+</div>
+</section>
+</div>
+<!-- END CONTENT -->
+
+<!-- BEGIN FOOTER // -->
+<footer>
+  <div class="right-section">
+    <ul class="link-list">
+      <li>
+        <span style="color:#5fafff">Last updated 2015-08-26 14:32:22</span>
+      </li>
+    </ul>
+  </div>
+</footer>
+<!-- END FOOTER // -->
+
+</div>
+<!-- END LAYOUT -->
+
+<!-- Core JavaScript -->
+<script src="http://supervillainui.com/js/app.min.js"></script>
+<script src="http://supervillainui.com/js/extended/jquery-1.11.0.js"></script>
+<script src="http://supervillainui.com/js/extended/jquery.easing.min.js"></script>
+<script src="http://supervillainui.com/js/extended/jquery.swipebox.min.js"></script>
+</body>
+</html>
diff --git a/SVUI_!Core/language/_load.xml b/SVUI_!Core/language/_load.xml
new file mode 100644
index 0000000..4e44749
--- /dev/null
+++ b/SVUI_!Core/language/_load.xml
@@ -0,0 +1,12 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+	<Script file="english_ui.lua"/>
+    <Script file="italian_ui.lua"/>
+    <Script file="french_ui.lua"/>
+    <Script file="russian_ui.lua"/>
+    <Script file="german_ui.lua"/>
+    <Script file="taiwanese_ui.lua"/>
+    <Script file="spanish_ui.lua"/>
+    <Script file="korean_ui.lua"/>
+    <Script file="chinese_ui.lua"/>
+    <Script file="portuguese_ui.lua"/>
+</Ui>
\ No newline at end of file
diff --git a/SVUI_!Core/language/chinese_ui.lua b/SVUI_!Core/language/chinese_ui.lua
new file mode 100644
index 0000000..00ef491
--- /dev/null
+++ b/SVUI_!Core/language/chinese_ui.lua
@@ -0,0 +1,473 @@
+local L = Librarian("Linguist"):Lang("zhCN");
+if not L then return end
+L["Conversation"]    = "对话"
+L["General"]         = "综合"
+L["LocalDefense"]    = "本地防务"
+L["LookingForGroup"] = "寻求组队"
+L["Trade"]           = "交易"
+L["WorldDefense"]    = "世界防务"
+L["S_Conversation"]    = "话"
+L["S_General"]        = "综"
+L["S_LocalDefense"]    = "本"
+L["S_LookingForGroup"] = "寻"
+L["S_Trade"]          = "交"
+L["S_WorldDefense"]    = "世"
+L["Hearthstone"] = true;
+--[[LOGIN MESSAGE]]--
+L["LOGIN_MSG"] = "歡迎使用 |cffFFFF1ASVUI|r! 让您的 %s 和你 %s."
+L["LOGIN_MSG2"] = "|cffAA78FF%s|r 版, 請輸入/sv 進入設定介面."
+--[[OPTION MESSAGES]]--
+L["AURAS_DESC"] = "小地图旁的光环图标设置."
+L["BAGS_DESC"] = "调整 SVUI 背包设置."
+L["CHAT_DESC"] = "对话框架设定"
+L["STATS_DESC"] = "Configure docked stat panels.";
+L["SVUI_DESC"] = "SVUI 为一套功能完整,可用来替换 WOW 原始介面的套件"
+L["NAMEPLATE_DESC"] = "修改血条设定."
+L["PANEL_DESC"] = "调整左、右对话框的大小,此设定将会影响对话与背包框架的大小."
+L["ART_DESC"] = "调整外观设定."
+L["TOGGLEART_DESC"] = "启用 / 停用此外观."
+L["TOOLTIP_DESC"] = "鼠标提示资讯设定选项."
+L["TEXT_FORMAT_DESC"] = "Select the formatting of this text"
+L["import"] = "现有的配置文件"
+L["import_desc"] = "你可以通过在文本框内输入一个名字创立一个新的配置文件,也可以选择一个已经存在的配置文件。"
+L["import_sub"] = "从当前可用的配置文件里面选择一个。"
+L["copy_name"] = "复制自"
+L["copy_desc"] = "从当前某个已保存的配置文件复制到当前正使用的配置文件。"
+L["current"] = "Current Profile:"
+L["default"] = "默认"
+L["delete"] = "删除一个配置文件"
+L["delete_confirm"] = "你确定要删除所选择的配置文件么?"
+L["delete_desc"] = "从数据库里删除不再使用的配置文件,以节省空间,并且清理SavedVariables文件。"
+L["delete_sub"] = "从数据库里删除一个配置文件。"
+L["intro"] = "你可以选择一个活动的数据配置文件,这样你的每个角色就可以拥有不同的设置值,可以给你的插件配置带来极大的灵活性。"
+L["export"] = "新建"
+L["export_sub"] = "新建一个空的配置文件。"
+L["profiles"] = "配置文件"
+L["profiles_sub"] = "管理配置文件"
+L["reset"] = "重置配置文件"
+L["reset_desc"] = "将当前的配置文件恢复到它的默认值,用于你的配置文件损坏,或者你只是想重来的情况。"
+L["reset_sub"] = "将当前的配置文件恢复为默认值"
+L["SVUI_DockBottomCenter"] = "Bottom Data Dock"
+L["SVUI_DockTopCenter"] = "Top Data Dock"
+--[[REACTION TEXTS]]--
+L[" is drinking."] = true;
+L["Leeeeeroy!"] = true;
+L["No Food: "] = "缺少食物Buff: "
+L["No Flask: "] = "缺少合剂: "
+L["All Buffed!"] = "已获得所有增益!"
+L["Check food and flask"] = "检查食物和合剂"
+L["Thanks for "] = "谢谢你的 "
+L[" received from "] = " 收到来自于 "
+L["GO!"] = "开始!"
+L["Pulling %s in %s.."] = "正在拉: %s,倒數 %s.."
+L["Pull ABORTED!"] = "取消拉怪!"
+L["%s has prepared a %s - [%s]."] = "%s 放置了 %s - [%s]."
+L["%s has prepared a %s."] = "%s 放置了 %s"
+L["%s has put down a %s."] = "%s 放置了 %s"
+L["%s is casting %s."] = "%s 开启了 %s"
+L["%s is casting %s. Click!"] = "%s 正在开启 %s... 请点击!"
+L["%s used a %s."] = "%s 使用了一个 %s."
+--[[FORMATTED INSTALLER TEXTS]]--
+L["|cffD3CF00Recommended|r"] = true;
+L["Recommended: |cff99FF00Kaboom!|r"] = true;
+L["Recommended: |cff99FF00Super|r"] = true;
+L["Recommended: |cffFF0000Small Row!|r"] = true;
+L["Recommended: |cffFF0000Icon Lovers!|r"] = true;
+L["|cffFF9F00KABOOOOM!|r"] = true;
+L["|cffAF30FFThe Darkest Night|r"] = true;
+L["|cff00FFFFPlain and Simple|r"] = true;
+L["|cff00FFFFLets Do This|r"] = true;
+L["|cff00FFFFSimply Simple|r"] = true;
+L["|cff00FFFFEl Compacto|r"] = true;
+L["|cff00FFFFHealer Extraordinaire|r"] = true;
+L["|cff00FFFFLean And Clean|r"] = true;
+L["|cff00FFFFMore For Less|r"] = true;
+L["|cff00FFFFWhat Big Buttons You Have|r"] = true;
+L["|cff00FFFFThe Double Down|r"] = true;
+--[[NORMAL INSTALLER TEXTS]]--
+L["This is SVUI version %s!"] = true;
+L["Before I can turn you loose, persuing whatever villainy you feel will advance your professional career ... I need to ask some questions and turn a few screws first."] = true;
+L["At any time you can get to the config options by typing the command /sv. For quick changes to frame, bar or color sets, call your henchman by clicking the button on the bottom right of your screen. (Its the one with his stupid face on it)"] = true;
+L["CHOOSE_OR_DIE"] = CHOOSE_FACTION.." "..OR_CAPS.." "..HIT.." "..CONTINUE;
+L["Whether you want to or not, you will be needing a communicator so other villains can either update you on their doings-of-evil or inform you about the MANY abilities of Chuck Norris"] = true;
+L["The chat windows function the same as standard chat windows, you can right click the tabs and drag them, rename them, slap them around, you know... whatever. Clickity-click to setup your chat windows."] = true;
+L["Your current resolution is %s, this is considered a %s resolution."] = true;
+L["This resolution requires that you change some settings to get everything to fit on your screen."] = true;
+L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."] = true;
+L["You may need to further alter these settings depending how low you resolution is."] = true;
+L["This resolution doesn't require that you change settings for the UI to fit on your screen."] = true;
+L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."] = true;
+L["This is completely optional."] = true;
+L["So what you think your better than me with your big monitor? HUH?!?!"] = true;
+L["Dont forget whos in charge here! But enjoy the incredible detail."] = true;
+L["Why are you playing this on what I would assume is a calculator display?"] = true;
+L["Enjoy the ONE incredible pixel that fits on this screen."] = true;
+L["Choose a theme layout you wish to use for your initial setup."] = true;
+L["You can always change fonts and colors of any element of SVUI from the in-game configuration."] = true;
+L["This theme tells the world that you are a villain who can put on a show "] = true;
+L["or better yet, you ARE the show!"] = true;
+L["Kaboom!"] = true;
+L["This theme indicates that you have no interest in wasting time"] = true;
+L["the dying begins NOW!"] = true;
+L["Darkness"] = true;
+L["This theme is for villains who take pride in their class"] = true;
+L["villains know how to reprezent!"] = true;
+L["This theme is for any villain who sticks to their traditions"] = true;
+L["you don't need fancyness to kick some ass!"] = true;
+L["Vintage"] = true;
+L["Layout"] = true;
+L["You can now choose what primary unitframe style you wish to use."] = true;
+L["This will change the layout of your unitframes (ie.. Player, Target, Pet, Party, Raid ...etc)."] = true;
+L["This layout is anything but minimal! Using this is like being at a rock concert"] = true;
+L["then annihilating the crowd with frickin lazer beams!"] = true;
+L["Super"] = true;
+L["This layout is for the villain who just wants to get things done!"] = true;
+L["But he still wants to see your face before he hits you!"] = true;
+L["Simple"] = true;
+L["Just the necessities so you can see more of the world around you."] = true;
+L["You dont need no fanciness getting in the way of world domination do you?"] = true;
+L["Compact"] = true;
+L["This has all the pizzaz of Super frames but uses Compact party and raid frames."] = true;
+L["Sometimes a little fifty-fifty goes a long way."] = true;
+L["Healer"] = true;
+L["Bar Setup"] = true;
+L["Choose a layout for your action bars."] = true;
+L["Sometimes you need big buttons, sometimes you don't. Your choice here."] = true;
+L["Lets keep it slim and deadly, not unlike a ninja sword."] = true;
+L["You dont ever even look at your bar hardly, so pick this one!"] = true;
+L["Small Row"] = true;
+L["Granted, you dont REALLY need the buttons due to your hotkey-leetness, you just like watching cooldowns!"] = true;
+L["Sure thing cowboy, your secret is safe with me!"] = true;
+L["Small X2"] = true;
+L["The better to PEW-PEW you with my dear!"] = true;
+L["When you have little time for mouse accuracy, choose this set!"] = true;
+L["Big Row"] = true;
+L["It's like dual-wielding two big reasons for your enemies to back the **** up!"] = true;
+L["Double your bars then double their size for maximum button goodness!"] = true;
+L["Big X2"] = true;
+L["Auras System"] = true;
+L["Select the type of aura system you want to use with SVUI's unitframes. The Icon Lovers set will display only icons and aurabars won't be used. The Vintage set will use the original game style and the Gimme Everything set does just what it says.... icons, bars and awesomeness."] = true;
+L["If you have an icon or aurabar that you don't want to display simply hold down shift and right click the icon for it to suffer a painful death."] = true;
+L["Vintage"] = true;
+L["Icon Lovers"] = true;
+L["The Works!"] = true;
+L["Installation Complete"] = true;
+L["Thats it! All done! Now we just need to hand these choices off to the henchmen so they can get you ready to (..insert evil tasks here..)!"] = true;
+L["Click the button below to reload and get on your way! Good luck villain!"] = true;
+L["THE_BUTTON_BELOW"] = "THE\nBUTTON\nBELOW";
+--[[UI TEXTS]]--
+L["Meanwhile"]=true;
+L["..at "]=true;
+L["Binding"]="绑定"
+L["Key"]="键"
+L["KEY_ALT"]="A"
+L["KEY_CTRL"]="C"
+L["KEY_DELETE"]="Del"
+L["KEY_HOME"]="Hm"
+L["KEY_INSERT"]="Ins"
+L["KEY_MOUSEBUTTON"]="M"
+L["KEY_MOUSEWHEELDOWN"]="MwD"
+L["KEY_MOUSEWHEELUP"]="MwU"
+L["KEY_NUMPAD"]="N"
+L["KEY_PAGEDOWN"]="PD"
+L["KEY_PAGEUP"]="PU"
+L["KEY_SHIFT"]="S"
+L["KEY_SPACE"]="SpB"
+L["No bindings set."]="无绑定设定"
+L["Remove Bar %d Action Page"]="移除第 %d 快捷列"
+L["Trigger"]="触发器"
+L["Delete Grays"]="删除灰色物品"
+L["Hold Control + Right Click:"]='按住 Ctrl 并按鼠标右键:'
+L["Hold Shift + Drag:"]='按住 Shift 并拖动: '
+L["Hold Shift:"]="按住 Shift:"
+L["Purchase"]="购买"
+L["Reset Position"]="重设位置"
+L["Sort Bags"]="背包整理"
+L["Sort Tab"]="选项排列"
+L["Stack Bags to Bank"]="堆叠背包到银行"
+L["Stack Bank to Bags"]="堆叠银行到背包"
+L["Stack Items"]="堆叠物品"
+L["Temporary Move"]='移动背包'
+L["Toggle Bags"]="背包开关"
+L["Vendor Grays"]="出售灰色物品"
+L["AFK"]="离开"
+L["DND"]="忙碌"
+L["G"]="公会"
+L["I"]='副本'
+L["IL"]='副本队长'
+L["Invalid Target"]="无效的目标"
+L["O"]="干部"
+L["P"]="队伍"
+L["PL"]="队长"
+L["R"]="团队"
+L["RL"]="团队队长"
+L["RW"]="团队警告"
+L["says"]="说"
+L["whispers"]="密语"
+L["yells"]="大喊"
+L["(Hold Shift) Memory Usage"]="(按住Shift) 内存占用"
+L["AP"]="攻击强度"
+L["AVD: "]="免伤: "
+L["Avoidance Breakdown"]="免伤统计"
+L["Bandwidth"]="频宽"
+L["Bases Assaulted"]="已占领基地"
+L["Bases Defended"]="已守住基地"
+L["Carts Controlled"]="载具控制"
+L["Character: "]="角色: "
+L["Chest"]="胸"
+L["Combat Time"]="战斗时间"
+L["copperabbrev"]="|cffeda55f铜|r"
+L["Defeated"]="已击杀"
+L["Deficit:"]="赤字:"
+L["Demolishers Destroyed"]="已摧毁攻城车"
+L["Download"]="下载"
+L["DPS"]="伤害输出"
+L["Earned:"]="赚取:"
+L["Feet"]="脚"
+L["Flags Captured"]="已夺取旗帜"
+L["Flags Returned"]="已归还旗帜"
+L["Friends List"]="好友列表"
+L["Friends"]="好友"
+L["Galleon"]="帆船"
+L["Gates Destroyed"]="已摧毁大门"
+L["goldabbrev"]="|cffffd700金|r"
+L["Graveyards Assaulted"]="已突袭墓地"
+L["Graveyards Defended"]="已守住墓地"
+L["Hands"]="手"
+L["Head"]="头"
+L["Hit"]="命中"
+L["Home Latency:"]="本机延迟:"
+L["HP"]="生命值"
+L["HPS"]="治疗输出"
+L["Legs"]="腿"
+L["lvl"]="等级"
+L["Main Hand"]="主手"
+L["Mitigation By Level: "]="等级减伤: "
+L["Nalak"]="纳拉克"
+L["No Guild"]="没有公会"
+L["Offhand"]="副手"
+L["Oondasta"]="乌达斯塔"
+L["Orb Possessions"]="宝珠属地"
+L["Profit:"]="利润:"
+L["Reset Data: Hold Shift + Right Click"]="重置数据: 按住 Shift + 右键点击"
+L["Saved Raid(s)"]="已有进度的副本"
+L["Server: "]="伺服器: "
+L["Session:"]="本次登入:"
+L["Sha of Anger"]="愤怒之煞"
+L["Shoulder"]="肩"
+L["silverabbrev"]="|cffc7c7cf银|r"
+L["SP"]="法能强度"
+L["Spent:"]="花费:"
+L["Stats For:"]="统计:"
+L["Total CPU:"]="CPU占用"
+L["Total Memory:"]="总记忆体:"
+L["Total: "]="合计: "
+L["Towers Assaulted"]="已占领哨塔"
+L["Towers Defended"]="已守住哨塔"
+L["Undefeated"]="未击杀"
+L["Unhittable:"]="未命中:"
+L["Victory Points"]="胜利点数"
+L["Waist"]="腰"
+L["World Boss(s)"]="世界首领"
+L["Wrist"]="护腕"
+L["%s: %s tried to call the protected function '%s'."]="%s: %s 尝试调用保护函数 '%s'."
+L["No locals to dump"]="没有本地文件"
+L["%s is attempting to share his filters with you. Would you like to accept the request?"]="%s 试图与你分享过滤器配置. 你是否接受?"
+L["%s is attempting to share the profile %s with you. Would you like to accept the request?"]="%s 试图与你分享配置文件 %s. 你是否接受?"
+L["Data From: %s"]="数据来源: %s"
+L["Filter download complete from %s, would you like to apply changes now?"]="过滤器配置下载于 %s, 你是否现在变更?"
+L["Lord! It's a miracle! The download up and vanished like a fart in the wind! Try Again!"]="天啊! 太奇葩了! 下载消失了! 就像在风中放了一个屁... 再试一次吧!"
+L["Profile download complete from %s, but the profile %s already exists. Change the name or else it will overwrite the existing profile."]="配置文件从 %s 下载完成, 但是配置文件 %s 已存在. 请更改名称, 否则它会覆盖你的现有配置文件."
+L["Profile download complete from %s, would you like to load the profile %s now?"]="配置文件从 %s 下载完成, 你是否加载配置文件 %s?"
+L["Profile request sent. Waiting for response from player."]="已发送文件请求. 等待对方响应."
+L["Request was denied by user."]="请求被对方拒绝."
+L["Your profile was successfully recieved by the player."]="你的配置文件已被其他玩家成功接收."
+L["Auras Set"]="光环样式设置"
+L["Auras System"]="光环样式"
+L["Caster DPS"]="法系输出"
+L["Chat Set"]="对话设定"
+L["Chat"]="对话设定"
+L["Choose a theme layout you wish to use for your initial setup."]="为你的个人设置选择一个你喜欢的皮肤主题."
+L["Vintage"]="经典"
+L["Classic"]="经典"
+L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."]="点击下面的按钮调整对话框、单位框架的尺寸,以及移动快捷列位置"
+L["Config Mode:"]="设置模式:"
+L["CVars Set"]="参数设定"
+L["CVars"]="参数"
+L["Gloom & Doom"]="黑暗"
+L["Disable"]="禁用"
+L["SVUI Installation"]="安装 SVUI"
+L["Finished"]="完成"
+L["Grid Size:"]="网格尺寸:"
+L["Healer"]="治疗"
+L["High Resolution"]="高分辨率"
+L["high"]="高"
+L["Icons Only"]="图标"
+L["If you have an icon or aurabar that you don't want to display simply hold down shift and right click the icon for it to disapear."]="如果你有不想显示的图标或光环条, 你可以简单的通过按住Shift右键点击使它隐藏."
+L["Importance: |cff07D400High|r"]="重要度: |cff07D400高|r"
+L["Importance: |cffD3CF00Medium|r"]="重要性: |cffD3CF00中|r"
+L["Importance: |cffFF0000Low|r"]="重要性:|cffFF0000低|r"
+L["Installation Complete"]="安装完成"
+L["Integrated"]="整合"
+L["Layout Set"]="界面布局设置"
+L["Layout"]="界面布局"
+L["Lock"]="锁定"
+L["Low Resolution"]="低分辨率"
+L["low"]="低"
+L["Frames unlocked. Move them now and click Lock when you are done."]="解除框架移动锁定. 现在可以移动它们, 移好后请点击「锁定」."
+L["Nudge"]="微调"
+L["Physical DPS"]="物理输出"
+L["Pixel Perfect Set"]="像素完美設置"
+L["Pixel Perfect"]="像素完美"
+L["Please click the button below so you can setup variables and ReloadUI."]="请按下方按钮设定变数并重载介面。"
+L["Please click the button below to setup your CVars."]="请按下方按钮设定参数."
+L["Please press the continue button to go onto the next step."]="请按继续按钮到下一步"
+L["Resolution Style Set"]="分辨率样式设置"
+L["Resolution"]="分辨率"
+L["Select the type of aura system you want to use with SVUI's unitframes. The integrated system utilizes both aura-bars and aura-icons. The icons only system will display only icons and aurabars won't be used."]='选择你要显示在单位框架上的光环系统, "综合"将显示图标和光环条, "图标"将只显示图标,不显示光环条.'
+L["Setup Chat"]="设定对话视窗"
+L["Setup CVars"]="设定参数"
+L["Skip Process"]="略过"
+L["Sticky Frames"]="框架依附"
+L["Tank"]="坦克"
+L["The chat windows function the same as Blizzard standard chat windows, you can right click the tabs and drag them around, rename, etc. Please click the button below to setup your chat windows."]="对话视窗与 WOW 原始对话视窗的操作方式相同,你可以拖拉、移动分页或重新命名分页。请按下方按钮以设定对话视窗。"
+L["The in-game configuration menu can be accesses by typing the /sv command or by clicking the 'C' button on the minimap. Press the button below if you wish to skip the installation process."]="若要进入内建设定选单,请输入 /sv,或者按一下小地图旁的 C 按钮。若要略过安装程序,请按下方按钮。"
+L["The Pixel Perfect option will change the overall apperance of your UI. Using Pixel Perfect is a slight performance increase over the traditional layout."]="像素完美选项将改变你的整体用户界面, 使用像素完美能轻微提升传统界面的性能."
+L["Theme Set"]="主题设置"
+L["Theme Setup"]="主题安装"
+L["This install process will help you learn some of the features in SVUI has to offer and also prepare your user interface for usage."]="此安装程序有助你了解 SVUI 部份功能,并可协助你预先设定 UI。"
+L["This is completely optional."]="这是可选项。"
+L["This part of the installation process sets up your chat windows names, positions and colors."]="此安装步骤将会设定对话视窗的名称、位置和颜色。"
+L["This part of the installation process sets up your World of Warcraft default options it is recommended you should do this step for everything to behave properly."]="此安装步骤将会设定 WOW 预设选项,建议你执行此步骤,以确保功能均可正常运作。"
+L["This resolution doesn't require that you change settings for the UI to fit on your screen."]="这个分辨率不需要你改动任何设置以适应你的屏幕。"
+L["This resolution requires that you change some settings to get everything to fit on your screen."]="这个分辨率需要你改变一些设置才能适应你的屏幕。"
+L["This will change the layout of your unitframes, raidframes, and statistics."]="此材质适用于对话框架、下拉式选单等物件上。"
+L["Trade"]="拾取/交易"
+L["Using this option will cause your borders around frames to be 1 pixel wide instead of 3 pixel. You may have to finish the installation to notice a differance. By default this is enable."]="此安装步骤将会使你的周围边框帧是1像素宽而不是3像素, 你可能在安装时已经注意到这一差异, 这是一个默认的启用."
+L["Welcome to SVUI version %s!"]="欢迎使用 SVUI 版本 %s!"
+L["You are now finished with the installation process. If you are in need of technical support please visit us at http://www.wowinterface.com."]=true;
+L["You can always change fonts and colors of any element of SVUI from the in-game configuration."]="你可以在游戏内的设定选项内更改SVUI的字体、颜色等设定."
+L["You can now choose what layout you wish to use based on your combat role."]="你现在可以根据你的战斗角色选择合适的布局。"
+L["You may need to further alter these settings depending how low you resolution is."]="根据你的分辨率你可能需要改动这些设置。"
+L["Your current resolution is %s, this is considered a %s resolution."]="你当前的分辨率是 %s, 这被认为是个 %s 分辨率。"
+L["Bars"]="条"
+L["Calendar"]="日历"
+L["Can't Roll"]="无法需求此装备"
+L["Disband Group"]="解散队伍"
+L["Empty Slot"]="空栏位"
+L["Enable"]="启用"
+L["Experience"]="经验/声望条"
+L["Fishy Loot"]="贪婪"
+L["Left Click:"]="鼠标左键:"
+L["Raid Menu"]="团队选单"
+L["Remaining:"]="剩余:"
+L["Rested:"]="休息:"
+L["Right Click:"]="鼠标右键:"
+L["Show BG Texts"]="显示战场资讯文字"
+L["Toggle Chat Frame"]="开关对话框架"
+L["Toggle Configuration"]="设置开关"
+L["XP:"]="经验:"
+L["You don't have permission to mark targets."]="你没有标记目标的权限"
+L["ABOVE_THREAT_FORMAT"]='%s: %.0f%% [%.0f%% 以上 |cff%02x%02x%02x%s|r]'
+L[" Frames"]="框架"
+L["Alternative Power"]="特殊能量条"
+L["Arena Frames"]="竞技场框架"
+L["Auras Frame"]="BUFF/DEBUFF 框"
+L["Bags"]="背包"
+L["Bar "]="快捷列 "
+L["BNet Frame"]="战网提示资讯"
+L["Special Ability Button"]="特殊技能键"
+L["Boss Frames"]="首领框架"
+L["Experience Bar"]="经验条"
+L["Focus Castbar"]="焦点目标施法条"
+L["Focus Frame"]="专注目标框架"
+L["FocusTarget Frame"]="专注目标的目标框架"
+L["GM Ticket Frame"]="GM 对话框"
+L["Left Dock"]="左侧对话框"
+L["Loot / Alert Frames"]="拾取 / 提醒框"
+L["Loot Frame"]="拾取框"
+L["Loss Control Icon"]="失去控制图标"
+L["MA Frames"]="主助理框"
+L["Micromenu"]="微型系统菜单"
+L["Minimap"]="小地图"
+L["MT Frames"]="主坦克框"
+L["Party Frames"]="队伍框架"
+L["Pet Bar"]="宠物快捷列"
+L["Pet Frame"]="宠物框架"
+L["PetTarget Frame"]="宠物目标框架"
+L["Player Castbar"]="玩家施法条"
+L["Player Frame"]="玩家框架"
+L["Raid 1-"]="团队 1-"
+L["Reputation Bar"]="声望条"
+L["Right Dock"]="右侧对话框"
+L["Stance Bar"]="姿态条"
+L["Target Castbar"]="目标施法条"
+L["Target Frame"]="目标框架"
+L["TargetTarget Frame"]="目标的目标框架"
+L["Tooltip"]="浮动提示"
+L["Totems"]="图腾条"
+L["Vehicle Seat Frame"]="载具座位框"
+L["Watch Frame"]="任务追踪框"
+L["Weapons"]="武器(毒药/强化等)"
+L["Discipline"]="戒律"
+L["Holy"]="神圣"
+L["Mistweaver"]='织雾'
+L["Restoration"]="恢复"
+L[" |cff00ff00bound to |r"]=" |cff00ff00绑定到 |r"
+L["%s frame(s) has a conflicting anchor point, please change either the buff or debuff anchor point so they are not attached to each other. Forcing the debuffs to be attached to the main unitframe until fixed."]="%s 个框架锚点冲突,请移动buff或者debuff锚点让他们彼此不依附。暂时强制debuff依附到主框架。"
+L["All keybindings cleared for |cff00ff00%s|r."]="取消 |cff00ff00%s|r 所有绑定的快捷键."
+L["Already Running.. Bailing Out!"]='正在运行!'
+L["Battleground statistics temporarily hidden, to show type /bgstats."]='战场资讯暂时隐藏, 你可以通过输入 /bgstats 或右键点击小地图旁「C」按钮显示.'
+L["Battleground statistics will now show again if you are inside a battleground."]="当你处于战场时战场资讯将再次显示."
+L["Binds Discarded"]="取消绑定"
+L["Binds Saved"]="储存绑定"
+L["Confused.. Try Again!"]='请再试一次!'
+L["Deleted %d gray items. Total Worth: %s"]="已删除 %d 个灰色物品. 总价值: "
+L["No gray items to delete."]="没有要删除的灰色物品"
+L["No gray items to sell."]="无灰色物品出售."
+L["The spell '%s' has been added to the BlackList unitframe aura filter."]='法术"%s"已经被添加到单位框架的光环过滤器中.'
+L["Vendored gray items for:"]="已出售灰色物品:"
+L["You don't have enough money to repair."]="没有足够的资金来修复."
+L["You must be at a vendor."]="你必需以商人为目标."
+L["Your items have been repaired for: "]="装备已修复: "
+L["Your items have been repaired using guild bank funds for: "]="物品已使用公会银行资金修复: "
+L["Your version of SVUI is out of date. You can download the latest version from http://www.wowinterface.com"]="SVUI 版本已过期,请至 http://www.wowinterface.com 下载最新版"
+L["|cFFE30000Lua error recieved. You can view the error message when you exit combat."]="|cFFE30000LUA错误已接收, 你可以在脱离战斗后检查.|r"
+L["A setting you have changed will change an option for this character only. This setting that you have changed will be uneffected by changing user profiles. Changing this setting requires that you reload your User Interface."]="你所做的改动只会影响到使用这个插件的本角色, 你需要重新加载界面才能使改动生效."
+L["Are you sure you want to delete all your gray items?"]="确定需要摧毁你的灰色物品?"
+L["Are you sure you want to disband the group?"]="确定要解散队伍?"
+L["Are you sure you want to reset every mover back to it's default position?"]="确定需要重置所有框架至默认位置?"
+L["Because of the mass confusion caused by the new aura system I've implemented a new step to the installation process. This is optional. If you like how your auras are setup go to the last step and click finished to not be prompted again. If for some reason you are prompted repeatedly please restart your game."]="由于大量的改动导致光环系统需要一个新的安装过程. 这是可选的, 最后一步将设置你的光环样式. 点击「完成」将不再提示. 如果由于某些原因反复提示, 请重新开启游戏."
+L["Can't buy anymore slots!"]="银行背包栏位已达最大值"
+L["Disable Warning"]='停用警告'
+L["Discard"]="取消"
+L["Do you swear not to post in technical support about something not working without first disabling the addon/package combination first?"]=true;
+L["Hover your mouse over any actionbutton or spellbook button to bind it. Press the escape key or right click to clear the current actionbutton's keybinding."]="移动滑鼠到快捷列或技能书按钮上绑定快捷键. 按ESC或滑鼠右键取消目前快捷键"
+L["I Swear"]='我承诺'
+L["Oh lord, you have got SVUI and Tukui both enable at the same time. Select an addon to disable."]="你不能同时使用SVUI和Tukui, 请选择一个禁用."
+L["One or more of the changes you have made require a ReloadUI."]="已变更一或多个设定,需重载介面."
+L["One or more of the changes you have made will effect all characters using this addon. You will have to reload the user interface to see the changes you have made."]="你所做的改动可能会影响到使用这个插件的所有角色,你需要重新加载界面才能使改动生效。"
+L["Save"]="储存"
+L["Using the healer layout it is highly recommended you download the addon Clique if you wish to have the click-to-heal function."]=true;
+L["You have changed the pixel perfect option. You will have to complete the installation process to remove any graphical bugs."]="你已改变了像素完美中的选项, 你必须完成安装过程以消除任何图形错误."
+L["You have changed your UIScale, however you still have the AutoScale option enable in SV. Press accept if you would like to disable the Auto Scale option."]="你改变了界面缩放比例,然而SVUI的自动缩放选项是开启的。点击接受以关闭SVUI的自动缩放。"
+L["You must purchase a bank slot first!"]="你必需购买一个银行背包栏位"
+L["Count"]="计数"
+L["Targeted By:"]="同目标的有:"
+L["A raid marker feature is available by pressing Escape -> Keybinds scroll to the bottom under SVUI and setting a keybind for the raid marker."]="你可以通过按ESC键 -> 按键设置, 滚动到SVUI设置下方设置一个快速标记的快捷键."
+L["SVUI has a dual spec feature which allows you to load different profiles based on your current spec on the fly. You can enable this from the profiles tab."]="SVUI可以根据你所使用的天赋自动套用不同的设置档. 你可以在配置文件中使用此功能."
+L["For technical support visit us at http://www.wowinterface.com."]="如需技术支援请至 http://www.wowinterface.com."
+L["If you accidently remove a chat frame you can always go the in-game configuration menu, press install, go to the chat portion and reset them."]="如果你不慎移除了对话框, 你可以重新安装一次重置他们."
+L["If you are experiencing issues with SVUI try disabling all your addons except SVUI, remember SVUI is a full UI replacement addon, you cannot run two addons that do the same thing."]="如果你遇到问题, SVUI会尝试禁用你除了SVUI之外的插件. 请记住你不能用不同的插件实现同一功能."
+L["The buff panel to the right of minimap is a list of your consolidated buffs. You can disable it in Buffs and Debuffs options of SV."]="小地图右侧的光环条是你的整合Buff条, 你可以在你的SVUI光环设置中关闭此功能."
+L["The focus unit can be set by typing /focus when you are targeting the unit you want to focus. It is recommended you make a macro to do this."]="你可以通过 /focus 命令设置焦点目标."
+L["To move abilities on the actionbars by default hold shift + drag. You can change the modifier key from the actionbar options menu."]="你可以通过按住Shift拖动技能条中的按键. 你可以在 Blizzard 的快捷列设置中更改按键."
+L["To setup which channels appear in which chat frame, right click the chat tab and go to settings."]="你可以通过右键点击对话框标签栏设置你需要在对话框内显示的频道."
+L["Using the /farmmode <size> command will spawn a larger minimap on your screen that can be moved around, very useful when farming."]="使用 /farmmode 命令可以切换小地图的显示模式为大型可移动小地图, 这在你Farm的时候会很有用."
+L["You can access copy chat and chat menu functions by mouse over the top right corner of chat panel and left/right click on the button that will appear."]="你可以通过鼠标滑过对话框右上角点击复制图标打开对话复制窗口."
+L["You can see someones average item level of their gear by holding shift and mousing over them. It should appear inside the tooltip."]="你可以通过按住Shift并将鼠标滑过目标看到目标的装备等级, 这将显示在你的鼠标提示框内."
+L["You can set your keybinds quickly by typing /kb."]="你可以通过输入 /kb 快速绑定按键."
+L["You can toggle the microbar by using your middle mouse button on the minimap you can also accomplish this by enabling the actual microbar located in the actionbar settings."]="你可以通过鼠标中键点击小地图或在快捷列设置内选择打开微型系统栏."
+L["You can use the /resetui command to reset all of your moveables. You can also use the command to reset a specific mover, /resetui <mover name>.\nExample: /resetui Player Frame"]="使用 /resetui 命令可以重置你的所有框架位置. 你也可以通过命令 /resetui <框架名称> 单独重置某个框架.\n例如: /resetui Player Frame"
+L["Ghost"]="鬼魂"
+L["Offline"]="离线"
\ No newline at end of file
diff --git a/SVUI_!Core/language/english_ui.lua b/SVUI_!Core/language/english_ui.lua
new file mode 100644
index 0000000..e778afc
--- /dev/null
+++ b/SVUI_!Core/language/english_ui.lua
@@ -0,0 +1,496 @@
+local L = Librarian("Linguist"):Lang("enUS", true);
+if not L then return; end
+L["Hearthstone"] = true;
+L["Conversation"]    = true
+L["General"]         = true
+L["LocalDefense"]    = true
+L["LookingForGroup"] = true
+L["Trade"]           = true
+L["WorldDefense"]    = true
+L["S_Conversation"]       = "C"
+L["S_General"]           = "G"
+L["S_LocalDefense"]       = "LD"
+L["S_LookingForGroup"]    = "LFG"
+L["S_Trade"]             = "T"
+L["S_WorldDefense"]       = "WD"
+--[[LOGIN MESSAGE]]--
+L["LOGIN_MSG"] = "Welcome to |cffFFFF1ASVUI|r! Keep your %s and your %s."
+L["LOGIN_MSG2"] = "Version |cffAA78FF%s|r, type |cff00FF00/sv|r to access the in-game configuration menu, or |cff00FF00/sv help|r for a list of other commands."
+--[[OPTION MESSAGES]]--
+L["AURAS_DESC"] = "Configure the aura icons that appear near the minimap."
+L["BAGS_DESC"] = "Adjust bag settings for SV."
+L["CHAT_DESC"] = "Adjust chat settings for SV."
+L["STATS_DESC"] = "Configure docked stat panels."
+L["SVUI_DESC"] = "SVUI is a complete User Interface replacement addon for World of Warcraft."
+L["NAMEPLATE_DESC"] = "Modify the nameplate settings."
+L["PANEL_DESC"] = "Adjust the size of your left and right panels, this will effect your chat and bags."
+L["ART_DESC"] = "Enable / Disable Window Modifications."
+L["TOGGLEART_DESC"] = "Enable / Disable this change."
+L["TOOLTIP_DESC"] = "Setup options for the Tooltip."
+L["TEXT_FORMAT_DESC"] = "Select the formatting of this text"
+L["import"] = "Existing Profiles"
+L["import_desc"] = "You can either create a new profile by entering a name in the editbox, or choose one of the already existing profiles."
+L["import_sub"] = "Select one of your currently available profiles."
+L["copy_name"] = "Copy From"
+L["copy_desc"] = "Copy the settings from one existing profile into the currently active profile."
+L["current"] = "Current Profile:"
+L["default"] = "Default"
+L["delete"] = "Delete a Profile"
+L["delete_confirm"] = "Are you sure you want to delete the selected profile?"
+L["delete_desc"] = "Delete existing and unused profiles from the database to save space, and cleanup the SavedVariables file."
+L["delete_sub"] = "Deletes a profile from the database."
+L["intro"] = "You can change the active database profile, so you can have different settings for every character."
+L["export"] = "Save As"
+L["export_sub"] = "Create a new empty profile."
+L["profiles"] = "Profiles"
+L["profiles_sub"] = "Manage Profiles"
+L["reset"] = "Reset Profile"
+L["reset_desc"] = "Reset the current profile back to its default values, in case your configuration is broken, or you simply want to start over."
+L["reset_sub"] = "Reset the current profile to the default"
+L["SVUI_DockBottomCenter"] = "Bottom Data Dock"
+L["SVUI_DockTopCenter"] = "Top Data Dock"
+--[[REACTION TEXTS]]--
+L[" is drinking."] = true;
+L["Leeeeeroy!"] = true;
+L["No Food: "] = true;
+L["No Flask: "] = true;
+L["All Buffed!"] = true;
+L["Check food and flask"] = true;
+L["Thanks for "] = true;
+L[" received from "] = true;
+L["GO!"] = true;
+L["Pulling %s in %s.."] = true
+L["Pull ABORTED!"] = true
+L["%s has prepared a %s - [%s]."] = true
+L["%s has prepared a %s."] = true
+L["%s has put down a %s."] = true
+L["%s is casting %s."] = true
+L["%s is casting %s. Click!"] = true
+L["%s used a %s."] = true
+--[[FORMATTED INSTALLER TEXTS]]--
+L["|cffD3CF00Recommended|r"] = true;
+L["Recommended: |cff99FF00Kaboom!|r"] = true;
+L["Recommended: |cff99FF00Super|r"] = true;
+L["Recommended: |cffFF0000Small Row!|r"] = true;
+L["Recommended: |cffFF0000Icon Lovers!|r"] = true;
+L["|cffFF9F00KABOOOOM!|r"] = true;
+L["|cffAF30FFThe Darkest Night|r"] = true;
+L["|cff00FFFFPlain and Simple|r"] = true;
+L["|cff00FFFFLets Do This|r"] = true;
+L["|cff00FFFFSimply Simple|r"] = true;
+L["|cff00FFFFEl Compacto|r"] = true;
+L["|cff00FFFFHealer Extraordinaire|r"] = true;
+L["|cff00FFFFLean And Clean|r"] = true;
+L["|cff00FFFFMore For Less|r"] = true;
+L["|cff00FFFFWhat Big Buttons You Have|r"] = true;
+L["|cff00FFFFThe Double Down|r"] = true;
+--[[NORMAL INSTALLER TEXTS]]--
+L["This is SVUI version %s!"] = true;
+L["Before I can turn you loose, persuing whatever villainy you feel will advance your professional career ... I need to ask some questions and turn a few screws first."] = true;
+L["At any time you can get to the config options by typing the command /sv. For quick changes to frame, bar or color sets, call your henchman by clicking the button on the bottom right of your screen. (Its the one with his stupid face on it)"] = true;
+L["CHOOSE_OR_DIE"] = CHOOSE_FACTION.." "..OR_CAPS.." "..HIT.." "..CONTINUE;
+L["Whether you want to or not, you will be needing a communicator so other villains can either update you on their doings-of-evil or inform you about the MANY abilities of Chuck Norris"] = true;
+L["The chat windows function the same as standard chat windows, you can right click the tabs and drag them, rename them, slap them around, you know... whatever. Clickity-click to setup your chat windows."] = true;
+L["Your current resolution is %s, this is considered a %s resolution."] = true;
+L["This resolution requires that you change some settings to get everything to fit on your screen."] = true;
+L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."] = true;
+L["You may need to further alter these settings depending how low you resolution is."] = true;
+L["This resolution doesn't require that you change settings for the UI to fit on your screen."] = true;
+L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."] = true;
+L["This is completely optional."] = true;
+L["So what you think your better than me with your big monitor? HUH?!?!"] = true;
+L["Dont forget whos in charge here! But enjoy the incredible detail."] = true;
+L["Why are you playing this on what I would assume is a calculator display?"] = true;
+L["Enjoy the ONE incredible pixel that fits on this screen."] = true;
+L["Choose a theme layout you wish to use for your initial setup."] = true;
+L["You can always change fonts and colors of any element of SVUI from the in-game configuration."] = true;
+L["This theme tells the world that you are a villain who can put on a show "] = true;
+L["or better yet, you ARE the show!"] = true;
+L["Kaboom!"] = true;
+L["This theme indicates that you have no interest in wasting time"] = true;
+L["the dying begins NOW!"] = true;
+L["Darkness"] = true;
+L["This theme is for villains who take pride in their class"] = true;
+L["villains know how to reprezent!"] = true;
+L["This theme is for any villain who sticks to their traditions"] = true;
+L["you don't need fancyness to kick some ass!"] = true;
+L["Vintage"] = true;
+L["Layout"] = true;
+L["You can now choose what primary unitframe style you wish to use."] = true;
+L["This will change the layout of your unitframes (ie.. Player, Target, Pet, Party, Raid ...etc)."] = true;
+L["This layout is anything but minimal! Using this is like being at a rock concert"] = true;
+L["then annihilating the crowd with frickin lazer beams!"] = true;
+L["Super"] = true;
+L["This layout is for the villain who just wants to get things done!"] = true;
+L["But he still wants to see your face before he hits you!"] = true;
+L["Simple"] = true;
+L["Just the necessities so you can see more of the world around you."] = true;
+L["You dont need no fanciness getting in the way of world domination do you?"] = true;
+L["Compact"] = true;
+L["This has all the pizzaz of Super frames but uses Compact party and raid frames."] = true;
+L["Sometimes a little fifty-fifty goes a long way."] = true;
+L["Healer"] = true;
+L["Bar Setup"] = true;
+L["Choose a layout for your action bars."] = true;
+L["Sometimes you need big buttons, sometimes you don't. Your choice here."] = true;
+L["Lets keep it slim and deadly, not unlike a ninja sword."] = true;
+L["You dont ever even look at your bar hardly, so pick this one!"] = true;
+L["Small Row"] = true;
+L["Granted, you dont REALLY need the buttons due to your hotkey-leetness, you just like watching cooldowns!"] = true;
+L["Sure thing cowboy, your secret is safe with me!"] = true;
+L["Small X2"] = true;
+L["The better to PEW-PEW you with my dear!"] = true;
+L["When you have little time for mouse accuracy, choose this set!"] = true;
+L["Big Row"] = true;
+L["It's like dual-wielding two big reasons for your enemies to back the **** up!"] = true;
+L["Double your bars then double their size for maximum button goodness!"] = true;
+L["Big X2"] = true;
+L["Auras System"] = true;
+L["Select the type of aura system you want to use with SVUI's unitframes. The Icon Lovers set will display only icons and aurabars won't be used. The Vintage set will use the original game style and the Gimme Everything set does just what it says.... icons, bars and awesomeness."] = true;
+L["If you have an icon or aurabar that you don't want to display simply hold down shift and right click the icon for it to suffer a painful death."] = true;
+L["Vintage"] = true;
+L["Icon Lovers"] = true;
+L["The Works!"] = true;
+L["Installation Complete"] = true;
+L["Thats it! All done! Now we just need to hand these choices off to the henchmen so they can get you ready to (..insert evil tasks here..)!"] = true;
+L["Click the button below to reload and get on your way! Good luck villain!"] = true;
+L["THE_BUTTON_BELOW"] = "THE\nBUTTON\nBELOW";
+--[[UI TEXTS]]--
+L["Meanwhile"]=true;
+L["..at "]=true;
+L["Binding"]=true;
+L["Key"]=true;
+L["KEY_ALT"]="A"
+L["KEY_CTRL"]="C"
+L["KEY_DELETE"]="Del"
+L["KEY_HOME"]="Hm"
+L["KEY_INSERT"]="Ins"
+L["KEY_MOUSEBUTTON"]="M"
+L["KEY_MOUSEWHEELDOWN"]="MwD"
+L["KEY_MOUSEWHEELUP"]="MwU"
+L["KEY_NUMPAD"]="N"
+L["KEY_PAGEDOWN"]="PD"
+L["KEY_PAGEUP"]="PU"
+L["KEY_SHIFT"]="S"
+L["KEY_SPACE"]="SpB"
+L["No bindings set."]=true;
+L["Remove Bar %d Action Page"]=true;
+L["Trigger"]=true;
+L["Delete Grays"]=true;
+L["Hold Control + Right Click:"]=true;
+L["Hold Shift + Drag:"]=true;
+L["Hold Shift:"]=true;
+L["Purchase"]=true;
+L["Reset Position"]=true;
+L["Sort Bags"]=true;
+L["Sort Tab"]=true;
+L["Stack Bags to Bank"]=true;
+L["Stack Bank to Bags"]=true;
+L["Stack Items"]=true;
+L["Temporary Move"]=true;
+L["Toggle Bags"]=true;
+L["Vendor Grays"]=true;
+L["AFK"]=true;
+L["DND"]=true;
+L["G"]=true;
+L["I"]=true;
+L["IL"]=true;
+L["Invalid Target"]=true;
+L["O"]=true;
+L["P"]=true;
+L["PL"]=true;
+L["R"]=true;
+L["RL"]=true;
+L["RW"]=true;
+L["says"]=true;
+L["whispers"]=true;
+L["yells"]=true;
+L["(Hold Shift) Memory Usage"]=true;
+L["AP"]=true;
+L["AVD: "]=true;
+L["Avoidance Breakdown"]=true;
+L["Bandwidth"]=true;
+L["Bases Assaulted"]=true;
+L["Bases Defended"]=true;
+L["Carts Controlled"]=true;
+L["Character: "]=true;
+L["Chest"]=true;
+L["Combat Time"]=true;
+L["copperabbrev"]="|cffeda55fc|r"
+L["Defeated"]=true;
+L["Deficit:"]=true;
+L["Demolishers Destroyed"]=true;
+L["Download"]=true;
+L["DPS"]=true;
+L["Earned:"]=true;
+L["Feet"]=true;
+L["Flags Captured"]=true;
+L["Flags Returned"]=true;
+L["Friends List"]=true;
+L["Friends"]=true;
+L["Galleon"]=true;
+L["Gates Destroyed"]=true;
+L["goldabbrev"]="|cffffd700g|r"
+L["Graveyards Assaulted"]=true;
+L["Graveyards Defended"]=true;
+L["Hands"]=true;
+L["Head"]=true;
+L["Hit"]=true;
+L["Home Latency:"]=true;
+L["HP"]=true;
+L["HPS"]=true;
+L["Legs"]=true;
+L["lvl"]=true;
+L["Main Hand"]=true;
+L["Mitigation By Level: "]=true;
+L["Nalak"]=true;
+L["No Guild"]=true;
+L["Offhand"]=true;
+L["Oondasta"]=true;
+L["Orb Possessions"]=true;
+L["Profit:"]=true;
+L["Reset Data: Hold Shift + Right Click"]=true;
+L["Saved Raid(s)"]=true;
+L["Server: "]=true;
+L["Session:"]=true;
+L["Sha of Anger"]=true;
+L["Shoulder"]=true;
+L["silverabbrev"]="|cffc7c7cfs|r"
+L["SP"]=true;
+L["Spent:"]=true;
+L["Stats For:"]=true;
+L["Total CPU:"]=true;
+L["Total Memory:"]=true;
+L["Total: "]=true;
+L["Towers Assaulted"]=true;
+L["Towers Defended"]=true;
+L["Undefeated"]=true;
+L["Unhittable:"]=true;
+L["Victory Points"]=true;
+L["Waist"]=true;
+L["World Boss(s)"]=true;
+L["Wrist"]=true;
+L["%s: %s tried to call the protected function '%s'."]=true;
+L["No locals to dump"]=true;
+L["Bars"]=true;
+L["Calendar"]=true;
+L["Can't Roll"]=true;
+L["Disband Group"]=true;
+L["Empty Slot"]=true;
+L["Enable"]=true;
+L["Experience"]=true;
+L["Fishy Loot"]=true;
+L["Left Click:"]=true;
+L["Raid Menu"]=true;
+L["Remaining:"]=true;
+L["Rested:"]=true;
+L["Right Click:"]=true;
+L["Show BG Texts"]=true;
+L["Toggle Chat Frame"]=true;
+L["Toggle Configuration"]=true;
+L["XP:"]=true;
+L["You don't have permission to mark targets."]=true;
+L["ABOVE_THREAT_FORMAT"]='%s: %.0f%% [%.0f%% above |cff%02x%02x%02x%s|r]'
+L[" Frames"]=true;
+L["Alternative Power"]=true;
+L["Arena Frames"]=true;
+L["Auras Frame"]=true;
+L["Bags"]=true;
+L["Bar "]=true;
+L["BNet Frame"]=true;
+L["Special Ability Button"]=true;
+L["Boss Frames"]=true;
+L["Experience Bar"]=true;
+L["Focus Castbar"]=true;
+L["Focus Frame"]=true;
+L["FocusTarget Frame"]=true;
+L["GM Ticket Frame"]=true;
+L["Left Dock"]=true;
+L["Loot / Alert Frames"]=true;
+L["Loot Frame"]=true;
+L["Loss Control Icon"]=true;
+L["MA Frames"]=true;
+L["Micromenu"]=true;
+L["Minimap"]=true;
+L["MT Frames"]=true;
+L["Party Frames"]=true;
+L["Pet Bar"]=true;
+L["Pet Frame"]=true;
+L["PetTarget Frame"]=true;
+L["Player Castbar"]=true;
+L["Player Frame"]=true;
+L["Raid 1-"]=true;
+L["Reputation Bar"]=true;
+L["Right Dock"]=true;
+L["Stance Bar"]=true;
+L["Target Castbar"]=true;
+L["Target Frame"]=true;
+L["TargetTarget Frame"]=true;
+L["Tooltip"]=true;
+L["Totems"]=true;
+L["Vehicle Seat Frame"]=true;
+L["Watch Frame"]=true;
+L["Weapons"]=true;
+L["Discipline"]=true;
+L["Holy"]=true;
+L["Mistweaver"]=true;
+L["Restoration"]=true;
+L[" |cff00ff00bound to |r"]=true;
+L["All keybindings cleared for |cff00ff00%s|r."]=true;
+L["Already Running.. Bailing Out!"]=true;
+L["Battleground statistics temporarily hidden, to show type /bgstats."]=true;
+L["Battleground statistics will now show again if you are inside a battleground."]=true;
+L["Binds Discarded"]=true;
+L["Binds Saved"]=true;
+L["Confused.. Try Again!"]=true;
+L["Deleted %d gray items. Total Worth: %s"]=true;
+L["No gray items to delete."]=true;
+L["No gray items to sell."]=true;
+L["The spell '%s' has been added to the BlackList unitframe aura filter."]=true;
+L["Vendored gray items for:"]=true;
+L["You don't have enough money to repair."]=true;
+L["You must be at a vendor."]=true;
+L["Your items have been repaired for: "]=true;
+L["Your items have been repaired using guild bank funds for: "]=true;
+L["Your version of SVUI is out of date. You can download the latest version from http://www.wowinterface.com"]=true;
+L["|cFFE30000Lua error recieved. You can view the error message when you exit combat."]=true;
+L["A setting you have changed will change an option for this character only. This setting that you have changed will be uneffected by changing user profiles. Changing this setting requires that you reload your User Interface."]=true;
+L["Are you sure you want to delete all your gray items?"]=true;
+L["Are you sure you want to disband the group?"]=true;
+L["Are you sure you want to reset every mover back to it's default position?"]=true;
+L["Because of the mass confusion caused by the new aura system I've implemented a new step to the installation process. This is optional. If you like how your auras are setup go to the last step and click finished to not be prompted again. If for some reason you are prompted repeatedly please restart your game."]=true;
+L["Can't buy anymore slots!"]=true;
+L["Disable Warning"]=true;
+L["Discard"]=true;
+L["Do you swear not to post in technical support about something not working without first disabling the addon/package combination first?"]=true;
+L["Hover your mouse over any actionbutton or spellbook button to bind it. Press the escape key or right click to clear the current actionbutton's keybinding."]=true;
+L["I Swear"]=true;
+L["One or more of the changes you have made require a ReloadUI."]=true;
+L["One or more of the changes you have made will effect all characters using this addon. You will have to reload the user interface to see the changes you have made."]=true;
+L["Save"]=true;
+L["Using the healer layout it is highly recommended you download the addon Clique if you wish to have the click-to-heal function."]=true;
+L["You have changed the pixel perfect option. You will have to complete the installation process to remove any graphical bugs."]=true;
+L["You have changed your UIScale, however you still have the AutoScale option enable in SV. Press accept if you would like to disable the Auto Scale option."]=true;
+L["You must purchase a bank slot first!"]=true;
+L["Count"]=true;
+L["Targeted By:"]=true;
+L["Ghost"]=true;
+L["Offline"]=true;
+L["Your version of SVUI is out of date. Please, download the latest version from http://www.wowinterface.com."]=true;
+L["Equipment"]=true;
+L["EQUIPMENT_DESC"]="Adjust the settings for switching your gear set when you change specialization or enter a battleground."
+L["No Change"]=true;
+L["Specialization"]=true;
+L["Enable/Disable the specialization switch."]=true;
+L["Primary Talent"]=true;
+L["Choose the equipment set to use for your primary specialization."]=true;
+L["Secondary Talent"]=true;
+L["Choose the equipment set to use for your secondary specialization."]=true;
+L["Battleground"]=true;
+L["Enable/Disable the battleground switch."]=true;
+L["Equipment Set"]=true;
+L["Choose the equipment set to use when you enter a battleground or arena."]=true;
+L["You have equipped equipment set: "]=true;
+L["DURABILITY_DESC"]="Adjust the settings for the durability information on the character screen."
+L["Enable/Disable the display of durability information on the character screen."]=true;
+L["Damaged Only"]=true;
+L["Only show durabitlity information for items that are damaged."]=true;
+L["ITEMLEVEL_DESC"]="Adjust the settings for the item level information on the character screen."
+L["Enable/Disable the display of item levels on the character screen."]=true;
+L["Miscellaneous"]=true;
+L["Equipment Set Overlay"]=true;
+L["Show the associated equipment sets for the items in your bags (or bank)."]=true;
+L["Layout Transparency"]=true;
+L["Changes the transparency of all the moveables."]=true;
+L["Automatic Role Assignment"]=true;
+L["Enables the automatic role assignment based on specialization for party / raid members (only work when you are group leader or group assist)."]=true;
+L["Hide Role Icon in combat"]=true;
+L["All role icons (Damage/Healer/Tank) on the unit frames are hidden when you go into combat."]=true;
+L["GPS"]=true;
+L["Show the direction and distance to the selected party or raid member."]=true;
+L["Attack Icon"]=true;
+L["Show attack icon for units that are not tapped by you or your group, but still give kill credit when attacked."]=true;
+L["Show class icon for units."]=true;
+L["Above Minimap"]=true;
+L["Location Digits"]=true;
+L["Number of digits for map location."]=true;
+L["Hide minimap while in combat."]=true;
+L["FadeIn Delay"]=true;
+L["The time to wait before fading the minimap back in after combat hide. (0 = Disabled)"]=true;
+L["Minimap Button Bar"]=true;
+L["Style Buttons"]=true;
+L["Customize the minimap buttons in SVUI style."]=true;
+L["SVUI Style"]=true;
+L["Change settings for how the minimap buttons are styled."]=true;
+L["The size of the minimap buttons."]=true;
+L["No Anchor Bar"]=true;
+L["Horizontal Anchor Bar"]=true;
+L["Vertical Anchor Bar"]=true;
+L["Layout Direction"]=true;
+L["Normal is right to left or top to bottom, or select reversed to switch directions."]=true;
+L["Normal"]=true;
+L["Reversed"]=true;
+L["PvP Autorelease"]=true;
+L["Automatically release body when killed inside a battleground."]=true;
+L["Track Reputation"]=true;
+L["Automatically change your watched faction on the reputation bar to the faction you got reputation points for."]=true;
+L["Select Quest Reward"]=true;
+L["Automatically select the quest reward with the highest vendor sell value."]=true;
+L["Item Level"]=true;
+L["Target Range"]=true;
+L["Distance"]=true;
+L["Actionbar1DataPanel"]='Actionbar 1'
+L["Actionbar3DataPanel"]='Actionbar 3'
+L["Actionbar5DataPanel"]='Actionbar 5'
+L["Sunsong Ranch"]=true;
+L["The Halfhill Market"]=true;
+L["Tilled Soil"]=true;
+L["Right-click to drop the item."]=true;
+L["Toolbox"]=true;
+L["COMIX_DESC"]="Toggle the comic popups during combat"
+L["FARMING_MODE_DESC"]="Adjust the settings for the tools that help your farming and professions."
+L["SNACKS_DESC"]="Adjust the settings for the consumables bar."
+L["Toolbox Bars"]=true;
+L["Toolbox Portal Bar"]=true;
+L["Toolbox Seed Bar"]=true;
+L["Toolbox Tools Bar"]=true;
+L["Enable/Disable the laborer bars."]=true;
+L["Only active buttons"]=true;
+L["Only show the buttons for the seeds, portals, tools you have in your bags."]=true;
+L["Drop Tools"]=true;
+L["Automatically drop tools from your bags when leaving the farming area."]=true;
+L["Seed Bar Direction"]=true;
+L["The direction of the seed bar buttons (Horizontal or Vertical)."]=true;
+L["Threat Text"]=true;
+L["Display threat level as text on targeted, boss or mouseover nameplate."]=true;
+L["Target Count"]=true;
+L["Display the number of party / raid members targetting the nameplate unit."]=true;
+L["Heal Glow"]=true;
+L["Direct AoE heals will let the unit frames of the affected party / raid members glow for the defined time period."]=true;
+L["Glow Duration"]=true;
+L["The amount of time the unit frames of party / raid members will glow when affected by a direct AoE heal."]=true;
+L["Glow Color"]=true;
+L["Raid Marker Bar"]=true;
+L["Display a quick action bar for raid targets and world markers."]=true;
+L["Modifier Key"]=true;
+L["Set the modifier key for placing world markers."]=true;
+L["Shift Key"]=true;
+L["Ctrl Key"]=true;
+L["Alt Key"]=true;
+L["Raid Markers"]=true;
+L["Click to clear the mark."]=true;
+L["Click to mark the target."]=true;
+L["%sClick to remove all worldmarkers."]=true;
+L["%sClick to place a worldmarker."]=true;
+L["WatchFrame"]=true;
+L["WATCHFRAME_DESC"]="Adjust the settings for the visibility of the watchframe (questlog) to your personal preference."
+L["Hidden"]=true;
+L["Collapsed"]=true;
+L["Settings"]=true;
+L["City (Resting)"]=true;
+L["PvP"]=true;
+L["Arena"]=true;
+L["Party"]=true;
+L["Raid"]=true;
+L["Progression Info"]=true;
+L["Display the players raid progression in the tooltip, this may not immediately update when mousing over a unit."]=true
\ No newline at end of file
diff --git a/SVUI_!Core/language/french_ui.lua b/SVUI_!Core/language/french_ui.lua
new file mode 100644
index 0000000..a3b74f8
--- /dev/null
+++ b/SVUI_!Core/language/french_ui.lua
@@ -0,0 +1,592 @@
+local L = Librarian("Linguist"):Lang("frFR");
+if not L then return; end
+L["Conversation"]    = "Conversation"
+L["General"]         = "Général"
+L["LocalDefense"]    = "DéfenseLocale"
+L["LookingForGroup"] = "RechercheDeGroupe"
+L["Trade"]           = "Commerce"
+L["WorldDefense"]    = "DéfenseUniverselle"
+L["S_Conversation"]    = "C"
+L["S_General"]        = "G"
+L["S_LocalDefense"]    = "DL"
+L["S_LookingForGroup"] = "RG"
+L["S_Trade"]          = "C"
+L["S_WorldDefense"]    = "DM"
+L["Hearthstone"] = true;
+--[[LOGIN MESSAGE]]--
+L["LOGIN_MSG"] = "Bienvenue sur |cffFFFF1ASVUI|r! Gardez votre %s et votre %s."
+L["LOGIN_MSG2"] = "Version |cffAA78FF%s|r, tapez /sv afin d'accéder au menu de configuration en jeu."
+--[[OPTION MESSAGES]]--
+L["AURAS_DESC"] = "Configure les icônes qui apparaissent près de la Minicarte."
+L["BAGS_DESC"] = "Ajuster les paramètres des sacs pour SV."
+L["CHAT_DESC"] = "Ajuste les paramètres du Chat pour SV."
+L["STATS_DESC"] = "Configure docked stat panels.";
+L["SVUI_DESC"] = "SVUI est une interface de remplacement complète pour World of Warcraft"
+L["NAMEPLATE_DESC"] = "Modifier la configuration des noms d'unités"
+L["PANEL_DESC"] = "Ajuste la largeur et la hauteur des fenêtres de chat, cela ajuste aussi les sacs."
+L["ART_DESC"] = "Ajuste les paramètres d'habillage."
+L["TOGGLEART_DESC"] = "Active ou désactive l'habillage SVUI des éléments ci-dessous."
+L["TOOLTIP_DESC"] = "Configuration des Info-bulles."
+L["TEXT_FORMAT_DESC"] = "Select the formatting of this text"
+L["import"] = "Profils existants"
+L["import_desc"] = "Vous pouvez créer un nouveau profil en entrant un nouveau nom dans la boîte de saisie, ou en choississant un des profils déjà existants."
+L["import_sub"] = "Permet de choisir un des profils déjà disponibles."
+L["copy_name"] = "Copier à partir de"
+L["copy_desc"] = "Copie les paramètres d'un profil déjà existant dans le profil actuellement actif."
+L["current"] = "Current Profile:"
+L["default"] = "Défaut"
+L["delete"] = "Supprimer un profil"
+L["delete_confirm"] = "Etes-vous sûr de vouloir supprimer le profil sélectionné ?"
+L["delete_desc"] = "Supprime les profils existants inutilisés de la base de données afin de gagner de la place et de nettoyer le fichier SavedVariables."
+L["delete_sub"] = "Supprime un profil de la base de données."
+L["intro"] = "Vous pouvez changer le profil actuel afin d'avoir des paramètres différents pour chaque personnage, permettant ainsi d'avoir une configuration très flexible."
+L["export"] = "Nouveau"
+L["export_sub"] = "Créée un nouveau profil vierge."
+L["profiles"] = "Profils"
+L["profiles_sub"] = "Gestion des profils"
+L["reset"] = "Réinitialiser le profil"
+L["reset_desc"] = "Réinitialise le profil actuel au cas où votre configuration est corrompue ou si vous voulez tout simplement faire table rase."
+L["reset_sub"] = "Réinitialise le profil actuel avec les paramètres par défaut."
+L["SVUI_DockBottomCenter"] = "Bottom Data Dock"
+L["SVUI_DockTopCenter"] = "Top Data Dock"
+--[[REACTION TEXTS]]--
+L[" is drinking."] = true;
+L["Leeeeeroy!"] = true;
+L["No Food: "] = "Sans nourriture: "
+L["No Flask: "] = "Sans flacon: "
+L["All Buffed!"] = "Tout le monde possède sa nourriture et son flacon!"
+L["Check food and flask"] = "Vérifier nourriture et flacon"
+L["Thanks for "] = "Merci pour "
+L[" received from "] = " reçu de "
+L["GO!"] = "Départ!"
+L["Pulling %s in %s.."] = "Pull %s dans %s.."
+L["Pull ABORTED!"] = "Pull ABANDONNE!"
+L["%s has prepared a %s - [%s]."] = "%s a préparé un %s - [%s]."
+L["%s has prepared a %s."] = "%s a préparé un %s."
+L["%s has put down a %s."] = "%s a déposé au sol un %s."
+L["%s is casting %s."] = "%s lance le sort %s."
+L["%s is casting %s. Click!"] = "%s invoque %s. Click!"
+L["%s used a %s."] = "%s used a %s."
+--[[FORMATTED INSTALLER TEXTS]]--
+L["|cffD3CF00Recommended|r"] = true;
+L["Recommended: |cff99FF00Kaboom!|r"] = true;
+L["Recommended: |cff99FF00Super|r"] = true;
+L["Recommended: |cffFF0000Small Row!|r"] = true;
+L["Recommended: |cffFF0000Icon Lovers!|r"] = true;
+L["|cffFF9F00KABOOOOM!|r"] = true;
+L["|cffAF30FFThe Darkest Night|r"] = true;
+L["|cff00FFFFPlain and Simple|r"] = true;
+L["|cff00FFFFLets Do This|r"] = true;
+L["|cff00FFFFSimply Simple|r"] = true;
+L["|cff00FFFFEl Compacto|r"] = true;
+L["|cff00FFFFHealer Extraordinaire|r"] = true;
+L["|cff00FFFFLean And Clean|r"] = true;
+L["|cff00FFFFMore For Less|r"] = true;
+L["|cff00FFFFWhat Big Buttons You Have|r"] = true;
+L["|cff00FFFFThe Double Down|r"] = true;
+--[[NORMAL INSTALLER TEXTS]]--
+L["This is SVUI version %s!"] = true;
+L["Before I can turn you loose, persuing whatever villainy you feel will advance your professional career ... I need to ask some questions and turn a few screws first."] = true;
+L["At any time you can get to the config options by typing the command /sv. For quick changes to frame, bar or color sets, call your henchman by clicking the button on the bottom right of your screen. (Its the one with his stupid face on it)"] = true;
+L["CHOOSE_OR_DIE"] = CHOOSE_FACTION.." "..OR_CAPS.." "..HIT.." "..CONTINUE;
+L["Whether you want to or not, you will be needing a communicator so other villains can either update you on their doings-of-evil or inform you about the MANY abilities of Chuck Norris"] = true;
+L["The chat windows function the same as standard chat windows, you can right click the tabs and drag them, rename them, slap them around, you know... whatever. Clickity-click to setup your chat windows."] = true;
+L["Your current resolution is %s, this is considered a %s resolution."] = true;
+L["This resolution requires that you change some settings to get everything to fit on your screen."] = true;
+L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."] = true;
+L["You may need to further alter these settings depending how low you resolution is."] = true;
+L["This resolution doesn't require that you change settings for the UI to fit on your screen."] = true;
+L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."] = true;
+L["This is completely optional."] = true;
+L["So what you think your better than me with your big monitor? HUH?!?!"] = true;
+L["Dont forget whos in charge here! But enjoy the incredible detail."] = true;
+L["Why are you playing this on what I would assume is a calculator display?"] = true;
+L["Enjoy the ONE incredible pixel that fits on this screen."] = true;
+L["Choose a theme layout you wish to use for your initial setup."] = true;
+L["You can always change fonts and colors of any element of SVUI from the in-game configuration."] = true;
+L["This theme tells the world that you are a villain who can put on a show "] = true;
+L["or better yet, you ARE the show!"] = true;
+L["Kaboom!"] = true;
+L["This theme indicates that you have no interest in wasting time"] = true;
+L["the dying begins NOW!"] = true;
+L["Darkness"] = true;
+L["This theme is for villains who take pride in their class"] = true;
+L["villains know how to reprezent!"] = true;
+L["This theme is for any villain who sticks to their traditions"] = true;
+L["you don't need fancyness to kick some ass!"] = true;
+L["Vintage"] = true;
+L["Layout"] = true;
+L["You can now choose what primary unitframe style you wish to use."] = true;
+L["This will change the layout of your unitframes (ie.. Player, Target, Pet, Party, Raid ...etc)."] = true;
+L["This layout is anything but minimal! Using this is like being at a rock concert"] = true;
+L["then annihilating the crowd with frickin lazer beams!"] = true;
+L["Super"] = true;
+L["This layout is for the villain who just wants to get things done!"] = true;
+L["But he still wants to see your face before he hits you!"] = true;
+L["Simple"] = true;
+L["Just the necessities so you can see more of the world around you."] = true;
+L["You dont need no fanciness getting in the way of world domination do you?"] = true;
+L["Compact"] = true;
+L["This has all the pizzaz of Super frames but uses Compact party and raid frames."] = true;
+L["Sometimes a little fifty-fifty goes a long way."] = true;
+L["Healer"] = true;
+L["Bar Setup"] = true;
+L["Choose a layout for your action bars."] = true;
+L["Sometimes you need big buttons, sometimes you don't. Your choice here."] = true;
+L["Lets keep it slim and deadly, not unlike a ninja sword."] = true;
+L["You dont ever even look at your bar hardly, so pick this one!"] = true;
+L["Small Row"] = true;
+L["Granted, you dont REALLY need the buttons due to your hotkey-leetness, you just like watching cooldowns!"] = true;
+L["Sure thing cowboy, your secret is safe with me!"] = true;
+L["Small X2"] = true;
+L["The better to PEW-PEW you with my dear!"] = true;
+L["When you have little time for mouse accuracy, choose this set!"] = true;
+L["Big Row"] = true;
+L["It's like dual-wielding two big reasons for your enemies to back the **** up!"] = true;
+L["Double your bars then double their size for maximum button goodness!"] = true;
+L["Big X2"] = true;
+L["Auras System"] = true;
+L["Select the type of aura system you want to use with SVUI's unitframes. The Icon Lovers set will display only icons and aurabars won't be used. The Vintage set will use the original game style and the Gimme Everything set does just what it says.... icons, bars and awesomeness."] = true;
+L["If you have an icon or aurabar that you don't want to display simply hold down shift and right click the icon for it to suffer a painful death."] = true;
+L["Vintage"] = true;
+L["Icon Lovers"] = true;
+L["The Works!"] = true;
+L["Installation Complete"] = true;
+L["Thats it! All done! Now we just need to hand these choices off to the henchmen so they can get you ready to (..insert evil tasks here..)!"] = true;
+L["Click the button below to reload and get on your way! Good luck villain!"] = true;
+L["THE_BUTTON_BELOW"] = "THE\nBUTTON\nBELOW";
+--[[UI TEXTS]]--
+L["Meanwhile"]=true;
+L["..at "]=true;
+L["A taint has occured that is preventing you from using the queue system. Please reload your user interface and try again."]="Une alteration s'est produite et vous empêche d'utiliser la file d'attente. Veuillez recharger votre interface utilisateur et essayer à nouveau."
+L["Binding"]="Raccourcis"
+L["Key"]="Touche"
+L["KEY_ALT"]="A"
+L["KEY_CTRL"]="C"
+L["KEY_DELETE"]="Suppr"
+L["KEY_HOME"]="Hm"
+L["KEY_INSERT"]="Ins"
+L["KEY_MOUSEBUTTON"]="M"
+L["KEY_MOUSEWHEELDOWN"]="MwD"
+L["KEY_MOUSEWHEELUP"]="MwU"
+L["KEY_NUMPAD"]="N"
+L["KEY_PAGEDOWN"]="PD"
+L["KEY_PAGEUP"]="PU"
+L["KEY_SHIFT"]="S"
+L["KEY_SPACE"]="SpB"
+L["No bindings set."]="Aucune assignation"
+L["Remove Bar %d Action Page"]="Retirer la pagination de la barre d'action"
+L["Trigger"]="Déclencheur"
+L["Delete Grays"]="Détruire les objets gris."
+L["Hold Control + Right Click:"]="Contrôle enfoncée + Clic droit"
+L["Hold Shift + Drag:"]="Majscule enfoncée + Déplacer"
+L["Hold Shift:"]="Maintenir MAJ:"
+L["Purchase"]="Acheter"
+L["Reset Position"]="Réinitialiser la position"
+L["Sort Bags"]="Trier les sacs"
+L["Sort Tab"]=true;
+L["Stack Bags to Bank"]="Empiler des Sacs vers la Banque"
+L["Stack Bank to Bags"]="Empiler de la Banque vers les Sacs"
+L["Stack Items"]="Empilement des objets"
+L["Temporary Move"]="Bouger temporairement"
+L["Toggle Bags"]="Afficher les sacs"
+L["Vendor Grays"]="Vendre les objets gris"
+L["AFK"]="ABS"
+L["DND"]="NPD"
+L["G"]="G"
+L["I"]="I"
+L["IL"]="IL"
+L["Invalid Target"]="Cible incorrecte"
+L["O"]="O"
+L["P"]="Gr"
+L["PL"]="CdG"
+L["R"]="R"
+L["RL"]="RL"
+L["RW"]="RW"
+L["says"]="dit"
+L["whispers"]="chuchote"
+L["yells"]="crie"
+L["(Hold Shift) Memory Usage"]="(Maintenir MAJ) Utilisation de la Mémoire."
+L["AP"]="PA"
+L["AVD: "]="AVD: "
+L["Avoidance Breakdown"]="Répartition de l'évitement"
+L["Bandwidth"]="Bande passante"
+L["Bases Assaulted"]="Bases assaillis"
+L["Bases Defended"]="Bases défendues"
+L["Carts Controlled"]="Chariots contrôlés"
+L["Character: "]="Personnage: "
+L["Chest"]="Torse"
+L["Combat Time"]="Durée du Combat"
+L["copperabbrev"]="|cffeda55fc|r"
+L["Defeated"]="Defaite"
+L["Deficit:"]="Déficit:"
+L["Demolishers Destroyed"]="Démolisseurs détruits"
+L["Download"]="Téléchargement"
+L["DPS"]="DPS"
+L["Earned:"]="Gagné:"
+L["Feet"]="Pieds"
+L["Flags Captured"]="Drapeaux capturés"
+L["Flags Returned"]="Drapeaux retournés"
+L["Friends List"]="Liste d'amis"
+L["Friends"]="Amis"
+L["Galleon"]="Galion"
+L["Gates Destroyed"]="Portes détruites"
+L["goldabbrev"]="|cffffd700g|r"
+L["Graveyards Assaulted"]="Cimetières assaillis"
+L["Graveyards Defended"]="Cimetières défendus"
+L["Hands"]="Mains"
+L["Head"]="Tête"
+L["Hit"]="Toucher"
+L["Home Latency:"]="Latence du Domicile:"
+L["HP"]="PdS"
+L["HPS"]="HPS"
+L["Legs"]="Jambes"
+L["lvl"]="niveau"
+L["Main Hand"]="Main droite"
+L["Mitigation By Level: "]="Réduction par niveau: "
+L["Nalak"]="Nalak"
+L["No Guild"]="Non Guildé"
+L["Offhand"]="Main gauche"
+L["Oondasta"]="Oondasta"
+L["Orb Possessions"]="Orbes obtenues"
+L["Profit:"]="Profit:"
+L["Reset Data: Hold Shift + Right Click"]="RAZ des données: Shift + Clic droit"
+L["Saved Raid(s)"]="Raid(s) Sauvegardé(s)"
+L["Server: "]="Serveur: "
+L["Session:"]="Session:"
+L["Sha of Anger"]="Sha de la colère"
+L["Shoulder"]="Épaule"
+L["silverabbrev"]="|cffc7c7cfs|r"
+L["SP"]="PdS"
+L["Spent:"]="Dépensé: "
+L["Stats For:"]="Stats pour:"
+L["Total CPU:"]="Charge du CPU:"
+L["Total Memory:"]="Mémoire totale:"
+L["Total: "]="Total: "
+L["Towers Assaulted"]="Tours attaquées"
+L["Towers Defended"]="Tours défendues"
+L["Undefeated"]="Invaincu"
+L["Unhittable:"]="Intouchable:"
+L["Victory Points"]="Points de Victoire"
+L["Waist"]="Ceinture"
+L["World Boss(s)"]="Boss Mondiaux"
+L["Wrist"]="Poignets"
+L["%s: %s tried to call the protected function '%s'."]="%s: %s a essayé d'appeler la fonction protégée '%s'."
+L["No locals to dump"]="Aucunes données à vider"
+L["%s is attempting to share his filters with you. Would you like to accept the request?"]="%s tente de partager ses profils avec vous. Voulez-vous accepter la demande?"
+L["%s is attempting to share the profile %s with you. Would you like to accept the request?"]="%s tente de partager le profil %s avec vous. Voulez-vous accepter la demande?"
+L["Data From: %s"]="Donnée de: %s"
+L["Filter download complete from %s, would you like to apply changes now?"]="Téléchargement du filtre de %s complet, voulez-vous appliquer les changements maintenant ?"
+L["Lord! It's a miracle! The download up and vanished like a fart in the wind! Try Again!"]="Seigneur ! C'est un miracle ! Le téléchargement monte et a disparu comme une pet dans le vent! Essayez encore !"
+L["Profile download complete from %s, but the profile %s already exists. Change the name or else it will overwrite the existing profile."]="Téléchargement du profil de %s complet, néanmoins le profil de % existe déjà. Changez le nom ou bien il écrasera le profil existant."
+L["Profile download complete from %s, would you like to load the profile %s now?"]="Téléchargement du profil de %s complet, voulez-vous charger le profil %s maintenant?"
+L["Profile request sent. Waiting for response from player."]="Requête du profil envoyé. En attente de la reponse du joueur."
+L["Request was denied by user."]="La requête a ete refusée par l'utilisateur."
+L["Your profile was successfully recieved by the player."]="Votre profil a été reçu avec succès par le joueur."
+L["Auras Set"]="Configuration des Auras"
+L["Auras System"]="Système d'Auras"
+L["Caster DPS"]="DPS Distance"
+L["Chat Set"]="Chat configuré"
+L["Chat"]="Discussion"
+L["Choose a theme layout you wish to use for your initial setup."]="Choisissez un modèle de thème que vous souhaitez utiliser pour votre configuration initiale."
+L["Vintage"]="Classique"
+L["Classic"]="Classique"
+L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."]="Cliquez sur le bouton ci-dessous pour redimensionner vos fenêtres de chat, vos cadres d'unités et repositionner vos barres d'actions."
+L["Config Mode:"]="Mode Configuration:"
+L["CVars Set"]="CVars configurés"
+L["CVars"]="CVars"
+L["Gloom & Doom"]="Sombre"
+L["Disable"]="Désactiver"
+L["SVUI Installation"]="Installation d'SVUI"
+L["Finished"]="Terminé"
+L["Grid Size:"]="Taille de la Grille:"
+L["Healer"]="Soigneur"
+L["High Resolution"]="Haute Résolution"
+L["high"]="Haute"
+L["Icons Only"]="Icônes seulement"
+L["If you have an icon or aurabar that you don't want to display simply hold down shift and right click the icon for it to disapear."]="Si vous avez une icône ou une barre d'aura que vous ne souhaitez pas afficher il suffit de maintenir la touche MAJ enfoncée et d'effectuer un clic droit sur l'icône correspondante pour la faire disparaitre."
+L["Importance: |cff07D400High|r"]="Importance: |cff07D400Haute|r"
+L["Importance: |cffD3CF00Medium|r"]="Importance: |cffD3CF00Moyenne|r"
+L["Importance: |cffFF0000Low|r"]="Importance: |cffFF0000Faible|r"
+L["Installation Complete"]="Installation terminée"
+L["Integrated"]="Intégré"
+L["Layout Set"]="Disposition configurée"
+L["Layout"]="Disposition"
+L["Lock"]="Verrouiller"
+L["Low Resolution"]="Basse résolution"
+L["low"]="Faible"
+L["Frames unlocked. Move them now and click Lock when you are done."]="Cadres déverrouillés. Déplacez-les et cliquez sur Verrouiller une fois terminé."
+L["Nudge"]=true;
+L["Physical DPS"]="DPS Physique"
+L["Pixel Perfect Set"]="Réglage Pixel Parfait"
+L["Pixel Perfect"]="Pixel Parfait"
+L["Please click the button below so you can setup variables and ReloadUI."]="Pour configurer les variables et recharger l'interface, cliquez sur le bouton ci-dessous."
+L["Please click the button below to setup your CVars."]="Pour configurer les CVars, cliquez sur le bouton ci-dessous."
+L["Please press the continue button to go onto the next step."]="Pour passer à l'étape suivante, cliquez sur le bouton Continuer."
+L["Resolution Style Set"]="Paramètre de résolution configuré"
+L["Resolution"]="Résolution"
+L["Select the type of aura system you want to use with SVUI's unitframes. The integrated system utilizes both aura-bars and aura-icons. The icons only system will display only icons and aurabars won't be used. The classic system will configure your auras to be default."]="Sélectionnez le type de système aura que vous souhaitez utiliser avec UnitFrames SV. Le système intégré utilise à la fois les barres d'Auras et les icônes d'Auras. Le systeme icône seul va afficher uniquement les icônes et barres d'auras ne sera pas utilisé. Le système classique permet de configurer vos Auras par défaut."
+L["Setup Chat"]="Configurer le Chat."
+L["Setup CVars"]="Configurer les CVars"
+L["Skip Process"]="Passer cette étape"
+L["Sticky Frames"]="Cadres adhésifs"
+L["Tank"]="Tank"
+L["The chat windows function the same as Blizzard standard chat windows, you can right click the tabs and drag them around, rename, etc. Please click the button below to setup your chat windows."]="La fenêtre de chat d'SVUi utilise les même fonctions que celle Blizzard, vous pouvez faire un clic droit sur un onglet pour le déplacer, le renommer, etc."
+L["The in-game configuration menu can be accesses by typing the /sv command or by clicking the 'C' button on the minimap. Press the button below if you wish to skip the installation process."]="Le menu de configuration est accessible en tapant la commande /sv ou en cliquant sur le bouton 'C' sur la Minicarte. Cliquez sur le bouton ci-dessous si vous voulez passer le processus d'installation."
+L["The Pixel Perfect option will change the overall apperance of your UI. Using Pixel Perfect is a slight performance increase over the traditional layout."]="Le thème Pixel Parfait change entièrement l'apparence de votre UI. Utiliser le thème Piwel Parfait consomme moins de ressource que le thème traditionnel."
+L["Theme Set"]="Choisir le thème"
+L["Theme Setup"]="Configuration du thème"
+L["This install process will help you learn some of the features in SVUI has to offer and also prepare your user interface for usage."]="Ce programme d'installation vous aidera à découvrir quelques fonctionnalités qu'SVUI offre et préparera également votre interface à son utilisation."
+L["This is completely optional."]="Ceci est totalement optionnel."
+L["This part of the installation process sets up your chat windows names, positions and colors."]="Cette partie du processus d'installation configure les noms, positions et couleurs de vos fenêtres de chat."
+L["This part of the installation process sets up your World of Warcraft default options it is recommended you should do this step for everything to behave properly."]="Cette partie du processus d'installation paramètrera vos options par défaut de World of Warcraft. Il est recommandé d'effectuer cette étape afin que tout fonctionne correctement."
+L["This resolution doesn't require that you change settings for the UI to fit on your screen."]="Cette résolution ne nécessite pas que vous modifiez les paramètres de l'interface utilisateur pour s'adapter à votre écran."
+L["This resolution requires that you change some settings to get everything to fit on your screen."]="Cette résolution nécessite que vous modifiez les paramètres de l'interface utilisateur pour s'adapter sur votre écran."
+L["This will change the layout of your unitframes, raidframes, and statistics."]="Ceci changera la disposition des cadres d'unités, des cadres de Raid et des Textes d'informations."
+L["Trade"]="Métiers"
+L["Using this option will cause your borders around frames to be 1 pixel wide instead of 3 pixel. You may have to finish the installation to notice a differance. By default this is enable."]="L'utilisation de cette option modifiera vos bordures d'images à 1 pixel de large au lieu de 3 pixels. Vous devez terminer l'installation pour constater une différence. Par défaut cette option est activée."
+L["Welcome to SVUI version %s!"]="Bienvenue sur la version %s d'SVUI!"
+L["You are now finished with the installation process. If you are in need of technical support please visit us at http://www.wowinterface.com."]="Vous avez maintenant terminé le processus d'installation. Si vous avez besoin d'un support technique, merci de vous rendre sur http://www.wowinterface.com"
+L["You can always change fonts and colors of any element of SVUI from the in-game configuration."]="Vous pouvez toujours modifier les polices et les couleurs de n'importe quel élément d'SVUI dans la configuration du jeu."
+L["You can now choose what layout you wish to use based on your combat role."]="Vous pouvez maintenant choisir quelle disposition vous souhaitez utiliser en fonction de votre rôle lors d'un combat."
+L["You may need to further alter these settings depending how low you resolution is."]="Vous devrez peut-être encore modifier ces paramètres en fonction d'un changement de résolution."
+L["Your current resolution is %s, this is considered a %s resolution."]="Votre résolution actuelle est %s, elle est donc considérée comme une %s Résolution."
+L["Bars"]="Barres"
+L["Calendar"]=true;
+L["Can't Roll"]="Ne peut pas jeter les dés"
+L["Disband Group"]="Dissoudre le groupe"
+L["Empty Slot"]="Emplacement libre"
+L["Enable"]="Activer"
+L["Experience"]="Expérience"
+L["Fishy Loot"]="Butin de pêche"
+L["Left Click:"]="Clic Gauche:"
+L["Raid Menu"]="Menu Raid"
+L["Remaining:"]="Restant:"
+L["Rested:"]="Reposé:"
+L["Right Click:"]="Clic Droit:"
+L["Show BG Texts"]="Voir les textes de BG"
+L["Toggle Chat Frame"]="Activer la fenêtre de discussion"
+L["Toggle Configuration"]="Afficher la Configuration"
+L["XP:"]="XP:"
+L["You don't have permission to mark targets."]="Vous n'avez pas la permission de marquer les cibles."
+L["ABOVE_THREAT_FORMAT"]='%s: %.0f%% [%.0f%% above |cff%02x%02x%02x%s|r]'
+L[" Frames"]="Fenêtres"
+L["Alternative Power"]="Puissance Alternative"
+L["Arena Frames"]="Cadre d'arène"
+L["Auras Frame"]="Fenêtre des Auras"
+L["Bags"]="Sacs"
+L["Bar "]="Barre "
+L["BNet Frame"]="Fenetre BNet"
+L["Special Ability Button"]="Bouton du Boss"
+L["Boss Frames"]="Cadre du Boss"
+L["Experience Bar"]="Barre d'expérience"
+L["Focus Castbar"]="Barre d'incantation du Focus"
+L["Focus Frame"]="Cadre de la Focalisation"
+L["FocusTarget Frame"]="Cadre de la cible de votre focalisation"
+L["GM Ticket Frame"]="Fenêtre du ticket MJ"
+L["Left Dock"]="Chat de gauche"
+L["Loot / Alert Frames"]="Butin / Fenêtre d'alerte"
+L["Loot Frame"]="Fenêtre du butin"
+L["Loss Control Icon"]="Icône de la perte de contrôle"
+L["MA Frames"]="Fenêtre du second Tank"
+L["Micromenu"]="Micromenure"
+L["Minimap"]="Minicarte"
+L["MT Frames"]="Fenêtre du Tank"
+L["Party Frames"]="Cadre de groupe"
+L["Pet Bar"]="Barre de familier"
+L["Pet Frame"]="Cadre du familier"
+L["PetTarget Frame"]="Cadre de la cible du familier"
+L["Player Castbar"]="Barre d'incantation du joueur"
+L["Player Frame"]="Cadre du joueur"
+L["Raid 1-"]="Raid 1-"
+L["Reputation Bar"]="Barre de réputation"
+L["Right Dock"]="Chat de droite"
+L["Stance Bar"]="Barre de posture"
+L["Target Castbar"]="Barre d'incantation de la cible"
+L["Target Frame"]="Cadre de la cible"
+L["TargetTarget Frame"]="Cadre de la cible de votre cible"
+L["Tooltip"]="Info-bulle"
+L["Totems"]="Totems"
+L["Vehicle Seat Frame"]="Fenêtre de l'assise du vehicule"
+L["Watch Frame"]="Fenêtre des quètes"
+L["Weapons"]="Armes"
+L["Discipline"]="Discipline"
+L["Holy"]="Sacré"
+L["Mistweaver"]="Tisse-Brume"
+L["Restoration"]="Restauration"
+L[" |cff00ff00bound to |r"]="|cff00ff00assigné à |r"
+L["%s frame(s) has a conflicting anchor point, please change either the buff or debuff anchor point so they are not attached to each other. Forcing the debuffs to be attached to the main unitframe until fixed."]="% du (des) cadre(s) à un point d'ancrage contradictoire(s), merci de changer le point d'ancrage des améliorations ou des affaiblissements de sorte qu'ils ne soint pas attachés les uns aux autres. Forcer les affaiblissement à être attaché au cadre d'unité principale jusqu'à ce qu'ils soient fixés."
+L["All keybindings cleared for |cff00ff00%s|r."]="Tous les raccourcis ont été effacés pour |cff00ff00%s|r."
+L["Already Running.. Bailing Out!"]="Déjà en cours d'exécution..."
+L["Battleground statistics temporarily hidden, to show type /bgstats."]="Textes d'informations des champs de bataille temporairement masqués, pour les afficher tapez /bgstats ou clic droit sur le 'C' près de la minicarte."
+L["Battleground statistics will now show again if you are inside a battleground."]="Les textes d'informations des champs de bataille seront à nouveau affichés si vous êtes dans un champs de bataille."
+L["Binds Discarded"]="Raccourcis annulés"
+L["Binds Saved"]="Raccourcis sauvegardés"
+L["Confused.. Try Again!"]="Confus...Essayez à nouveau!"
+L["Deleted %d gray items. Total Worth: %s"]="%d Objet(s) gris détruit(s). Valeur totale perdue :%s"
+L["No gray items to delete."]="Aucun objet gris à détruire."
+L["No gray items to sell."]="Aucun objet gris à vendre."
+L["The spell '%s' has been added to the BlackList unitframe aura filter."]="Le sort '%s' a bien été ajouté à la liste noire des filtres des cadres d'unités."
+L["Vendored gray items for:"]="Objets gris vendus pour:"
+L["You don't have enough money to repair."]="Vous n'avez pas assez d'argent pour réparer votre équipement."
+L["You must be at a vendor."]="Vous devez être chez un marchand."
+L["Your items have been repaired for: "]="Votre équipement a été réparé pour: "
+L["Your items have been repaired using guild bank funds for: "]="Votre équipement a été réparé avec l'argent de la banque de guilde pour: "
+L["Your version of SVUI is out of date. You can download the latest version from http://www.wowinterface.com"]="Votre version d'SVUI n'est pas à jour. Vous pouvez télécharger la dernière version sur http://www.wowinterface.com"
+L["|cFFE30000Lua error recieved. You can view the error message when you exit combat."]="|cFFE30000Erreur Lua reçue. Vous pouvez voir ce message d'erreur quand vous sortez de combat."
+L["A setting you have changed will change an option for this character only. This setting that you have changed will be uneffected by changing user profiles. Changing this setting requires that you reload your User Interface."]="Un réglage que vous avez modifié ne s'appliquera que pour ce personnage. La modification de ce réglage ne sera pas affecté par un changement de profil. Changer ce réglage requiert de relancer l'interface."
+L["Are you sure you want to delete all your gray items?"]="Êtes-vous sûr de vouloir détruire tous vos Objets Gris ?"
+L["Are you sure you want to disband the group?"]="Êtes-vous sûr de vouloir dissoudre le groupe ? "
+L["Are you sure you want to reset every mover back to it's default position?"]="Êtes-vous sûre de vouloir réinitialiser tous les cadres à leur position par défaut ?"
+L["Because of the mass confusion caused by the new aura system I've implemented a new step to the installation process. This is optional. If you like how your auras are setup go to the last step and click finished to not be prompted again. If for some reason you are prompted repeatedly please restart your game."]="En raison de la confusion générale provoquée par le nouveau système d'aura, j'ai mis en place une nouvelle étape dans le processus d'installation. Cette option est facultative. Si vous aimez la façon dont vos auras sont configurés allez à la dernière étape et cliquez sur Terminé pour ne pas être averti à nouveau.  Si, pour une raison quelconque, vous êtes averti de nouveau, relancez complètement le jeu."
+L["Can't buy anymore slots!"]="Impossible d'acheter plus emplacements !"
+L["Disable Warning"]="Désactiver l'alerte"
+L["Discard"]="Annuler"
+L["Do you swear not to post in technical support about something not working without first disabling the addon/package combination first?"]="Jurez-vous de ne pas avoir posté sur le support technique du forum sur quelquechose qui ne fonctionne pas sans avoir desactivé en premier la combinaison Addon/Package?"
+L["Hover your mouse over any actionbutton or spellbook button to bind it. Press the escape key or right click to clear the current actionbutton's keybinding."]="Passez votre souris sur n'importe quel bouton d'action ou bouton du grimoire pour lui attribuer un raccourcis. Appuyez sur la touche Echap ou le clic droit pour effacer le raccourci en cours."
+L["I Swear"]="Je le jure"
+L["Oh lord, you have got SVUI and Tukui both enable at the same time. Select an addon to disable."]="Oh seigneur, vous avez SVUI et Tukui d'activé en même temps. Selectionnez un add-on à désactiver."
+L["One or more of the changes you have made require a ReloadUI."]="Une ou plusieurs modifications que vous avez effectuées necessitent un rechargement de l'interface."
+L["One or more of the changes you have made will effect all characters using this addon. You will have to reload the user interface to see the changes you have made."]="Un ou plusieurs changement(s) que vous avez effectués a une incidence sur tous les personnages qui utilise cet addon. Vous devriez recharger l'interface utilisateur pour voir le(s) changement(s) apporté(s)."
+L["Save"]="Sauvegarder"
+L["Using the healer layout it is highly recommended you download the addon Clique if you wish to have the click-to-heal function."]=true;
+L["You have changed the pixel perfect option. You will have to complete the installation process to remove any graphical bugs."]="Vous avez modifié l'option Pixel Parfait. Vous devrez compléter le processus d'installation pour éliminer les bugs graphiques."
+L["You have changed your UIScale, however you still have the AutoScale option enable in SV. Press accept if you would like to disable the Auto Scale option."]="Vous venez de changer l'échelle de votre interface, alors que votre option d'échelle automatique est encore activée dans SV. Cliquer sur accepter si vous voulez désactiver l'option d'échelle automatique."
+L["You must purchase a bank slot first!"]="Vous devez d'abord acheter un emplacement de banque !"
+L["Count"]="Nombre:"
+L["Targeted By:"]="Ciblé par:"
+L["A raid marker feature is available by pressing Escape -> Keybinds scroll to the bottom under SVUI and setting a keybind for the raid marker."]="Une fonction marqueur de raid est disponible en appuyant sur Echap -> Raccourcis, défilez en bas d'SVUI et paramétrez le raccourcis pour le marqueur de raid."
+L["SVUI has a dual spec feature which allows you to load different profiles based on your current spec on the fly. You can enable this from the profiles tab."]="SVUI dispose d'une fonction double spécialisation qui vous permet de charger à la volée des profils différents en fonction de votre specialisation actuelle."
+L["For technical support visit us at http://www.wowinterface.com."]="Pour tout support technique, merci de nous visiter à http://www.wowinterface.com."
+L["If you accidently remove a chat frame you can always go the in-game configuration menu, press install, go to the chat portion and reset them."]="Si vous supprimez accidentellement un cadre de discussion, vous pouvez toujours aller dans le menu de configuration d'SV. Cliquez ensuite sur Installation puis passez à l'étape concernant les fenêtres de discussion pour remettre à zero les paramètres."
+L["If you are experiencing issues with SVUI try disabling all your addons except SVUI, remember SVUI is a full UI replacement addon, you cannot run two addons that do the same thing."]="Si vous rencontrez des problèmes avec SVUI, essayez de désactiver tous vos addons sauf SV. Rappelez-vous que'SVUi est une interface utilisateur complète et que vous ne pouvez pas exécuter deux addons qui font la même chose."
+L["The buff panel to the right of minimap is a list of your consolidated buffs. You can disable it in Buffs and Debuffs options of SV."]="Le panneau d'améliorations à droite de la minicarte est une liste de vos améliorations groupées. Vous pouvez la désactiver dans la section Améliorations et Affaiblissement d'SV."
+L["The focus unit can be set by typing /focus when you are targeting the unit you want to focus. It is recommended you make a macro to do this."]="La cadre de focus peut être défini en tapent /focus quand vous êtes en train de cibler une unité que vous voulez focus. Il est recommandé de faire une macro pour cela."
+L["To move abilities on the actionbars by default hold shift + drag. You can change the modifier key from the actionbar options menu."]="Pour déplacer par défaut les capacités des barres d'actions, maintenant MAJ + déplacer. Vous pouvez modifier la touche de modification dans le menu des barres d'actions."
+L["To setup which channels appear in which chat frame, right click the chat tab and go to settings."]="Pour configurer quels canaux de discussions doivent apparaitre de les fenêtres de Chat, faites un clic droit sur l'onglet de Chat et allez dans les paramètres."
+L["Using the /farmmode <size> command will spawn a larger minimap on your screen that can be moved around, very useful when farming."]="En utilisant la commande /farmmode <taille>, vous pouvez afficher une minicarte plus grande qui peut être déplacée. Très utile pour les métiers de récolte."
+L["You can access copy chat and chat menu functions by mouse over the top right corner of chat panel and left/right click on the button that will appear."]="Vous pouvez accéder à une copie du Chat et des fonctions du Chat en survolant avec votre souris le coin haut droit de la fenêtre de discussion. Cliquez ensuite sur le bouton."
+L["You can see someones average item level of their gear by holding shift and mousing over them. It should appear inside the tooltip."]="Vous pouvez voir le niveau d'objet moyen de n'importe qui en maintenant la touche MAJ enfoncée puis en passant votre souris sur un joueur. Le score apparaitra dans la bulle d'information."
+L["You can set your keybinds quickly by typing /kb."]="Vous pouvez assignez rapidement vos raccourcis en tapant /kb."
+L["You can toggle the microbar by using your middle mouse button on the minimap you can also accomplish this by enabling the actual microbar located in the actionbar settings."]="Vous pouvez afficher la microbar en utilisant le bouton central de votre souris sur la minicarte. Vous pouvez aussi l'afficher via les réglages des Barres d'actions"
+L["You can use the /resetui command to reset all of your moveables. You can also use the command to reset a specific mover, /resetui <mover name>.\nExample: /resetui Player Frame"]="Vous pouvez utiliser la commande /resetui pour réinitialiser l'ensemble de vos cadres. Vous pouvez aussi utiliser la commande /resetui <nom du cadre> pour réinitialiser un cadre spécifique.\nExemple: /resetui Player Frame"
+L["Ghost"]="Fantôme"
+L["Offline"]="Déconnecté"
+L["ENH_LOGIN_MSG"]="Vous utilisez |cff1784d1SVUI Enhanced|r version %s%s|r."
+L["Your version of SVUI is to old. Please, download the latest version from http://www.wowinterface.com."]=true;
+L["Equipment"]="Équipement"
+L["EQUIPMENT_DESC"]="Ajustez les réglages pour passer d'un équipement à l'autre lorsque vous changez de spécialisation ou lorsque que vous effectuez un Champs de Bataille."
+L["No Change"]="Ne pas changer"
+L["Specialization"]="Spécialisation"
+L["Enable/Disable the specialization switch."]="Activer / Désactiver la fonction du changement d'équipement lorsque vous changez de spécialisation."
+L["Primary Talent"]="Spécialisation principale"
+L["Choose the equipment set to use for your primary specialization."]="Choisissez le set d'équipement à utiliser pour votre spécialisation principale."
+L["Secondary Talent"]="Spécialisaion secondaire"
+L["Choose the equipment set to use for your secondary specialization."]="Choisissez le set d'équipement à utiliser pour votre spécialisation secondaire."
+L["Battleground"]="Champs de Bataille"
+L["Enable/Disable the battleground switch."]="Activer / Désactiver la fonction du changement d'équipement lorsque vous entrez dans un Champs de Bataille ou une Arène."
+L["Equipment Set"]="Set d'équipement"
+L["Choose the equipment set to use when you enter a battleground or arena."]="Choisissez le set d'équipement à utiliser quant vous entrez dans un Champs de Bataille ou une Arène."
+L["You have equipped equipment set: "]="Vous avez équipez le set d'équipement: "
+L["DURABILITY_DESC"]="Ajustez les réglages pour afficher la durabilité sur l'écran d'infos de personnage."
+L["Enable/Disable the display of durability information on the character screen."]="Activer / Désactiver l'affichage des informations de durabilité sur l'écran d'infos de personnage."
+L["Damaged Only"]="Dégâts seulement"
+L["Only show durabitlity information for items that are damaged."]="Afficher la durabilité seulement quand l'équipement est endommagé."
+L["ITEMLEVEL_DESC"]="Réglez les paramètres pour afficher le niveau d'objet sur l'écran d'infos de personnage."
+L["Enable/Disable the display of item levels on the character screen."]="Activer / Désactiver l'affichage des informations du niveau d'objet sur l'écran d'infos de personnage."
+L["Miscellaneous"]="Divers"
+L["Equipment Set Overlay"]="Nom du set d'équipement"
+L["Show the associated equipment sets for the items in your bags (or bank)."]="Affiche le nom associés au set d'équipement sur vos objets dans vos sacs et votre banque."
+L["Layout Transparency"]="Transparence des Ancres"
+L["Changes the transparency of all the moveables."]="Change la transparence des Ancres"
+L["Automatic Role Assignment"]="Assigner automatiquement le rôle"
+L["Enables the automatic role assignment based on specialization for party / raid members (only work when you are group leader or group assist)."]="Active l'assignation automatique des rôles des membres selon la spécialisation dans le Groupe / Raid (Fonctionne seulement quand vous êtes le leader ou que vous possédez une assiste.)"
+L["Hide Role Icon in combat"]="Cachez les icônes de rôle en combat"
+L["All role icons (Damage/Healer/Tank) on the unit frames are hidden when you go into combat."]="Cachez toutes les icônes de rôle (Dommages/Healer/Tank) sur les cadres d'unité quand vous serait en combat."
+L["GPS"]="GPS"
+L["Show the direction and distance to the selected party or raid member."]="Affiche la direction et la distance entre vous et la cible du groupe ou du raid."
+L["Attack Icon"]="Icône d'Attaque"
+L["Show attack icon for units that are not tapped by you or your group, but still give kill credit when attacked."]="Affiche une icône d'attaque sur les unités que vous ou votre groupe n'avez pas encore tapé, mais dont vous pouvez revendiquer la paternité."
+L["Show class icon for units."]=true;
+L["Above Minimap"]="Sous la minicarte"
+L["Location Digits"]="Chiffres d'emplacement"
+L["Number of digits for map location."]="Nombre de chiffres pour l'emplacement."
+L["Hide minimap while in combat."]="Cacher la minicarte quand vous êtes en combat"
+L["FadeIn Delay"]="Délais d'estompage"
+L["The time to wait before fading the minimap back in after combat hide. (0 = Disabled)"]="Le temps à attendre avant que la minicarte s'estompe avec que le combat ait commencé. (0 = désactié)"
+L["Style Buttons"]="Boutons Style"
+L["Customize the minimap buttons in SVUI style."]="Habillez les boutons de la minicarte avec le style SV."
+L["SVUI Style"]="SVUI Style"
+L["Change settings for how the minimap buttons are styled."]="Change les réglages pour comment sont habillés les boutons."
+L["The size of the minimap buttons."]="Taille des boutons de la minicarte."
+L["No Anchor Bar"]="Ne pas ancré à une Barre"
+L["Horizontal Anchor Bar"]="Ancrer honrizontalement à la Barre"
+L["Vertical Anchor Bar"]="Ancrer verticalement à la Barre"
+L["Layout Direction"]=true;
+L["Normal is right to left or top to bottom, or select reversed to switch directions."]=true;
+L["Normal"]=true;
+L["Reversed"]=true;
+L["PvP Autorelease"]="Libération automatique en PVP"
+L["Automatically release body when killed inside a battleground."]="Libère automatiquement votre corps quand vous êtes tué en Champs de Bataille."
+L["Track Reputation"]="Suivre la Réputation"
+L["Automatically change your watched faction on the reputation bar to the faction you got reputation points for."]="Change automatiquement la réputation suivie sur la barre de réputation avec la faction que vous êtes en train de faire."
+L["Select Quest Reward"]="Sélection de la récompense de quête"
+L["Automatically select the quest reward with the highest vendor sell value."]="Sélectionne automatiquement la récompense de quête qui vaut la plus chère chez le vendeur."
+L["Item Level"]="Niveau d'objet"
+L["Target Range"]=true;
+L["Distance"]="Distance"
+L["Actionbar1DataPanel"]="Barre d'actions 1"
+L["Actionbar3DataPanel"]="Barre d'actions 3"
+L["Actionbar5DataPanel"]="Barre d'actions 5"
+L["Sunsong Ranch"]="Ferme Chant du Soleil"
+L["The Halfhill Market"]="Marché de Micolline"
+L["Tilled Soil"]="Terre labourée"
+L["Right-click to drop the item."]="Clique droit pour lacher l'objet."
+L["Toolbox"]="Ferme"
+L["COMIX_DESC"]="Toggle the comic popups during combat"
+L["FARMING_MODE_DESC"]="Réglez les paramètres des outils qui vous aideront à pratiquer une agriculture plus efficace avec votre Ferme (Ferme Chant du Soleil)."
+L["SNACKS_DESC"]=""
+L["Toolbox Bars"]="Barre d'agriculture"
+L["Toolbox Portal Bar"]="Barre des portails"
+L["Toolbox Seed Bar"]="Barre des graines"
+L["Toolbox Tools Bar"]="Barre des outils"
+L["Enable/Disable the laborer bars."]="Activer / Désactiver la barre d'agriculture"
+L["Only active buttons"]="Seulement les boutons actifs"
+L["Only show the buttons for the seeds, portals, tools you have in your bags."]="Affiche seulement les boutons pour les graines, portails et outils que vous avez dans vos sacs."
+L["Drop Tools"]="Jeter les outils"
+L["Automatically drop tools from your bags when leaving the farming area."]="Jeter automatiquement les outils de votre sac après avoir quitté la ferme."
+L["Seed Bar Direction"]="Direction de la barre des graines."
+L["The direction of the seed bar buttons (Horizontal or Vertical)."]="Sélectionnez la direction de la barre de graine (Horizontal ou Vertical)."
+L["Threat Text"]="Texte de menace"
+L["Display threat level as text on targeted, boss or mouseover nameplate."]="Affiche le niveau de menace sur le cadre d'unité de la cible, du boss, ou en passant votre souris."
+L["Target Count"]=true;
+L["Display the number of party / raid members targetting the nameplate unit."]=true;
+L["Heal Glow"]="Prédiction des soins"
+L["Direct AoE heals will let the unit frames of the affected party / raid members glow for the defined time period."]="Les soins directs d'AoE laisserons sur les cadres d'unités du groupe / raid un montant fixe défini pour la période du soin."
+L["Glow Duration"]="Durée de la prédiction"
+L["The amount of time the unit frames of party / raid members will glow when affected by a direct AoE heal."]="Le temps que les cadres d'unités du groupe / Raid seront affectés par la prédiction de soin."
+L["Glow Color"]="Couleur de la prédiction"
+L["Raid Marker Bar"]="Barre d'action de marquage d'icône ou terrain"
+L["Display a quick action bar for raid targets and world markers."]="Affiche une barre d'action pour ajouter une icône sur les cibles ou marquer le terrain"
+L["Modifier Key"]="Touche de marquage de terrain"
+L["Set the modifier key for placing world markers."]="Configurez la touche de modification pour placer des marquages de terrain rapidement.|cff1784d1Fonctionne seulement en groupe ou en raid.|r"
+L["Shift Key"]="Touche MAJ"
+L["Ctrl Key"]="Touche CTRL"
+L["Alt Key"]="Touche ALT "
+L["Raid Markers"]="Icône ou Marquage de terrain"
+L["Click to clear the mark."]="Cliquez pour supprimer l'icône sur la cible."
+L["Click to mark the target."]="Cliquez pour placer une icône sur la cible."
+L["%sClick to remove all worldmarkers."]="%sClic pour supprimer tous les marquages de terrain."
+L["%sClick to place a worldmarker."]="%sClic pour placer un marqueur de terrain."
+L["WatchFrame"]="Fenêtre d'objectifs"
+L["WATCHFRAME_DESC"]="Réglez les paramètres pour la visibilité de la fenêtre d'objectifs (journal de quête) avec vos préférences personnelles."
+L["Hidden"]="Caché"
+L["Collapsed"]="Replié"
+L["Settings"]="Paramètres"
+L["City (Resting)"]="Ville (repos)"
+L["PvP"]="PvP"
+L["Arena"]="Arêne"
+L["Party"]="Groupe"
+L["Raid"]="Raid"
+L["Progression Info"]="Information de progression"
+L["Display the players raid progression in the tooltip, this may not immediately update when mousing over a unit."]="Affiche la progression (Raid) du joueur dans une infos-bulle (ne peut être mis à jour immédiatement lorsque la souris survole une unité)."
\ No newline at end of file
diff --git a/SVUI_!Core/language/german_ui.lua b/SVUI_!Core/language/german_ui.lua
new file mode 100644
index 0000000..2a531c1
--- /dev/null
+++ b/SVUI_!Core/language/german_ui.lua
@@ -0,0 +1,590 @@
+local L = Librarian("Linguist"):Lang("deDE");
+if not L then return end
+L["Conversation"]    = "Chat"
+L["General"]         = "Allgemein"
+L["LocalDefense"]    = "LokaleVerteidigung"
+L["LookingForGroup"] = "SucheNachGruppe"
+L["Trade"]           = "Handel"
+L["WorldDefense"]    = "WeltVerteidigung"
+L["S_Conversation"]     = "C"
+L["S_General"]         = "A"
+L["S_LocalDefense"]     = "LV"
+L["S_LookingForGroup"]  = "LFG"
+L["S_Trade"]           = "H"
+L["S_WorldDefense"]     = "GV"
+L["Hearthstone"] = "Ruhestein";
+--[[LOGIN MESSAGE]]--
+L["LOGIN_MSG"] = "Willkommen zu |cffFFFF1ASVUI|r! halten Sie Ihre %s und Ihre %s."
+L["LOGIN_MSG2"] = "Version |cffAA78FF%s|r, Tippe /sv um das Konfigurationsmenü aufzurufen."
+--[[OPTION MESSAGES]]--
+L["AURAS_DESC"] = "Konfiguriere die Symbole für die Stärkungs- und Schwächungszauber nahe der Minimap."
+L["BAGS_DESC"] = "Konfiguriere die Einstellungen für die Taschen."
+L["CHAT_DESC"] = "Anpassen der Chateinstellungen für SV."
+L["STATS_DESC"] = "Configure docked stat panels.";
+L["SVUI_DESC"] = "SVUI ist ein komplettes Benutzerinterface für World of Warcraft."
+L["NAMEPLATE_DESC"] = "Konfiguriere die Einstellungen für die Namensplaketten."
+L["PANEL_DESC"] = "Stellt die Größe der linken und rechten Leisten ein, dies hat auch Einfluss auf den Chat und die Taschen."
+L["ART_DESC"] = "Passe die Einstellungen für externe Addon PrestoChange / Optionen an."
+L["TOGGLEART_DESC"] = "Aktiviere / Deaktiviere diesen Style."
+L["TOOLTIP_DESC"] = "Konfiguriere die Einstellungen für Tooltips."
+L["TEXT_FORMAT_DESC"] = "Select the formatting of this text"
+L["import"] = "Vorhandene Profile"
+L["import_desc"] = "Du kannst ein neues Profil erstellen, indem du einen neuen Namen in der Eingabebox 'Neu' eingibst, oder wähle eines der vorhandenen Profile aus."
+L["import_sub"] = "Wählt ein bereits vorhandenes Profil aus."
+L["copy_name"] = "Kopieren von..."
+L["copy_desc"] = "Kopiere die Einstellungen von einem vorhandenen Profil in das aktive Profil."
+L["default"] = "Standard"
+L["delete"] = "Profil löschen"
+L["delete_confirm"] = "Willst du das ausgewählte Profil wirklich löschen?"
+L["delete_desc"] = "Lösche vorhandene oder unbenutzte Profile aus der Datenbank um Platz zu sparen und um die SavedVariables Datei 'sauber' zu halten."
+L["delete_sub"] = "Löscht ein Profil aus der Datenbank."
+L["intro"] = "Hier kannst du das aktive Datenbankprofile ändern, damit du verschiedene Einstellungen für jeden Charakter erstellen kannst, wodurch eine sehr flexible Konfiguration möglich wird."
+L["export"] = "Neu"
+L["export_sub"] = "Ein neues Profil erstellen."
+L["profiles"] = "Profile"
+L["profiles_sub"] = "Profile verwalten"
+L["reset"] = "Profil zurücksetzen"
+L["reset_desc"] = "Setzt das momentane Profil auf Standardwerte zurück, für den Fall das mit der Konfiguration etwas schief lief oder weil du einfach neu starten willst."
+L["reset_sub"] = "Das aktuelle Profil auf Standard zurücksetzen."
+L["SVUI_DockBottomCenter"] = "Bottom Data Dock"
+L["SVUI_DockTopCenter"] = "Top Data Dock"
+--[[REACTION TEXTS]]--
+L[" is drinking."] = true;
+L["Leeeeeroy!"] = true;
+L["No Food: "] = "Kein Essen: "
+L["No Flask: "] = "Kein Fläschchen: "
+L["All Buffed!"] = "Alles drin!"
+L["Check food and flask"] = "Überprüfe Food und Flask"
+L["Thanks for "] = "Danke für "
+L[" received from "] = " erhalten von "
+L["GO!"] = "GO!"
+L["Pulling %s in %s.."] = "Pull %s in %s.."
+L["Pull ABORTED!"] = "Pull ABGEBROCHEN!"
+L["%s has prepared a %s - [%s]."] = "%s bereitet ein %s vor - [%s]."
+L["%s has prepared a %s."] = "%s bereitet ein %s vor."
+L["%s has put down a %s."] = "%s stellt ein %s auf."
+L["%s is casting %s."] = "%s zaubert ein %s."
+L["%s is casting %s. Click!"] = "%s zaubert ein %s. Klick!"
+L["%s used a %s."] = "%s nahm %s."
+--[[FORMATTED INSTALLER TEXTS]]--
+L["|cffD3CF00Recommended|r"] = true;
+L["Recommended: |cff99FF00Kaboom!|r"] = true;
+L["Recommended: |cff99FF00Super|r"] = true;
+L["Recommended: |cffFF0000Small Row!|r"] = true;
+L["Recommended: |cffFF0000Icon Lovers!|r"] = true;
+L["|cffFF9F00KABOOOOM!|r"] = true;
+L["|cffAF30FFThe Darkest Night|r"] = true;
+L["|cff00FFFFPlain and Simple|r"] = true;
+L["|cff00FFFFLets Do This|r"] = true;
+L["|cff00FFFFSimply Simple|r"] = true;
+L["|cff00FFFFEl Compacto|r"] = true;
+L["|cff00FFFFHealer Extraordinaire|r"] = true;
+L["|cff00FFFFLean And Clean|r"] = true;
+L["|cff00FFFFMore For Less|r"] = true;
+L["|cff00FFFFWhat Big Buttons You Have|r"] = true;
+L["|cff00FFFFThe Double Down|r"] = true;
+--[[NORMAL INSTALLER TEXTS]]--
+L["This is SVUI version %s!"] = true;
+L["Before I can turn you loose, persuing whatever villainy you feel will advance your professional career ... I need to ask some questions and turn a few screws first."] = true;
+L["At any time you can get to the config options by typing the command /sv. For quick changes to frame, bar or color sets, call your henchman by clicking the button on the bottom right of your screen. (Its the one with his stupid face on it)"] = true;
+L["CHOOSE_OR_DIE"] = CHOOSE_FACTION.." "..OR_CAPS.." "..HIT.." "..CONTINUE;
+L["Whether you want to or not, you will be needing a communicator so other villains can either update you on their doings-of-evil or inform you about the MANY abilities of Chuck Norris"] = true;
+L["The chat windows function the same as standard chat windows, you can right click the tabs and drag them, rename them, slap them around, you know... whatever. Clickity-click to setup your chat windows."] = true;
+L["Your current resolution is %s, this is considered a %s resolution."] = true;
+L["This resolution requires that you change some settings to get everything to fit on your screen."] = true;
+L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."] = true;
+L["You may need to further alter these settings depending how low you resolution is."] = true;
+L["This resolution doesn't require that you change settings for the UI to fit on your screen."] = true;
+L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."] = true;
+L["This is completely optional."] = true;
+L["So what you think your better than me with your big monitor? HUH?!?!"] = true;
+L["Dont forget whos in charge here! But enjoy the incredible detail."] = true;
+L["Why are you playing this on what I would assume is a calculator display?"] = true;
+L["Enjoy the ONE incredible pixel that fits on this screen."] = true;
+L["Choose a theme layout you wish to use for your initial setup."] = true;
+L["You can always change fonts and colors of any element of SVUI from the in-game configuration."] = true;
+L["This theme tells the world that you are a villain who can put on a show "] = true;
+L["or better yet, you ARE the show!"] = true;
+L["Kaboom!"] = true;
+L["This theme indicates that you have no interest in wasting time"] = true;
+L["the dying begins NOW!"] = true;
+L["Darkness"] = true;
+L["This theme is for villains who take pride in their class"] = true;
+L["villains know how to reprezent!"] = true;
+L["This theme is for any villain who sticks to their traditions"] = true;
+L["you don't need fancyness to kick some ass!"] = true;
+L["Vintage"] = true;
+L["Layout"] = true;
+L["You can now choose what primary unitframe style you wish to use."] = true;
+L["This will change the layout of your unitframes (ie.. Player, Target, Pet, Party, Raid ...etc)."] = true;
+L["This layout is anything but minimal! Using this is like being at a rock concert"] = true;
+L["then annihilating the crowd with frickin lazer beams!"] = true;
+L["Super"] = true;
+L["This layout is for the villain who just wants to get things done!"] = true;
+L["But he still wants to see your face before he hits you!"] = true;
+L["Simple"] = true;
+L["Just the necessities so you can see more of the world around you."] = true;
+L["You dont need no fanciness getting in the way of world domination do you?"] = true;
+L["Compact"] = true;
+L["This has all the pizzaz of Super frames but uses Compact party and raid frames."] = true;
+L["Sometimes a little fifty-fifty goes a long way."] = true;
+L["Healer"] = true;
+L["Bar Setup"] = true;
+L["Choose a layout for your action bars."] = true;
+L["Sometimes you need big buttons, sometimes you don't. Your choice here."] = true;
+L["Lets keep it slim and deadly, not unlike a ninja sword."] = true;
+L["You dont ever even look at your bar hardly, so pick this one!"] = true;
+L["Small Row"] = true;
+L["Granted, you dont REALLY need the buttons due to your hotkey-leetness, you just like watching cooldowns!"] = true;
+L["Sure thing cowboy, your secret is safe with me!"] = true;
+L["Small X2"] = true;
+L["The better to PEW-PEW you with my dear!"] = true;
+L["When you have little time for mouse accuracy, choose this set!"] = true;
+L["Big Row"] = true;
+L["It's like dual-wielding two big reasons for your enemies to back the **** up!"] = true;
+L["Double your bars then double their size for maximum button goodness!"] = true;
+L["Big X2"] = true;
+L["Auras System"] = true;
+L["Select the type of aura system you want to use with SVUI's unitframes. The Icon Lovers set will display only icons and aurabars won't be used. The Vintage set will use the original game style and the Gimme Everything set does just what it says.... icons, bars and awesomeness."] = true;
+L["If you have an icon or aurabar that you don't want to display simply hold down shift and right click the icon for it to suffer a painful death."] = true;
+L["Vintage"] = true;
+L["Icon Lovers"] = true;
+L["The Works!"] = true;
+L["Installation Complete"] = true;
+L["Thats it! All done! Now we just need to hand these choices off to the henchmen so they can get you ready to (..insert evil tasks here..)!"] = true;
+L["Click the button below to reload and get on your way! Good luck villain!"] = true;
+L["THE_BUTTON_BELOW"] = "THE\nBUTTON\nBELOW";
+--[[UI TEXTS]]--
+L["Meanwhile"]=true;
+L["..at "]=true;
+L["A taint has occured that is preventing you from using the queue system. Please reload your user interface and try again."]=true;
+L["Binding"]="Belegung"
+L["Key"]="Taste"
+L["KEY_ALT"]="A"
+L["KEY_CTRL"]="C"
+L["KEY_DELETE"]="Del"
+L["KEY_HOME"]="Hm"
+L["KEY_INSERT"]="Ins"
+L["KEY_MOUSEBUTTON"]="M"
+L["KEY_MOUSEWHEELDOWN"]="MwD"
+L["KEY_MOUSEWHEELUP"]="MwU"
+L["KEY_NUMPAD"]="N"
+L["KEY_PAGEDOWN"]="PD"
+L["KEY_PAGEUP"]="PU"
+L["KEY_SHIFT"]="S"
+L["KEY_SPACE"]="SpB"
+L["No bindings set."]="Keine Belegungen gesetzt."
+L["Remove Bar %d Action Page"]='Entferne Leiste %d Aktion Seite'
+L["Trigger"]='Auslöser'
+L["Delete Grays"]="Graue löschen"
+L["Hold Control + Right Click:"]='Halte Steuerung + Rechtsklick:'
+L["Hold Shift + Drag:"]='Halte Shift + Bewege die Maus:'
+L["Hold Shift:"]="Halte Shift"
+L["Purchase"]="Kaufen"
+L["Reset Position"]='Position zurücksetzen'
+L["Sort Bags"]="Taschen sortieren"
+L["Sort Tab"]=true;
+L["Stack Bags to Bank"]='Staple Gegenstände von den Taschen in die Bank'
+L["Stack Bank to Bags"]='Staple Gegenstände von der Bank in die Taschen'
+L["Stack Items"]="Staple Gegenstände"
+L["Temporary Move"]='Temporäres Bewegen'
+L["Toggle Bags"]='Taschen umschalten'
+L["Vendor Grays"]="Graue Gegenstände verkaufen"
+L["AFK"]="AFK"
+L["DND"]='DND'
+L["G"]="G"
+L["I"]="I"
+L["IL"]="IL"
+L["Invalid Target"]='Ungültiges Ziel'
+L["O"]="O"
+L["P"]="P"
+L["PL"]="PL"
+L["R"]="R"
+L["RL"]="RL"
+L["RW"]="RW"
+L["says"]='sagen'
+L["whispers"]='flüstern'
+L["yells"]='schreien'
+L["(Hold Shift) Memory Usage"]="(Shift gedrückt) Speichernutzung"
+L["AP"]="AP"
+L["AVD: "]="AVD: "
+L["Avoidance Breakdown"]="Vermeidung Aufgliederung"
+L["Bandwidth"]="Bandbreite"
+L["Bases Assaulted"]='Stützpunkte eingenommen'
+L["Bases Defended"]='Stützpunkte verteidigt'
+L["Carts Controlled"]='Karten kontrolliert'
+L["Character: "]="Charakter: "
+L["Chest"]="Brust"
+L["Combat Time"]="Kampfzeit"
+L["copperabbrev"]="|cffeda55fc|r"
+L["Defeated"]='Besiegt'
+L["Deficit:"]="Defizit:"
+L["Demolishers Destroyed"]='Verwüster zerstört'
+L["Download"]='Download'
+L["DPS"]="DPS"
+L["Earned:"]="Verdient:"
+L["Feet"]="Füße"
+L["Flags Captured"]='Flaggen eingenommen'
+L["Flags Returned"]='Flaggen zurückgeholt'
+L["Friends List"]="Freundesliste"
+L["Friends"]="Freunde"
+L["Galleon"]='Galleon'
+L["Gates Destroyed"]='Tore zerstört'
+L["goldabbrev"]="|cffffd700g|r"
+L["Graveyards Assaulted"]='Friedhöfe angegriffen'
+L["Graveyards Defended"]='Friedhöfe verteidigt'
+L["Hands"]="Hände"
+L["Head"]="Kopf"
+L["Hit"]="Hit"
+L["Home Latency:"]="Standort Latenz"
+L["HP"]="HP"
+L["HPS"]="HPS"
+L["Legs"]="Beine"
+L["lvl"]="lvl"
+L["Main Hand"]="Waffenhand"
+L["Mitigation By Level: "]="Milderung durch Stufe:"
+L["Nalak"]='Nalak, der Sturmfürst'
+L["No Guild"]='Keine Gilde'
+L["Offhand"]="Schildhand"
+L["Oondasta"]='Oondasta'
+L["Orb Possessions"]='Erhaltene Kugeln'
+L["Profit:"]="Gewinn:"
+L["Reset Data: Hold Shift + Right Click"]="Daten zurücksetzen: Halte Shift + Rechtsklick"
+L["Saved Raid(s)"]="Gespeicherte Schlachtzüge"
+L["Server: "]="Server: "
+L["Session:"]="Sitzung:"
+L["Sha of Anger"]='Sha des Zorns'
+L["Shoulder"]="Schulter"
+L["silverabbrev"]="|cffc7c7cfs|r"
+L["SP"]="SP"
+L["Spent:"]="Ausgegeben:"
+L["Stats For:"]='Stats Für:'
+L["Total CPU:"]="Gesamt CPU:"
+L["Total Memory:"]="Gesamte Speichernutzung:"
+L["Total: "]="Gesamt: "
+L["Towers Assaulted"]='Türme angegriffen'
+L["Towers Defended"]='Türme verteidigt'
+L["Undefeated"]='Unbesiegt'
+L["Unhittable:"]="Unhittable:"
+L["Victory Points"]='Siegpunkte'
+L["Waist"]="Taille"
+L["World Boss(s)"]="Weltboss(e)"
+L["Wrist"]="Handgelenke"
+L["%s: %s tried to call the protected function '%s'."]="%s: %s versucht die geschützte Funktion aufrufen '%s'."
+L["No locals to dump"]="Keine Lokalisierung zum verwerfen"
+L["%s is attempting to share his filters with you. Would you like to accept the request?"]='%s möchte seine Filter Einstellungen mit dir teilen. Möchtest du die Anfrage annehmen?'
+L["%s is attempting to share the profile %s with you. Would you like to accept the request?"]='%s versucht das Profil %s mit dir zu teilen. Möchtest du die Anfrage annehmen?'
+L["Data From: %s"]="Datei von: %s"
+L["Filter download complete from %s, would you like to apply changes now?"]='Filter komplett heruntergeladen von %s, möchtest du die änderungen nun vornehmen?'
+L["Lord! It's a miracle! The download up and vanished like a fart in the wind! Try Again!"]="Herr! Es ist ein Wunder! Der Download verschwand wie ein Furz im Wind! Versuche es nochmal!"
+L["Profile download complete from %s, but the profile %s already exists. Change the name or else it will overwrite the existing profile."]='Profil komplett heruntergeladen von %s, allerdings ist das Profil %s bereits vorhanden. Ändere den Namen oder das bereits existierente Profil wird überschrieben.'
+L["Profile download complete from %s, would you like to load the profile %s now?"]='Profil komplett heruntergeladen von %s, möchtest du das profil %s nun laden?'
+L["Profile request sent. Waiting for response from player."]='Profil Anfrage gesendet. Warte auf die Antwort des Spielers.'
+L["Request was denied by user."]='Die Anfrage wurde vom Benutzer abgelehnt.'
+L["Your profile was successfully recieved by the player."]='Dein Profil wurde erfolgreich von dem Spieler empfangen.'
+L["Auras Set"]="Auren gesetzt"
+L["Auras System"]="Auren System"
+L["Caster DPS"]="Fernkampf DD"
+L["Chat Set"]="Chat gesetzt"
+L["Chat"]="Chat"
+L["Choose a theme layout you wish to use for your initial setup."]='Wähle ein Layout, welches du bei deinem ersten Setup verwenden möchtest.'
+L["Vintage"]='Klassisch'
+L["Classic"]='Klassisch'
+L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."]="Klicke auf die Taste unten um die Größe deiner Chatfenster, Einheitenfenster und die Umpositionierung deiner Aktionsleisten durchzuführen."
+L["Config Mode:"]='Konfigurationsmodus:'
+L["CVars Set"]="CVars gesetzt"
+L["CVars"]="CVars"
+L["Gloom & Doom"]='Dunkel'
+L["Disable"]="Deaktivieren"
+L["SVUI Installation"]="SVUI Installation"
+L["Finished"]="Beendet"
+L["Grid Size:"]="Rastergröße:"
+L["Healer"]="Heiler"
+L["High Resolution"]="Hohe Auflösung"
+L["high"]="hoch"
+L["Icons Only"]='Nur Symbole'
+L["If you have an icon or aurabar that you don't want to display simply hold down shift and right click the icon for it to disapear."]="Wenn du ein Symbol oder eine Aurenleiste nicht angezeigt haben willst, dann halte Shift gedrückt und klicke mit Rechtsklick auf das Symbol um es auszublenden."
+L["Importance: |cff07D400High|r"]="Bedeutung: |cff07D400Hoch|r"
+L["Importance: |cffD3CF00Medium|r"]="Bedeutung: |cffD3CF00Mittel|r"
+L["Importance: |cffFF0000Low|r"]="Bedeutung: |cffD3CF00Niedrig|r"
+L["Installation Complete"]="Installation komplett"
+L["Integrated"]='Integriert'
+L["Layout Set"]="Layout gesetzt"
+L["Layout"]="Layout"
+L["Lock"]="Sperren"
+L["Low Resolution"]='Niedrige Auflösung'
+L["low"]="niedrig"
+L["Frames unlocked. Move them now and click Lock when you are done."]="Ankerpunkte entriegelt. Bewege die Ankerpunkte und klicke 'sperren', wenn du fertig bist."
+L["Nudge"]=true;
+L["Physical DPS"]="Physische DPS"
+L["Pixel Perfect Set"]="Pixel Perfekt aktivieren"
+L["Pixel Perfect"]='Pixel Perfekt'
+L["Please click the button below so you can setup variables and ReloadUI."]="Bitte klicke die Taste unten um den Installationsprozess abzuschließen und das Benutzerinterface neu zu laden."
+L["Please click the button below to setup your CVars."]="Klicke 'Installiere CVars' um die CVars einzurichten."
+L["Please press the continue button to go onto the next step."]="Bitte drücke die Weiter-Taste um zum nächsten Schritt zu gelangen."
+L["Resolution Style Set"]="Auflösungsart gesetzt"
+L["Resolution"]="Auflösung"
+L["Select the type of aura system you want to use with SVUI's unitframes. The integrated system utilizes both aura-bars and aura-icons. The icons only system will display only icons and aurabars won't be used. The classic system will configure your auras to be default."]="Wähle einen Typ von Auren System den du mit den SVUI Einheitenfenstern benutzen willst. Das Integrierte System nutzt beides Auren Leisten und Auren Symbole. Das Symbol System nutzt nur Symbole und keinerlei Aurenleisten. Das Klassische System wird deine Auren zum Standard konfigurieren."
+L["Setup Chat"]="Chateinstellungen"
+L["Setup CVars"]="Installiere CVars"
+L["Skip Process"]="Schritt überspringen"
+L["Sticky Frames"]="Anheftende Fenster"
+L["Tank"]="Tank"
+L["The chat windows function the same as Blizzard standard chat windows, you can right click the tabs and drag them around, rename, etc. Please click the button below to setup your chat windows."]="Die Chatfensterfunktionen sind die gleichen, wie die Chatfenster von Blizzard. Du kannst auf die Tabs rechtsklicken und sie z.B. neu zu positionieren, umzubenennen, etc. Bitte klicke den Button unten um das Chatfenster einzurichten."
+L["The in-game configuration menu can be accesses by typing the /sv command or by clicking the 'C' button on the minimap. Press the button below if you wish to skip the installation process."]="Das SVUI-Konfigurationsmenü kannst du entweder mit /sv oder durch das Anklicken der 'C' Taste an der Minimap aufrufen. Drücke 'Schritt überspringen' um zum nächsten Schritt zu gelangen."
+L["The Pixel Perfect option will change the overall apperance of your UI. Using Pixel Perfect is a slight performance increase over the traditional layout."]='Die Pixel-Perfekt-Option wird das allgemeine Erscheinungsbild verändern. Das Verwenden von Pixel Perfekt bringt eine kleine Leistungssteigerung gegenüber dem Standard Layout'
+L["Theme Set"]='Thema gesetzt'
+L["Theme Setup"]='Thema Setup'
+L["This install process will help you learn some of the features in SVUI has to offer and also prepare your user interface for usage."]="Dieser Installationsprozess wird dir helfen, die Funktionen von SVUI für deine Benutzeroberfläche besser kennenzulernen."
+L["This is completely optional."]="Das ist komplett Optional."
+L["This part of the installation process sets up your chat windows names, positions and colors."]="Dieser Abschnitt der Installation stellt die Chat Fenster Namen, Positionen und Farben ein."
+L["This part of the installation process sets up your World of Warcraft default options it is recommended you should do this step for everything to behave properly."]="Dieser Installationsprozess richtet alle wichtigen Cvars deines World of Warcrafts ein, um eine problemlose Nutzung zu ermöglichen."
+L["This resolution doesn't require that you change settings for the UI to fit on your screen."]="Diese Auflösung benötigt keine Änderungen um mit der Benutzeroberfläche zu funktionieren."
+L["This resolution requires that you change some settings to get everything to fit on your screen."]="Diese Auflösung benötigt Änderungen um mit der Benutzeroberfläche zu funktionieren."
+L["This will change the layout of your unitframes, raidframes, and statistics."]="Dies wird das Layout der Einheitenfenster, Schlachtzugsfenster und Infotexte ändern"
+L["Trade"]='Handel'
+L["Using this option will cause your borders around frames to be 1 pixel wide instead of 3 pixel. You may have to finish the installation to notice a differance. By default this is enable."]='Mit dieser Option kannst du den Rahmen um die Fenster von 1 Pixel auf 3 Pixel vergrößern. Du solltest die Installation abschließen um einen Unterschied zu sehen. Die Option ist standardmäßig deaktiviert'
+L["Welcome to SVUI version %s!"]="Willkommen bei SVUI Version %s!"
+L["You are now finished with the installation process. If you are in need of technical support please visit us at http://www.wowinterface.com."]="Du hast den Installationsprozess abgeschlossen. Solltest du technische Hilfe benötigen, besuche uns auf http://www.wowinterface.com."
+L["You can always change fonts and colors of any element of SVUI from the in-game configuration."]='Du kannst jederzeit in der Ingame-Konfiguration Schriften und Farben von jedem Element des Interfaces ändern.'
+L["You can now choose what layout you wish to use based on your combat role."]="Du kannst nun auf Basis deiner Rolle im Kampf ein Layout wählen."
+L["You may need to further alter these settings depending how low you resolution is."]="Unter Umständen musst du, je nachdem wie niedrig deine Auflösung ist, diese Einstellungen ändern."
+L["Your current resolution is %s, this is considered a %s resolution."]="Deine Aktuelle Auflösung ist %s, diese wird als eine %s Auflösung angesehen."
+L["Bars"]='Leisten'
+L["Calendar"]=true;
+L["Can't Roll"]="Es kann nicht gewürfelt werden."
+L["Disband Group"]="Gruppe auflösen"
+L["Empty Slot"]="Leerer Platz"
+L["Enable"]="Eingeschaltet"
+L["Experience"]="Erfahrung"
+L["Fishy Loot"]="Faule Beute"
+L["Left Click:"]="Linksklick:"
+L["Raid Menu"]="Schlachtzugsmenü"
+L["Remaining:"]="Verbleibend:"
+L["Rested:"]="Ausgeruht:"
+L["Right Click:"]="Rechtsklick:"
+L["Show BG Texts"]='Zeige Schlachtfeldtexte'
+L["Toggle Chat Frame"]="Chatfenster an-/ausschalten"
+L["Toggle Configuration"]='Konfiguration umschalten'
+L["XP:"]="EP:"
+L["You don't have permission to mark targets."]="Du hast keine Rechte um ein Ziel zu markieren."
+L["ABOVE_THREAT_FORMAT"]='%s: %.0f%% [%.0f%% above |cff%02x%02x%02x%s|r]'
+L[" Frames"]=" Fenster"
+L["Alternative Power"]="Alternative Energie"
+L["Arena Frames"]="Arena Fenster"
+L["Auras Frame"]="Aurenfenster"
+L["Bags"]="Taschen"
+L["Bar "]="Leiste "
+L["BNet Frame"]="BNet-Fenster"
+L["Special Ability Button"]="Special Ability Button"
+L["Boss Frames"]="Boss Fenster"
+L["Experience Bar"]="Erfahrungsleiste"
+L["Focus Castbar"]="Fokus Zauberbalken"
+L["Focus Frame"]="Fokusfenster"
+L["FocusTarget Frame"]="Fokus-Ziel Fenster"
+L["GM Ticket Frame"]="GM-Ticket-Fenster"
+L["Left Dock"]="Linker Chat"
+L["Loot / Alert Frames"]="Beute-/Alarmfenster"
+L["Loot Frame"]="Beutefenster"
+L["Loss Control Icon"]="Kontrollverlustsymbol"
+L["MA Frames"]="MA-Fenster"
+L["Micromenu"]="Mikroleiste"
+L["Minimap"]='Minimap'
+L["MT Frames"]="MT-Fenster"
+L["Party Frames"]="Gruppenfenster"
+L["Pet Bar"]="Begleisterleiste"
+L["Pet Frame"]="Begleiterfenster"
+L["PetTarget Frame"]="Begleiter-Ziel Fenster"
+L["Player Castbar"]="Spieler Zauberbalken"
+L["Player Frame"]="Spielerfenster"
+L["Raid 1-"]="Schlachtzug 1-"
+L["Reputation Bar"]="Rufleiste"
+L["Right Dock"]="Rechter Chat"
+L["Stance Bar"]="Haltungsleiste"
+L["Target Castbar"]="Ziel Zauberbalken"
+L["Target Frame"]="Zielfenster"
+L["TargetTarget Frame"]="Ziel des Ziels Fenster"
+L["Tooltip"]="Tooltip"
+L["Totems"]="Totems"
+L["Vehicle Seat Frame"]="Fahrzeugfenster"
+L["Watch Frame"]="Beobachtungsfenster"
+L["Weapons"]="Waffen"
+L["Discipline"]="Disziplin"
+L["Holy"]="Heilig"
+L["Mistweaver"]='Nebelwirker'
+L["Restoration"]="Wiederherstellung"
+L[" |cff00ff00bound to |r"]=" |cff00ff00gebunden zu |r"
+L["%s frame(s) has a conflicting anchor point, please change either the buff or debuff anchor point so they are not attached to each other. Forcing the debuffs to be attached to the main unitframe until fixed."]="Es liegt ein Konflikt bei den Ankerpunkten des Rahmens %s vor. Bitte ändere entweder den Ankerpunkt des Stärkungs- oder Schwächungszaubers, damit diese nicht länger mit einander verbunden sind. Verbinde die Schwächungszauber mit dem Hauptrahmen, damit dieses Problem behoben wird."
+L["All keybindings cleared for |cff00ff00%s|r."]="Alle Tastaturbelegungen gelöscht für |cff00ff00%s|r."
+L["Already Running.. Bailing Out!"]='Bereits ausgeführt..Warte ab!'
+L["Battleground statistics temporarily hidden, to show type /bgstats."]='Schlachtfeld-Infotexte sind kurzzeitig versteckt, um sie wieder anzuzeigen tippe /bgstats oder rechtsklicke auf das "C" Symbol nahe der Minimap.'
+L["Battleground statistics will now show again if you are inside a battleground."]='Schlachtfeld-Infotexte werden wieder angezeigt, solange du dich in einem Schlachtfeld befindest.'
+L["Binds Discarded"]="Tastaturbelegungen verworfen"
+L["Binds Saved"]="Tastaturbelegungen gespeichert"
+L["Confused.. Try Again!"]='Verwirrt.. Versuche es erneut!'
+L["Deleted %d gray items. Total Worth: %s"]="Es wurden %d graue Gegenstände gelöscht. Gesamtwert: %s"
+L["No gray items to delete."]="Es sind keine grauen Gegenstände zum Löschen vorhanden."
+L["No gray items to sell."]="Keine grauen Gegenstände zum Verkaufen vorhanden."
+L["The spell '%s' has been added to the BlackList unitframe aura filter."]='Der Zauber "%s" wurde zur schwarzen Liste der Einheitenfenster hinzugefügt.'
+L["Vendored gray items for:"]="Graue Gegenstände verkauft für:"
+L["You don't have enough money to repair."]="Du hast nicht genügend Gold für die Reparatur."
+L["You must be at a vendor."]="Du musst bei einem Händler sein."
+L["Your items have been repaired for: "]="Deine Gegenstände wurden repariert für: "
+L["Your items have been repaired using guild bank funds for: "]="Deine Gegenstände wurden repariert. Die Gildenbank kostete das: "
+L["Your version of SVUI is out of date. You can download the latest version from http://www.wowinterface.com"]="Deine Version von SVUI ist veraltet. Du kannst die aktuelle Version von http://www.wowinterface.com laden"
+L["|cFFE30000Lua error recieved. You can view the error message when you exit combat."]='|cFFE30000Lua Fehler erhalten. Du kannst die Fehlermeldung ansehen, wenn du den Kampf verlässt.'
+L["A setting you have changed will change an option for this character only. This setting that you have changed will be uneffected by changing user profiles. Changing this setting requires that you reload your User Interface."]="Eine Einstellung, die du geändert hast, betrifft nur einen Charakter. Diese Einstellung, die du verändert hast, wird die Benutzerprofile unbeeinflusst lassen. Eine Änderung dieser Einstellung erfordert, dass du dein Interface neu laden musst."
+L["Are you sure you want to delete all your gray items?"]="Bist du sicher, dass du alle grauen Gegenstände löschen willst?"
+L["Are you sure you want to disband the group?"]="Bist Du Dir sicher, dass du die Gruppe auflösen willst?"
+L["Are you sure you want to reset every mover back to it's default position?"]="Bist du dir sicher, dass du jeden Beweger an die Standard-Position zurücksetzen möchtest?"
+L["Because of the mass confusion caused by the new aura system I've implemented a new step to the installation process. This is optional. If you like how your auras are setup go to the last step and click finished to not be prompted again. If for some reason you are prompted repeatedly please restart your game."]="Aufgrund der großen Verwirrung, die durch das neue Auren-System verursacht wurde, habe ich einen neuen Schritt zum Installationsprozess hinzugefügt. Dieser ist optional. Wenn du deine Auren so eingestellt lassen willst, wie sie sind, gehe einfach zum letzten Schritt und klicke auf fertig um nicht erneut aufgefordert zu werden. Wirst du, aus welchen Grund auch immer, öfter aufgefordert, starte bitte dein Spiel neu"
+L["Can't buy anymore slots!"]="Kann keine Slots mehr kaufen"
+L["Disable Warning"]='Deaktiviere Warnung'
+L["Discard"]="Verwerfen"
+L["Do you swear not to post in technical support about something not working without first disabling the addon/package combination first?"]='Schwörst du, dass du keinen Beitrag im Supportforum posten wirst, ohne vorher alle anderen Addons/Package zu deaktivieren?'
+L["Hover your mouse over any actionbutton or spellbook button to bind it. Press the escape key or right click to clear the current actionbutton's keybinding."]="Bewege deine Maus über einen Aktionsbutton oder dein Zauberbuch um ihn mit einem Hotkey zu belegen. Drücke Escape oder rechte Maustaste um die aktuelle Tastenbelegung des Buttons zu löschen."
+L["I Swear"]='Ich schwöre'
+L["Oh lord, you have got SVUI and Tukui both enable at the same time. Select an addon to disable."]=true;
+L["One or more of the changes you have made require a ReloadUI."]="Eine oder mehrere Einstellungen, die du vorgenommen hast, benötigen ein Neuladen des Benutzerinterfaces um in Effekt zu treten."
+L["One or more of the changes you have made will effect all characters using this addon. You will have to reload the user interface to see the changes you have made."]="Eine oder mehrere Änderungen, die du getroffen hast, betrifft alle Charaktere die dieses Addon benutzen. Du musst das Benutzerinterface neu laden um die Änderungen, die du durchgeführt hast, zu sehen."
+L["Save"]="Speichern"
+L["Using the healer layout it is highly recommended you download the addon Clique if you wish to have the click-to-heal function."]=true;
+L["You have changed the pixel perfect option. You will have to complete the installation process to remove any graphical bugs."]="Du hast die Pixel-Perfekt-Option geändert. Du solltest nun den Installationsprozess beenden um mögliche grafische Fehler zu beseitigen."
+L["You have changed your UIScale, however you still have the AutoScale option enable in SV. Press accept if you would like to disable the Auto Scale option."]="Du hast die Skalierung des benutzerinterfaces geändert, während du die automatische Skalierung in SVUI aktiv hast. Drücke Annehmen um die automatische Skalierung zu deaktivieren."
+L["You must purchase a bank slot first!"]="Du musst erst ein Bankfach kaufen!"
+L["Count"]="Zähler"
+L["Targeted By:"]="Ziel von:"
+L["A raid marker feature is available by pressing Escape -> Keybinds scroll to the bottom under SVUI and setting a keybind for the raid marker."]='Ein Feature für Schlachtzugsmarkierung ist verfügbar, wenn du Escape drückst und Tastaturbelegung wählst, scrolle anschließend bis unter die Kategorie SVUI und wähle eine Tastenbelegung für die Schlachtzugsmarkierung.'
+L["SVUI has a dual spec feature which allows you to load different profiles based on your current spec on the fly. You can enable this from the profiles tab."]='SVUI hat ein Feature für Dualspezialisierungen, welches dich abhängig von deiner momentanen Spezialisierung verschiedene Profile laden lässt. Dieses Feature kannst du im Abschnitt Profil aktivieren.'
+L["For technical support visit us at http://www.wowinterface.com."]='Für technische Hilfe besuche uns unter http://www.wowinterface.com.'
+L["If you accidently remove a chat frame you can always go the in-game configuration menu, press install, go to the chat portion and reset them."]='Wenn du ausversehen das Chatfenster entfernen solltest, kannst du ganz einfach in die Ingame-Konfiguration gehen und den Installationsprozess erneut aufrufen. Drücke Installieren und gehe zu den Chateinstellungen und setze diese zurück.'
+L["If you are experiencing issues with SVUI try disabling all your addons except SVUI, remember SVUI is a full UI replacement addon, you cannot run two addons that do the same thing."]='Wenn du Probleme mit SVUI hast, deaktiviere alle Addons außer SV. Denke auch daran, dass SVUI die komplette Benutzeroberfläche ersetzt, d.h. du kannst kein Addon verwenden, welches die gleichen Funktionen wie SVUI nutzt.'
+L["The buff panel to the right of minimap is a list of your consolidated buffs. You can disable it in Buffs and Debuffs options of SV."]='Die Stärkungszauberleiste rechts neben der Minimap ist eine Liste der zusammengefassten Stärkungszauber. Du kannst diese in den Stärkungs- und Schwachungszauber-Optionen in SVUI deaktivieren.'
+L["The focus unit can be set by typing /focus when you are targeting the unit you want to focus. It is recommended you make a macro to do this."]='Du kannst, während du ein Ziel hast, das Fokusfenster durch die Eingabe von /fokus setzen. Es wird empfohlen ein Makro dafür zu nutzen.'
+L["To move abilities on the actionbars by default hold shift + drag. You can change the modifier key from the actionbar options menu."]='Um Fähigkeiten auf der Aktionsleiste zu verschieben nutze Shift und bewege zeitgleich die Maus. Du kannst die Modifier-Taste im Aktionsleistenmenü umstellen.'
+L["To setup which channels appear in which chat frame, right click the chat tab and go to settings."]='Um einzustellen welcher Kanal im welchem Chatfenster angezeigt werden soll, klicke rechts auf das Chattab und gehe auf Einstellungen.'
+L["Using the /farmmode <size> command will spawn a larger minimap on your screen that can be moved around, very useful when farming."]='Benutze das /farmmode <Größe> Kommando um eine größere Minimap auf dem Bildschirm erscheinen zu lassen, die sich verschieben lässt. Sehr nützlich zum Farmen.'
+L["You can access copy chat and chat menu functions by mouse over the top right corner of chat panel and left/right click on the button that will appear."]='Du kannst die Funktionen Chat Kopieren und Chatmenü aufrufen, wenn du die Maus in die obere rechte Ecke des Chatfensters bewegst und links-/rechtsklickst.'
+L["You can see someones average item level of their gear by holding shift and mousing over them. It should appear inside the tooltip."]='Du kannst die durchschnittliche Gegenstandsstufe von jemanden sehen, wenn du bei gedrückter Shift-Taste mit der Maus über ihn fährst. Die Gegenstandsstufe wird dann im Tooltip angezeigt.'
+L["You can set your keybinds quickly by typing /kb."]='Du kannst deine Tastaturbelegung schnell ändern, wenn du /kb eintippst.'
+L["You can toggle the microbar by using your middle mouse button on the minimap you can also accomplish this by enabling the actual microbar located in the actionbar settings."]='Du kannst die Mikroleiste durch mittleren Mausklick auf der Minimap aufrufen oder auch die tatsächliche Mikroleiste in den Aktionsleisten Optionen aktivieren.'
+L["You can use the /resetui command to reset all of your moveables. You can also use the command to reset a specific mover, /resetui <mover name>.\nExample: /resetui Player Frame"]='Du kannst durch benutzen von /resetui alle Ankerpunkte zurücksetzen. Du kannst das Kommando auch benutzen um spezielle Anker zurückzusetzen, /resetui <Anker Name>.\nBeispiel: /resetui Player Frame'
+L["Ghost"]="Geist"
+L["Offline"]="Offline"
+L["ENH_LOGIN_MSG"]="Sie verwenden |cff1784d1SVUI Enhanced|r Version %s%s|r."
+L["Your version of SVUI is to old. Please, download the latest version from http://www.wowinterface.com."]="Ihre Version von SVUI ist zu alt (erforderlich v6.51 oder höher). Bitte laden Sie die neueste Version von http://www.wowinterface.com."
+L["Equipment"]="Ausrüstung"
+L["EQUIPMENT_DESC"]="Passen Sie die Einstellungen für das Ändern Ihrer Ausrüstung an, wenn Sie Ihre Talentspezialisierung ändern oder ein Schlachtfeld betreten."
+L["No Change"]="Keine Änderung"
+L["Specialization"]="Talentspezialisierung"
+L["Enable/Disable the specialization switch."]="Automatische Änderung der Ausrüstung beim Talentwechsel aktivieren / deaktivieren."
+L["Primary Talent"]="Primäre Talentspezialisierung"
+L["Choose the equipment set to use for your primary specialization."]="Wählen Sie das Ausrüstungsset für Ihre primäre Talentspezialisierung."
+L["Secondary Talent"]="Sekundäre Talentspezialisierung"
+L["Choose the equipment set to use for your secondary specialization."]="Wählen Sie das Ausrüstungsset für Ihre sekundäre Talentspezialisierung."
+L["Battleground"]="Schlachtfeld"
+L["Enable/Disable the battleground switch."]="Automatische Änderung der Ausrüstung beim Betreten eines Schlachtfelds aktivieren / deaktivieren."
+L["Equipment Set"]="Ausrüstungsset"
+L["Choose the equipment set to use when you enter a battleground or arena."]="Wählen Sie Ihr Ausrüstungsset für Schlachtfelder oder die Arena."
+L["You have equipped equipment set: "]="Sie haben das folgende Ausrüstungsset angelegt: "
+L["DURABILITY_DESC"]="Passen Sie die Einstellungen für die Haltbarkeit im Charakterfenster an."
+L["Enable/Disable the display of durability information on the character screen."]="Anzeige der Haltbarkeit im Charakterfenster."
+L["Damaged Only"]="Nur Beschädigte"
+L["Only show durabitlity information for items that are damaged."]="Nur die Haltbarkeit für beschädigte Ausrüstungsteile anzeigen."
+L["ITEMLEVEL_DESC"]="Passen Sie die Einstellungen für die Anzeige von Gegenstandsstufen im Charakterfenster an."
+L["Enable/Disable the display of item levels on the character screen."]="Anzeige von Gegenstandsstufen im Charakterfenster aktivieren / deaktivieren."
+L["Miscellaneous"]="Verschiedenes"
+L["Equipment Set Overlay"]='Ausrüstungssettext'
+L["Show the associated equipment sets for the items in your bags (or bank)."]='Zeige auf Gegenständen im Rucksack (oder der Bank) die zugehörigen Ausrüstungssets als Text an.'
+L["Layout Transparency"]="Transparenz Ankerpunkte"
+L["Changes the transparency of all the moveables."]="Konfiguriere die Einstellungen der Transparenz der Ankerpukte"
+L["Automatic Role Assignment"]='Automatische Rollenzuweisung'
+L["Enables the automatic role assignment based on specialization for party / raid members (only work when you are group leader or group assist)."]='Aktiviert die automatische Rollenzuweisung basierend auf der Talentspezialisierung der Gruppen- oder Schlachtzugsmitglieder. Funktioniert nur, wenn Sie Gruppenleiter oder -assistent sind.'
+L["Hide Role Icon in combat"]='Verstecke Rollensymbol im Kampf'
+L["All role icons (Damage/Healer/Tank) on the unit frames are hidden when you go into combat."]='Alle Rollensymbole (Schaden/Heiler/Tank) auf den Einheitenfenstern werden versteckt, wenn der Charakter sich im Kampf befindet.'
+L["Show the direction and distance to the selected party or raid member."]="Zeige die Richtung und Entfernung zum ausgewählten Gruppen- oder Schlachtzugsmitglied an."
+L["Attack Icon"]='Angriffssymbol'
+L["Show attack icon for units that are not tapped by you or your group, but still give kill credit when attacked."]='Zeige Angriffssymbol für Gegner, die noch nicht von Ihnen markiert, aber trotzdem Belohnungen gewähren, wenn sie von Ihnen angegriffen werden'
+L["Show class icon for units."]='Zeige Klassensymbole für Einheiten'
+L["Above Minimap"]="Oberhalb der Minimap"
+L["Location Digits"]="Koordinaten Nachkommastellen"
+L["Number of digits for map location."]="Anzahl der Nachkommastellen der Koordinaten."
+L["Hide minimap while in combat."]="Ausblenden der Minimap während des Kampfes."
+L["FadeIn Delay"]="Einblendungsverzögerung"
+L["The time to wait before fading the minimap back in after combat hide. (0 = Disabled)"]="Die Zeit vor dem wieder Einblenden der Minimap nach dem Kampf. (0 = deaktiviert)"
+L["Style Buttons"]="Style Buttons"
+L["Customize the minimap buttons in SVUI style."]='Stylene die Minimap-Buttons im SVUI-Stil.'
+L["SVUI Style"]="Style Stil"
+L["Change settings for how the minimap buttons are styled."]="Ändern der Einstellungen, wie die Minimap-Buttons gestylent werden."
+L["The size of the minimap buttons."]="Die Größe der Minimap-Buttons."
+L["No Anchor Bar"]="Keine Ankerleiste"
+L["Horizontal Anchor Bar"]="Horizontale Ankerleiste"
+L["Vertical Anchor Bar"]="Vertikale Ankerleiste"
+L["Layout Direction"]=true;
+L["Normal is right to left or top to bottom, or select reversed to switch directions."]=true;
+L["Normal"]=true;
+L["Reversed"]=true;
+L["PvP Autorelease"]="Automatische Freigabe im PvP"
+L["Automatically release body when killed inside a battleground."]="Gibt automatisch Ihren Geist frei, wenn Sie auf dem Schlachtfeld getötet wurden."
+L["Track Reputation"]="Ruf beobachten"
+L["Automatically change your watched faction on the reputation bar to the faction you got reputation points for."]="Ändere automatisch die beobachtete Fraktion auf der Erfahrungsleiste zu der Fraktion für die Sie grade Rufpunkte erhalten haben."
+L["Select Quest Reward"]='Wähle Questbelohnung'
+L["Automatically select the quest reward with the highest vendor sell value."]='Wählt automatisch die Questbelohnung mit dem höchsten Wiederverkaufswert beim Händler'
+L["Item Level"]='Gegenstandsstufe'
+L["Target Range"]='Zielabstand'
+L["Distance"]='Entfernung'
+L["Actionbar1DataPanel"]='Aktionsleiste 1'
+L["Actionbar3DataPanel"]='Aktionsleiste 3'
+L["Actionbar5DataPanel"]='Aktionsleiste 5'
+L["Sunsong Ranch"]='Gehöft Sonnensang'
+L["The Halfhill Market"]='Der Halbhügelmarkt'
+L["Tilled Soil"]='Gepflügtes Erdreich'
+L["Right-click to drop the item."]='Mit der rechten Maustaste klicken, um den Gegenstand abzulegen.'
+L["Toolbox"]='Landwirt'
+L["COMIX_DESC"]="Toggle the comic popups during combat"
+L["FARMING_MODE_DESC"]='Einstellungen für alle Werkzeuge, die Sie effizienter auf Gehöft Sonnensang arbeiten lassen.'
+L["SNACKS_DESC"]=""
+L["Toolbox Bars"]='Landwirt Aktionsleisten'
+L["Toolbox Portal Bar"]='Landwirt Portalleiste'
+L["Toolbox Seed Bar"]='Landwirt Saatleiste'
+L["Toolbox Tools Bar"]='Landwirt Werkzeugleiste'
+L["Enable/Disable the laborer bars."]='Aktivieren / Deaktivieren der Landwirtleisten'
+L["Only active buttons"]='Nur aktive Buttons'
+L["Only show the buttons for the seeds, portals, tools you have in your bags."]='Nur Buttons für Saat, Portale und Werkzeuge anzeigen, wenn diese in Ihrem Rucksack vorhanden sind.'
+L["Drop Tools"]='Werkzeuge ablegen'
+L["Automatically drop tools from your bags when leaving the farming area."]='Beim Verlassen der Farm automatisch die Werkzeuge zerstören.'
+L["Seed Bar Direction"]='Richtung Saatleiste'
+L["The direction of the seed bar buttons (Horizontal or Vertical)."]='Die Ausbreitungsrichtung der Saatleiste (horizontal oder vertikal)'
+L["Threat Text"]="Bedrohungstext"
+L["Display threat level as text on targeted, boss or mouseover nameplate."]=" Bedrohung als Text auf der Namensplakette des Ziels anzeigen."
+L["Target Count"]="Zähler für Angreifende"
+L["Display the number of party / raid members targetting the nameplate unit."]="Anzahl der Gruppenmitglieder die den Gegner der Namensplakette angreifen."
+L["Heal Glow"]='Heilungsleuchten'
+L["Direct AoE heals will let the unit frames of the affected party / raid members glow for the defined time period."]='Direkte AoE-Heilungen lassen die Einheitenfenster von Gruppen- oder Schlachtzugsmitgliedern für eine festgelegte Zeit leuchten.'
+L["Glow Duration"]='Richtung des Leuchtens'
+L["The amount of time the unit frames of party / raid members will glow when affected by a direct AoE heal."]="Die Zeitdauer die Einheitenfenster von Gruppen- oder Schlachtzugsmitgliedern leuchten, wenn diese durch direkte AoE-Heilungen betroffen sind."
+L["Glow Color"]='Farbe des Leuchtens'
+L["Raid Marker Bar"]="Leiste Schlachtzugsymbole"
+L["Display a quick action bar for raid targets and world markers."]="Aktionsleiste für Schlachtzugsymbole und Weltmarkierungen anzeigen."
+L["Modifier Key"]="Modifizierungstaste"
+L["Set the modifier key for placing world markers."]="Modifizierungstaste für die Platzierung von Weltmarkierungen einstellen."
+L["Shift Key"]="Shift Taste"
+L["Ctrl Key"]="Steuerungstaste"
+L["Alt Key"]="Alt Taste"
+L["Raid Markers"]="Schlachtzugsymbole"
+L["Click to clear the mark."]="Klicken um die Weltmarkierung zu entfernen."
+L["Click to mark the target."]="Klicken um das Ziel zu markieren."
+L["%sClick to remove all worldmarkers."]="Drücken Sie die %staste um alle Weltmarkierungen zu entfernen."
+L["%sClick to place a worldmarker."]="Drücken Sie die %staste um eine Weltmarkierung zu platzieren."
+L["WatchFrame"]="Questlog"
+L["WATCHFRAME_DESC"]='Passen Sie die Einstellungen für die Sichtbarkeit des Questlogs ganz an ihre persönlichen Bedürfnisse an.'
+L["Hidden"]='Versteckt'
+L["Collapsed"]='Eingeklappt'
+L["Settings"]='Einstellungen'
+L["City (Resting)"]='Stadt (erholend)'
+L["PvP"]='PvP'
+L["Arena"]='Arena'
+L["Party"]='Gruppe'
+L["Raid"]='Schlachtzug'
+L["Progression Info"]='Schlachtzugfortschritt'
+L["Display the players raid progression in the tooltip, this may not immediately update when mousing over a unit."]='Zeigt den Schlachtzugfortschritt eines Charakters im Tooltip an. Es kann einen kurzen Moement dauern, bis diese Information agezeigt / aktualisiert wird.'
\ No newline at end of file
diff --git a/SVUI_!Core/language/italian_ui.lua b/SVUI_!Core/language/italian_ui.lua
new file mode 100644
index 0000000..dd0035f
--- /dev/null
+++ b/SVUI_!Core/language/italian_ui.lua
@@ -0,0 +1,593 @@
+local L = Librarian("Linguist"):Lang("itIT");
+if not L then return; end
+L["Conversation"]    = "Conversazione"
+L["General"]         = "Generale"
+L["LocalDefense"]    = "DifesaLocale"
+L["LookingForGroup"] = "CercaGruppo"
+L["Trade"]           = "Commercio"
+L["WorldDefense"]    = "DifesaMondiale"
+L["S_Conversation"]    = "BN"
+L["S_General"]        = "G"
+L["S_LocalDefense"]    = "DL"
+L["S_LookingForGroup"] = "CG"
+L["S_Trade"]          = "C"
+L["S_WorldDefense"]    = "DM"
+L["Hearthstone"] = true;
+--[[LOGIN MESSAGE]]--
+L["LOGIN_MSG"] = "Benvenuti a |cffFFFF1ASVUI|r! Mantenete il vostro %s e il vostro %s."
+L["LOGIN_MSG2"] = "versione |cffAA78FF%s|r, Tipo / sv per accedere al menu di configurazione in-game."
+--[[OPTION MESSAGES]]--
+L["AURAS_DESC"] = "Configure the aura icons that appear near the minimap."
+L["BAGS_DESC"] = "Adjust bag settings for SV."
+L["CHAT_DESC"] = "Adjust chat settings for SV."
+L["STATS_DESC"] = "Configure docked stat panels.";
+L["SVUI_DESC"] = "SVUI is a complete User Interface replacement addon for World of Warcraft."
+L["NAMEPLATE_DESC"] = "Modify the nameplate settings."
+L["PANEL_DESC"] = "Adjust the size of your left and right panels, this will effect your chat and bags."
+L["ART_DESC"] = "Adjust Style settings."
+L["TOGGLEART_DESC"] = "Enable / Disable this style."
+L["TOOLTIP_DESC"] = "Setup options for the Tooltip."
+L["TEXT_FORMAT_DESC"] = "Select the formatting of this text"
+L["import"] = "Profili esistenti"
+L["import_desc"] = "Puoi creare un nuovo profilo digitando il nome della casella di testo, oppure scegliendone uno tra i profili gia' esistenti."
+L["import_sub"] = "Seleziona uno dei profili disponibili."
+L["copy_name"] = "Copia Da"
+L["copy_desc"] = "Copia le impostazioni da un profilo esistente, nel profilo attivo in questo momento."
+L["current"] = "Profilo Attivo:"
+L["default"] = "Standard"
+L["delete"] = "Cancella un profilo"
+L["delete_confirm"] = "Sei sicuro di voler cancellare il profilo selezionato?"
+L["delete_desc"] = "Cancella i profili non utilizzati dal database per risparmiare spazio e mantenere puliti i file di configurazione SavedVariables."
+L["delete_sub"] = "Cancella un profilo dal Database."
+L["intro"] = "Puoi cambiare il profilo attivo, in modo da usare impostazioni diverse per ogni personaggio."
+L["export"] = "Nuovo"
+L["export_sub"] = "Crea un nuovo profilo vuoto."
+L["profiles"] = "Profili"
+L["profiles_sub"] = "Gestisci Profili"
+L["reset"] = "Reimposta Profilo"
+L["reset_desc"] = "Riporta il tuo profilo attivo alle sue impostazioni di default, nel caso in cui la tua configurazione si sia corrotta, o semplicemente tu voglia re-inizializzarla."
+L["reset_sub"] = "Reimposta il profilo ai suoi valori di default."
+L["SVUI_DockBottomCenter"] = "Bottom Data Dock"
+L["SVUI_DockTopCenter"] = "Top Data Dock"
+--[[REACTION TEXTS]]--
+L[" is drinking."] = true;
+L["Leeeeeroy!"] = true;
+L["No Food: "] = "Senza beneficio da cibo: "
+L["No Flask: "] = "Senza beneficio da tonico: "
+L["All Buffed!"] = "Tutti i benefici sono attivi!"
+L["Check food and flask"] = "Controllo cibi e tonici"
+L["Thanks for "] = "Grazie per "
+L[" received from "] = " ricevuto/a da "
+L["GO!"] = "VIA!"
+L["Pulling %s in %s.."] = "Avvio incontro %s in %s.."
+L["Pull ABORTED!"] = "Avvio incontro ANNULLATO!"
+L["%s has prepared a %s - [%s]."] = "%s ha preparato un/una %s - [%s]."
+L["%s has prepared a %s."] = "%s ha preparato un/una %s."
+L["%s has put down a %s."] = "%s ha messo già un/una %s."
+L["%s is casting %s."] = "%s sta lanciando %s."
+L["%s is casting %s. Click!"] = "%s sta lanciando %s. Cliccate!"
+L["%s used a %s."] = "%s ha utilizzato un/una %s."
+--[[FORMATTED INSTALLER TEXTS]]--
+L["|cffD3CF00Recommended|r"] = true;
+L["Recommended: |cff99FF00Kaboom!|r"] = true;
+L["Recommended: |cff99FF00Super|r"] = true;
+L["Recommended: |cffFF0000Small Row!|r"] = true;
+L["Recommended: |cffFF0000Icon Lovers!|r"] = true;
+L["|cffFF9F00KABOOOOM!|r"] = true;
+L["|cffAF30FFThe Darkest Night|r"] = true;
+L["|cff00FFFFPlain and Simple|r"] = true;
+L["|cff00FFFFLets Do This|r"] = true;
+L["|cff00FFFFSimply Simple|r"] = true;
+L["|cff00FFFFEl Compacto|r"] = true;
+L["|cff00FFFFHealer Extraordinaire|r"] = true;
+L["|cff00FFFFLean And Clean|r"] = true;
+L["|cff00FFFFMore For Less|r"] = true;
+L["|cff00FFFFWhat Big Buttons You Have|r"] = true;
+L["|cff00FFFFThe Double Down|r"] = true;
+--[[NORMAL INSTALLER TEXTS]]--
+L["This is SVUI version %s!"] = true;
+L["Before I can turn you loose, persuing whatever villainy you feel will advance your professional career ... I need to ask some questions and turn a few screws first."] = true;
+L["At any time you can get to the config options by typing the command /sv. For quick changes to frame, bar or color sets, call your henchman by clicking the button on the bottom right of your screen. (Its the one with his stupid face on it)"] = true;
+L["CHOOSE_OR_DIE"] = CHOOSE_FACTION.." "..OR_CAPS.." "..HIT.." "..CONTINUE;
+L["Whether you want to or not, you will be needing a communicator so other villains can either update you on their doings-of-evil or inform you about the MANY abilities of Chuck Norris"] = true;
+L["The chat windows function the same as standard chat windows, you can right click the tabs and drag them, rename them, slap them around, you know... whatever. Clickity-click to setup your chat windows."] = true;
+L["Your current resolution is %s, this is considered a %s resolution."] = true;
+L["This resolution requires that you change some settings to get everything to fit on your screen."] = true;
+L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."] = true;
+L["You may need to further alter these settings depending how low you resolution is."] = true;
+L["This resolution doesn't require that you change settings for the UI to fit on your screen."] = true;
+L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."] = true;
+L["This is completely optional."] = true;
+L["So what you think your better than me with your big monitor? HUH?!?!"] = true;
+L["Dont forget whos in charge here! But enjoy the incredible detail."] = true;
+L["Why are you playing this on what I would assume is a calculator display?"] = true;
+L["Enjoy the ONE incredible pixel that fits on this screen."] = true;
+L["Choose a theme layout you wish to use for your initial setup."] = true;
+L["You can always change fonts and colors of any element of SVUI from the in-game configuration."] = true;
+L["This theme tells the world that you are a villain who can put on a show "] = true;
+L["or better yet, you ARE the show!"] = true;
+L["Kaboom!"] = true;
+L["This theme indicates that you have no interest in wasting time"] = true;
+L["the dying begins NOW!"] = true;
+L["Darkness"] = true;
+L["This theme is for villains who take pride in their class"] = true;
+L["villains know how to reprezent!"] = true;
+L["This theme is for any villain who sticks to their traditions"] = true;
+L["you don't need fancyness to kick some ass!"] = true;
+L["Vintage"] = true;
+L["Layout"] = true;
+L["You can now choose what primary unitframe style you wish to use."] = true;
+L["This will change the layout of your unitframes (ie.. Player, Target, Pet, Party, Raid ...etc)."] = true;
+L["This layout is anything but minimal! Using this is like being at a rock concert"] = true;
+L["then annihilating the crowd with frickin lazer beams!"] = true;
+L["Super"] = true;
+L["This layout is for the villain who just wants to get things done!"] = true;
+L["But he still wants to see your face before he hits you!"] = true;
+L["Simple"] = true;
+L["Just the necessities so you can see more of the world around you."] = true;
+L["You dont need no fanciness getting in the way of world domination do you?"] = true;
+L["Compact"] = true;
+L["This has all the pizzaz of Super frames but uses Compact party and raid frames."] = true;
+L["Sometimes a little fifty-fifty goes a long way."] = true;
+L["Healer"] = true;
+L["Bar Setup"] = true;
+L["Choose a layout for your action bars."] = true;
+L["Sometimes you need big buttons, sometimes you don't. Your choice here."] = true;
+L["Lets keep it slim and deadly, not unlike a ninja sword."] = true;
+L["You dont ever even look at your bar hardly, so pick this one!"] = true;
+L["Small Row"] = true;
+L["Granted, you dont REALLY need the buttons due to your hotkey-leetness, you just like watching cooldowns!"] = true;
+L["Sure thing cowboy, your secret is safe with me!"] = true;
+L["Small X2"] = true;
+L["The better to PEW-PEW you with my dear!"] = true;
+L["When you have little time for mouse accuracy, choose this set!"] = true;
+L["Big Row"] = true;
+L["It's like dual-wielding two big reasons for your enemies to back the **** up!"] = true;
+L["Double your bars then double their size for maximum button goodness!"] = true;
+L["Big X2"] = true;
+L["Auras System"] = true;
+L["Select the type of aura system you want to use with SVUI's unitframes. The Icon Lovers set will display only icons and aurabars won't be used. The Vintage set will use the original game style and the Gimme Everything set does just what it says.... icons, bars and awesomeness."] = true;
+L["If you have an icon or aurabar that you don't want to display simply hold down shift and right click the icon for it to suffer a painful death."] = true;
+L["Vintage"] = true;
+L["Icon Lovers"] = true;
+L["The Works!"] = true;
+L["Installation Complete"] = true;
+L["Thats it! All done! Now we just need to hand these choices off to the henchmen so they can get you ready to (..insert evil tasks here..)!"] = true;
+L["Click the button below to reload and get on your way! Good luck villain!"] = true;
+L["THE_BUTTON_BELOW"] = "THE\nBUTTON\nBELOW";
+--[[UI TEXTS]]--
+L["Meanwhile"]=true;
+L["..at "]=true;
+L["A taint has occured that is preventing you from using the queue system. Please reload your user interface and try again."]=true;
+L["Binding"]=true;
+L["Key"]=true;
+L["KEY_ALT"]="A"
+L["KEY_CTRL"]="C"
+L["KEY_DELETE"]="Del"
+L["KEY_HOME"]="Hm"
+L["KEY_INSERT"]="Ins"
+L["KEY_MOUSEBUTTON"]="M"
+L["KEY_MOUSEWHEELDOWN"]="MwD"
+L["KEY_MOUSEWHEELUP"]="MwU"
+L["KEY_NUMPAD"]="N"
+L["KEY_PAGEDOWN"]="PD"
+L["KEY_PAGEUP"]="PU"
+L["KEY_SHIFT"]="S"
+L["KEY_SPACE"]="SpB"
+L["No bindings set."]=true;
+L["Remove Bar %d Action Page"]=true;
+L["Trigger"]=true;
+L["Delete Grays"]=true;
+L["Hold Control + Right Click:"]=true;
+L["Hold Shift + Drag:"]=true;
+L["Hold Shift:"]=true;
+L["Purchase"]=true;
+L["Reset Position"]=true;
+L["Sort Bags"]=true;
+L["Sort Tab"]=true;
+L["Stack Bags to Bank"]=true;
+L["Stack Bank to Bags"]=true;
+L["Stack Items"]=true;
+L["Temporary Move"]=true;
+L["Toggle Bags"]=true;
+L["Vendor Grays"]=true;
+L["AFK"]=true;
+L["DND"]=true;
+L["G"]=true;
+L["I"]=true;
+L["IL"]=true;
+L["Invalid Target"]=true;
+L["O"]=true;
+L["P"]=true;
+L["PL"]=true;
+L["R"]=true;
+L["RL"]=true;
+L["RW"]=true;
+L["says"]=true;
+L["whispers"]=true;
+L["yells"]=true;
+L["(Hold Shift) Memory Usage"]=true;
+L["AP"]=true;
+L["AVD: "]=true;
+L["Avoidance Breakdown"]=true;
+L["Bandwidth"]=true;
+L["Bases Assaulted"]=true;
+L["Bases Defended"]=true;
+L["Carts Controlled"]=true;
+L["Character: "]=true;
+L["Chest"]=true;
+L["Combat Time"]=true;
+L["copperabbrev"]="|cffeda55fc|r"
+L["Defeated"]=true;
+L["Deficit:"]=true;
+L["Demolishers Destroyed"]=true;
+L["Download"]=true;
+L["DPS"]=true;
+L["Earned:"]=true;
+L["Feet"]=true;
+L["Flags Captured"]=true;
+L["Flags Returned"]=true;
+L["Friends List"]=true;
+L["Friends"]=true;
+L["Galleon"]=true;
+L["Gates Destroyed"]=true;
+L["goldabbrev"]="|cffffd700g|r"
+L["Graveyards Assaulted"]=true;
+L["Graveyards Defended"]=true;
+L["Hands"]=true;
+L["Head"]=true;
+L["Hit"]=true;
+L["Home Latency:"]=true;
+L["HP"]=true;
+L["HPS"]=true;
+L["Legs"]=true;
+L["lvl"]=true;
+L["Main Hand"]=true;
+L["Mitigation By Level: "]=true;
+L["Nalak"]=true;
+L["No Guild"]=true;
+L["Offhand"]=true;
+L["Oondasta"]=true;
+L["Orb Possessions"]=true;
+L["Profit:"]=true;
+L["Reset Data: Hold Shift + Right Click"]=true;
+L["Saved Raid(s)"]=true;
+L["Server: "]=true;
+L["Session:"]=true;
+L["Sha of Anger"]=true;
+L["Shoulder"]=true;
+L["silverabbrev"]="|cffc7c7cfs|r"
+L["SP"]=true;
+L["Spent:"]=true;
+L["Stats For:"]=true;
+L["Total CPU:"]=true;
+L["Total Memory:"]=true;
+L["Total: "]=true;
+L["Towers Assaulted"]=true;
+L["Towers Defended"]=true;
+L["Undefeated"]=true;
+L["Unhittable:"]=true;
+L["Victory Points"]=true;
+L["Waist"]=true;
+L["World Boss(s)"]=true;
+L["Wrist"]=true;
+L["%s: %s tried to call the protected function '%s'."]=true;
+L["No locals to dump"]=true;
+L["%s is attempting to share his filters with you. Would you like to accept the request?"]=true;
+L["%s is attempting to share the profile %s with you. Would you like to accept the request?"]=true;
+L["Data From: %s"]=true;
+L["Filter download complete from %s, would you like to apply changes now?"]=true;
+L["Lord! It's a miracle! The download up and vanished like a fart in the wind! Try Again!"]=true;
+L["Profile download complete from %s, but the profile %s already exists. Change the name or else it will overwrite the existing profile."]=true;
+L["Profile download complete from %s, would you like to load the profile %s now?"]=true;
+L["Profile request sent. Waiting for response from player."]=true;
+L["Request was denied by user."]=true;
+L["Your profile was successfully recieved by the player."]=true;
+L["Auras Set"]=true;
+L["Auras System"]=true;
+L["Caster DPS"]=true;
+L["Chat Set"]=true;
+L["Chat"]=true;
+L["Choose a theme layout you wish to use for your initial setup."]=true;
+L["Vintage"]=true;
+L["Classic"]=true;
+L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."]=true;
+L["Config Mode:"]=true;
+L["CVars Set"]=true;
+L["CVars"]=true;
+L["Gloom & Doom"]=true;
+L["Disable"]=true;
+L["SVUI Installation"]=true;
+L["Finished"]=true;
+L["Grid Size:"]=true;
+L["Healer"]=true;
+L["High Resolution"]=true;
+L["high"]=true;
+L["Icons Only"]=true;
+L["If you have an icon or aurabar that you don't want to display simply hold down shift and right click the icon for it to disapear."]=true;
+L["Importance: |cff07D400High|r"]=true;
+L["Importance: |cffD3CF00Medium|r"]=true;
+L["Importance: |cffFF0000Low|r"]=true;
+L["Installation Complete"]=true;
+L["Integrated"]=true;
+L["Layout Set"]=true;
+L["Layout"]=true;
+L["Lock"]=true;
+L["Low Resolution"]=true;
+L["low"]=true;
+L["Frames unlocked. Move them now and click Lock when you are done."]=true;
+L["Nudge"]=true;
+L["Physical DPS"]=true;
+L["Pixel Perfect Set"]=true;
+L["Pixel Perfect"]=true;
+L["Please click the button below so you can setup variables and ReloadUI."]=true;
+L["Please click the button below to setup your CVars."]=true;
+L["Please press the continue button to go onto the next step."]=true;
+L["Resolution Style Set"]=true;
+L["Resolution"]=true;
+L["Select the type of aura system you want to use with SVUI's unitframes. The integrated system utilizes both aura-bars and aura-icons. The icons only system will display only icons and aurabars won't be used. The classic system will configure your auras to be default."]=true;
+L["Setup Chat"]=true;
+L["Setup CVars"]=true;
+L["Skip Process"]=true;
+L["Sticky Frames"]=true;
+L["Tank"]=true;
+L["The chat windows function the same as Blizzard standard chat windows, you can right click the tabs and drag them around, rename, etc. Please click the button below to setup your chat windows."]=true;
+L["The in-game configuration menu can be accesses by typing the /sv command or by clicking the 'C' button on the minimap. Press the button below if you wish to skip the installation process."]=true;
+L["The Pixel Perfect option will change the overall apperance of your UI. Using Pixel Perfect is a slight performance increase over the traditional layout."]=true;
+L["Theme Set"]=true;
+L["Theme Setup"]=true;
+L["This install process will help you learn some of the features in SVUI has to offer and also prepare your user interface for usage."]=true;
+L["This is completely optional."]=true;
+L["This part of the installation process sets up your chat windows names, positions and colors."]=true;
+L["This part of the installation process sets up your World of Warcraft default options it is recommended you should do this step for everything to behave properly."]=true;
+L["This resolution doesn't require that you change settings for the UI to fit on your screen."]=true;
+L["This resolution requires that you change some settings to get everything to fit on your screen."]=true;
+L["This will change the layout of your unitframes, raidframes, and statistics."]=true;
+L["Trade"]=true;
+L["Using this option will cause your borders around frames to be 1 pixel wide instead of 3 pixel. You may have to finish the installation to notice a differance. By default this is enable."]=true;
+L["Welcome to SVUI version %s!"]=true;
+L["You are now finished with the installation process. If you are in need of technical support please visit us at http://www.wowinterface.com."]=true;
+L["You can always change fonts and colors of any element of SVUI from the in-game configuration."]=true;
+L["You can now choose what layout you wish to use based on your combat role."]=true;
+L["You may need to further alter these settings depending how low you resolution is."]=true;
+L["Your current resolution is %s, this is considered a %s resolution."]=true;
+L["Bars"]=true;
+L["Calendar"]=true;
+L["Can't Roll"]=true;
+L["Disband Group"]=true;
+L["Empty Slot"]=true;
+L["Enable"]=true;
+L["Experience"]=true;
+L["Fishy Loot"]=true;
+L["Left Click:"]=true;
+L["Raid Menu"]=true;
+L["Remaining:"]=true;
+L["Rested:"]=true;
+L["Right Click:"]=true;
+L["Show BG Texts"]=true;
+L["Toggle Chat Frame"]=true;
+L["Toggle Configuration"]=true;
+L["XP:"]=true;
+L["You don't have permission to mark targets."]=true;
+L["ABOVE_THREAT_FORMAT"]='%s: %.0f%% [%.0f%% above |cff%02x%02x%02x%s|r]'
+L[" Frames"]=true;
+L["Alternative Power"]=true;
+L["Arena Frames"]=true;
+L["Auras Frame"]=true;
+L["Bags"]=true;
+L["Bar "]=true;
+L["BNet Frame"]=true;
+L["Special Ability Button"]=true;
+L["Boss Frames"]=true;
+L["Experience Bar"]=true;
+L["Focus Castbar"]=true;
+L["Focus Frame"]=true;
+L["FocusTarget Frame"]=true;
+L["GM Ticket Frame"]=true;
+L["Left Dock"]=true;
+L["Loot / Alert Frames"]=true;
+L["Loot Frame"]=true;
+L["Loss Control Icon"]=true;
+L["MA Frames"]=true;
+L["Micromenu"]=true;
+L["Minimap"]=true;
+L["MT Frames"]=true;
+L["Party Frames"]=true;
+L["Pet Bar"]=true;
+L["Pet Frame"]=true;
+L["PetTarget Frame"]=true;
+L["Player Castbar"]=true;
+L["Player Frame"]=true;
+L["Raid 1-"]=true;
+L["Reputation Bar"]=true;
+L["Right Dock"]=true;
+L["Stance Bar"]=true;
+L["Target Castbar"]=true;
+L["Target Frame"]=true;
+L["TargetTarget Frame"]=true;
+L["Tooltip"]=true;
+L["Totems"]=true;
+L["Vehicle Seat Frame"]=true;
+L["Watch Frame"]=true;
+L["Weapons"]=true;
+L["Discipline"]=true;
+L["Holy"]=true;
+L["Mistweaver"]=true;
+L["Restoration"]=true;
+L[" |cff00ff00bound to |r"]=true;
+L["%s frame(s) has a conflicting anchor point, please change either the buff or debuff anchor point so they are not attached to each other. Forcing the debuffs to be attached to the main unitframe until fixed."]=true;
+L["All keybindings cleared for |cff00ff00%s|r."]=true;
+L["Already Running.. Bailing Out!"]=true;
+L["Battleground statistics temporarily hidden, to show type /bgstats."]=true;
+L["Battleground statistics will now show again if you are inside a battleground."]=true;
+L["Binds Discarded"]=true;
+L["Binds Saved"]=true;
+L["Confused.. Try Again!"]=true;
+L["Deleted %d gray items. Total Worth: %s"]=true;
+L["No gray items to delete."]=true;
+L["No gray items to sell."]=true;
+L["The spell '%s' has been added to the BlackList unitframe aura filter."]=true;
+L["Vendored gray items for:"]=true;
+L["You don't have enough money to repair."]=true;
+L["You must be at a vendor."]=true;
+L["Your items have been repaired for: "]=true;
+L["Your items have been repaired using guild bank funds for: "]=true;
+L["Your version of SVUI is out of date. You can download the latest version from http://www.wowinterface.com"]=true;
+L["|cFFE30000Lua error recieved. You can view the error message when you exit combat."]=true;
+L["A setting you have changed will change an option for this character only. This setting that you have changed will be uneffected by changing user profiles. Changing this setting requires that you reload your User Interface."]=true;
+L["Are you sure you want to delete all your gray items?"]=true;
+L["Are you sure you want to disband the group?"]=true;
+L["Are you sure you want to reset every mover back to it's default position?"]=true;
+L["Because of the mass confusion caused by the new aura system I've implemented a new step to the installation process. This is optional. If you like how your auras are setup go to the last step and click finished to not be prompted again. If for some reason you are prompted repeatedly please restart your game."]=true;
+L["Can't buy anymore slots!"]=true;
+L["Disable Warning"]=true;
+L["Discard"]=true;
+L["Do you swear not to post in technical support about something not working without first disabling the addon/package combination first?"]=true;
+L["Hover your mouse over any actionbutton or spellbook button to bind it. Press the escape key or right click to clear the current actionbutton's keybinding."]=true;
+L["I Swear"]=true;
+L["Oh lord, you have got SVUI and Tukui both enable at the same time. Select an addon to disable."]=true;
+L["One or more of the changes you have made require a ReloadUI."]=true;
+L["One or more of the changes you have made will effect all characters using this addon. You will have to reload the user interface to see the changes you have made."]=true;
+L["Save"]=true;
+L["Using the healer layout it is highly recommended you download the addon Clique if you wish to have the click-to-heal function."]=true;
+L["You have changed the pixel perfect option. You will have to complete the installation process to remove any graphical bugs."]=true;
+L["You have changed your UIScale, however you still have the AutoScale option enable in SV. Press accept if you would like to disable the Auto Scale option."]=true;
+L["You must purchase a bank slot first!"]=true;
+L["Count"]=true;
+L["Targeted By:"]=true;
+L["A raid marker feature is available by pressing Escape -> Keybinds scroll to the bottom under SVUI and setting a keybind for the raid marker."]=true;
+L["SVUI has a dual spec feature which allows you to load different profiles based on your current spec on the fly. You can enable this from the profiles tab."]=true;
+L["For technical support visit us at http://www.wowinterface.com."]=true;
+L["If you accidently remove a chat frame you can always go the in-game configuration menu, press install, go to the chat portion and reset them."]=true;
+L["If you are experiencing issues with SVUI try disabling all your addons except SVUI, remember SVUI is a full UI replacement addon, you cannot run two addons that do the same thing."]=true;
+L["The buff panel to the right of minimap is a list of your consolidated buffs. You can disable it in Buffs and Debuffs options of SV."]=true;
+L["The focus unit can be set by typing /focus when you are targeting the unit you want to focus. It is recommended you make a macro to do this."]=true;
+L["To move abilities on the actionbars by default hold shift + drag. You can change the modifier key from the actionbar options menu."]=true;
+L["To setup which channels appear in which chat frame, right click the chat tab and go to settings."]=true;
+L["Using the /farmmode <size> command will spawn a larger minimap on your screen that can be moved around, very useful when farming."]=true;
+L["You can access copy chat and chat menu functions by mouse over the top right corner of chat panel and left/right click on the button that will appear."]=true;
+L["You can see someones average item level of their gear by holding shift and mousing over them. It should appear inside the tooltip."]=true;
+L["You can set your keybinds quickly by typing /kb."]=true;
+L["You can toggle the microbar by using your middle mouse button on the minimap you can also accomplish this by enabling the actual microbar located in the actionbar settings."]=true;
+L["You can use the /resetui command to reset all of your moveables. You can also use the command to reset a specific mover, /resetui <mover name>.\nExample: /resetui Player Frame"]=true;
+L["Ghost"]=true;
+L["Offline"]=true;
+L["ENH_LOGIN_MSG"]="You are using |cff1784d1SVUI Enhanced|r version %s%s|r."
+L["Your version of SVUI is to old. Please, download the latest version from http://www.wowinterface.com."]=true;
+L["Equipment"]=true;
+L["EQUIPMENT_DESC"]="Adjust the settings for switching your gear set when you change specialization or enter a battleground."
+L["No Change"]=true;
+L["Specialization"]=true;
+L["Enable/Disable the specialization switch."]=true;
+L["Primary Talent"]=true;
+L["Choose the equipment set to use for your primary specialization."]=true;
+L["Secondary Talent"]=true;
+L["Choose the equipment set to use for your secondary specialization."]=true;
+L["Battleground"]=true;
+L["Enable/Disable the battleground switch."]=true;
+L["Equipment Set"]=true;
+L["Choose the equipment set to use when you enter a battleground or arena."]=true;
+L["You have equipped equipment set: "]=true;
+L["DURABILITY_DESC"]="Adjust the settings for the durability information on the character screen."
+L["Enable/Disable the display of durability information on the character screen."]=true;
+L["Damaged Only"]=true;
+L["Only show durabitlity information for items that are damaged."]=true;
+L["ITEMLEVEL_DESC"]="Adjust the settings for the item level information on the character screen."
+L["Enable/Disable the display of item levels on the character screen."]=true;
+L["Miscellaneous"]=true;
+L["Equipment Set Overlay"]=true;
+L["Show the associated equipment sets for the items in your bags (or bank)."]=true;
+L["Layout Transparency"]=true;
+L["Changes the transparency of all the moveables."]=true;
+L["Automatic Role Assignment"]=true;
+L["Enables the automatic role assignment based on specialization for party / raid members (only work when you are group leader or group assist)."]=true;
+L["Hide Role Icon in combat"]=true;
+L["All role icons (Damage/Healer/Tank) on the unit frames are hidden when you go into combat."]=true;
+L["GPS"]=true;
+L["Show the direction and distance to the selected party or raid member."]=true;
+L["Attack Icon"]=true;
+L["Show attack icon for units that are not tapped by you or your group, but still give kill credit when attacked."]=true;
+L["Show class icon for units."]=true;
+L["Above Minimap"]=true;
+L["Location Digits"]=true;
+L["Number of digits for map location."]=true;
+L["Hide minimap while in combat."]=true;
+L["FadeIn Delay"]=true;
+L["The time to wait before fading the minimap back in after combat hide. (0 = Disabled)"]=true;
+L["Minimap Button Bar"]=true;
+L["Style Buttons"]=true;
+L["Customize the minimap buttons in SVUI style."]=true;
+L["SVUI Style"]=true;
+L["Change settings for how the minimap buttons are styled."]=true;
+L["The size of the minimap buttons."]=true;
+L["No Anchor Bar"]=true;
+L["Horizontal Anchor Bar"]=true;
+L["Vertical Anchor Bar"]=true;
+L["Layout Direction"]=true;
+L["Normal is right to left or top to bottom, or select reversed to switch directions."]=true;
+L["Normal"]=true;
+L["Reversed"]=true;
+L["PvP Autorelease"]=true;
+L["Automatically release body when killed inside a battleground."]=true;
+L["Track Reputation"]=true;
+L["Automatically change your watched faction on the reputation bar to the faction you got reputation points for."]=true;
+L["Select Quest Reward"]=true;
+L["Automatically select the quest reward with the highest vendor sell value."]=true;
+L["Item Level"]=true;
+L["Target Range"]=true;
+L["Distance"]=true;
+L["Actionbar1DataPanel"]='Actionbar 1'
+L["Actionbar3DataPanel"]='Actionbar 3'
+L["Actionbar5DataPanel"]='Actionbar 5'
+L["Sunsong Ranch"]="Tenuta Cantasole"
+L["The Halfhill Market"]="Mercato di Mezzocolle"
+L["Tilled Soil"]="Terreno Coltivato"
+L["Right-click to drop the item."]=true;
+L["Toolbox"]=true;
+L["COMIX_DESC"]="Toggle the comic popups during combat"
+L["FARMING_MODE_DESC"]="Adjust the settings for the tools that help your farming and professions."
+L["SNACKS_DESC"]="Adjust the settings for the consumables bar."
+L["Toolbox Bars"]=true;
+L["Toolbox Portal Bar"]=true;
+L["Toolbox Seed Bar"]=true;
+L["Toolbox Tools Bar"]=true;
+L["Enable/Disable the laborer bars."]=true;
+L["Only active buttons"]=true;
+L["Only show the buttons for the seeds, portals, tools you have in your bags."]=true;
+L["Drop Tools"]=true;
+L["Automatically drop tools from your bags when leaving the farming area."]=true;
+L["Seed Bar Direction"]=true;
+L["The direction of the seed bar buttons (Horizontal or Vertical)."]=true;
+L["Threat Text"]=true;
+L["Display threat level as text on targeted, boss or mouseover nameplate."]=true;
+L["Target Count"]=true;
+L["Display the number of party / raid members targetting the nameplate unit."]=true;
+L["Heal Glow"]=true;
+L["Direct AoE heals will let the unit frames of the affected party / raid members glow for the defined time period."]=true;
+L["Glow Duration"]=true;
+L["The amount of time the unit frames of party / raid members will glow when affected by a direct AoE heal."]=true;
+L["Glow Color"]=true;
+L["Raid Marker Bar"]=true;
+L["Display a quick action bar for raid targets and world markers."]=true;
+L["Modifier Key"]=true;
+L["Set the modifier key for placing world markers."]=true;
+L["Shift Key"]=true;
+L["Ctrl Key"]=true;
+L["Alt Key"]=true;
+L["Raid Markers"]=true;
+L["Click to clear the mark."]=true;
+L["Click to mark the target."]=true;
+L["%sClick to remove all worldmarkers."]=true;
+L["%sClick to place a worldmarker."]=true;
+L["WatchFrame"]=true;
+L["WATCHFRAME_DESC"]="Adjust the settings for the visibility of the watchframe (questlog) to your personal preference."
+L["Hidden"]=true;
+L["Collapsed"]=true;
+L["Settings"]=true;
+L["City (Resting)"]=true;
+L["PvP"]=true;
+L["Arena"]=true;
+L["Party"]=true;
+L["Raid"]=true;
+L["Progression Info"]=true;
+L["Display the players raid progression in the tooltip, this may not immediately update when mousing over a unit."]=true
\ No newline at end of file
diff --git a/SVUI_!Core/language/korean_ui.lua b/SVUI_!Core/language/korean_ui.lua
new file mode 100644
index 0000000..e752517
--- /dev/null
+++ b/SVUI_!Core/language/korean_ui.lua
@@ -0,0 +1,593 @@
+local L = Librarian("Linguist"):Lang("koKR");
+if not L then return; end
+L["Conversation"]    = "대화"
+L["General"]         = "공개"
+L["LocalDefense"]    = "수비"
+L["LookingForGroup"] = "파티찾기"
+L["Trade"]           = "거래"
+L["WorldDefense"]    = "전쟁"
+L["S_Conversation"]    = "대화"
+L["S_General"]        = "공"
+L["S_LocalDefense"]    = "수"
+L["S_LookingForGroup"] = "파찾"
+L["S_Trade"]          = "거"
+L["S_WorldDefense"]    = "쟁"
+L["Hearthstone"] = true;
+--[[LOGIN MESSAGE]]--
+L["LOGIN_MSG"] = "|cffFFFF1AUI를 악당|r에 오신 것을 환영합니다! 귀하의 유지 %s 당신을 %s."
+L["LOGIN_MSG2"] = "버전 |cffAA78FF%s|r, 유형 /sv 는 게임의 구성 메뉴에 액세스합니다."
+--[[OPTION MESSAGES]]--
+L["AURAS_DESC"] = "Configure the aura icons that appear near the minimap."
+L["BAGS_DESC"] = "SVUI 위해 가방 설정을 조정합니다."
+L["CHAT_DESC"] = "SVUI의 대화창을 설정합니다."
+L["STATS_DESC"] = "Configure docked stat panels.";
+L["SVUI_DESC"] = "SVUI는 WoW의 애드온을 대신하는 완전한 애드온입니다."
+L["NAMEPLATE_DESC"] = "이름표의 설정을 수정합니다."
+L["PANEL_DESC"] = "좌우 패널의 너비를 조절합니다. 이 값에 따라 대화창과 가방의 크기가 변경됩니다."
+L["ART_DESC"] = "애드온이나 프레임의 스킨을 설정합니다."
+L["TOGGLEART_DESC"] = "스킨 사용 / 중지"
+L["TOOLTIP_DESC"] = "툴팁을 설정합니다."
+L["TEXT_FORMAT_DESC"] = "Select the formatting of this text"
+L["import"] = "프로필 선택"
+L["import_desc"] = "새로운 이름을 입력하거나, 이미 있는 프로필중 하나를 선택하여 새로운 프로필을 만들 수 있습니다."
+L["import_sub"] = "당신이 현재 이용할수 있는 프로필을 선택합니다."
+L["copy_name"] = "복사"
+L["copy_desc"] = "현재 사용중인 프로필에, 선택한 프로필의 설정을 복사합니다."
+L["current"] = "Current Profile:"
+L["default"] = "기본값"
+L["delete"] = "프로필 삭제"
+L["delete_confirm"] = "정말로 선택한 프로필의 삭제를 원하십니까?"
+L["delete_desc"] = "데이터베이스에 사용중이거나 저장된 프로파일 삭제로 SavedVariables 파일의 정리와 공간 절약이 됩니다."
+L["delete_sub"] = "데이터베이스의 프로필을 삭제합니다."
+L["intro"] = "모든 캐릭터의 다양한 설정과 사용중인 데이터베이스 프로필, 어느것이던지 매우 다루기 쉽게 바꿀수 있습니다."
+L["export"] = "새로운 프로필"
+L["export_sub"] = "새로운 프로필을 만듭니다."
+L["profiles"] = "프로필"
+L["profiles_sub"] = "프로필 설정"
+L["reset"] = "프로필 초기화"
+L["reset_desc"] = "단순히 다시 새롭게 구성을 원하는 경우, 현재 프로필을 기본값으로 초기화 합니다."
+L["reset_sub"] = "현재의 프로필을 기본값으로 초기화 합니다"
+L["SVUI_DockBottomCenter"] = "Bottom Data Dock"
+L["SVUI_DockTopCenter"] = "Top Data Dock"
+--[[REACTION TEXTS]]--
+L[" is drinking."] = true;
+L["Leeeeeroy!"] = true;
+L["No Food: "] = true;
+L["No Flask: "] = true;
+L["All Buffed!"] = true;
+L["Check food and flask"] = true;
+L["Thanks for "] = true;
+L[" received from "] = true;
+L["GO!"] = true;
+L["Pulling %s in %s.."] = true
+L["Pull ABORTED!"] = true
+L["%s has prepared a %s - [%s]."] = true
+L["%s has prepared a %s."] = true
+L["%s has put down a %s."] = true
+L["%s is casting %s."] = true
+L["%s is casting %s. Click!"] = true
+L["%s used a %s."] = true
+--[[FORMATTED INSTALLER TEXTS]]--
+L["|cffD3CF00Recommended|r"] = true;
+L["Recommended: |cff99FF00Kaboom!|r"] = true;
+L["Recommended: |cff99FF00Super|r"] = true;
+L["Recommended: |cffFF0000Small Row!|r"] = true;
+L["Recommended: |cffFF0000Icon Lovers!|r"] = true;
+L["|cffFF9F00KABOOOOM!|r"] = true;
+L["|cffAF30FFThe Darkest Night|r"] = true;
+L["|cff00FFFFPlain and Simple|r"] = true;
+L["|cff00FFFFLets Do This|r"] = true;
+L["|cff00FFFFSimply Simple|r"] = true;
+L["|cff00FFFFEl Compacto|r"] = true;
+L["|cff00FFFFHealer Extraordinaire|r"] = true;
+L["|cff00FFFFLean And Clean|r"] = true;
+L["|cff00FFFFMore For Less|r"] = true;
+L["|cff00FFFFWhat Big Buttons You Have|r"] = true;
+L["|cff00FFFFThe Double Down|r"] = true;
+--[[NORMAL INSTALLER TEXTS]]--
+L["This is SVUI version %s!"] = true;
+L["Before I can turn you loose, persuing whatever villainy you feel will advance your professional career ... I need to ask some questions and turn a few screws first."] = true;
+L["At any time you can get to the config options by typing the command /sv. For quick changes to frame, bar or color sets, call your henchman by clicking the button on the bottom right of your screen. (Its the one with his stupid face on it)"] = true;
+L["CHOOSE_OR_DIE"] = CHOOSE_FACTION.." "..OR_CAPS.." "..HIT.." "..CONTINUE;
+L["Whether you want to or not, you will be needing a communicator so other villains can either update you on their doings-of-evil or inform you about the MANY abilities of Chuck Norris"] = true;
+L["The chat windows function the same as standard chat windows, you can right click the tabs and drag them, rename them, slap them around, you know... whatever. Clickity-click to setup your chat windows."] = true;
+L["Your current resolution is %s, this is considered a %s resolution."] = true;
+L["This resolution requires that you change some settings to get everything to fit on your screen."] = true;
+L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."] = true;
+L["You may need to further alter these settings depending how low you resolution is."] = true;
+L["This resolution doesn't require that you change settings for the UI to fit on your screen."] = true;
+L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."] = true;
+L["This is completely optional."] = true;
+L["So what you think your better than me with your big monitor? HUH?!?!"] = true;
+L["Dont forget whos in charge here! But enjoy the incredible detail."] = true;
+L["Why are you playing this on what I would assume is a calculator display?"] = true;
+L["Enjoy the ONE incredible pixel that fits on this screen."] = true;
+L["Choose a theme layout you wish to use for your initial setup."] = true;
+L["You can always change fonts and colors of any element of SVUI from the in-game configuration."] = true;
+L["This theme tells the world that you are a villain who can put on a show "] = true;
+L["or better yet, you ARE the show!"] = true;
+L["Kaboom!"] = true;
+L["This theme indicates that you have no interest in wasting time"] = true;
+L["the dying begins NOW!"] = true;
+L["Darkness"] = true;
+L["This theme is for villains who take pride in their class"] = true;
+L["villains know how to reprezent!"] = true;
+L["This theme is for any villain who sticks to their traditions"] = true;
+L["you don't need fancyness to kick some ass!"] = true;
+L["Vintage"] = true;
+L["Layout"] = true;
+L["You can now choose what primary unitframe style you wish to use."] = true;
+L["This will change the layout of your unitframes (ie.. Player, Target, Pet, Party, Raid ...etc)."] = true;
+L["This layout is anything but minimal! Using this is like being at a rock concert"] = true;
+L["then annihilating the crowd with frickin lazer beams!"] = true;
+L["Super"] = true;
+L["This layout is for the villain who just wants to get things done!"] = true;
+L["But he still wants to see your face before he hits you!"] = true;
+L["Simple"] = true;
+L["Just the necessities so you can see more of the world around you."] = true;
+L["You dont need no fanciness getting in the way of world domination do you?"] = true;
+L["Compact"] = true;
+L["This has all the pizzaz of Super frames but uses Compact party and raid frames."] = true;
+L["Sometimes a little fifty-fifty goes a long way."] = true;
+L["Healer"] = true;
+L["Bar Setup"] = true;
+L["Choose a layout for your action bars."] = true;
+L["Sometimes you need big buttons, sometimes you don't. Your choice here."] = true;
+L["Lets keep it slim and deadly, not unlike a ninja sword."] = true;
+L["You dont ever even look at your bar hardly, so pick this one!"] = true;
+L["Small Row"] = true;
+L["Granted, you dont REALLY need the buttons due to your hotkey-leetness, you just like watching cooldowns!"] = true;
+L["Sure thing cowboy, your secret is safe with me!"] = true;
+L["Small X2"] = true;
+L["The better to PEW-PEW you with my dear!"] = true;
+L["When you have little time for mouse accuracy, choose this set!"] = true;
+L["Big Row"] = true;
+L["It's like dual-wielding two big reasons for your enemies to back the **** up!"] = true;
+L["Double your bars then double their size for maximum button goodness!"] = true;
+L["Big X2"] = true;
+L["Auras System"] = true;
+L["Select the type of aura system you want to use with SVUI's unitframes. The Icon Lovers set will display only icons and aurabars won't be used. The Vintage set will use the original game style and the Gimme Everything set does just what it says.... icons, bars and awesomeness."] = true;
+L["If you have an icon or aurabar that you don't want to display simply hold down shift and right click the icon for it to suffer a painful death."] = true;
+L["Vintage"] = true;
+L["Icon Lovers"] = true;
+L["The Works!"] = true;
+L["Installation Complete"] = true;
+L["Thats it! All done! Now we just need to hand these choices off to the henchmen so they can get you ready to (..insert evil tasks here..)!"] = true;
+L["Click the button below to reload and get on your way! Good luck villain!"] = true;
+L["THE_BUTTON_BELOW"] = "THE\nBUTTON\nBELOW";
+--[[UI TEXTS]]--
+L["Meanwhile"]=true;
+L["..at "]=true;
+L["A taint has occured that is preventing you from using the queue system. Please reload your user interface and try again."]=true;
+L["Binding"]="단축키 지정"
+L["Key"]="단축키"
+L["KEY_ALT"]="A"
+L["KEY_CTRL"]="C"
+L["KEY_DELETE"]="Del"
+L["KEY_HOME"]="Hm"
+L["KEY_INSERT"]="Ins"
+L["KEY_MOUSEBUTTON"]="M"
+L["KEY_MOUSEWHEELDOWN"]="MwD"
+L["KEY_MOUSEWHEELUP"]="MwU"
+L["KEY_NUMPAD"]="N"
+L["KEY_PAGEDOWN"]="PD"
+L["KEY_PAGEUP"]="PU"
+L["KEY_SHIFT"]="S"
+L["KEY_SPACE"]="SpB"
+L["No bindings set."]="설정된 단축키가 없음"
+L["Remove Bar %d Action Page"]=true;
+L["Trigger"]=true;
+L["Delete Grays"]="회색템 삭제"
+L["Hold Control + Right Click:"]=true;
+L["Hold Shift + Drag:"]=true;
+L["Hold Shift:"]="Shift 고정:"
+L["Purchase"]="구매"
+L["Reset Position"]=true;
+L["Sort Bags"]="가방 정렬"
+L["Sort Tab"]=true;
+L["Stack Bags to Bank"]=true;
+L["Stack Bank to Bags"]=true;
+L["Stack Items"]="묶음 항목"
+L["Temporary Move"]=true;
+L["Toggle Bags"]=true;
+L["Vendor Grays"]="회색 아이템을 판매합니다."
+L["AFK"]="자리비움"
+L["DND"]=true;
+L["G"]="G"
+L["I"]=true;
+L["IL"]=true;
+L["Invalid Target"]=true;
+L["O"]="O"
+L["P"]="P"
+L["PL"]="PL"
+L["R"]="R"
+L["RL"]="RL"
+L["RW"]="RW"
+L["says"]=true;
+L["whispers"]=true;
+L["yells"]=true;
+L["(Hold Shift) Memory Usage"]="(Shift 고정시) 메모리 사용량"
+L["AP"]="전투력"
+L["AVD: "]="완방: "
+L["Avoidance Breakdown"]="방어합 수치"
+L["Bandwidth"]="대역폭"
+L["Bases Assaulted"]=true;
+L["Bases Defended"]=true;
+L["Carts Controlled"]=true;
+L["Character: "]="캐릭터:"
+L["Chest"]="가슴"
+L["Combat Time"]=true;
+L["copperabbrev"]="|cffeda55fc|r"
+L["Defeated"]=true;
+L["Deficit:"]="적자:"
+L["Demolishers Destroyed"]=true;
+L["Download"]=true;
+L["DPS"]="DPS"
+L["Earned:"]="수입:"
+L["Feet"]="발"
+L["Flags Captured"]=true;
+L["Flags Returned"]=true;
+L["Friends List"]="친구 목록"
+L["Friends"]="친구"
+L["Galleon"]=true;
+L["Gates Destroyed"]=true;
+L["goldabbrev"]="|cffffd700g|r"
+L["Graveyards Assaulted"]=true;
+L["Graveyards Defended"]=true;
+L["Hands"]="손"
+L["Head"]="머리"
+L["Hit"]="적중도"
+L["Home Latency:"]="지연 시간:"
+L["HP"]="주문력"
+L["HPS"]="HPS"
+L["Legs"]="다리"
+L["lvl"]="레벨"
+L["Main Hand"]="주장비"
+L["Mitigation By Level: "]=true;
+L["Nalak"]=true;
+L["No Guild"]=true;
+L["Offhand"]="보조장비"
+L["Oondasta"]=true;
+L["Orb Possessions"]=true;
+L["Profit:"]="이익:"
+L["Reset Data: Hold Shift + Right Click"]=true;
+L["Saved Raid(s)"]="귀속된 던전(s)"
+L["Server: "]="서버: "
+L["Session:"]="현재 접속:"
+L["Sha of Anger"]=true;
+L["Shoulder"]="어깨"
+L["silverabbrev"]="|cffc7c7cfs|r"
+L["SP"]="주문력"
+L["Spent:"]="지출:"
+L["Stats For:"]=true;
+L["Total CPU:"]="전체 CPU 사용량:"
+L["Total Memory:"]="전체 메모리:"
+L["Total: "]="합계:"
+L["Towers Assaulted"]=true;
+L["Towers Defended"]=true;
+L["Undefeated"]=true;
+L["Unhittable:"]="전체 완방:"
+L["Victory Points"]=true;
+L["Waist"]="허리"
+L["World Boss(s)"]=true;
+L["Wrist"]="손목"
+L["%s: %s tried to call the protected function '%s'."]=true;
+L["No locals to dump"]=true;
+L["%s is attempting to share his filters with you. Would you like to accept the request?"]=true;
+L["%s is attempting to share the profile %s with you. Would you like to accept the request?"]=true;
+L["Data From: %s"]=true;
+L["Filter download complete from %s, would you like to apply changes now?"]=true;
+L["Lord! It's a miracle! The download up and vanished like a fart in the wind! Try Again!"]=true;
+L["Profile download complete from %s, but the profile %s already exists. Change the name or else it will overwrite the existing profile."]=true;
+L["Profile download complete from %s, would you like to load the profile %s now?"]=true;
+L["Profile request sent. Waiting for response from player."]=true;
+L["Request was denied by user."]=true;
+L["Your profile was successfully recieved by the player."]=true;
+L["Auras Set"]=true;
+L["Auras System"]=true;
+L["Caster DPS"]="원거리 딜러"
+L["Chat Set"]="대화창 설정"
+L["Chat"]="대화창"
+L["Choose a theme layout you wish to use for your initial setup."]=true;
+L["Vintage"]=true;
+L["Classic"]=true;
+L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."]="채팅창, 유닛프레임 크기를 조정하거나 행동 단축바 위치를 조정하려면 하단 버튼을 클릭하세요."
+L["Config Mode:"]=true;
+L["CVars Set"]="CVars 설정"
+L["CVars"]="게임 인터페이스 설정(CVars)"
+L["Gloom & Doom"]=true;
+L["Disable"]=true;
+L["SVUI Installation"]="SVUI 설치"
+L["Finished"]="마침"
+L["Grid Size:"]="격자 크기 :"
+L["Healer"]="힐러"
+L["High Resolution"]=true;
+L["high"]="높은"
+L["Icons Only"]=true;
+L["If you have an icon or aurabar that you don't want to display simply hold down shift and right click the icon for it to disapear."]=true;
+L["Importance: |cff07D400High|r"]="중요도: |cff07D400높음|r"
+L["Importance: |cffD3CF00Medium|r"]="중요도: |cffD3CF00보통|r"
+L["Importance: |cffFF0000Low|r"]="중요도 : |cffFF0000낮음|r"
+L["Installation Complete"]="설치 완료"
+L["Integrated"]=true;
+L["Layout Set"]="레이아웃 설정"
+L["Layout"]="레이아웃"
+L["Lock"]="잠금"
+L["Low Resolution"]=true;
+L["low"]="낮은"
+L["Frames unlocked. Move them now and click Lock when you are done."]="이동이 가능합니다. 클릭하면 다시 이동이 불가능합니다."
+L["Nudge"]=true;
+L["Physical DPS"]="근접 DPS"
+L["Pixel Perfect Set"]=true;
+L["Pixel Perfect"]=true;
+L["Please click the button below so you can setup variables and ReloadUI."]="아래 버튼을 누르시면 설치를 마무리하고 UI를 재시작합니다."
+L["Please click the button below to setup your CVars."]="SVUI의 게임 인터페이스 설정(CVars)을 설치하려면 아래 버튼을 클릭하세요."
+L["Please press the continue button to go onto the next step."]="다음 단계로 가시려면 계속 버튼을 누르세요."
+L["Resolution Style Set"]="해상도 스타일 설정"
+L["Resolution"]="해상도"
+L["Select the type of aura system you want to use with SVUI's unitframes. The integrated system utilizes both aura-bars and aura-icons. The icons only system will display only icons and aurabars won't be used. The classic system will configure your auras to be default."]=true;
+L["Setup Chat"]="대화창 설치"
+L["Setup CVars"]="저장된 대화창 설정 설치"
+L["Skip Process"]="건너뛰기"
+L["Sticky Frames"]="달라붙는 프레임"
+L["Tank"]="방어전담"
+L["The chat windows function the same as Blizzard standard chat windows, you can right click the tabs and drag them around, rename, etc. Please click the button below to setup your chat windows."]="SVUI의 대화창은 기본 대화창과 유사합니다. 대화탭을 우클릭하거나 드래그해서 이동하거나 이름을 바꿀 수 있습니다.\n 아래 버튼을 클릭하여 대화창을 설치하세요."
+L["The in-game configuration menu can be accesses by typing the /sv command or by clicking the 'C' button on the minimap. Press the button below if you wish to skip the installation process."]="게임 내 설정메뉴는 /sv를 입력하시거나 미니맵 옆의 'C' 버튼을 클릭하시면 됩니다. 이 과정을 건너뛰시려면 아래 버튼을 누르십시오."
+L["The Pixel Perfect option will change the overall apperance of your UI. Using Pixel Perfect is a slight performance increase over the traditional layout."]=true;
+L["Theme Set"]=true;
+L["Theme Setup"]=true;
+L["This install process will help you learn some of the features in SVUI has to offer and also prepare your user interface for usage."]="이 설치과정은 UI의 사용에 대한 준비를 제공함과 동시에 몇가지의 구성요소에 대해 배울 수 있습니다."
+L["This is completely optional."]="이것은 완전히 선택 사항입니다."
+L["This part of the installation process sets up your chat windows names, positions and colors."]="이 설치 단계는 당신의 대화창의 위치, 이름, 색상을 설정합니다."
+L["This part of the installation process sets up your World of Warcraft default options it is recommended you should do this step for everything to behave properly."]="이 설치 단계는 당신의 WoW 기본 설정을 바꿔줍니다. 이 과정은 다른 단계에 있어서도 중요하니 설치를 강력히 추천합니다."
+L["This resolution doesn't require that you change settings for the UI to fit on your screen."]="이 해상도는 UI를 당신의 화면에 맞추기 위해 설정을 변경할 필요가 없습니다."
+L["This resolution requires that you change some settings to get everything to fit on your screen."]="이 해상도는 UI를 당신의 화면에 맞추기 위해 몇가지 설정을 변경해야 할 필요가 있습니다."
+L["This will change the layout of your unitframes, raidframes, and statistics."]="유닛프레임 및 정보문자의 레이아웃이 변경됩니다."
+L["Trade"]=true;
+L["Using this option will cause your borders around frames to be 1 pixel wide instead of 3 pixel. You may have to finish the installation to notice a differance. By default this is enable."]=true;
+L["Welcome to SVUI version %s!"]="SVUI 버전 %s에 오신 것을 환영합니다!"
+L["You are now finished with the installation process. If you are in need of technical support please visit us at http://www.wowinterface.com."]=true;
+L["You can always change fonts and colors of any element of SVUI from the in-game configuration."]=true;
+L["You can now choose what layout you wish to use based on your combat role."]="이제 당신의 역할에 따른 레이아웃을 선택할 수 있습니다."
+L["You may need to further alter these settings depending how low you resolution is."]="당신의 해상도가 얼마나 낮은지에 따라 설정을 더 조절해야할 수도 있습니다."
+L["Your current resolution is %s, this is considered a %s resolution."]="당신의 현재 해상도는 %s 이며, 이것은 %s 해상도로 간주됩니다."
+L["Bars"]=true;
+L["Calendar"]=true;
+L["Can't Roll"]="주사위를 굴릴 수 없습니다."
+L["Disband Group"]="그룹 해체"
+L["Empty Slot"]="빈 슬롯"
+L["Enable"]="사용"
+L["Experience"]="현재 경험치"
+L["Fishy Loot"]="낚시 전리품"
+L["Left Click:"]="왼쪽 클릭 :"
+L["Raid Menu"]="공격대 메뉴"
+L["Remaining:"]="남은: "
+L["Rested:"]="휴식 경험치:"
+L["Right Click:"]="오른쪽 클릭하십시오 :"
+L["Show BG Texts"]=true;
+L["Toggle Chat Frame"]=true;
+L["Toggle Configuration"]=true;
+L["XP:"]="경험치:"
+L["You don't have permission to mark targets."]="전술목표를 설정할 권한이 없습니다."
+L["ABOVE_THREAT_FORMAT"]="%s: %.0f%% [%.0f%% above |cff%02x%02x%02x%s|r]"
+L[" Frames"]=true;
+L["Alternative Power"]=true;
+L["Arena Frames"]="투기장 프레임"
+L["Auras Frame"]=true;
+L["Bags"]="가방"
+L["Bar "]="바 "
+L["BNet Frame"]=true;
+L["Special Ability Button"]=true;
+L["Boss Frames"]="보스 프레임"
+L["Experience Bar"]=true;
+L["Focus Castbar"]=true;
+L["Focus Frame"]="주시대상 프레임"
+L["FocusTarget Frame"]="주시대상의 대상 프레임"
+L["GM Ticket Frame"]=true;
+L["Left Dock"]=true;
+L["Loot / Alert Frames"]=true;
+L["Loot Frame"]=true;
+L["Loss Control Icon"]=true;
+L["MA Frames"]=true;
+L["Micromenu"]=true;
+L["Minimap"]=true;
+L["MT Frames"]=true;
+L["Party Frames"]="파티 프레임"
+L["Pet Bar"]="소환수 바"
+L["Pet Frame"]="소환수 프레임"
+L["PetTarget Frame"]="소환수 대상 프레임"
+L["Player Castbar"]=true;
+L["Player Frame"]="플레이어 프레임"
+L["Raid 1-"]=true;
+L["Reputation Bar"]=true;
+L["Right Dock"]=true;
+L["Stance Bar"]=true;
+L["Target Castbar"]=true;
+L["Target Frame"]="대상 프레임"
+L["TargetTarget Frame"]="대상의대상 프레임"
+L["Tooltip"]="툴팁"
+L["Totems"]=true;
+L["Vehicle Seat Frame"]=true;
+L["Watch Frame"]=true;
+L["Weapons"]=true;
+L["Discipline"]="수양"
+L["Holy"]="신성"
+L["Mistweaver"]=true;
+L["Restoration"]="회복"
+L[" |cff00ff00bound to |r"]="|cff00ff00단축키 지정: |r"
+L["%s frame(s) has a conflicting anchor point, please change either the buff or debuff anchor point so they are not attached to each other. Forcing the debuffs to be attached to the main unitframe until fixed."]="%s 프레임의 기준점 충돌로 인해 버프 혹은 디버프의 기준점이 변경되었습니다. 수정되기 전까지 주 유닛프레임에 종속됩니다."
+L["All keybindings cleared for |cff00ff00%s|r."]="|cff00ff00%s|r의 단축키 설정이 제거됩니다."
+L["Already Running.. Bailing Out!"]=true;
+L["Battleground statistics temporarily hidden, to show type /bgstats."]=true;
+L["Battleground statistics will now show again if you are inside a battleground."]=true;
+L["Binds Discarded"]="단축키 삭제"
+L["Binds Saved"]="단축키 저장"
+L["Confused.. Try Again!"]=true;
+L["Deleted %d gray items. Total Worth: %s"]="%d개의 회색 아이템을 삭제했습니다. 환산: %s:\n "
+L["No gray items to delete."]="삭제할 회색 아이템이 없습니다."
+L["No gray items to sell."]="판매할 회색 아이템이 없습니다."
+L["The spell '%s' has been added to the BlackList unitframe aura filter."]=true;
+L["Vendored gray items for:"]="회색 항목 판매:"
+L["You don't have enough money to repair."]="수리 비용이 부족합니다."
+L["You must be at a vendor."]="당신은 상인을 만나야 합니다."
+L["Your items have been repaired for: "]="수리 비용:"
+L["Your items have been repaired using guild bank funds for: "]="길드금고에서 사용된 수리 비용:"
+L["Your version of SVUI is out of date. You can download the latest version from http://www.wowinterface.com"]="당신의 SVUI 버전이 구버전입니다. 당신은 http://www.wowinterface.com에서 최신 버전을 다운로드하실 수 있습니다."
+L["|cFFE30000Lua error recieved. You can view the error message when you exit combat."]=true;
+L["A setting you have changed will change an option for this character only. This setting that you have changed will be uneffected by changing user profiles. Changing this setting requires that you reload your User Interface."]=true;
+L["Are you sure you want to delete all your gray items?"]="모든 회색 아이템을 삭제하시겠습니까?"
+L["Are you sure you want to disband the group?"]="당신은 그룹을 해체 하시겠습니까?"
+L["Are you sure you want to reset every mover back to it's default position?"]="이동된 프레임을 기본값으로 복구하시겠습니까?"
+L["Because of the mass confusion caused by the new aura system I've implemented a new step to the installation process. This is optional. If you like how your auras are setup go to the last step and click finished to not be prompted again. If for some reason you are prompted repeatedly please restart your game."]=true;
+L["Can't buy anymore slots!"]="더 이상 가방 칸을 늘릴 수 없습니다."
+L["Disable Warning"]=true;
+L["Discard"]="삭제"
+L["Do you swear not to post in technical support about something not working without first disabling the addon/package combination first?"]=true;
+L["Hover your mouse over any actionbutton or spellbook button to bind it. Press the escape key or right click to clear the current actionbutton's keybinding."]="행동단축바나 주문책 버튼 위에 커서를 올려놓은 후 단축키를 지정합니다.  ESC나 우클릭시 지정된 단축키가 해제됩니다."
+L["I Swear"]=true;
+L["Oh lord, you have got SVUI and Tukui both enable at the same time. Select an addon to disable."]=true;
+L["One or more of the changes you have made require a ReloadUI."]="변경된 사항이 적용되기 위해서는 UI 재시작이 필요합니다."
+L["One or more of the changes you have made will effect all characters using this addon. You will have to reload the user interface to see the changes you have made."]="몇가지 변경설정들은 이 애드온을 사용하는 모든 캐릭터에 적용될 것입니다. 이 변경설정들을 보려면 UI를 재시작해야 합니다."
+L["Save"]="저장"
+L["Using the healer layout it is highly recommended you download the addon Clique if you wish to have the click-to-heal function."]=true;
+L["You have changed the pixel perfect option. You will have to complete the installation process to remove any graphical bugs."]=true;
+L["You have changed your UIScale, however you still have the AutoScale option enable in SV. Press accept if you would like to disable the Auto Scale option."]="UI 배율이 변경되었지만 SVUI의 자동크기 설정이 켜져있습니다. 자동크기 설정을 끄고 싶다면 '수락'을 누르세요."
+L["You must purchase a bank slot first!"]="우선 은행가방 칸을 구입해야됩니다!"
+L["Count"]="갯수"
+L["Targeted By:"]="선택:"
+L["A raid marker feature is available by pressing Escape -> Keybinds scroll to the bottom under SVUI and setting a keybind for the raid marker."]=true;
+L["SVUI has a dual spec feature which allows you to load different profiles based on your current spec on the fly. You can enable this from the profiles tab."]=true;
+L["For technical support visit us at http://www.wowinterface.com."]=true;
+L["If you accidently remove a chat frame you can always go the in-game configuration menu, press install, go to the chat portion and reset them."]=true;
+L["If you are experiencing issues with SVUI try disabling all your addons except SVUI, remember SVUI is a full UI replacement addon, you cannot run two addons that do the same thing."]=true;
+L["The buff panel to the right of minimap is a list of your consolidated buffs. You can disable it in Buffs and Debuffs options of SV."]=true;
+L["The focus unit can be set by typing /focus when you are targeting the unit you want to focus. It is recommended you make a macro to do this."]=true;
+L["To move abilities on the actionbars by default hold shift + drag. You can change the modifier key from the actionbar options menu."]=true;
+L["To setup which channels appear in which chat frame, right click the chat tab and go to settings."]=true;
+L["Using the /farmmode <size> command will spawn a larger minimap on your screen that can be moved around, very useful when farming."]=true;
+L["You can access copy chat and chat menu functions by mouse over the top right corner of chat panel and left/right click on the button that will appear."]=true;
+L["You can see someones average item level of their gear by holding shift and mousing over them. It should appear inside the tooltip."]=true;
+L["You can set your keybinds quickly by typing /kb."]=true;
+L["You can toggle the microbar by using your middle mouse button on the minimap you can also accomplish this by enabling the actual microbar located in the actionbar settings."]=true;
+L["You can use the /resetui command to reset all of your moveables. You can also use the command to reset a specific mover, /resetui <mover name>.\nExample: /resetui Player Frame"]=true;
+L["Ghost"]="유령"
+L["Offline"]="오프라인"
+L["ENH_LOGIN_MSG"]="You are using |cff1784d1SVUI Enhanced|r version %s%s|r."
+L["Your version of SVUI is to old. Please, download the latest version from http://www.wowinterface.com."]=true;
+L["Equipment"]=true;
+L["EQUIPMENT_DESC"]="Adjust the settings for switching your gear set when you change specialization or enter a battleground."
+L["No Change"]=true;
+L["Specialization"]=true;
+L["Enable/Disable the specialization switch."]=true;
+L["Primary Talent"]=true;
+L["Choose the equipment set to use for your primary specialization."]=true;
+L["Secondary Talent"]=true;
+L["Choose the equipment set to use for your secondary specialization."]=true;
+L["Battleground"]=true;
+L["Enable/Disable the battleground switch."]=true;
+L["Equipment Set"]=true;
+L["Choose the equipment set to use when you enter a battleground or arena."]=true;
+L["You have equipped equipment set: "]=true;
+L["DURABILITY_DESC"]="Adjust the settings for the durability information on the character screen."
+L["Enable/Disable the display of durability information on the character screen."]=true;
+L["Damaged Only"]=true;
+L["Only show durabitlity information for items that are damaged."]=true;
+L["ITEMLEVEL_DESC"]="Adjust the settings for the item level information on the character screen."
+L["Enable/Disable the display of item levels on the character screen."]=true;
+L["Miscellaneous"]=true;
+L["Equipment Set Overlay"]=true;
+L["Show the associated equipment sets for the items in your bags (or bank)."]=true;
+L["Layout Transparency"]=true;
+L["Changes the transparency of all the moveables."]=true;
+L["Automatic Role Assignment"]=true;
+L["Enables the automatic role assignment based on specialization for party / raid members (only work when you are group leader or group assist)."]=true;
+L["Hide Role Icon in combat"]=true;
+L["All role icons (Damage/Healer/Tank) on the unit frames are hidden when you go into combat."]=true;
+L["GPS"]=true;
+L["Show the direction and distance to the selected party or raid member."]=true;
+L["Attack Icon"]=true;
+L["Show attack icon for units that are not tapped by you or your group, but still give kill credit when attacked."]=true;
+L["Show class icon for units."]=true;
+L["Above Minimap"]=true;
+L["Location Digits"]=true;
+L["Number of digits for map location."]=true;
+L["Hide minimap while in combat."]=true;
+L["FadeIn Delay"]=true;
+L["The time to wait before fading the minimap back in after combat hide. (0 = Disabled)"]=true;
+L["Minimap Button Bar"]=true;
+L["Style Buttons"]=true;
+L["Customize the minimap buttons in SVUI style."]=true;
+L["SVUI Style"]=true;
+L["Change settings for how the minimap buttons are styled."]=true;
+L["The size of the minimap buttons."]=true;
+L["No Anchor Bar"]=true;
+L["Horizontal Anchor Bar"]=true;
+L["Vertical Anchor Bar"]=true;
+L["Layout Direction"]=true;
+L["Normal is right to left or top to bottom, or select reversed to switch directions."]=true;
+L["Normal"]=true;
+L["Reversed"]=true;
+L["PvP Autorelease"]=true;
+L["Automatically release body when killed inside a battleground."]=true;
+L["Track Reputation"]=true;
+L["Automatically change your watched faction on the reputation bar to the faction you got reputation points for."]=true;
+L["Select Quest Reward"]=true;
+L["Automatically select the quest reward with the highest vendor sell value."]=true;
+L["Item Level"]=true;
+L["Target Range"]=true;
+L["Distance"]=true;
+L["Actionbar1DataPanel"]='Actionbar 1'
+L["Actionbar3DataPanel"]='Actionbar 3'
+L["Actionbar5DataPanel"]='Actionbar 5'
+L["Sunsong Ranch"]="태양노래 농장"
+L["The Halfhill Market"]="언덕골 시장"
+L["Tilled Soil"]="갈아엎은 흙"
+L["Right-click to drop the item."]=true;
+L["Toolbox"]=true;
+L["COMIX_DESC"]="Toggle the comic popups during combat"
+L["FARMING_MODE_DESC"]="Adjust the settings for the tools that help your farming and professions."
+L["SNACKS_DESC"]="Adjust the settings for the consumables bar."
+L["Toolbox Bars"]=true;
+L["Toolbox Portal Bar"]=true;
+L["Toolbox Seed Bar"]=true;
+L["Toolbox Tools Bar"]=true;
+L["Enable/Disable the laborer bars."]=true;
+L["Only active buttons"]=true;
+L["Only show the buttons for the seeds, portals, tools you have in your bags."]=true;
+L["Drop Tools"]=true;
+L["Automatically drop tools from your bags when leaving the farming area."]=true;
+L["Seed Bar Direction"]=true;
+L["The direction of the seed bar buttons (Horizontal or Vertical)."]=true;
+L["Threat Text"]=true;
+L["Display threat level as text on targeted, boss or mouseover nameplate."]=true;
+L["Target Count"]=true;
+L["Display the number of party / raid members targetting the nameplate unit."]=true;
+L["Heal Glow"]=true;
+L["Direct AoE heals will let the unit frames of the affected party / raid members glow for the defined time period."]=true;
+L["Glow Duration"]=true;
+L["The amount of time the unit frames of party / raid members will glow when affected by a direct AoE heal."]=true;
+L["Glow Color"]=true;
+L["Raid Marker Bar"]=true;
+L["Display a quick action bar for raid targets and world markers."]=true;
+L["Modifier Key"]=true;
+L["Set the modifier key for placing world markers."]=true;
+L["Shift Key"]=true;
+L["Ctrl Key"]=true;
+L["Alt Key"]=true;
+L["Raid Markers"]=true;
+L["Click to clear the mark."]=true;
+L["Click to mark the target."]=true;
+L["%sClick to remove all worldmarkers."]=true;
+L["%sClick to place a worldmarker."]=true;
+L["WatchFrame"]=true;
+L["WATCHFRAME_DESC"]="Adjust the settings for the visibility of the watchframe (questlog) to your personal preference."
+L["Hidden"]=true;
+L["Collapsed"]=true;
+L["Settings"]=true;
+L["City (Resting)"]=true;
+L["PvP"]=true;
+L["Arena"]=true;
+L["Party"]=true;
+L["Raid"]=true;
+L["Progression Info"]=true;
+L["Display the players raid progression in the tooltip, this may not immediately update when mousing over a unit."]=true
\ No newline at end of file
diff --git a/SVUI_!Core/language/portuguese_ui.lua b/SVUI_!Core/language/portuguese_ui.lua
new file mode 100644
index 0000000..fc26346
--- /dev/null
+++ b/SVUI_!Core/language/portuguese_ui.lua
@@ -0,0 +1,573 @@
+local L = Librarian("Linguist"):Lang("ptBR");
+if not L then return; end
+L["Conversation"]    = "Conversa"
+L["General"]         = "Geral"
+L["LocalDefense"]    = "DefesaLocal"
+L["LookingForGroup"] = "ProcurandoGrupo"
+L["Trade"]           = "Comércio"
+L["WorldDefense"]    = "DefesaGlobal"
+L["S_Conversation"]    = "C"
+L["S_General"]        = "Ge"
+L["S_LocalDefense"]    = "DL"
+L["S_LookingForGroup"] = "PG"
+L["S_Trade"]          = "Co"
+L["S_WorldDefense"]    = "DG"
+L["Hearthstone"] = true;
+--[[LOGIN MESSAGE]]--
+L["LOGIN_MSG"] = "Bem vindo à |cffFFFF1ASVUI|r! Manter o seu %s e seu %s."
+L["LOGIN_MSG2"] = "Versão |cffAA78FF%s|r, escreva /sv para acessar o menu de configuração em jogo."
+--[[OPTION MESSAGES]]--
+L["AURAS_DESC"] = "Configurar os ícones das auras que aparecem perto do minimapa."
+L["BAGS_DESC"] = "Ajustar definições das bolsas para a SV."
+L["CHAT_DESC"] = "Adjustar definições do bate-papo para o SV."
+L["STATS_DESC"] = "Configure docked stat panels.";
+L["SVUI_DESC"] = "A SVUI é um Addon completo de substituição da interface original do World of Warcraft."
+L["NAMEPLATE_DESC"] = "Modificar as definições das Placas de Identificação."
+L["PANEL_DESC"] = "Ajustar o tamanho dos painéis da esquerda e direita, isto irá afetar suas bolsas e bate-papo."
+L["ART_DESC"] = "Ajustar definições de Aparências."
+L["TOGGLEART_DESC"] = "Ativa / Desativa a aparência deste quadro."
+L["TOOLTIP_DESC"] = "Opções de configuração para a Tooltip."
+L["TEXT_FORMAT_DESC"] = "Select the formatting of this text"
+L["SVUI_DockBottomCenter"] = "Bottom Data Dock"
+L["SVUI_DockTopCenter"] = "Top Data Dock"
+--[[REACTION TEXTS]]--
+L[" is drinking."] = true;
+L["Leeeeeroy!"] = true;
+L["No Food: "] = "No Food: "
+L["No Flask: "] = "No Flask: "
+L["All Buffed!"] = "All Buffed!"
+L["Check food and flask"] = "Check food and flask"
+L["Thanks for "] = "Thanks for "
+L[" received from "] = " received from "
+L["GO!"] = "GO!"
+L["Pulling %s in %s.."] = "Pulling %s in %s.."
+L["Pull ABORTED!"] = "Pull ABORTED!"
+L["%s has prepared a %s - [%s]."] = "%s has prepared a %s - [%s]."
+L["%s has prepared a %s."] = "%s has prepared a %s."
+L["%s has put down a %s."] = "%s has put down a %s."
+L["%s is casting %s."] = "%s is casting %s."
+L["%s is casting %s. Click!"] = "%s is casting %s. Click!"
+L["%s used a %s."] = "%s used a %s."
+--[[FORMATTED INSTALLER TEXTS]]--
+L["|cffD3CF00Recommended|r"] = true;
+L["Recommended: |cff99FF00Kaboom!|r"] = true;
+L["Recommended: |cff99FF00Super|r"] = true;
+L["Recommended: |cffFF0000Small Row!|r"] = true;
+L["Recommended: |cffFF0000Icon Lovers!|r"] = true;
+L["|cffFF9F00KABOOOOM!|r"] = true;
+L["|cffAF30FFThe Darkest Night|r"] = true;
+L["|cff00FFFFPlain and Simple|r"] = true;
+L["|cff00FFFFLets Do This|r"] = true;
+L["|cff00FFFFSimply Simple|r"] = true;
+L["|cff00FFFFEl Compacto|r"] = true;
+L["|cff00FFFFHealer Extraordinaire|r"] = true;
+L["|cff00FFFFLean And Clean|r"] = true;
+L["|cff00FFFFMore For Less|r"] = true;
+L["|cff00FFFFWhat Big Buttons You Have|r"] = true;
+L["|cff00FFFFThe Double Down|r"] = true;
+--[[NORMAL INSTALLER TEXTS]]--
+L["This is SVUI version %s!"] = true;
+L["Before I can turn you loose, persuing whatever villainy you feel will advance your professional career ... I need to ask some questions and turn a few screws first."] = true;
+L["At any time you can get to the config options by typing the command /sv. For quick changes to frame, bar or color sets, call your henchman by clicking the button on the bottom right of your screen. (Its the one with his stupid face on it)"] = true;
+L["CHOOSE_OR_DIE"] = CHOOSE_FACTION.." "..OR_CAPS.." "..HIT.." "..CONTINUE;
+L["Whether you want to or not, you will be needing a communicator so other villains can either update you on their doings-of-evil or inform you about the MANY abilities of Chuck Norris"] = true;
+L["The chat windows function the same as standard chat windows, you can right click the tabs and drag them, rename them, slap them around, you know... whatever. Clickity-click to setup your chat windows."] = true;
+L["Your current resolution is %s, this is considered a %s resolution."] = true;
+L["This resolution requires that you change some settings to get everything to fit on your screen."] = true;
+L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."] = true;
+L["You may need to further alter these settings depending how low you resolution is."] = true;
+L["This resolution doesn't require that you change settings for the UI to fit on your screen."] = true;
+L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."] = true;
+L["This is completely optional."] = true;
+L["So what you think your better than me with your big monitor? HUH?!?!"] = true;
+L["Dont forget whos in charge here! But enjoy the incredible detail."] = true;
+L["Why are you playing this on what I would assume is a calculator display?"] = true;
+L["Enjoy the ONE incredible pixel that fits on this screen."] = true;
+L["Choose a theme layout you wish to use for your initial setup."] = true;
+L["You can always change fonts and colors of any element of SVUI from the in-game configuration."] = true;
+L["This theme tells the world that you are a villain who can put on a show "] = true;
+L["or better yet, you ARE the show!"] = true;
+L["Kaboom!"] = true;
+L["This theme indicates that you have no interest in wasting time"] = true;
+L["the dying begins NOW!"] = true;
+L["Darkness"] = true;
+L["This theme is for villains who take pride in their class"] = true;
+L["villains know how to reprezent!"] = true;
+L["This theme is for any villain who sticks to their traditions"] = true;
+L["you don't need fancyness to kick some ass!"] = true;
+L["Vintage"] = true;
+L["Layout"] = true;
+L["You can now choose what primary unitframe style you wish to use."] = true;
+L["This will change the layout of your unitframes (ie.. Player, Target, Pet, Party, Raid ...etc)."] = true;
+L["This layout is anything but minimal! Using this is like being at a rock concert"] = true;
+L["then annihilating the crowd with frickin lazer beams!"] = true;
+L["Super"] = true;
+L["This layout is for the villain who just wants to get things done!"] = true;
+L["But he still wants to see your face before he hits you!"] = true;
+L["Simple"] = true;
+L["Just the necessities so you can see more of the world around you."] = true;
+L["You dont need no fanciness getting in the way of world domination do you?"] = true;
+L["Compact"] = true;
+L["This has all the pizzaz of Super frames but uses Compact party and raid frames."] = true;
+L["Sometimes a little fifty-fifty goes a long way."] = true;
+L["Healer"] = true;
+L["Bar Setup"] = true;
+L["Choose a layout for your action bars."] = true;
+L["Sometimes you need big buttons, sometimes you don't. Your choice here."] = true;
+L["Lets keep it slim and deadly, not unlike a ninja sword."] = true;
+L["You dont ever even look at your bar hardly, so pick this one!"] = true;
+L["Small Row"] = true;
+L["Granted, you dont REALLY need the buttons due to your hotkey-leetness, you just like watching cooldowns!"] = true;
+L["Sure thing cowboy, your secret is safe with me!"] = true;
+L["Small X2"] = true;
+L["The better to PEW-PEW you with my dear!"] = true;
+L["When you have little time for mouse accuracy, choose this set!"] = true;
+L["Big Row"] = true;
+L["It's like dual-wielding two big reasons for your enemies to back the **** up!"] = true;
+L["Double your bars then double their size for maximum button goodness!"] = true;
+L["Big X2"] = true;
+L["Auras System"] = true;
+L["Select the type of aura system you want to use with SVUI's unitframes. The Icon Lovers set will display only icons and aurabars won't be used. The Vintage set will use the original game style and the Gimme Everything set does just what it says.... icons, bars and awesomeness."] = true;
+L["If you have an icon or aurabar that you don't want to display simply hold down shift and right click the icon for it to suffer a painful death."] = true;
+L["Vintage"] = true;
+L["Icon Lovers"] = true;
+L["The Works!"] = true;
+L["Installation Complete"] = true;
+L["Thats it! All done! Now we just need to hand these choices off to the henchmen so they can get you ready to (..insert evil tasks here..)!"] = true;
+L["Click the button below to reload and get on your way! Good luck villain!"] = true;
+L["THE_BUTTON_BELOW"] = "THE\nBUTTON\nBELOW";
+--[[UI TEXTS]]--
+L["Meanwhile"]=true;
+L["..at "]=true;
+L["A taint has occured that is preventing you from using the queue system. Please reload your user interface and try again."]="Um erro aconteceu que está previnindo você de usar o sistema de fila. Por favor recarregue sua interface e tente novamente."
+L["Binding"]="Ligações"
+L["Key"]="Tecla"
+L["KEY_ALT"]="A"
+L["KEY_CTRL"]="C"
+L["KEY_DELETE"]="Del"
+L["KEY_HOME"]="Hm"
+L["KEY_INSERT"]="Ins"
+L["KEY_MOUSEBUTTON"]="M"
+L["KEY_MOUSEWHEELDOWN"]="MwD"
+L["KEY_MOUSEWHEELUP"]="MwU"
+L["KEY_NUMPAD"]="N"
+L["KEY_PAGEDOWN"]="PD"
+L["KEY_PAGEUP"]="PU"
+L["KEY_SHIFT"]="S"
+L["KEY_SPACE"]="SpB"
+L["No bindings set."]="Sem atalhos definidos"
+L["Remove Bar %d Action Page"]="Remover paginação de ação da barra %d."
+L["Trigger"]="Gatilho"
+L["Delete Grays"]="Destruir itens cinzentos"
+L["Hold Control + Right Click:"]="Segurar Control + Clique Direito:"
+L["Hold Shift + Drag:"]="Segurar Shift + Arrastar:"
+L["Hold Shift:"]="Segurar Shift:"
+L["Purchase"]="Comprar"
+L["Reset Position"]="Redefinir Posição"
+L["Sort Bags"]="Organizar Bolsas"
+L["Sort Tab"]=true;
+L["Stack Bags to Bank"]="Empilhar Bolsas para Banco"
+L["Stack Bank to Bags"]="Empilhar Banco para Bolsas"
+L["Stack Items"]="Empilhar itens"
+L["Temporary Move"]="Layout Temporariamente"
+L["Toggle Bags"]="Mostrar/Ocultar Bolsas"
+L["Vendor Grays"]="Vender Itens Cinzentos"
+L["AFK"]="LDT"
+L["DND"]="NP"
+L["G"]="G"
+L["I"]="I"
+L["IL"]="IL"
+L["Invalid Target"]="Alvo inválido"
+L["O"]="O"
+L["P"]="P"
+L["PL"]="PL"
+L["R"]="R"
+L["RL"]="RL"
+L["RW"]="AR"
+L["says"]="diz"
+L["whispers"]="sussurra"
+L["yells"]="grita"
+L["(Hold Shift) Memory Usage"]="(Segurar Shift) Memória em Uso"
+L["AP"]="PA"
+L["AVD: "]="AVD: "
+L["Avoidance Breakdown"]="Separação de Anulação"
+L["Bandwidth"]="Largura de Banda"
+L["Bases Assaulted"]="Bases Assaltadas"
+L["Bases Defended"]="Bases Defendidas"
+L["Carts Controlled"]="Carrinhos Controlados"
+L["Character: "]="Personagem: "
+L["Chest"]="Torso"
+L["Combat Time"]="Tempo de Combate"
+L["copperabbrev"]="|cffeda55fc|r"
+L["Defeated"]="Derrotado"
+L["Deficit:"]="Défice:"
+L["Demolishers Destroyed"]="Demolidores Destruidos"
+L["Download"]="Download"
+L["DPS"]="DPS"
+L["Earned:"]="Ganho:"
+L["Feet"]="Pés"
+L["Flags Captured"]="Bandeiras Capturadas"
+L["Flags Returned"]="Bandeiras Recuperadas"
+L["Friends List"]="Lista de Amigos"
+L["Friends"]="Amigos"
+L["Galleon"]="Gailleon"
+L["Gates Destroyed"]="Portões Destruidos"
+L["goldabbrev"]="|cffffd700g|r"
+L["Graveyards Assaulted"]="Cemitérios Assaltados"
+L["Graveyards Defended"]="Cemitérios Defendidos"
+L["Hands"]="Mãos"
+L["Head"]="Cabeça"
+L["Hit"]="Acerto"
+L["Home Latency:"]="Latência de Casa:"
+L["HP"]="PV"
+L["HPS"]="PVS"
+L["Legs"]="Pernas"
+L["lvl"]="nível"
+L["Main Hand"]="Mão Principal"
+L["Mitigation By Level: "]="Mitigação por nível"
+L["Nalak"]="Nalak"
+L["No Guild"]="Sem Guilda"
+L["Offhand"]="Mão Secundária"
+L["Oondasta"]="Oondasta"
+L["Orb Possessions"]="Posse de Orbes"
+L["Profit:"]="Lucro:"
+L["Reset Data: Hold Shift + Right Click"]="Redefinir Dados: Segurar Shifr + Clique Direito"
+L["Saved Raid(s)"]="Raide(s) Salva(s)"
+L["Server: "]="Servidor: "
+L["Session:"]="Sessão:"
+L["Sha of Anger"]="Sha da Raiva"
+L["Shoulder"]="Ombros"
+L["silverabbrev"]="|cffc7c7cfs|r"
+L["SP"]="PM"
+L["Spent:"]="Gasto:"
+L["Stats For:"]="Estatísticas para:"
+L["Total CPU:"]="CPU Total:"
+L["Total Memory:"]="Memória Total:"
+L["Total: "]="Total: "
+L["Towers Assaulted"]="Torres Assaltadas"
+L["Towers Defended"]="Torres Defendidas"
+L["Undefeated"]="Invicto"
+L["Unhittable:"]="Inacertável"
+L["Victory Points"]="Pontos de Vitória"
+L["Waist"]="Cintura"
+L["World Boss(s)"]="Chefe"
+L["Wrist"]="Pulsos"
+L["%s: %s tried to call the protected function '%s'."]="%s: %s tentou chamar a função protegida '%s'."
+L["No locals to dump"]="Sem locais para despejar"
+L["%s is attempting to share his filters with you. Would you like to accept the request?"]="%s está tentando compartilhar os filtros dele com você. Gostaria de aceitar o pedido?"
+L["%s is attempting to share the profile %s with you. Would you like to accept the request?"]="%s está tentando compartilhar o perfil %s com você. Gostaria de aceitar o pedido?"
+L["Data From: %s"]="Dados De: %s"
+L["Filter download complete from %s, would you like to apply changes now?"]="Baixa de filtros de %s completada, gostaria de aplicar as alterações agora?"
+L["Lord! It's a miracle! The download up and vanished like a fart in the wind! Try Again!"]="Senhor! É um milagre! O Download sumiu como um peido no vento! Tente novamente!"
+L["Profile download complete from %s, but the profile %s already exists. Change the name or else it will overwrite the existing profile."]="Baixa de perfil completada de %s, mas o perfil %s já existe. Altere o nome ou ele irá sobrescrever o perfil existente."
+L["Profile download complete from %s, would you like to load the profile %s now?"]="Baixa de perfil completada de %s, gostaria de carregar o perfil %s agora?"
+L["Profile request sent. Waiting for response from player."]="Pedido de perfil enviado. Aguardando a resposta do jogador."
+L["Request was denied by user."]="Pedido negado pelo usuário."
+L["Your profile was successfully recieved by the player."]="Seu perfil foi recebido com sucesso pelo jogador."
+L["Auras Set"]="Auras configuradas"
+L["Auras System"]="Sistema de Auras"
+L["Caster DPS"]="DPS Lançador"
+L["Chat Set"]="Bate-Papo configurado"
+L["Chat"]="Bate-papo"
+L["Choose a theme layout you wish to use for your initial setup."]="Escolha o tema de layout que deseje usar inicialmente."
+L["Vintage"]="Clássico"
+L["Classic"]="Clássico"
+L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."]="Clique no botão abaixo para redimensionar os seus quadros de bate-papo, quadros de unidades, e reposicionar as suas barras de ações."
+L["Config Mode:"]="Modo de configuração"
+L["CVars Set"]="CVars configuradas"
+L["CVars"]="CVars"
+L["Gloom & Doom"]="Escuro"
+L["Disable"]="Desativar"
+L["SVUI Installation"]="Instalação do SVUI"
+L["Finished"]="Terminado"
+L["Grid Size:"]="Tamanho da Grade"
+L["Healer"]="Curandeiro"
+L["High Resolution"]="Alta Resolução"
+L["high"]="alto"
+L["Icons Only"]="Apenas Ícones"
+L["If you have an icon or aurabar that you don't want to display simply hold down shift and right click the icon for it to disapear."]="Se existir um ícone ou uma barra de aura que você não queira ver exibida simplesmente mantenha pressionada a tecla Shift e clique no ícone com o botão direito para que o ícone/barra de aura desapareça."
+L["Importance: |cff07D400High|r"]="Importância: |cff07D400Alta|r"
+L["Importance: |cffD3CF00Medium|r"]="Importância: |cffD3CF00Média|r"
+L["Importance: |cffFF0000Low|r"]="Importância: |cffFF0000Baixa|r"
+L["Installation Complete"]="Instalação Completa"
+L["Integrated"]="Integrado"
+L["Layout Set"]="Definições do Layout"
+L["Layout"]="Layout"
+L["Lock"]="Travar"
+L["Low Resolution"]="Baixa Resolução"
+L["low"]="baixo"
+L["Frames unlocked. Move them now and click Lock when you are done."]="Movedores destravados. Mova-os agora e clique Travar quando acabar."
+L["Nudge"]="Ajuste fino"
+L["Physical DPS"]="DPS Físico"
+L["Pixel Perfect Set"]="Perfeição em Pixel Configurado"
+L["Pixel Perfect"]="Perfeição em Píxel"
+L["Please click the button below so you can setup variables and ReloadUI."]="Por favor, clique no botão abaixo para que possa configurar as variáveis e Recarregar a IU."
+L["Please click the button below to setup your CVars."]="Por favor, clique no botão abaixo para configurar as suas Cvars."
+L["Please press the continue button to go onto the next step."]="Por favor, pressione o botão Continuar para passar à próxima etapa."
+L["Resolution Style Set"]="Estilo de Resolução defenido"
+L["Resolution"]="Resolução"
+L["Select the type of aura system you want to use with SVUI's unitframes. The integrated system utilizes both aura-bars and aura-icons. The icons only system will display only icons and aurabars won't be used. The classic system will configure your auras to be default."]="Selecione qual sistema de auras você gostaria de usar com os quadros de unidades do SV. O sistema integrado utiliza ambos barras e ícones para as auras. O sistema somente ícones mostrará somente os ícones e não usará as barras. O sistema clássico configurará suas auras para ser o padrão."
+L["Setup Chat"]="Configurar Bate-papo"
+L["Setup CVars"]="Configurar CVars"
+L["Skip Process"]="Pular Processo"
+L["Sticky Frames"]="Quadros Pegadiços"
+L["Tank"]="Tanque"
+L["The chat windows function the same as Blizzard standard chat windows, you can right click the tabs and drag them around, rename, etc. Please click the button below to setup your chat windows."]="As janelas de bate-papo funcionam da mesma forma das da Blizzard, você pode usar o botão direito nas guias para os arrastar, mudar o nome, etc. Por favor clique no botão abaixo para configurar as suas janelas de bate-papo"
+L["The in-game configuration menu can be accesses by typing the /sv command or by clicking the 'C' button on the minimap. Press the button below if you wish to skip the installation process."]="O modo configuração em jogo pode ser acessado escrevendo o comando /sv ou clicando no botão 'C' no minimapa. Pressione o botão abaixo se desejar pular o processo de instalação"
+L["The Pixel Perfect option will change the overall apperance of your UI. Using Pixel Perfect is a slight performance increase over the traditional layout."]="A opção Perfeição em Píxel mudará a aparência geral da sua IU. Usar Perfeição em Píxel tem uma pequena melhora de performance sobre o leiaute tradicional."
+L["Theme Set"]="Tema configurado"
+L["Theme Setup"]="Configuração do Tema"
+L["This install process will help you learn some of the features in SVUI has to offer and also prepare your user interface for usage."]="Este processo de instalação vai mostrar-lhe algumas das opções que a SVUI tem para oferecer e também vai preparar a sua interface para ser usada."
+L["This is completely optional."]="Isto é completamente opcional."
+L["This part of the installation process sets up your chat windows names, positions and colors."]="Esta parte da instalação é para definir os nomes, posições e cores das suas janelas de bate-papo."
+L["This part of the installation process sets up your World of Warcraft default options it is recommended you should do this step for everything to behave properly."]="Esta parte da instalação serve para definir as suas opcões padrão do WoW, é recomendado fazer isto para que tudo funcione corretamente."
+L["This resolution doesn't require that you change settings for the UI to fit on your screen."]="Esta resolução não exige que altere as definições para que a interface caiba no seu ecrã (monitor)."
+L["This resolution requires that you change some settings to get everything to fit on your screen."]="Esta resolução requer que altere algumas definições para que tudo caiba no seu ecrã (monitor)."
+L["This will change the layout of your unitframes, raidframes, and statistics."]="Isto vai mudar o layout dos seus quadros de unidades, quadros de raide e textos informativos."
+L["Trade"]="Comércio"
+L["Using this option will cause your borders around frames to be 1 pixel wide instead of 3 pixel. You may have to finish the installation to notice a differance. By default this is enable."]="Usar essa opção criará bordas em torno dos quadros de 1 píxel de largura em vez de 3 píxels. Você pode ter que terminar a instalação para notar alguma diferença. Por padrão está opção está ativada."
+L["Welcome to SVUI version %s!"]="Bem-vindo à versão %s da SVUI!"
+L["You are now finished with the installation process. If you are in need of technical support please visit us at http://www.wowinterface.com."]="O processo de instalação está agora terminado. Se precisar de suporte técnico por favor visite-nos no site http://www.wowinterface.com."
+L["You can always change fonts and colors of any element of SVUI from the in-game configuration."]="As cores e fontes da SVUI podem ser mudadas em qualquer momento no modo de configuração demtro do jogo."
+L["You can now choose what layout you wish to use based on your combat role."]="Pode agora escolher o layout que pretende usar baseado no seu papel."
+L["You may need to further alter these settings depending how low you resolution is."]="Poderá ter de alterar estas definições dependendo de quão baixa for a sua resolução."
+L["Your current resolution is %s, this is considered a %s resolution."]="A sua resolução actual é %s, esta é considerada uma resolução %s."
+L["Bars"]="Barras"
+L["Calendar"]="Calendário"
+L["Can't Roll"]="Não pode rolar"
+L["Disband Group"]="Dissolver Grupo"
+L["Empty Slot"]="Espaço Vazio"
+L["Enable"]="Ativar"
+L["Experience"]="Experiência"
+L["Fishy Loot"]="Saque de Peixes"
+L["Left Click:"]="Clique Esquerdo:"
+L["Raid Menu"]="Menu de Raide"
+L["Remaining:"]="Restante:"
+L["Rested:"]="Descansado:"
+L["Right Click:"]="Clique Direito:"
+L["Show BG Texts"]="Mostrar Textos do CB"
+L["Toggle Chat Frame"]="Mostrar/Ocultar Bat-papo"
+L["Toggle Configuration"]="Mostrar/Ocultar Modo de Configuração"
+L["XP:"]="XP:"
+L["You don't have permission to mark targets."]="Você não tem permissão para marcar alvos."
+L["ABOVE_THREAT_FORMAT"]="%s: %.0f%% [%.0f%% above |cff%02x%02x%02x%s|r]"
+L[" Frames"]="Quadros"
+L["Alternative Power"]="Recurso Alternativo"
+L["Arena Frames"]="Quadros de Arenas"
+L["Auras Frame"]="Quadros de Auras"
+L["Bags"]="Bolsas"
+L["Bar "]="Barra "
+L["BNet Frame"]="Quadro do Bnet"
+L["Special Ability Button"]="Botão de Chefe"
+L["Boss Frames"]="Quadros dos Chefes"
+L["Experience Bar"]="Barra de Experiência"
+L["Focus Castbar"]="Barra de Lançamento do Foco"
+L["Focus Frame"]="Quadro do Foco"
+L["FocusTarget Frame"]="Quadro do Alvo do Foco"
+L["GM Ticket Frame"]="Quadro de Consulta com GM"
+L["Left Dock"]="Bate-papo esquerdo"
+L["Loot / Alert Frames"]="Quadro de Saque / Alerta"
+L["Loot Frame"]="Quadro de Saque"
+L["Loss Control Icon"]="Ícone de Perda de Controle"
+L["MA Frames"]="Quadro do Assistente Principal"
+L["Micromenu"]="Micromenura"
+L["Minimap"]="Minimapa"
+L["MT Frames"]="Quadro do Tank Principal"
+L["Party Frames"]="Quadros de Grupo"
+L["Pet Bar"]="Barra do Ajudante"
+L["Pet Frame"]="Quadro do Ajudante"
+L["PetTarget Frame"]="Quadro do Alvo do Ajudante"
+L["Player Castbar"]="Barra de lançamento do Jogador"
+L["Player Frame"]="Quadro do Jogador"
+L["Raid 1-"]="Raide 1-"
+L["Reputation Bar"]="Barra de Reputação"
+L["Right Dock"]="Bate-papo direito"
+L["Stance Bar"]="Barra de Postura"
+L["Target Castbar"]="Barra de lançamento do Alvo"
+L["Target Frame"]="Quadro do Alvo"
+L["TargetTarget Frame"]="Quadro do Alvo do Alvo"
+L["Tooltip"]="Tooltip"
+L["Totems"]="Totens"
+L["Vehicle Seat Frame"]="Quadro de Assento de Veículo"
+L["Watch Frame"]="Quadro de acompanhamento de Objetivos"
+L["Weapons"]="Armas"
+L["Discipline"]="Disciplina"
+L["Holy"]="Sagrado"
+L["Mistweaver"]="Tecelão da Névoa"
+L["Restoration"]="Restauração"
+L[" |cff00ff00bound to |r"]=" |cff00ff00Ligado a |r"
+L["%s frame(s) has a conflicting anchor point, please change either the buff or debuff anchor point so they are not attached to each other. Forcing the debuffs to be attached to the main unitframe until fixed."]="%s quadro(s) tem um ponto de fixação em conflito, por favor mude o ponto de fixação do quadro de bônus ou de penalidades para que eles não fiquem ligados uns aos outros. Forçando as penalidades a ficarem anexadas ao quadro principal até que sejam consertados."
+L["All keybindings cleared for |cff00ff00%s|r."]="Todos os atalhos livres para"
+L["Already Running.. Bailing Out!"]="Já está executando... Cancelando a ordenação!"
+L["Battleground statistics temporarily hidden, to show type /bgstats."]="Os textos Informativos dos Campos de Batalha estão temporáriamente ocultos, para serem mostrados digite /bgstats ou clique direito no ícone 'C' perto do minimapa."
+L["Battleground statistics will now show again if you are inside a battleground."]="Os textos Informativos irão agora ser mostrados se estiver dentro de um Campo de Batalha."
+L["Binds Discarded"]="Ligações Descartadas"
+L["Binds Saved"]="Ligações Salvas"
+L["Confused.. Try Again!"]="Confuso... Tente novamente!"
+L["Deleted %d gray items. Total Worth: %s"]="%d itens cinzentos destruidos. Valor total %s"
+L["No gray items to delete."]="Nenhum item cinzento para destruir."
+L["No gray items to sell."]="Nenhum item cinzento para vender"
+L["The spell '%s' has been added to the BlackList unitframe aura filter."]='O feitiço "%s" foi adicionado à Lista Negra dos filtros das auras de unidades.'
+L["Vendored gray items for:"]="Vendeu os itens cinzentos por:"
+L["You don't have enough money to repair."]="Você não tem dinheiro suficiente para reparar."
+L["You must be at a vendor."]="Tem de estar num vendedor."
+L["Your items have been repaired for: "]="Seus itens foram reparadas por: "
+L["Your items have been repaired using guild bank funds for: "]="Seus itens foram reparados usando fundos do banco da guilda por: "
+L["Your version of SVUI is out of date. You can download the latest version from http://www.wowinterface.com"]="A sua versão da SVUI está desatualizada. Pode baixar a versão mais recente no site http://www.wowinterface.com."
+L["|cFFE30000Lua error recieved. You can view the error message when you exit combat."]="|cFFE30000Erro Lua recebido. Pode ver a mensagem de erro quando sair de combate"
+L["A setting you have changed will change an option for this character only. This setting that you have changed will be uneffected by changing user profiles. Changing this setting requires that you reload your User Interface."]="A definição que você alterou afetará apenas este personagem. Esta definição que você alterou não será afetada por mudanças de perfil. Alterar esta difinição requer que você recarregue a sua interface."
+L["Are you sure you want to delete all your gray items?"]="Tem a certeza de que deseja destruir todos os seus itens cinzentos?"
+L["Are you sure you want to disband the group?"]="Tem a certeza de que quer dissolver o grupo?"
+L["Are you sure you want to reset every mover back to it's default position?"]="Tem a certeza de que deseja restaurar todos os movedores de volta para a sua posição padrão?"
+L["Because of the mass confusion caused by the new aura system I've implemented a new step to the installation process. This is optional. If you like how your auras are setup go to the last step and click finished to not be prompted again. If for some reason you are prompted repeatedly please restart your game."]="Devido à grande confusão causada pelo novo sistema de auras foi implementado um novo passo no processo de instalação. Este passo é opcional, se você gosta da maneira que as suas auras estão configuradas vá para o último passo e clique em Terminado para não ser solicitado a configurar este passo novamente. Se por algum motivo for repetidamente solicitado a fazê-lo, por favor reinicie o seu jogo."
+L["Can't buy anymore slots!"]="Não é possível comprar mais espaços!"
+L["Disable Warning"]="Desativar Aviso"
+L["Discard"]="Descartar"
+L["Do you swear not to post in technical support about something not working without first disabling the addon/package combination first?"]="Você jura não postar no suporte técnico sobre alguma coisa não funcionando sem antes desabilitar a combinação addon/módulo?"
+L["Hover your mouse over any actionbutton or spellbook button to bind it. Press the escape key or right click to clear the current actionbutton's keybinding."]="Paire com o seu rato (mouse) sobre qualquer botão de ação ou botão do grimório para fazer uma Ligação. Pressione a tecla Escape ou clique com o botão direito para limpar o atalho atual."
+L["I Swear"]="Eu Juro"
+L["Oh lord, you have got SVUI and Tukui both enable at the same time. Select an addon to disable."]="Oh senhor, você está com os addons SVUI e Tuki ativos ao mesmo tempo. Selecione um para desativar."
+L["One or more of the changes you have made require a ReloadUI."]="Uma ou mais das alterações que fez requerem que recarregue a IU."
+L["One or more of the changes you have made will effect all characters using this addon. You will have to reload the user interface to see the changes you have made."]="Uma ou mais das alterações que fez afetará todos os personagens que usam este addon. Você terá que recarregar a interface para ver as alterações que fez."
+L["Save"]="Salvar"
+L["Using the healer layout it is highly recommended you download the addon Clique if you wish to have the click-to-heal function."]=true;
+L["You have changed the pixel perfect option. You will have to complete the installation process to remove any graphical bugs."]="Você alterou a opção Perfeição em Píxel. Precisará completar o processo de instalação para remover todos os problemas gráficos."
+L["You have changed your UIScale, however you still have the AutoScale option enable in SV. Press accept if you would like to disable the Auto Scale option."]="Você mudou a Escala da sua IU, no entanto ainda tem a opção de dimensionamento automático ativa na SV. Pressione Aceitar se gostaria de desativar a opção de dimensionamento automático."
+L["You must purchase a bank slot first!"]="Você deve comprar um espaço no banco primeiro!"
+L["Count"]="Contar"
+L["Targeted By:"]="Sendo Alvo de:"
+L["A raid marker feature is available by pressing Escape -> Keybinds scroll to the bottom under SVUI and setting a keybind for the raid marker."]="A opção Marcas de Raide está disponivel pressionando Escape -> Teclas de Atalho, rolando tudo para o fundo debaixo de SVUI e definindo uma tecla de atalho para o Raid Marker."
+L["SVUI has a dual spec feature which allows you to load different profiles based on your current spec on the fly. You can enable this from the profiles tab."]="A SVUI contém o modo de duas especializações, que permite que carregue perfis diferentes baseado na sua especialização atual rapidamente. Você pode ativar esta opção na guia Perfis."
+L["For technical support visit us at http://www.wowinterface.com."]="Para suporte técnico visite-nos no site http://www.wowinterface.com."
+L["If you accidently remove a chat frame you can always go the in-game configuration menu, press install, go to the chat portion and reset them."]="Se acidentalmente remover um quadro de conversação você pode sempre ir ao menu de configuração em jogo, pressionar instalar, ir até a etapa de bate-papo e os restaurar."
+L["If you are experiencing issues with SVUI try disabling all your addons except SVUI, remember SVUI is a full UI replacement addon, you cannot run two addons that do the same thing."]="Se estiver a ter problemas com a SVUI tente desativar todos os addons exceto a SVUI, lembre-se que a SVUI é um addon de substituição de interface completo, e não se consegue executar dois addons que fazem a mesma coisa."
+L["The buff panel to the right of minimap is a list of your consolidated buffs. You can disable it in Buffs and Debuffs options of SV."]="O painel de bônus a direita do minimapa é uma lista dos seus bônus consolidados. Você pode desativar isto nas opções de Bônus e Penalidades da SV."
+L["The focus unit can be set by typing /focus when you are targeting the unit you want to focus. It is recommended you make a macro to do this."]="A unidade de Foco pode ser definida escrevendo /focus quando voce tem no alvo a unidade que quer tal. É recomendado que faça uma macro para este efeito."
+L["To move abilities on the actionbars by default hold shift + drag. You can change the modifier key from the actionbar options menu."]="Para mover habilidades nas barras de ação (modo padrão) mantenha pressionado Shift enquanto arrasta. Você pode mudar a tecla no menu de opções das barras de ações."
+L["To setup which channels appear in which chat frame, right click the chat tab and go to settings."]="Para configurar que canais aparecem em cada quadro de conversação, clique com o botão direito no guia do bate-papo e vá a configurações."
+L["Using the /farmmode <size> command will spawn a larger minimap on your screen that can be moved around, very useful when farming."]="Usar o comando /farmmode <tamanho> fará aparecer um minimapa maior na sua tela que pode ser movido, muito útil quando se está a farmar."
+L["You can access copy chat and chat menu functions by mouse over the top right corner of chat panel and left/right click on the button that will appear."]="Você pode acessar ao 'copiar bate-papo' e ao menu de funções do bate-papo passando com o rato (mouse) no canto superior direito do painel e clicando botão esquerdo/direito no botão que irá aparecer."
+L["You can see someones average item level of their gear by holding shift and mousing over them. It should appear inside the tooltip."]="Você pode ver o nivel médio de itens que outra pessoa tem mantendo shift pressionado e passando com o rato (mouse) por cima deles. Deverá aparecer na tooltip."
+L["You can set your keybinds quickly by typing /kb."]="Você pode definir os seus atalhos rapidamente escrevendo /kb."
+L["You can toggle the microbar by using your middle mouse button on the minimap you can also accomplish this by enabling the actual microbar located in the actionbar settings."]="Você pode ativar a micro barra clicando no minimapa com o seu botão do meio do rato (mouse), pode também conseguir isto ativando a verdadeira micro barra nas definições das barras de ações."
+L["You can use the /resetui command to reset all of your moveables. You can also use the command to reset a specific mover, /resetui <mover name>.\nExample: /resetui Player Frame"]="Você pode usar o comando /resetui para restaurar todos os movedores. Pode usar este comando também para restaurar um movedor especifico escrevendo /resetui <nome do movedor> \nExemplo: /resetui Player Frame"
+L["Ghost"]="Fantasma"
+L["Offline"]="Desconectado"
+L["ENH_LOGIN_MSG"]="Você está a usar |cff1784d1SVUI Enhanced|r versão %s%s|r."
+L["Your version of SVUI is to old. Please, download the latest version from http://www.wowinterface.com."]="A sua versão do SVUI é muita antiga (requerida v6.51 ou superior). Por favor, descarregue a versão mais recente em http://www.wowinterface.com."
+L["Equipment"]="Equipamento"
+L["EQUIPMENT_DESC"]="Ajuste os parâmetros para a mudança de equipamento quando muda de especialização ou entra num campo de batalha."
+L["No Change"]="Sem mudança"
+L["Specialization"]="Especialização"
+L["Enable/Disable the specialization switch."]="Activar/desactivar a mudança com a especialização."
+L["Primary Talent"]="Talento primário"
+L["Choose the equipment set to use for your primary specialization."]="Escolha o conjunto de equipamento para usar com a especialização primária."
+L["Secondary Talent"]="Talento secundário"
+L["Choose the equipment set to use for your secondary specialization."]="Escolha o conjunto de equipamento para usar com a especialização secundária."
+L["Battleground"]="Campo de batalha"
+L["Enable/Disable the battleground switch."]="Activar/desactivar a mudança em Campo de batalha."
+L["Equipment Set"]="Conjunto de Equipamento"
+L["Choose the equipment set to use when you enter a battleground or arena."]="Escolha o conjunto de equipamento para usar quando entra num Campo de batalha."
+L["You have equipped equipment set: "]="Você tem equipado o conjunto: "
+L["DURABILITY_DESC"]="Ajuste as opções para a informação de durabilidade no ecrã de informação do personagem."
+L["Enable/Disable the display of durability information on the character screen."]="Activar/desactivar a informação de durabilidade no ecrã de informação do personagem."
+L["Damaged Only"]="Só Danificados"
+L["Only show durabitlity information for items that are damaged."]="Só mostrar informação de durabilidade para itens danificados."
+L["ITEMLEVEL_DESC"]="Adjust the settings for the item level information on the character screen."
+L["Enable/Disable the display of item levels on the character screen."]=true;
+L["Miscellaneous"]=true;
+L["Equipment Set Overlay"]=true;
+L["Show the associated equipment sets for the items in your bags (or bank)."]=true;
+L["Layout Transparency"]=true;
+L["Changes the transparency of all the moveables."]=true;
+L["Automatic Role Assignment"]=true;
+L["Enables the automatic role assignment based on specialization for party / raid members (only work when you are group leader or group assist)."]=true;
+L["Hide Role Icon in combat"]=true;
+L["All role icons (Damage/Healer/Tank) on the unit frames are hidden when you go into combat."]=true;
+L["GPS"]="GPS"
+L["Show the direction and distance to the selected party or raid member."]="Mostrar a direcção e distância para o membro do grupo ou raide seleccionado."
+L["Attack Icon"]=true;
+L["Show attack icon for units that are not tapped by you or your group, but still give kill credit when attacked."]=true;
+L["Show class icon for units."]=true;
+L["Above Minimap"]=true;
+L["Location Digits"]=true;
+L["Number of digits for map location."]=true;
+L["Hide minimap while in combat."]=true;
+L["FadeIn Delay"]=true;
+L["The time to wait before fading the minimap back in after combat hide. (0 = Disabled)"]=true;
+L["Style Buttons"]="Customizar Botões"
+L["Customize the minimap buttons in SVUI style."]="Customiza os botões do minimapa no estilo do SV."
+L["SVUI Style"]="Estilo de Customização"
+L["Change settings for how the minimap buttons are styled."]="Mudar definições de como os botões do minimapa são customizados."
+L["The size of the minimap buttons."]="O tamanho dos botões do minimapa."
+L["No Anchor Bar"]="Sem Ancora de Barra"
+L["Horizontal Anchor Bar"]="Ancora de Barra Horizontal"
+L["Vertical Anchor Bar"]="Ancora de Barra Vertical"
+L["Layout Direction"]=true;
+L["Normal is right to left or top to bottom, or select reversed to switch directions."]=true;
+L["Normal"]=true;
+L["Reversed"]=true;
+L["PvP Autorelease"]="Auto-libertar em JxJ"
+L["Automatically release body when killed inside a battleground."]="Automaticamente libertar o corpo quando morto num campo de batalha."
+L["Track Reputation"]="Controlar Reputação"
+L["Automatically change your watched faction on the reputation bar to the faction you got reputation points for."]="Mudar automaticamente a facção controlada para a facção na qual acabou de ganhar pontos de reputação."
+L["Select Quest Reward"]=true;
+L["Automatically select the quest reward with the highest vendor sell value."]=true;
+L["Item Level"]=true;
+L["Target Range"]=true;
+L["Distance"]=true;
+L["Actionbar1DataPanel"]='Actionbar 1'
+L["Actionbar3DataPanel"]='Actionbar 3'
+L["Actionbar5DataPanel"]='Actionbar 5'
+L["Sunsong Ranch"]="Fazenda Sol Cantante"
+L["The Halfhill Market"]="Mercado da Meia Colina"
+L["Tilled Soil"]="Terra Arada"
+L["Right-click to drop the item."]=true;
+L["Toolbox"]=true;
+L["COMIX_DESC"]="Toggle the comic popups during combat"
+L["FARMING_MODE_DESC"]="Adjust the settings for the tools that help your farming and professions."
+L["SNACKS_DESC"]="Adjust the settings for the consumables bar."
+L["Toolbox Bars"]=true;
+L["Toolbox Portal Bar"]=true;
+L["Toolbox Seed Bar"]=true;
+L["Toolbox Tools Bar"]=true;
+L["Enable/Disable the laborer bars."]=true;
+L["Only active buttons"]=true;
+L["Only show the buttons for the seeds, portals, tools you have in your bags."]=true;
+L["Drop Tools"]=true;
+L["Automatically drop tools from your bags when leaving the farming area."]=true;
+L["Seed Bar Direction"]=true;
+L["The direction of the seed bar buttons (Horizontal or Vertical)."]=true;
+L["Threat Text"]=true;
+L["Display threat level as text on targeted, boss or mouseover nameplate."]=true;
+L["Target Count"]=true;
+L["Display the number of party / raid members targetting the nameplate unit."]=true;
+L["Heal Glow"]=true;
+L["Direct AoE heals will let the unit frames of the affected party / raid members glow for the defined time period."]=true;
+L["Glow Duration"]=true;
+L["The amount of time the unit frames of party / raid members will glow when affected by a direct AoE heal."]=true;
+L["Glow Color"]=true;
+L["Raid Marker Bar"]=true;
+L["Display a quick action bar for raid targets and world markers."]=true;
+L["Modifier Key"]=true;
+L["Set the modifier key for placing world markers."]=true;
+L["Shift Key"]=true;
+L["Ctrl Key"]=true;
+L["Alt Key"]=true;
+L["Raid Markers"]=true;
+L["Click to clear the mark."]=true;
+L["Click to mark the target."]=true;
+L["%sClick to remove all worldmarkers."]=true;
+L["%sClick to place a worldmarker."]=true;
+L["WatchFrame"]=true;
+L["WATCHFRAME_DESC"]="Adjust the settings for the visibility of the watchframe (questlog) to your personal preference."
+L["Hidden"]=true;
+L["Collapsed"]=true;
+L["Settings"]=true;
+L["City (Resting)"]=true;
+L["PvP"]=true;
+L["Arena"]=true;
+L["Party"]=true;
+L["Raid"]=true;
+L["Progression Info"]=true;
+L["Display the players raid progression in the tooltip, this may not immediately update when mousing over a unit."]=true
\ No newline at end of file
diff --git a/SVUI_!Core/language/russian_ui.lua b/SVUI_!Core/language/russian_ui.lua
new file mode 100644
index 0000000..3c0237d
--- /dev/null
+++ b/SVUI_!Core/language/russian_ui.lua
@@ -0,0 +1,593 @@
+local L = Librarian("Linguist"):Lang("ruRU");
+if not L then return; end
+L["Conversation"]    = "Разговор"
+L["General"]         = "Общий"
+L["LocalDefense"]    = "ОборонаЛокальный"
+L["LookingForGroup"] = "ПоискСпутников"
+L["Trade"]           = "Торговля"
+L["WorldDefense"]    = "ОборонаГлобальный"
+L["S_Conversation"]    = "Ра"
+L["S_General"]        = "О"
+L["S_LocalDefense"]    = "ОЛ"
+L["S_LookingForGroup"] = "ПС"
+L["S_Trade"]          = "Т"
+L["S_WorldDefense"]    = "ОГ"
+L["Hearthstone"] = true;
+--[[LOGIN MESSAGE]]--
+L["LOGIN_MSG"] = "обро пожаловать в |cffFFFF1ASVUI|r! Держите свои %s и ваши %s."
+L["LOGIN_MSG2"] = "Версия |cffAA78FF%s|r, наберите /sv для доступа в меню настроек."
+--[[OPTION MESSAGES]]--
+L["AURAS_DESC"] = "Настройка иконок эффектов, находящихся у миникарты."
+L["BAGS_DESC"] = "Настройки сумок SVUI"
+L["CHAT_DESC"] = "Настройте отображение чата SV."
+L["STATS_DESC"] = "Configure docked stat panels.";
+L["SVUI_DESC"] = "SVUI это аддон для полной замены пользовательского интерфейса World of Warcraft."
+L["NAMEPLATE_DESC"] = "Настройки индикаторов здоровья."
+L["PANEL_DESC"] = "Регулирование размеров левой и правой панелей. Это окажет эффект на чат и сумки."
+L["ART_DESC"] = "Установки скинов"
+L["TOGGLEART_DESC"] = "Включить / выключить этот скин."
+L["TOOLTIP_DESC"] = "Опций подсказки"
+L["TEXT_FORMAT_DESC"] = "Select the formatting of this text"
+L["import"] = "Существующие профили"
+L["import_desc"] = "Вы можете создать новый профиль, введя название в поле ввода, или выбрать один из уже существующих профилей."
+L["import_sub"] = "Выбор одиного из уже доступных профилей"
+L["copy_name"] = "Скопировать из"
+L["copy_desc"] = "Скопировать настройки из выбранного профиля в активный."
+L["current"] = "            "
+L["default"] = "По умолчанию"
+L["delete"] = "Удалить профиль"
+L["delete_confirm"] = "Вы уверены, что вы хотите удалить выбранный профиль?"
+L["delete_desc"] = "Удалить существующий и неиспользуемый профиль из БД для сохранения места, и очистить SavedVariables файл."
+L["delete_sub"] = "Удаление профиля из БД"
+L["intro"] = "Изменяя активный профиль, вы можете задать различные настройки модификаций для каждого персонажа."
+L["export"] = "Новый"
+L["export_sub"] = "Создать новый чистый профиль"
+L["profiles"] = "Профили"
+L["profiles_sub"] = "Управление профилями"
+L["reset"] = "Сброс профиля"
+L["reset_desc"] = "Если ваша конфигурации испорчена или если вы хотите настроить всё заново - сбросьте текущий профиль на стандартные значения."
+L["reset_sub"] = "Сброс текущего профиля на стандартный"
+L["SVUI_DockBottomCenter"] = "Bottom Data Dock"
+L["SVUI_DockTopCenter"] = "Top Data Dock"
+--[[REACTION TEXTS]]--
+L[" is drinking."] = true;
+L["Leeeeeroy!"] = true;
+L["No Food: "] = "Нет еды: "
+L["No Flask: "] = "Нет настоя: "
+L["All Buffed!"] = "Еда и настой есть у всех. Можно щемить!"
+L["Check food and flask"] = "Проверка еды и настоя"
+L["Thanks for "] = "Спасибо за "
+L[" received from "] = " получено от "
+L["GO!"] = "ВЫСТУПАЕМ!"
+L["Pulling %s in %s.."] = "Атакуем %s через %s.."
+L["Pull ABORTED!"] = "Атака ОТМЕНЕНА!"
+L["%s has prepared a %s - [%s]."] = "%s готовит %s - [%s]."
+L["%s has prepared a %s."] = "%s готовит %s."
+L["%s has put down a %s."] = "%s ставит %s."
+L["%s is casting %s."] = "%s создает %s."
+L["%s is casting %s. Click!"] = "%s создает %s. Кликаем!"
+L["%s used a %s."] = "%s использует %s."
+--[[FORMATTED INSTALLER TEXTS]]--
+L["|cffD3CF00Recommended|r"] = true;
+L["Recommended: |cff99FF00Kaboom!|r"] = true;
+L["Recommended: |cff99FF00Super|r"] = true;
+L["Recommended: |cffFF0000Small Row!|r"] = true;
+L["Recommended: |cffFF0000Icon Lovers!|r"] = true;
+L["|cffFF9F00KABOOOOM!|r"] = true;
+L["|cffAF30FFThe Darkest Night|r"] = true;
+L["|cff00FFFFPlain and Simple|r"] = true;
+L["|cff00FFFFLets Do This|r"] = true;
+L["|cff00FFFFSimply Simple|r"] = true;
+L["|cff00FFFFEl Compacto|r"] = true;
+L["|cff00FFFFHealer Extraordinaire|r"] = true;
+L["|cff00FFFFLean And Clean|r"] = true;
+L["|cff00FFFFMore For Less|r"] = true;
+L["|cff00FFFFWhat Big Buttons You Have|r"] = true;
+L["|cff00FFFFThe Double Down|r"] = true;
+--[[NORMAL INSTALLER TEXTS]]--
+L["This is SVUI version %s!"] = true;
+L["Before I can turn you loose, persuing whatever villainy you feel will advance your professional career ... I need to ask some questions and turn a few screws first."] = true;
+L["At any time you can get to the config options by typing the command /sv. For quick changes to frame, bar or color sets, call your henchman by clicking the button on the bottom right of your screen. (Its the one with his stupid face on it)"] = true;
+L["CHOOSE_OR_DIE"] = CHOOSE_FACTION.." "..OR_CAPS.." "..HIT.." "..CONTINUE;
+L["Whether you want to or not, you will be needing a communicator so other villains can either update you on their doings-of-evil or inform you about the MANY abilities of Chuck Norris"] = true;
+L["The chat windows function the same as standard chat windows, you can right click the tabs and drag them, rename them, slap them around, you know... whatever. Clickity-click to setup your chat windows."] = true;
+L["Your current resolution is %s, this is considered a %s resolution."] = true;
+L["This resolution requires that you change some settings to get everything to fit on your screen."] = true;
+L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."] = true;
+L["You may need to further alter these settings depending how low you resolution is."] = true;
+L["This resolution doesn't require that you change settings for the UI to fit on your screen."] = true;
+L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."] = true;
+L["This is completely optional."] = true;
+L["So what you think your better than me with your big monitor? HUH?!?!"] = true;
+L["Dont forget whos in charge here! But enjoy the incredible detail."] = true;
+L["Why are you playing this on what I would assume is a calculator display?"] = true;
+L["Enjoy the ONE incredible pixel that fits on this screen."] = true;
+L["Choose a theme layout you wish to use for your initial setup."] = true;
+L["You can always change fonts and colors of any element of SVUI from the in-game configuration."] = true;
+L["This theme tells the world that you are a villain who can put on a show "] = true;
+L["or better yet, you ARE the show!"] = true;
+L["Kaboom!"] = true;
+L["This theme indicates that you have no interest in wasting time"] = true;
+L["the dying begins NOW!"] = true;
+L["Darkness"] = true;
+L["This theme is for villains who take pride in their class"] = true;
+L["villains know how to reprezent!"] = true;
+L["This theme is for any villain who sticks to their traditions"] = true;
+L["you don't need fancyness to kick some ass!"] = true;
+L["Vintage"] = true;
+L["Layout"] = true;
+L["You can now choose what primary unitframe style you wish to use."] = true;
+L["This will change the layout of your unitframes (ie.. Player, Target, Pet, Party, Raid ...etc)."] = true;
+L["This layout is anything but minimal! Using this is like being at a rock concert"] = true;
+L["then annihilating the crowd with frickin lazer beams!"] = true;
+L["Super"] = true;
+L["This layout is for the villain who just wants to get things done!"] = true;
+L["But he still wants to see your face before he hits you!"] = true;
+L["Simple"] = true;
+L["Just the necessities so you can see more of the world around you."] = true;
+L["You dont need no fanciness getting in the way of world domination do you?"] = true;
+L["Compact"] = true;
+L["This has all the pizzaz of Super frames but uses Compact party and raid frames."] = true;
+L["Sometimes a little fifty-fifty goes a long way."] = true;
+L["Healer"] = true;
+L["Bar Setup"] = true;
+L["Choose a layout for your action bars."] = true;
+L["Sometimes you need big buttons, sometimes you don't. Your choice here."] = true;
+L["Lets keep it slim and deadly, not unlike a ninja sword."] = true;
+L["You dont ever even look at your bar hardly, so pick this one!"] = true;
+L["Small Row"] = true;
+L["Granted, you dont REALLY need the buttons due to your hotkey-leetness, you just like watching cooldowns!"] = true;
+L["Sure thing cowboy, your secret is safe with me!"] = true;
+L["Small X2"] = true;
+L["The better to PEW-PEW you with my dear!"] = true;
+L["When you have little time for mouse accuracy, choose this set!"] = true;
+L["Big Row"] = true;
+L["It's like dual-wielding two big reasons for your enemies to back the **** up!"] = true;
+L["Double your bars then double their size for maximum button goodness!"] = true;
+L["Big X2"] = true;
+L["Auras System"] = true;
+L["Select the type of aura system you want to use with SVUI's unitframes. The Icon Lovers set will display only icons and aurabars won't be used. The Vintage set will use the original game style and the Gimme Everything set does just what it says.... icons, bars and awesomeness."] = true;
+L["If you have an icon or aurabar that you don't want to display simply hold down shift and right click the icon for it to suffer a painful death."] = true;
+L["Vintage"] = true;
+L["Icon Lovers"] = true;
+L["The Works!"] = true;
+L["Installation Complete"] = true;
+L["Thats it! All done! Now we just need to hand these choices off to the henchmen so they can get you ready to (..insert evil tasks here..)!"] = true;
+L["Click the button below to reload and get on your way! Good luck villain!"] = true;
+L["THE_BUTTON_BELOW"] = "THE\nBUTTON\nBELOW";
+--[[UI TEXTS]]--
+L["Meanwhile"]=true;
+L["..at "]=true;
+L["A taint has occured that is preventing you from using the queue system. Please reload your user interface and try again."]="Произошла ошибка, которая не позволит встать в очередь. Пожалуйста, перезагрузите интерфейс и попробуйте снова"
+L["Binding"]="Назначение"
+L["Key"]="Клавиша"
+L["KEY_ALT"]="A"
+L["KEY_CTRL"]="C"
+L["KEY_DELETE"]="Del"
+L["KEY_HOME"]="Hm"
+L["KEY_INSERT"]="Ins"
+L["KEY_MOUSEBUTTON"]="M"
+L["KEY_MOUSEWHEELDOWN"]="MwD"
+L["KEY_MOUSEWHEELUP"]="MwU"
+L["KEY_NUMPAD"]="N"
+L["KEY_PAGEDOWN"]="PD"
+L["KEY_PAGEUP"]="PU"
+L["KEY_SHIFT"]="S"
+L["KEY_SPACE"]="SpB"
+L["No bindings set."]="Нет назначений"
+L["Remove Bar %d Action Page"]="Удалить панель %d из списка переключаемых"
+L["Trigger"]="Триггер"
+L["Delete Grays"]="Удалить предметы серого качества"
+L["Hold Control + Right Click:"]="Зажать control + ПКМ:"
+L["Hold Shift + Drag:"]="Зажать shift и перетаскивать:"
+L["Hold Shift:"]="С зажатым shift'ом:"
+L["Purchase"]="Приобрести слот"
+L["Reset Position"]="Сбросить позицию"
+L["Sort Bags"]="Сортировать"
+L["Sort Tab"]="Сортировать вкладки"
+L["Stack Bags to Bank"]="Сложить в банк"
+L["Stack Bank to Bags"]="Сложить в сумки"
+L["Stack Items"]="Собрать предметы"
+L["Temporary Move"]="Временное перемещение"
+L["Toggle Bags"]="Показать сумки"
+L["Vendor Grays"]="Продавать серые предметы"
+L["AFK"]="АФК"
+L["DND"]="ДНД"
+L["G"]="Г"
+L["I"]="П"
+L["IL"]="ЛП"
+L["Invalid Target"]="Неверная цель"
+L["O"]="Оф"
+L["P"]="Гр"
+L["PL"]="Лидер гр."
+L["R"]="Р"
+L["RL"]="РЛ"
+L["RW"]="Объявление"
+L["says"]="говорит"
+L["whispers"]="шепчет"
+L["yells"]="кричит"
+L["(Hold Shift) Memory Usage"]="(Зажать Shift) Использование памяти"
+L["AP"]="Сила Ат."
+L["AVD: "]="Защита: "
+L["Avoidance Breakdown"]="Распределение защиты"
+L["Bandwidth"]="Канал"
+L["Bases Assaulted"]="Штурмы баз"
+L["Bases Defended"]="Оборона баз"
+L["Carts Controlled"]="Захваты вагонеток"
+L["Character: "]="Персонаж: "
+L["Chest"]="Грудь"
+L["Combat Time"]="В бою"
+L["copperabbrev"]="|cffeda55fм|r"
+L["Defeated"]="Убит"
+L["Deficit:"]="Убыток:"
+L["Demolishers Destroyed"]="Разрушителей уничтожено"
+L["Download"]="Загрузка"
+L["DPS"]="УВС"
+L["Earned:"]="Заработано"
+L["Feet"]="Ступни"
+L["Flags Captured"]="Захваты флага"
+L["Flags Returned"]="Возвраты флага"
+L["Friends List"]="Список друзей"
+L["Friends"]="Друзья"
+L["Galleon"]="Галлеон"
+L["Gates Destroyed"]="Врат разрушено"
+L["goldabbrev"]="|cffffd700з|r"
+L["Graveyards Assaulted"]="Штурмы кладбищ"
+L["Graveyards Defended"]="Оборона кладбищ"
+L["Hands"]="Кисти рук"
+L["Head"]="Голова"
+L["Hit"]="Метк."
+L["Home Latency:"]="Локальная задержка: "
+L["HP"]="+ Исцел."
+L["HPS"]="ИВС"
+L["Legs"]="Ноги"
+L["lvl"]="ур."
+L["Main Hand"]="Правая рука"
+L["Mitigation By Level: "]="Снижение на уровне: "
+L["Nalak"]="Налак"
+L["No Guild"]="Нет гильдии"
+L["Offhand"]="Левая рука"
+L["Oondasta"]="Ундаста"
+L["Orb Possessions"]="Захваты сферы"
+L["Profit:"]="Прибыль:"
+L["Reset Data: Hold Shift + Right Click"]="Сбросить нанные: Shift + ПКМ"
+L["Saved Raid(s)"]="Сохраненные рейды"
+L["Server: "]="На сервере:"
+L["Session:"]="За сеанс:"
+L["Sha of Anger"]="Ша Злости"
+L["Shoulder"]="Плечо"
+L["silverabbrev"]="|cffc7c7cfс|r"
+L["SP"]="+ Закл."
+L["Spent:"]="Потрачено:"
+L["Stats For:"]="Статистика для:"
+L["Total CPU:"]="Использование процессора:"
+L["Total Memory:"]="Всего памяти:"
+L["Total: "]="Всего: "
+L["Towers Assaulted"]="Штурмы башен"
+L["Towers Defended"]="Оборона башен"
+L["Undefeated"]="Не убит"
+L["Unhittable:"]="Полная защита от ударов"
+L["Victory Points"]="Очки победы"
+L["Waist"]="Пояс"
+L["World Boss(s)"]="Мировые боссы"
+L["Wrist"]="Запястья"
+L["%s: %s tried to call the protected function '%s'."]="%s: %s tried to call the protected function '%s'."
+L["No locals to dump"]="No locals to dump"
+L["%s is attempting to share his filters with you. Would you like to accept the request?"]="%s хочет передать Вам свои фильтры. Желаете ли Вы принять их?"
+L["%s is attempting to share the profile %s with you. Would you like to accept the request?"]="%s хочет передать Вам профиль %s. Желаете ли Вы принять его?"
+L["Data From: %s"]="Данные от: %s"
+L["Filter download complete from %s, would you like to apply changes now?"]="Завершена загрузка фильтров от %s. Желаете применить изменения сейчас?"
+L["Lord! It's a miracle! The download up and vanished like a fart in the wind! Try Again!"]="Чтоб его! Загрузка была... да всплыла. Попробуйте еще раз!"
+L["Profile download complete from %s, but the profile %s already exists. Change the name or else it will overwrite the existing profile."]="Загрузка профиля от %s завершена, но профиль %s уже существует. Измените его название или он перезапишет уже существующий профиль."
+L["Profile download complete from %s, would you like to load the profile %s now?"]="Загрузка профиля от %s завершена, хотите загрузить профиль %s сейчас?"
+L["Profile request sent. Waiting for response from player."]="Запрос на передачу профиля отправлен. Ждите, пожалуйста, ответа."
+L["Request was denied by user."]="Запрос отклонен пользователем."
+L["Your profile was successfully recieved by the player."]="Ваш профиль успешно получен целью. Ура, товарищи!"
+L["Auras Set"]="Ауры установлены"
+L["Auras System"]="Система аур"
+L["Caster DPS"]="Заклинатель"
+L["Chat Set"]="Чат настроен"
+L["Chat"]="Чат"
+L["Choose a theme layout you wish to use for your initial setup."]="Выберите тему, которую Вы хотите использовать."
+L["Vintage"]="Классическая"
+L["Classic"]="Классическая"
+L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."]="Нажмите кнопку ниже для изменения размеров вашего чата, рамок юнитов и перемещения ваших панелей действий."
+L["Config Mode:"]="Режим настройки:"
+L["CVars Set"]="Настройки сброшены"
+L["CVars"]="Настройки игры"
+L["Gloom & Doom"]="Темная"
+L["Disable"]="Выключить"
+L["SVUI Installation"]="Установка SVUI"
+L["Finished"]="Завершить"
+L["Grid Size:"]="Размер сетки"
+L["Healer"]="Лекарь"
+L["High Resolution"]="Высокое разрешение"
+L["high"]="высоким"
+L["Icons Only"]="Только иконки"
+L["If you have an icon or aurabar that you don't want to display simply hold down shift and right click the icon for it to disapear."]="Если Вы видите иконку или полосу аур, которую Вы не хотите отображать, просто зажмите shift и кликните на иконке правой кнопкой, чтобы она исчезла."
+L["Importance: |cff07D400High|r"]="Важность: |cff07D400Высокая|r"
+L["Importance: |cffD3CF00Medium|r"]="Важность: |cffD3CF00Средняя|r"
+L["Importance: |cffFF0000Low|r"]="Важность: |cffFF0000Низкая|r"
+L["Installation Complete"]="Установка завершена"
+L["Integrated"]="Интегрированная"
+L["Layout Set"]="Расположение установлено"
+L["Layout"]="Расположение"
+L["Lock"]="Закрепить"
+L["Low Resolution"]="Низкое разрешение"
+L["low"]="низким"
+L["Frames unlocked. Move them now and click Lock when you are done."]="Блокировка отключена. Передвиньте фреймы и нажмите 'Закрепить', когда закончите."
+L["Nudge"]="Сдвиг"
+L["Physical DPS"]="Физический урон"
+L["Pixel Perfect Set"]="Pixel Perfect установлен"
+L["Pixel Perfect"]="Pixel Perfect"
+L["Please click the button below so you can setup variables and ReloadUI."]="Пожалуйста, нажмите кнопку ниже для установки переменных и перезагрузки интерфейса."
+L["Please click the button below to setup your CVars."]="Пожалуйста, нажмите кнопку ниже для сброса настроек."
+L["Please press the continue button to go onto the next step."]="Пожалуйста, нажмите кнопку 'Продолжить' для перехода к следующему шагу"
+L["Resolution Style Set"]="Разрешение установлено"
+L["Resolution"]="Разрешение"
+L["Select the type of aura system you want to use with SVUI's unitframes. The integrated system utilizes both aura-bars and aura-icons. The icons only system will display only icons and aurabars won't be used. The classic system will configure your auras to be default."]="Выберите тип системы аур, которую вы хотите использовать на рамках юнитов SV. Интегрированная система использует и иконки, и полосы аур. Система иконок использует только иконки, полосы аур не будут использоваться. Классическая система настроит ауры на умолчания."
+L["Setup Chat"]="Настроить чат"
+L["Setup CVars"]="Сбросить настройки"
+L["Skip Process"]="Пропустить установку"
+L["Sticky Frames"]="Клейкие фреймы"
+L["Tank"]="Танк"
+L["The chat windows function the same as Blizzard standard chat windows, you can right click the tabs and drag them around, rename, etc. Please click the button below to setup your chat windows."]="Окна чата работают так же, как и в стандартном чате Blizzard. Вы можете нажать правую кнопку мыши на вкладках для перемещения, переименования и тд. Пожалуйста, нажмите кнопку ниже для настройки чата."
+L["The in-game configuration menu can be accesses by typing the /sv command or by clicking the 'C' button on the minimap. Press the button below if you wish to skip the installation process."]="Меню настроек можно вызвать командой /ес или кнопкой 'С' на миникарте. Нажмите кнопку ниже, если Вы хотите прервать процесс установки."
+L["The Pixel Perfect option will change the overall apperance of your UI. Using Pixel Perfect is a slight performance increase over the traditional layout."]="Опция Pixel PErfect изменит вид интерфейса. Использование этой опции даст небольшое улучшение производительности в стравнении с традиционным видом."
+L["Theme Set"]="Тема установлена"
+L["Theme Setup"]="Тема"
+L["This install process will help you learn some of the features in SVUI has to offer and also prepare your user interface for usage."]="Этот процесс установки поможет Вам узнать о некоторых функциях SVUI и подготовить Ваш интерфейс к использованию."
+L["This is completely optional."]="Это действие абсолютно не обязательно."
+L["This part of the installation process sets up your chat windows names, positions and colors."]="Эта часть установки настроит названия, позиции и цвета вкладок чата."
+L["This part of the installation process sets up your World of Warcraft default options it is recommended you should do this step for everything to behave properly."]="Эта часть установки сбросит настройки World of Warcraft на конфигурацию по умолчанию. Рекомендуется выполнить этот шаг для надлежащей работы интерфейса."
+L["This resolution doesn't require that you change settings for the UI to fit on your screen."]="Для соответствия интерфейса вашему экрану не требуется изменения настроек."
+L["This resolution requires that you change some settings to get everything to fit on your screen."]="Для соответствия интерфейса вашему экрану требуется изменение некоторых настроек."
+L["This will change the layout of your unitframes, raidframes, and statistics."]="Это изменит расположение ваших рамок юнитов, рейда и информационных текстов"
+L["Trade"]="Торговля"
+L["Using this option will cause your borders around frames to be 1 pixel wide instead of 3 pixel. You may have to finish the installation to notice a differance. By default this is enable."]="Использование этой опции сделаем границы вокруг фреймов шириной в 1 пиксейль вместо 3х. Вам может понадобиться завершить установку для того, чтобы заметить разницу. По умолчанию, опция включена."
+L["Welcome to SVUI version %s!"]="Добро пожаловать в SVUI версии %s!"
+L["You are now finished with the installation process. If you are in need of technical support please visit us at http://www.wowinterface.com."]="Вы завершили процесс установки. Если Вам требуется техническая поддержка, посетите сайт http://www.wowinterface.com."
+L["You can always change fonts and colors of any element of SVUI from the in-game configuration."]="Вы всегда можете изменить шрифты и цвета любого элемента SVUI из меню конфигурации. Классическая и пиксельная темы не отличаются для русского клиента."
+L["You can now choose what layout you wish to use based on your combat role."]="Вы можете выбрать используемое расположение, основываясь на Вашей роли."
+L["You may need to further alter these settings depending how low you resolution is."]="Вам может понадобиться дальнейшее изменение этих настроек в зависимости от того, насколько низким является ваше разрешение."
+L["Your current resolution is %s, this is considered a %s resolution."]="Ваше текущее разрешение - %s, это считается %s разрешением."
+L["Bars"]="Полосы"
+L["Calendar"]="Календарь"
+L["Can't Roll"]="Не могу бросить кости"
+L["Disband Group"]="Распустить группу"
+L["Empty Slot"]="Пустой слот"
+L["Enable"]="Включить"
+L["Experience"]="Опыт"
+L["Fishy Loot"]="Улов"
+L["Left Click:"]="ЛКМ:"
+L["Raid Menu"]="Рейдовое меню"
+L["Remaining:"]="Осталось:"
+L["Rested:"]="Бодрость:"
+L["Right Click:"]="ПКМ:"
+L["Show BG Texts"]="Показать текст ПБ"
+L["Toggle Chat Frame"]="Показать/скрыть чат"
+L["Toggle Configuration"]="Конфигурация"
+L["XP:"]="Опыт:"
+L["You don't have permission to mark targets."]="У вас нет разрешения на установку меток"
+L["ABOVE_THREAT_FORMAT"]='%s: %.0f%% [%.0f%% above |cff%02x%02x%02x%s|r]'
+L[" Frames"]=" "
+L["Alternative Power"]="Альтернативный ресурс"
+L["Arena Frames"]="Арена"
+L["Auras Frame"]="Ауры"
+L["Bags"]="Сумки"
+L["Bar "]="Панель "
+L["BNet Frame"]="Оповещения BNet"
+L["Special Ability Button"]="Кнопка босса"
+L["Boss Frames"]="Боссы"
+L["Experience Bar"]="Полоса опыта"
+L["Focus Castbar"]="Полоса заклинаний фокуса"
+L["Focus Frame"]="Фокус"
+L["FocusTarget Frame"]="Цель фокуса"
+L["GM Ticket Frame"]="Запрос ГМу"
+L["Left Dock"]="Левый чат"
+L["Loot / Alert Frames"]="Розыгрыш/оповещения"
+L["Loot Frame"]="Окно добычи"
+L["Loss Control Icon"]="Иконка потери контроля"
+L["MA Frames"]="Помощники"
+L["Micromenu"]="Микроменю"
+L["Minimap"]="Миникарта"
+L["MT Frames"]="Танки"
+L["Party Frames"]="Группа"
+L["Pet Bar"]="Панель питомца"
+L["Pet Frame"]="Питомец"
+L["PetTarget Frame"]="Цель питомца"
+L["Player Castbar"]="Полоса заклинаний игрока"
+L["Player Frame"]="Игрок"
+L["Raid 1-"]="Рейд 1-"
+L["Reputation Bar"]="Полоса репутации"
+L["Right Dock"]="Правый чат"
+L["Stance Bar"]="Панель стоек"
+L["Target Castbar"]="Полоса заклинаний цели"
+L["Target Frame"]="Цель"
+L["TargetTarget Frame"]="Цель цели"
+L["Tooltip"]="Подсказка"
+L["Totems"]="Тотемы"
+L["Vehicle Seat Frame"]="Техника"
+L["Watch Frame"]="Задания"
+L["Weapons"]="Оружие"
+L["Discipline"]="Послушание"
+L["Holy"]="Свет"
+L["Mistweaver"]="Ткач туманов"
+L["Restoration"]="Исцеление"
+L[" |cff00ff00bound to |r"]=" |cff00ff00назначено для |r"
+L["%s frame(s) has a conflicting anchor point, please change either the buff or debuff anchor point so they are not attached to each other. Forcing the debuffs to be attached to the main unitframe until fixed."]="Обнаружен конфликт точек фиксирования во фрейме(ах) %s. Пожалуйста, переназначьте фиксирование баффов и дебаффов так, чтобы они не крепились друг к другу. Установлено принудительное крепление дебаффов к фрейму."
+L["All keybindings cleared for |cff00ff00%s|r."]="Сброшены все назначения для |cff00ff00%s|r."
+L["Already Running.. Bailing Out!"]="Уже выполняется.. Бобер, выдыхай!"
+L["Battleground statistics temporarily hidden, to show type /bgstats."]='Информация поля боя временно скрыта. Для отображения введите /bgstat или ПКМ на иконке "С" у миникарты.'
+L["Battleground statistics will now show again if you are inside a battleground."]="Информация поля боя снова будет отображаться, если Вы находитесь на них."
+L["Binds Discarded"]="Назначения отменены"
+L["Binds Saved"]="Назначения сохранены"
+L["Confused.. Try Again!"]="Что за... Попробуйте еще раз!"
+L["Deleted %d gray items. Total Worth: %s"]="Удалено %d предметов серого качества. Общая стоимость: %s"
+L["No gray items to delete."]="Нет предметов серого качества для удаления."
+L["No gray items to sell."]="Нет предметов серого качества для продажи."
+L["The spell '%s' has been added to the BlackList unitframe aura filter."]='Заклинание "%s" было добавлено в фильтр "BlackList" аур рамок юнитов.'
+L["Vendored gray items for:"]="Проданы серые предметы на сумму:"
+L["You don't have enough money to repair."]="У вас недостаточно денег для ремонта."
+L["You must be at a vendor."]="Вы должны находиться у торговца"
+L["Your items have been repaired for: "]="Ваши предметы отремонтированы на: "
+L["Your items have been repaired using guild bank funds for: "]="Ваши предметы отремонтированы за счет гильдии на: "
+L["Your version of SVUI is out of date. You can download the latest version from http://www.wowinterface.com"]="Ваша версия SVUI устарела. Вы можете скачать последнюю версию на http://www.wowinterface.com"
+L["|cFFE30000Lua error recieved. You can view the error message when you exit combat."]="|cFFE30000Обнаружена ошибка lua. Вы получите отчет о ней после завершения боя."
+L["A setting you have changed will change an option for this character only. This setting that you have changed will be uneffected by changing user profiles. Changing this setting requires that you reload your User Interface."]="Настройка, которую Вы только что изменили, будет влиять только на этого персонажа. Она не будет изменяться при смене профиля. Также это изменение требует перезагрузки интерфейса для вступления в силу."
+L["Are you sure you want to delete all your gray items?"]="Вы уверенны, что хотите удалить все предметы серого качества?"
+L["Are you sure you want to disband the group?"]="Вы уверены, что хотите распустить группу?"
+L["Are you sure you want to reset every mover back to it's default position?"]="Вы уверены, что хотите сбросить все фиксаторы на позиции по умолчанию?"
+L["Because of the mass confusion caused by the new aura system I've implemented a new step to the installation process. This is optional. If you like how your auras are setup go to the last step and click finished to not be prompted again. If for some reason you are prompted repeatedly please restart your game."]="Из-за массового непонимания новой системы аур, я добавил новый шаг в установку. Он опционален. Если Вам нравится, как сейчас настроены Ваши ауры, передите до последнюю страницу установки и назмите \"Завершить\", чтобы это сообщение больше не появлялось. Если же оно появится снова, пожалуйста, перезапустите игру."
+L["Can't buy anymore slots!"]="Невозможно приобрести больше слотов!"
+L["Disable Warning"]="Отключить предупреждение"
+L["Discard"]="Отменить"
+L["Do you swear not to post in technical support about something not working without first disabling the addon/package combination first?"]="Клянетесь лы Вы не постить на форуме технической поддержки, что что-то не работает, до того, как отключите другие аддоны/модули?"
+L["Hover your mouse over any actionbutton or spellbook button to bind it. Press the escape key or right click to clear the current actionbutton's keybinding."]="Наведите курсор на любую кнопку на панели или в книге заклинаний, чтобы назначит ей клавишу. Нажмите правую кнопку мыши или 'Escape', чтобы сбросить назначение для этой кнопки."
+L["I Swear"]="Я клянусь!"
+L["Oh lord, you have got SVUI and Tukui both enable at the same time. Select an addon to disable."]="Японский городовой... у Вас одновременно включены SVUi и Tukui. Выюерите аддон для отключения."
+L["One or more of the changes you have made require a ReloadUI."]="Одно или несколько изменений требуют перезагрузки интерфейса"
+L["One or more of the changes you have made will effect all characters using this addon. You will have to reload the user interface to see the changes you have made."]="Одно или несколько изменений повлияют на всех персонажей, использующих этот аддон. Вы должны перезагрузить интерфейс для отображения этих изменений."
+L["Save"]="Сохранить"
+L["Using the healer layout it is highly recommended you download the addon Clique if you wish to have the click-to-heal function."]=true;
+L["You have changed the pixel perfect option. You will have to complete the installation process to remove any graphical bugs."]="Вы переключились в режим pixel perfect. Вы должны завершить установку для исправления графических багов."
+L["You have changed your UIScale, however you still have the AutoScale option enable in SV. Press accept if you would like to disable the Auto Scale option."]="Вы изменили масштаб интерфейса, однако у вас все еще активирована опция автоматического масштабирования в настройках SV. Нажмите 'Принять', если Вы хотите отключить эту опцию."
+L["You must purchase a bank slot first!"]="Сперва Вы должны приобрести дополнительный слот в банке!"
+L["Count"]="Кол-во"
+L["Targeted By:"]="Является целью:"
+L["A raid marker feature is available by pressing Escape -> Keybinds scroll to the bottom under SVUI and setting a keybind for the raid marker."]='Функция рейдовых меток доступна в Escape -> Назначение клавиш. Прокрутите вниз до раздела SVUI и назначьте клавишу для рейдовых меток.'
+L["SVUI has a dual spec feature which allows you to load different profiles based on your current spec on the fly. You can enable this from the profiles tab."]='В SVUI присутствует функция двойной специализации, которая позволит Вам использовать разные профили для разных наборов талантов. Вы можете включить эту функцию в разделе профилей.'
+L["For technical support visit us at http://www.wowinterface.com."]='За технической поддержкой обращайтесь на http://www.wowinterface.com.'
+L["If you accidently remove a chat frame you can always go the in-game configuration menu, press install, go to the chat portion and reset them."]='Если Вы случайно удалили вкладку чата, всегда можно сделать следующее: зайти в конфигурацию, запустить установку, дойти до шага настроек чата и сбросить их.'
+L["If you are experiencing issues with SVUI try disabling all your addons except SVUI, remember SVUI is a full UI replacement addon, you cannot run two addons that do the same thing."]='Если Вы испытываете проблемы с SVUI, попробуйте отключить все аддоны, кроме самого SV. Помните, SVUI это аддон, полностью заменяющий интерфейс, Вы не можете одновременно использовать два аддона, выполняющих одинаковые функции.'
+L["The buff panel to the right of minimap is a list of your consolidated buffs. You can disable it in Buffs and Debuffs options of SV."]='Панель с баффами справа от миникарты это список Ваших объединенных баффов. Вы можете отключить ее в разделе эффектов и аур в настройках SV.'
+L["The focus unit can be set by typing /focus when you are targeting the unit you want to focus. It is recommended you make a macro to do this."]='Запомненную цель (фокус) можно установить командой /focus при взятии нужного врага в цель. Для этого рекомендуется сделать макрос.'
+L["To move abilities on the actionbars by default hold shift + drag. You can change the modifier key from the actionbar options menu."]='Для перемещения способностей по панелям команд нужно перемещать их с зажатой клавишей shift. Вы можете поменять модификатор в опциях панелей команд.'
+L["To setup which channels appear in which chat frame, right click the chat tab and go to settings."]='Для настройки отображения каналов в чате кликните правой кнопкой мыши на закладке нужного чата и выберите пункт "параметры".'
+L["Using the /farmmode <size> command will spawn a larger minimap on your screen that can be moved around, very useful when farming."]='Использование команды /farmmode <размер> откроет миникарту большего размера, которую можно свободно перемещать по экрану. Очень полезно при фарме.'
+L["You can access copy chat and chat menu functions by mouse over the top right corner of chat panel and left/right click on the button that will appear."]='Вы можете получить доступ к функциям копирования чата и меню чата, наведя курсор на верхний правый угол панели чата и кликнув левой/правой кнопкой мыши на появившейся кнопке.'
+L["You can see someones average item level of their gear by holding shift and mousing over them. It should appear inside the tooltip."]="Вы можете узнать средний уровень предметов игрока, зажав shift и наведя на них курсор. Информация будет отражена в подсказке."
+L["You can set your keybinds quickly by typing /kb."]="Вы можете быстро назначать клавиши, введя команду /kb."
+L["You can toggle the microbar by using your middle mouse button on the minimap you can also accomplish this by enabling the actual microbar located in the actionbar settings."]="Вы можете получить доступ к микроменю, кликнув средней кнопкой мыши на миникарте. Также Вы можете включить обычное микроменю в настройках панелей команд"
+L["You can use the /resetui command to reset all of your moveables. You can also use the command to reset a specific mover, /resetui <mover name>.\nExample: /resetui Player Frame"]='Вы можете использовать команду /resetui чтобы сбросить положения всех фиксаторов. Вы также можете использовать команду /resetui <имя фиксатора> для сброса определенного фиксатора.\nПример: /resetui Player Frame'
+L["Ghost"]="Призрак"
+L["Offline"]="Не в сети"
+L["ENH_LOGIN_MSG"]="You are using |cff1784d1SVUI Enhanced|r version %s%s|r."
+L["Your version of SVUI is to old. Please, download the latest version from http://www.wowinterface.com."]=true;
+L["Equipment"]=true;
+L["EQUIPMENT_DESC"]="Adjust the settings for switching your gear set when you change specialization or enter a battleground."
+L["No Change"]=true;
+L["Specialization"]=true;
+L["Enable/Disable the specialization switch."]=true;
+L["Primary Talent"]=true;
+L["Choose the equipment set to use for your primary specialization."]=true;
+L["Secondary Talent"]=true;
+L["Choose the equipment set to use for your secondary specialization."]=true;
+L["Battleground"]=true;
+L["Enable/Disable the battleground switch."]=true;
+L["Equipment Set"]=true;
+L["Choose the equipment set to use when you enter a battleground or arena."]=true;
+L["You have equipped equipment set: "]=true;
+L["DURABILITY_DESC"]="Adjust the settings for the durability information on the character screen."
+L["Enable/Disable the display of durability information on the character screen."]=true;
+L["Damaged Only"]=true;
+L["Only show durabitlity information for items that are damaged."]=true;
+L["ITEMLEVEL_DESC"]="Adjust the settings for the item level information on the character screen."
+L["Enable/Disable the display of item levels on the character screen."]=true;
+L["Miscellaneous"]=true;
+L["Equipment Set Overlay"]=true;
+L["Show the associated equipment sets for the items in your bags (or bank)."]=true;
+L["Layout Transparency"]=true;
+L["Changes the transparency of all the moveables."]=true;
+L["Automatic Role Assignment"]=true;
+L["Enables the automatic role assignment based on specialization for party / raid members (only work when you are group leader or group assist)."]=true;
+L["Hide Role Icon in combat"]=true;
+L["All role icons (Damage/Healer/Tank) on the unit frames are hidden when you go into combat."]=true;
+L["GPS"]=true;
+L["Show the direction and distance to the selected party or raid member."]=true;
+L["Attack Icon"]=true;
+L["Show attack icon for units that are not tapped by you or your group, but still give kill credit when attacked."]=true;
+L["Show class icon for units."]=true;
+L["Above Minimap"]=true;
+L["Location Digits"]=true;
+L["Number of digits for map location."]=true;
+L["Hide minimap while in combat."]=true;
+L["FadeIn Delay"]=true;
+L["The time to wait before fading the minimap back in after combat hide. (0 = Disabled)"]=true;
+L["Minimap Button Bar"]=true;
+L["Style Buttons"]=true;
+L["Customize the minimap buttons in SVUI style."]=true;
+L["SVUI Style"]=true;
+L["Change settings for how the minimap buttons are styled."]=true;
+L["The size of the minimap buttons."]=true;
+L["No Anchor Bar"]=true;
+L["Horizontal Anchor Bar"]=true;
+L["Vertical Anchor Bar"]=true;
+L["Layout Direction"]=true;
+L["Normal is right to left or top to bottom, or select reversed to switch directions."]=true;
+L["Normal"]=true;
+L["Reversed"]=true;
+L["PvP Autorelease"]=true;
+L["Automatically release body when killed inside a battleground."]=true;
+L["Track Reputation"]=true;
+L["Automatically change your watched faction on the reputation bar to the faction you got reputation points for."]=true;
+L["Select Quest Reward"]=true;
+L["Automatically select the quest reward with the highest vendor sell value."]=true;
+L["Item Level"]=true;
+L["Target Range"]=true;
+L["Distance"]=true;
+L["Actionbar1DataPanel"]='Actionbar 1'
+L["Actionbar3DataPanel"]='Actionbar 3'
+L["Actionbar5DataPanel"]='Actionbar 5'
+L["Sunsong Ranch"]="Ферма Солнечной Песни"
+L["The Halfhill Market"]="Рынок Полугорья"
+L["Tilled Soil"]="Возделанная земля"
+L["Right-click to drop the item."]=true;
+L["Toolbox"]=true;
+L["COMIX_DESC"]="Toggle the comic popups during combat"
+L["FARMING_MODE_DESC"]="Adjust the settings for the tools that help your farming and professions."
+L["SNACKS_DESC"]="Adjust the settings for the consumables bar."
+L["Toolbox Bars"]=true;
+L["Toolbox Portal Bar"]=true;
+L["Toolbox Seed Bar"]=true;
+L["Toolbox Tools Bar"]=true;
+L["Enable/Disable the laborer bars."]=true;
+L["Only active buttons"]=true;
+L["Only show the buttons for the seeds, portals, tools you have in your bags."]=true;
+L["Drop Tools"]=true;
+L["Automatically drop tools from your bags when leaving the farming area."]=true;
+L["Seed Bar Direction"]=true;
+L["The direction of the seed bar buttons (Horizontal or Vertical)."]=true;
+L["Threat Text"]=true;
+L["Display threat level as text on targeted, boss or mouseover nameplate."]=true;
+L["Target Count"]=true;
+L["Display the number of party / raid members targetting the nameplate unit."]=true;
+L["Heal Glow"]=true;
+L["Direct AoE heals will let the unit frames of the affected party / raid members glow for the defined time period."]=true;
+L["Glow Duration"]=true;
+L["The amount of time the unit frames of party / raid members will glow when affected by a direct AoE heal."]=true;
+L["Glow Color"]=true;
+L["Raid Marker Bar"]=true;
+L["Display a quick action bar for raid targets and world markers."]=true;
+L["Modifier Key"]=true;
+L["Set the modifier key for placing world markers."]=true;
+L["Shift Key"]=true;
+L["Ctrl Key"]=true;
+L["Alt Key"]=true;
+L["Raid Markers"]=true;
+L["Click to clear the mark."]=true;
+L["Click to mark the target."]=true;
+L["%sClick to remove all worldmarkers."]=true;
+L["%sClick to place a worldmarker."]=true;
+L["WatchFrame"]=true;
+L["WATCHFRAME_DESC"]="Adjust the settings for the visibility of the watchframe (questlog) to your personal preference."
+L["Hidden"]=true;
+L["Collapsed"]=true;
+L["Settings"]=true;
+L["City (Resting)"]=true;
+L["PvP"]=true;
+L["Arena"]=true;
+L["Party"]=true;
+L["Raid"]=true;
+L["Progression Info"]=true;
+L["Display the players raid progression in the tooltip, this may not immediately update when mousing over a unit."]=true
\ No newline at end of file
diff --git a/SVUI_!Core/language/spanish_ui.lua b/SVUI_!Core/language/spanish_ui.lua
new file mode 100644
index 0000000..8430e93
--- /dev/null
+++ b/SVUI_!Core/language/spanish_ui.lua
@@ -0,0 +1,597 @@
+local Localization = Librarian("Linguist")
+local L = Localization:Lang("esES");
+if not L then
+	L = Localization:Lang("esMX")
+end
+if not L then return; end
+L["Conversation"]    = "Conversación"
+L["General"]         = "General"
+L["LocalDefense"]    = "DefensaLocal"
+L["LookingForGroup"] = "BuscarGrupo"
+L["Trade"]           = "Comercio"
+L["WorldDefense"]    = "DefensaGeneral"
+L["S_Conversation"]    = "D"
+L["S_General"]        = "G"
+L["S_LocalDefense"]    = "DL"
+L["S_LookingForGroup"] = "BDG"
+L["S_Trade"]          = "C"
+L["S_WorldDefense"]    = "DG"
+L["Hearthstone"] = true;
+--[[LOGIN MESSAGE]]--
+L["LOGIN_MSG"] = "Bienvenido a |cffFFFF1ASVUI|r! Mantenga su %s y su %s."
+L["LOGIN_MSG2"] = "Versión |cffAA78FF%s|r, escribe /sv para acceder al menú de configuración."
+--[[OPTION MESSAGES]]--
+L["AURAS_DESC"] = "Configura los iconos de las auras que aparecen cerca del minimapa."
+L["BAGS_DESC"] = "Ajusta las opciones de las bolsas para SV."
+L["CHAT_DESC"] = "Configura los ajustes del chat para SV."
+L["STATS_DESC"] = "Configure docked stat panels.";
+L["SVUI_DESC"] = "SVUI es un addon que reemplaza la interfaz completa de World of Warcraft."
+L["NAMEPLATE_DESC"] = "Modifica las opciones de la placa de nombre"
+L["PANEL_DESC"] = "Ajusta el tamaño de los paneles izquierdo y derecho. Esto afectará las ventanas de chat y las bolsas."
+L["ART_DESC"] = "Configura los Ajustes de Cubiertas."
+L["TOGGLEART_DESC"] = "Activa / Desactiva esta cubierta."
+L["TOOLTIP_DESC"] = "Configuración para las Descripciones Emergentes."
+L["TEXT_FORMAT_DESC"] = "Select the formatting of this text"
+L["import"] = "Perfiles existentes"
+L["import_desc"] = "Puedes crear un nuevo perfil introduciendo un nombre en el recuadro o puedes seleccionar un perfil de los ya existentes."
+L["import_sub"] = "Selecciona uno de los perfiles disponibles."
+L["copy_name"] = "Copiar de"
+L["copy_desc"] = "Copia los ajustes de un perfil existente al perfil actual."
+L["current"] = "Current Profile:"
+L["default"] = "Por defecto"
+L["delete"] = "Borrar un Perfil"
+L["delete_confirm"] = "¿Estas seguro que quieres borrar el perfil seleccionado?"
+L["delete_desc"] = "Borra los perfiles existentes y sin uso de la base de datos para ganar espacio y limpiar el archivo SavedVariables."
+L["delete_sub"] = "Borra un perfil de la base de datos."
+L["intro"] = "Puedes cambiar el perfil activo de tal manera que cada personaje tenga diferentes configuraciones."
+L["export"] = "Nuevo"
+L["export_sub"] = "Crear un nuevo perfil vacio."
+L["profiles"] = "Perfiles"
+L["profiles_sub"] = "Manejar Perfiles"
+L["reset"] = "Reiniciar Perfil"
+L["reset_desc"] = "Reinicia el perfil actual a los valores por defectos, en caso de que se haya estropeado la configuración o quieras volver a empezar de nuevo."
+L["reset_sub"] = "Reinicar el perfil actual al de por defecto"
+L["SVUI_DockBottomCenter"] = "Bottom Data Dock"
+L["SVUI_DockTopCenter"] = "Top Data Dock"
+--[[REACTION TEXTS]]--
+L[" is drinking."] = true;
+L["Leeeeeroy!"] = true;
+L["No Food: "] = "No Food: "
+L["No Flask: "] = "No Flask: "
+L["All Buffed!"] = "All Buffed!"
+L["Check food and flask"] = "Check food and flask"
+L["Thanks for "] = "Thanks for "
+L[" received from "] = " received from "
+L["GO!"] = "GO!"
+L["Pulling %s in %s.."] = "Pulling %s in %s.."
+L["Pull ABORTED!"] = "Pull ABORTED!"
+L["%s has prepared a %s - [%s]."] = "%s has prepared a %s - [%s]."
+L["%s has prepared a %s."] = "%s has prepared a %s."
+L["%s has put down a %s."] = "%s has put down a %s."
+L["%s is casting %s."] = "%s is casting %s."
+L["%s is casting %s. Click!"] = "%s is casting %s. Click!"
+L["%s used a %s."] = "%s used a %s."
+--[[FORMATTED INSTALLER TEXTS]]--
+L["|cffD3CF00Recommended|r"] = true;
+L["Recommended: |cff99FF00Kaboom!|r"] = true;
+L["Recommended: |cff99FF00Super|r"] = true;
+L["Recommended: |cffFF0000Small Row!|r"] = true;
+L["Recommended: |cffFF0000Icon Lovers!|r"] = true;
+L["|cffFF9F00KABOOOOM!|r"] = true;
+L["|cffAF30FFThe Darkest Night|r"] = true;
+L["|cff00FFFFPlain and Simple|r"] = true;
+L["|cff00FFFFLets Do This|r"] = true;
+L["|cff00FFFFSimply Simple|r"] = true;
+L["|cff00FFFFEl Compacto|r"] = true;
+L["|cff00FFFFHealer Extraordinaire|r"] = true;
+L["|cff00FFFFLean And Clean|r"] = true;
+L["|cff00FFFFMore For Less|r"] = true;
+L["|cff00FFFFWhat Big Buttons You Have|r"] = true;
+L["|cff00FFFFThe Double Down|r"] = true;
+--[[NORMAL INSTALLER TEXTS]]--
+L["This is SVUI version %s!"] = true;
+L["Before I can turn you loose, persuing whatever villainy you feel will advance your professional career ... I need to ask some questions and turn a few screws first."] = true;
+L["At any time you can get to the config options by typing the command /sv. For quick changes to frame, bar or color sets, call your henchman by clicking the button on the bottom right of your screen. (Its the one with his stupid face on it)"] = true;
+L["CHOOSE_OR_DIE"] = CHOOSE_FACTION.." "..OR_CAPS.." "..HIT.." "..CONTINUE;
+L["Whether you want to or not, you will be needing a communicator so other villains can either update you on their doings-of-evil or inform you about the MANY abilities of Chuck Norris"] = true;
+L["The chat windows function the same as standard chat windows, you can right click the tabs and drag them, rename them, slap them around, you know... whatever. Clickity-click to setup your chat windows."] = true;
+L["Your current resolution is %s, this is considered a %s resolution."] = true;
+L["This resolution requires that you change some settings to get everything to fit on your screen."] = true;
+L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."] = true;
+L["You may need to further alter these settings depending how low you resolution is."] = true;
+L["This resolution doesn't require that you change settings for the UI to fit on your screen."] = true;
+L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."] = true;
+L["This is completely optional."] = true;
+L["So what you think your better than me with your big monitor? HUH?!?!"] = true;
+L["Dont forget whos in charge here! But enjoy the incredible detail."] = true;
+L["Why are you playing this on what I would assume is a calculator display?"] = true;
+L["Enjoy the ONE incredible pixel that fits on this screen."] = true;
+L["Choose a theme layout you wish to use for your initial setup."] = true;
+L["You can always change fonts and colors of any element of SVUI from the in-game configuration."] = true;
+L["This theme tells the world that you are a villain who can put on a show "] = true;
+L["or better yet, you ARE the show!"] = true;
+L["Kaboom!"] = true;
+L["This theme indicates that you have no interest in wasting time"] = true;
+L["the dying begins NOW!"] = true;
+L["Darkness"] = true;
+L["This theme is for villains who take pride in their class"] = true;
+L["villains know how to reprezent!"] = true;
+L["This theme is for any villain who sticks to their traditions"] = true;
+L["you don't need fancyness to kick some ass!"] = true;
+L["Vintage"] = true;
+L["Layout"] = true;
+L["You can now choose what primary unitframe style you wish to use."] = true;
+L["This will change the layout of your unitframes (ie.. Player, Target, Pet, Party, Raid ...etc)."] = true;
+L["This layout is anything but minimal! Using this is like being at a rock concert"] = true;
+L["then annihilating the crowd with frickin lazer beams!"] = true;
+L["Super"] = true;
+L["This layout is for the villain who just wants to get things done!"] = true;
+L["But he still wants to see your face before he hits you!"] = true;
+L["Simple"] = true;
+L["Just the necessities so you can see more of the world around you."] = true;
+L["You dont need no fanciness getting in the way of world domination do you?"] = true;
+L["Compact"] = true;
+L["This has all the pizzaz of Super frames but uses Compact party and raid frames."] = true;
+L["Sometimes a little fifty-fifty goes a long way."] = true;
+L["Healer"] = true;
+L["Bar Setup"] = true;
+L["Choose a layout for your action bars."] = true;
+L["Sometimes you need big buttons, sometimes you don't. Your choice here."] = true;
+L["Lets keep it slim and deadly, not unlike a ninja sword."] = true;
+L["You dont ever even look at your bar hardly, so pick this one!"] = true;
+L["Small Row"] = true;
+L["Granted, you dont REALLY need the buttons due to your hotkey-leetness, you just like watching cooldowns!"] = true;
+L["Sure thing cowboy, your secret is safe with me!"] = true;
+L["Small X2"] = true;
+L["The better to PEW-PEW you with my dear!"] = true;
+L["When you have little time for mouse accuracy, choose this set!"] = true;
+L["Big Row"] = true;
+L["It's like dual-wielding two big reasons for your enemies to back the **** up!"] = true;
+L["Double your bars then double their size for maximum button goodness!"] = true;
+L["Big X2"] = true;
+L["Auras System"] = true;
+L["Select the type of aura system you want to use with SVUI's unitframes. The Icon Lovers set will display only icons and aurabars won't be used. The Vintage set will use the original game style and the Gimme Everything set does just what it says.... icons, bars and awesomeness."] = true;
+L["If you have an icon or aurabar that you don't want to display simply hold down shift and right click the icon for it to suffer a painful death."] = true;
+L["Vintage"] = true;
+L["Icon Lovers"] = true;
+L["The Works!"] = true;
+L["Installation Complete"] = true;
+L["Thats it! All done! Now we just need to hand these choices off to the henchmen so they can get you ready to (..insert evil tasks here..)!"] = true;
+L["Click the button below to reload and get on your way! Good luck villain!"] = true;
+L["THE_BUTTON_BELOW"] = "THE\nBUTTON\nBELOW";
+--[[UI TEXTS]]--
+L["Meanwhile"]=true;
+L["..at "]=true;
+L["A taint has occured that is preventing you from using the queue system. Please reload your user interface and try again."]="Un error ha ocurrido que te impide usar el sistema de cola. Recarga tu interfaz y trata nuevamente."
+L["Binding"]="Controles"
+L["Key"]="Tecla"
+L["KEY_ALT"]="A"
+L["KEY_CTRL"]="C"
+L["KEY_DELETE"]="Del"
+L["KEY_HOME"]="Hm"
+L["KEY_INSERT"]="Ins"
+L["KEY_MOUSEBUTTON"]="M"
+L["KEY_MOUSEWHEELDOWN"]="MwD"
+L["KEY_MOUSEWHEELUP"]="MwU"
+L["KEY_NUMPAD"]="N"
+L["KEY_PAGEDOWN"]="PD"
+L["KEY_PAGEUP"]="PU"
+L["KEY_SHIFT"]="S"
+L["KEY_SPACE"]="SpB"
+L["No bindings set."]="No hay teclas establecidas."
+L["Remove Bar %d Action Page"]="Quitar Barra %d de la paginación"
+L["Trigger"]="Disparador"
+L["Delete Grays"]="Borrar objetos grises"
+L["Hold Control + Right Click:"]="Mantén Control y Haz Clic Derecho:"
+L["Hold Shift + Drag:"]="Mantén Shift y Arrastra:"
+L["Hold Shift:"]="Mantener Shift:"
+L["Purchase"]="Comprar"
+L["Reset Position"]="Reestablecer Posición"
+L["Sort Bags"]="Ordenar Bolsas"
+L["Sort Tab"]=true;
+L["Stack Bags to Bank"]="Apilar Bolsas al Banco"
+L["Stack Bank to Bags"]="Apilar Banco a las Bolsas"
+L["Stack Items"]="Apilar Objetos"
+L["Temporary Move"]="Movimiento Temporal"
+L["Toggle Bags"]="Mostrar/Ocultar Bolsas"
+L["Vendor Grays"]="Vender Objetos Grises"
+L["AFK"]="Ausente"
+L["DND"]="Oc"
+L["G"]="H"
+L["I"]=true;
+L["IL"]="LI"
+L["Invalid Target"]="Objetivo Inválido"
+L["O"]="O"
+L["P"]="G"
+L["PL"]="LG"
+L["R"]="B"
+L["RL"]="LB"
+L["RW"]="AB"
+L["says"]="dice"
+L["whispers"]="susurra"
+L["yells"]="grita"
+L["(Hold Shift) Memory Usage"]="(Mantén Shift) Uso de Memoria"
+L["AP"]="PA"
+L["AVD: "]="EVA: "
+L["Avoidance Breakdown"]="Desglose de Evasión"
+L["Bandwidth"]="Ancho de Banda"
+L["Bases Assaulted"]="Bases Asaltadas"
+L["Bases Defended"]="Bases Defendidas"
+L["Carts Controlled"]="Vagonetas Controladas"
+L["Character: "]="Personaje: "
+L["Chest"]="Pecho"
+L["Combat Time"]="Tiempo de Combate"
+L["copperabbrev"]="|cffeda55fc|r"
+L["Defeated"]="Derrotado"
+L["Deficit:"]="Déficit:"
+L["Demolishers Destroyed"]="Demoledores Destruidos"
+L["Download"]="Descarga"
+L["DPS"]="DPS"
+L["Earned:"]="Ganada:"
+L["Feet"]="Pies"
+L["Flags Captured"]="Banderas Capturadas"
+L["Flags Returned"]="Banderas Recuperadas"
+L["Friends List"]="Lista de Amigos"
+L["Friends"]="Amigos"
+L["Galleon"]="Galeón"
+L["Gates Destroyed"]="Puertas Destruidas"
+L["goldabbrev"]="|cffffd700g|r"
+L["Graveyards Assaulted"]="Cementerios Asaltados"
+L["Graveyards Defended"]="Cementerios Defendidos"
+L["Hands"]="Manos"
+L["Head"]="Cabeza"
+L["Hit"]="Golpe"
+L["Home Latency:"]="Latencia Local:"
+L["HP"]="Salud"
+L["HPS"]="VPS"
+L["Legs"]="Piernas"
+L["lvl"]="Niv"
+L["Main Hand"]="Mano Derecha"
+L["Mitigation By Level: "]="Mitigación Por Nivel: "
+L["Nalak"]=true;
+L["No Guild"]="Sin Hermandad"
+L["Offhand"]="Mano Izquierda"
+L["Oondasta"]=true;
+L["Orb Possessions"]="Orbes en Posesión"
+L["Profit:"]="Ganancia:"
+L["Reset Data: Hold Shift + Right Click"]="Restablecer Datos: Mantén Shift + Clic Derecho"
+L["Saved Raid(s)"]="Banda(s) Guardada(s)"
+L["Server: "]="Servidor: "
+L["Session:"]="Sesión:"
+L["Sha of Anger"]="Sha de la Ira"
+L["Shoulder"]="Hombros"
+L["silverabbrev"]="|cffc7c7cfs|r"
+L["SP"]="PH"
+L["Spent:"]="Gastada:"
+L["Stats For:"]="Estadísticas para:"
+L["Total CPU:"]="CPU Total:"
+L["Total Memory:"]="Memoria Total:"
+L["Total: "]="Total: "
+L["Towers Assaulted"]="Torres Asaltadas"
+L["Towers Defended"]="Torres Defendidas"
+L["Undefeated"]="Invicto"
+L["Unhittable:"]="Imbatible:"
+L["Victory Points"]="Puntos de Victoria"
+L["Waist"]="Cintura"
+L["World Boss(s)"]="Jefe(s) Mundial(es)"
+L["Wrist"]="Muñeca"
+L["%s: %s tried to call the protected function '%s'."]="%s: %s intentó llamar a la función protegida '%s'."
+L["No locals to dump"]="No hay lang para volcar"
+L["%s is attempting to share his filters with you. Would you like to accept the request?"]="%s quiere compartir sus filtros contigo. ¿Aceptas la petición?"
+L["%s is attempting to share the profile %s with you. Would you like to accept the request?"]="%s quiere compartir el perfil %s contigo. ¿Aceptas la petición?"
+L["Data From: %s"]="Datos De: %s"
+L["Filter download complete from %s, would you like to apply changes now?"]="Se completó la descarga de los filtros de %s. ¿Quieres aplicar los cambios ahora?"
+L["Lord! It's a miracle! The download up and vanished like a fart in the wind! Try Again!"]="¡Milagro! ¡La descarga se desvaneció como pedo! Intenta de nuevo"
+L["Profile download complete from %s, but the profile %s already exists. Change the name or else it will overwrite the existing profile."]="Descarga de perfil de %s completa, pero el perfil %s ya existe. Cámbiale el nombre o se reemplazará el perfil existente."
+L["Profile download complete from %s, would you like to load the profile %s now?"]="Descarga de perfil de %s completa ¿Quieres cargar el perfil %s ahora?"
+L["Profile request sent. Waiting for response from player."]="Petición de perfil enviada. Esperando respuesta del jugador."
+L["Request was denied by user."]="Petición denegada por el jugador."
+L["Your profile was successfully recieved by the player."]="Tu perfil ha sido recibido exitosamente por el jugador."
+L["Auras Set"]="Auras Configuradas"
+L["Auras System"]="Sistema de Auras"
+L["Caster DPS"]="DPS Hechizos"
+L["Chat Set"]="Chat Configurado"
+L["Chat"]="Chat"
+L["Choose a theme layout you wish to use for your initial setup."]="Elige un tema de distribución para usar en tu configuración inicial."
+L["Vintage"]="Clásico"
+L["Classic"]="Clásico"
+L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."]="Haz clic en el botón de abajo para cambiar el tamaño de los marcos de chat y de unidad, y reubicar tus barras de acción."
+L["Config Mode:"]="Modo de Configuración"
+L["CVars Set"]="CVars Configuradas"
+L["CVars"]="CVars"
+L["Gloom & Doom"]="Oscuro"
+L["Disable"]="Desactivar"
+L["SVUI Installation"]="Instalación de SVUI"
+L["Finished"]="Terminado"
+L["Grid Size:"]="Tamaño de la Rejilla:"
+L["Healer"]="Sanador"
+L["High Resolution"]="Alta Resolución"
+L["high"]="alta"
+L["Icons Only"]="Sólo Iconos"
+L["If you have an icon or aurabar that you don't want to display simply hold down shift and right click the icon for it to disapear."]="Si tienes un icono o una barra de aura que no quieres ver simplemente mantén pulsado la tecla Shift y haz clic con el botón izquierdo del ratón en el icono para que desaparezca."
+L["Importance: |cff07D400High|r"]="Importancia: |cff07D400Alta|r"
+L["Importance: |cffD3CF00Medium|r"]="Importancia: |cffD3CF00Media|r"
+L["Importance: |cffFF0000Low|r"]="Importancia: |cffFF0000Baja|r"
+L["Installation Complete"]="Instalación Completa"
+L["Integrated"]="Integrado"
+L["Layout Set"]="Distribución Establecida"
+L["Layout"]="Distribución"
+L["Lock"]="Bloquear"
+L["Low Resolution"]="Baja Resolución"
+L["low"]="baja"
+L["Frames unlocked. Move them now and click Lock when you are done."]="Fijadores desbloqueados. Muévelos ahora y haz click en Bloquear cuando termines."
+L["Nudge"]="Ajuste Fino"
+L["Physical DPS"]="DPS Físico"
+L["Pixel Perfect Set"]="Perfección por Pixel Establecido"
+L["Pixel Perfect"]="Perfección por Pixel"
+L["Please click the button below so you can setup variables and ReloadUI."]="Haz clic en el botón de abajo para configurar variables y recargar la interfaz."
+L["Please click the button below to setup your CVars."]="Haz clic en el botón de abajo para configurar las CVars"
+L["Please press the continue button to go onto the next step."]="Presiona el botón de continuar para ir al siguiente paso"
+L["Resolution Style Set"]="Estilo de Resolución Establecido"
+L["Resolution"]="Resolución"
+L["Select the type of aura system you want to use with SVUI's unitframes. The integrated system utilizes both aura-bars and aura-icons. The icons only system will display only icons and aurabars won't be used. The classic system will configure your auras to be default."]="Elige el estilo de sistema de auras que deseas usar con los marcos de unidad de SV. El sistema integrado utiliza iconos y barras de auras. El sistema de sólo iconos no utiliza las barras. El sistema clásico configurará tus auras de forma predeterminada."
+L["Setup Chat"]="Configurar Chat"
+L["Setup CVars"]="Configurar CVars"
+L["Skip Process"]="Saltar Proceso"
+L["Sticky Frames"]="Marcos Adhesivos"
+L["Tank"]="Tanque"
+L["The chat windows function the same as Blizzard standard chat windows, you can right click the tabs and drag them around, rename, etc. Please click the button below to setup your chat windows."]="Las ventanas de chat funcionan igual que sus contrapartes estándar de Blizzard. Puedes hacer clic derecho en las pestañas y arrastrarlas, cambiarles el nombre, etc. Haz clic en el botón de abajo para configurar las ventanas de chat."
+L["The in-game configuration menu can be accesses by typing the /sv command or by clicking the 'C' button on the minimap. Press the button below if you wish to skip the installation process."]="El menú de configuración puede ser accedido mediante el comando /sv o haciendo clic en el botón 'C' del minimapa. Presiona el botón de abajo si deseas saltarte la instalación."
+L["The Pixel Perfect option will change the overall apperance of your UI. Using Pixel Perfect is a slight performance increase over the traditional layout."]="La opción de Perfección por Pixel cambiará la apariencia general de la interfaz. Este mejorará el desempeño ligeramente en comparación con el diseño tradicional"
+L["Theme Set"]="Establecer Tema"
+L["Theme Setup"]="Configurar Tema"
+L["This install process will help you learn some of the features in SVUI has to offer and also prepare your user interface for usage."]="El proceso de instalación te ayudará a aprender algunas de las características de SVUI y preparará la interfaz para su uso."
+L["This is completely optional."]="Esto es completamente opcional."
+L["This part of the installation process sets up your chat windows names, positions and colors."]="Esta parte de la instalación configura los nombres, posiciones y colores de las ventanas de chat."
+L["This part of the installation process sets up your World of Warcraft default options it is recommended you should do this step for everything to behave properly."]="Esta parte de la instalación configura las opciones predeterminadas de World of Warcraft. Se recomienda hacer este paso para que todo funcione apropiadamente."
+L["This resolution doesn't require that you change settings for the UI to fit on your screen."]="Esta resolución no necesita que cambies los ajustes para que quepa la interfaz en tu pantalla."
+L["This resolution requires that you change some settings to get everything to fit on your screen."]="Esta resolución requiere que cambies algunos ajustes para que todo quepa en tu pantalla."
+L["This will change the layout of your unitframes, raidframes, and statistics."]="Esto cambiará la distribución de tus marcos de unidad, de banda y textos de datos."
+L["Trade"]="Intercambio"
+L["Using this option will cause your borders around frames to be 1 pixel wide instead of 3 pixel. You may have to finish the installation to notice a differance. By default this is enable."]="Esta opción cambiará el ancho de los bordes de los marcos a 1 pixel, en lugar de 3. Es probable que necesites terminar la instalación para ver la diferencia. Está activado por defecto."
+L["Welcome to SVUI version %s!"]="Bienvenido(a) a SVUI versión %s!"
+L["You are now finished with the installation process. If you are in need of technical support please visit us at http://www.wowinterface.com."]="Ya has terminado con el proceso de instalación. Si necesitas ayuda o soporte técnico por favor visítanos en http://www.wowinterface.com."
+L["You can always change fonts and colors of any element of SVUI from the in-game configuration."]="Siempre puedes cambiar las fuentes y colores de cualquier elemento de SVUI desde la configuración."
+L["You can now choose what layout you wish to use based on your combat role."]="Ahora puedes elegir qué distribución quieres basándote en tu rol de combate."
+L["You may need to further alter these settings depending how low you resolution is."]="Puede que necesites cambiar estos ajutes dependiendo de qué tan baja sea tu resolución."
+L["Your current resolution is %s, this is considered a %s resolution."]="Tu resolución actual es %s, esto se considera una resolución %s."
+L["Bars"]="Barras"
+L["Calendar"]="Calendario"
+L["Can't Roll"]="No puede tirar dados"
+L["Disband Group"]="Disolver Grupo"
+L["Empty Slot"]="Hueco vacío"
+L["Enable"]="Habilitar"
+L["Experience"]="Experiencia"
+L["Fishy Loot"]="Botín Sospechoso"
+L["Left Click:"]="Click Izquierdo"
+L["Raid Menu"]="Menú de Banda"
+L["Remaining:"]="Restante"
+L["Rested:"]="Descansado:"
+L["Right Click:"]="Click Derecho"
+L["Show BG Texts"]="Mostrar Textos de CB"
+L["Toggle Chat Frame"]="Mostrar/Ocultar Marco de Chat"
+L["Toggle Configuration"]="Mostrar/Ocultar Configuración"
+L["XP:"]="XP:"
+L["You don't have permission to mark targets."]="No tienes permiso para marcar objetivos."
+L["ABOVE_THREAT_FORMAT"]="%s: %.0f%% [%.0f%% above |cff%02x%02x%02x%s|r]"
+L[" Frames"]=" Marcos"
+L["Alternative Power"]="Poder Alternativo"
+L["Arena Frames"]="Marcos de Arena"
+L["Auras Frame"]="Marco de Auras"
+L["Bags"]="Bolsas"
+L["Bar "]="Barra "
+L["BNet Frame"]="Marco BNet"
+L["Special Ability Button"]="Botón de Jefe"
+L["Boss Frames"]="Marco de Jefe"
+L["Experience Bar"]="Barra de Experiencia"
+L["Focus Castbar"]="Barra de Lanzamiento del Foco"
+L["Focus Frame"]="Marco de Foco"
+L["FocusTarget Frame"]="Marco de Objetivo del Foco"
+L["GM Ticket Frame"]="Marco de Consultas para el MJ"
+L["Left Dock"]="Chat Izquierdo"
+L["Loot / Alert Frames"]="Marcos de Botín / Alerta"
+L["Loot Frame"]="Marco de Botín"
+L["Loss Control Icon"]="Icono de Pérdida de Control"
+L["MA Frames"]="Marcos de AP"
+L["Micromenu"]="Micromenura"
+L["Minimap"]="Minimapa"
+L["MT Frames"]="Marcos de TP"
+L["Party Frames"]="Marco de Grupo"
+L["Pet Bar"]="Barra de Mascota"
+L["Pet Frame"]="Marco de Mascota"
+L["PetTarget Frame"]="Marco de Objetivo de Mascota"
+L["Player Castbar"]="Barra de Lanzamiento del Jugador"
+L["Player Frame"]="Marco de Jugador"
+L["Raid 1-"]="Banda 1-"
+L["Reputation Bar"]="Barra de Reputación"
+L["Right Dock"]="Chat Derecho"
+L["Stance Bar"]="Barra de Forma"
+L["Target Castbar"]="Barra de Lanzamiento del Objetivo"
+L["Target Frame"]="Marco de Objetivo"
+L["TargetTarget Frame"]="Marco de Objetivo de Objetivo"
+L["Tooltip"]="Descripción Emergente"
+L["Totems"]="Tótems"
+L["Vehicle Seat Frame"]="Marco del Asiento del Vehículo"
+L["Watch Frame"]="Marco de Vigilancia"
+L["Weapons"]="Armas"
+L["Discipline"]="Disciplina"
+L["Holy"]="Sagrado"
+L["Mistweaver"]="Tejedor de niebla"
+L["Restoration"]="Restauración"
+L[" |cff00ff00bound to |r"]=" |cff00ff00ligado(a) a |r"
+L["%s frame(s) has a conflicting anchor point, please change either the buff or debuff anchor point so they are not attached to each other. Forcing the debuffs to be attached to the main unitframe until fixed."]="El marco(s) %s tiene un punto de fijación en conflicto, por favor cambia el punto de fijación de los beneficios o los perjuicios para que no estén adjuntos entre ellos. Se forzará a los perjuicios para que se adjunten al marco de unidad principal hasta que se corrija."
+L["All keybindings cleared for |cff00ff00%s|r."]="Todos los atajos borrados para |cff00ff00%s|r."
+L["Already Running.. Bailing Out!"]="Ya está en ejecución... ¡Cancelando!"
+L["Battleground statistics temporarily hidden, to show type /bgstats."]="Textos de datos de los campos de batalla temporalmente ocultos, para mostrarlos escribe /bgstats o click derecho en 'C' donde el minimapa."
+L["Battleground statistics will now show again if you are inside a battleground."]="Los textos de datos de los campos de batalla serán visibles de nuevo si estás en un campo de batalla."
+L["Binds Discarded"]="Teclas Descartadas"
+L["Binds Saved"]="Teclas Guardadas"
+L["Confused.. Try Again!"]="Confundido... ¡Intenta de Nuevo!"
+L["Deleted %d gray items. Total Worth: %s"]="Se borraron %d objetos grises. Valor total: %s"
+L["No gray items to delete."]="No hay objetos grises para eliminar."
+L["No gray items to sell."]="No hay objetos grises para vender."
+L["The spell '%s' has been added to the BlackList unitframe aura filter."]="El hechizo '%s' ha sido añadido a la Lista Negra del filtro de auras del marco de unidad."
+L["Vendored gray items for:"]="Objetos grises vendidos por:"
+L["You don't have enough money to repair."]="No tienes suficiente dinero para reparaciones."
+L["You must be at a vendor."]="Debes estar cerca de un vendedor."
+L["Your items have been repaired for: "]="Tus objetos han sido reparados por:"
+L["Your items have been repaired using guild bank funds for: "]="Tus objetos han sido reparados con fondos del banco de hermandad por:"
+L["Your version of SVUI is out of date. You can download the latest version from http://www.wowinterface.com"]="Tu versión de SVUI no está actualizada. Puedes descargar la última versión de http://www.wowinterface.com"
+L["|cFFE30000Lua error recieved. You can view the error message when you exit combat."]="|cFFE30000Error de Lua recibido. Podrás ver el error cuando salgas de combate."
+L["A setting you have changed will change an option for this character only. This setting that you have changed will be uneffected by changing user profiles. Changing this setting requires that you reload your User Interface."]="La opción que has cambiado se aplicará sólo para este personaje. Esta opción no se verá alterada al cambiar el perfil de usuario. Cambiar esta opción requiere que recargues tu Interfaz de Usuario."
+L["Are you sure you want to delete all your gray items?"]="¿Estás seguro que quieres eliminar todos tus objetos grises?"
+L["Are you sure you want to disband the group?"]="¿Estás seguro que quieres deshacer el grupo?"
+L["Are you sure you want to reset every mover back to it's default position?"]="¿Estás seguro que quieres resetear cada fijador a su posición por defecto?"
+L["Because of the mass confusion caused by the new aura system I've implemented a new step to the installation process. This is optional. If you like how your auras are setup go to the last step and click finished to not be prompted again. If for some reason you are prompted repeatedly please restart your game."]="Debido a la gran confusión causada por el nuevo sistema de auras he implementado un nuevo paso en el proceso de instalación, esto es opcional. Si quieres conservar la configuración actual de tus auras ve al último paso de la instalación y haz clic en terminar para que este mensaje no vuelva a ser mostrado. Si por alguna razón se vuelve a mostrar por favor reinicia el juego."
+L["Can't buy anymore slots!"]="¡No puedes comprar más huecos!"
+L["Disable Warning"]="Deshabilitar Advertencia"
+L["Discard"]="Descartar"
+L["Do you swear not to post in technical support about something not working without first disabling the addon/package combination first?"]="¿Juras no escribir a Soporte Técnico acerca de algo que no funciona sin antes deshabilitar la combinación addon/módulo primero?"
+L["Hover your mouse over any actionbutton or spellbook button to bind it. Press the escape key or right click to clear the current actionbutton's keybinding."]="Pasa tu ratón por encima de un botón de acción o de un botón del libro de hechizos para ligarlo. Pulsa escape o botón derecho para limpiar la asignación actual del botón de acción."
+L["I Swear"]="Lo Juro"
+L["Oh lord, you have got SVUI and Tukui both enable at the same time. Select an addon to disable."]="Oh cielos, tienes SVUI y Tukui habilitados al mismo tiempo. Elige un addon a deshabilitar"
+L["One or more of the changes you have made require a ReloadUI."]="Uno o más de los cambios que has hecho requieren una recarga de la interfaz."
+L["One or more of the changes you have made will effect all characters using this addon. You will have to reload the user interface to see the changes you have made."]="Uno o más de los cambios que has hecho afectaran a todos los personajes que usen este addon. Tendrás que recargar la intefaz de usuario para ver el cambio que has realizado."
+L["Save"]="Guardar"
+L["Using the healer layout it is highly recommended you download the addon Clique if you wish to have the click-to-heal function."]=true;
+L["You have changed the pixel perfect option. You will have to complete the installation process to remove any graphical bugs."]="Has cambiado la opción de perfección por pixel. Tienes que completar la instalación para eliminar cualquier error gráfico."
+L["You have changed your UIScale, however you still have the AutoScale option enable in SV. Press accept if you would like to disable the Auto Scale option."]="Has cambiado la escala de tu interfaz, sin embargo aún tienes el AutoEscalado activado en SV. Pulsa aceptar si te gustaría desactivar el AutoEscalado."
+L["You must purchase a bank slot first!"]="¡Debes comprar un hueco del banco primero!"
+L["Count"]="Contador"
+L["Targeted By:"]="Objetivo De:"
+L["A raid marker feature is available by pressing Escape -> Keybinds scroll to the bottom under SVUI and setting a keybind for the raid marker."]="La opción de marcador de banda está disponible pulsando Escape -> Asignar teclas -> Recorrer hacia abajo hasta SVUI y establecer la tecla para el marcador de banda."
+L["SVUI has a dual spec feature which allows you to load different profiles based on your current spec on the fly. You can enable this from the profiles tab."]="SVUI tiene la posibilidad de cargar diferentes perfiles automáticamente al cambiar de especialización de talentos. Puedes activar esta función en la pestaña de perfiles."
+L["For technical support visit us at http://www.wowinterface.com."]="Para soporte técnico visítanos en http://www.wowinterface.com."
+L["If you accidently remove a chat frame you can always go the in-game configuration menu, press install, go to the chat portion and reset them."]="Si eliminas un marco de chat accidentalmente, siempre puedes ir a la configuración, pulsar instalar, ir a la parte del chat, y restaurarlo."
+L["If you are experiencing issues with SVUI try disabling all your addons except SVUI, remember SVUI is a full UI replacement addon, you cannot run two addons that do the same thing."]="Si has experimentado errores con SVUI prueba a desactivar todos tus addons excepto SVUI, recuerda que SVUI remplaza por completo la interfaz, no puede haber addons que hagan lo mismo."
+L["The buff panel to the right of minimap is a list of your consolidated buffs. You can disable it in Buffs and Debuffs options of SV."]="El panel de beneficios a la derecha del minimapa es una lista de los beneficios consolidados. Puedes desactivarlo en la pestaña de Beneficios y Perjuicios de SV."
+L["The focus unit can be set by typing /focus when you are targeting the unit you want to focus. It is recommended you make a macro to do this."]="El foco puede establecerse escribiendo /enfoque cuando tienes seleccionado al objetivo al cual quieres hacer foco. Es recomendable que hagas una macro para esto."
+L["To move abilities on the actionbars by default hold shift + drag. You can change the modifier key from the actionbar options menu."]="Para mover habilidades a las barras de acción mantener shift + arrastrar. Puedes cambiar la tecla de modificación desde el menú de opciones de la barra de acción."
+L["To setup which channels appear in which chat frame, right click the chat tab and go to settings."]="Para configurar que canales aparecen en el chat, haz clic con el botón derecho en la pestaña del chat y elige opciones."
+L["Using the /farmmode <size> command will spawn a larger minimap on your screen that can be moved around, very useful when farming."]="El comando /farmmode <tamaño> hace aparecer un minimapa más grande en su pantalla que puede moveablese, muy útil para recolectar."
+L["You can access copy chat and chat menu functions by mouse over the top right corner of chat panel and left/right click on the button that will appear."]="Puedes acceder a copiar y a las opciones del chat pasando el ratón sobre la esquina superior derecha del panel del chat y haciendo click en el botón que aparece."
+L["You can see someones average item level of their gear by holding shift and mousing over them. It should appear inside the tooltip."]="Puedes ver la media de nivel de objeto de un objetivo manteniendo pulsado shift mientras pasas el ratón por encima de él. El iNvl aparecerá en la descripción emergente."
+L["You can set your keybinds quickly by typing /kb."]="Puedes establecer tus atajos rapidamente escribiendo /kb."
+L["You can toggle the microbar by using your middle mouse button on the minimap you can also accomplish this by enabling the actual microbar located in the actionbar settings."]="Puedes acceder a la microbarra usando tu botón central del ratón sobre el minimapa. También puedes activarla desde las opciones de las barras de acción."
+L["You can use the /resetui command to reset all of your moveables. You can also use the command to reset a specific mover, /resetui <mover name>.\nExample: /resetui Player Frame"]="Puedes usar el commando /resetui para restablecer todos tus fijadores. También puedes usar el comando para restablecer alguno en específico, /resetui <fijador>. PSV: /resetui Player Frame"
+L["Ghost"]="Fantasma"
+L["Offline"]="Fuera de Línea"
+L["ENH_LOGIN_MSG"]="You are using |cff1784d1SVUI Enhanced|r version %s%s|r."
+L["Your version of SVUI is to old. Please, download the latest version from http://www.wowinterface.com."]=true;
+L["Equipment"]=true;
+L["EQUIPMENT_DESC"]="Adjust the settings for switching your gear set when you change specialization or enter a battleground."
+L["No Change"]=true;
+L["Specialization"]=true;
+L["Enable/Disable the specialization switch."]=true;
+L["Primary Talent"]=true;
+L["Choose the equipment set to use for your primary specialization."]=true;
+L["Secondary Talent"]=true;
+L["Choose the equipment set to use for your secondary specialization."]=true;
+L["Battleground"]=true;
+L["Enable/Disable the battleground switch."]=true;
+L["Equipment Set"]=true;
+L["Choose the equipment set to use when you enter a battleground or arena."]=true;
+L["You have equipped equipment set: "]=true;
+L["DURABILITY_DESC"]="Adjust the settings for the durability information on the character screen."
+L["Enable/Disable the display of durability information on the character screen."]=true;
+L["Damaged Only"]=true;
+L["Only show durabitlity information for items that are damaged."]=true;
+L["ITEMLEVEL_DESC"]="Adjust the settings for the item level information on the character screen."
+L["Enable/Disable the display of item levels on the character screen."]=true;
+L["Miscellaneous"]=true;
+L["Equipment Set Overlay"]=true;
+L["Show the associated equipment sets for the items in your bags (or bank)."]=true;
+L["Layout Transparency"]=true;
+L["Changes the transparency of all the moveables."]=true;
+L["Automatic Role Assignment"]=true;
+L["Enables the automatic role assignment based on specialization for party / raid members (only work when you are group leader or group assist)."]=true;
+L["Hide Role Icon in combat"]=true;
+L["All role icons (Damage/Healer/Tank) on the unit frames are hidden when you go into combat."]=true;
+L["GPS"]=true;
+L["Show the direction and distance to the selected party or raid member."]=true;
+L["Attack Icon"]=true;
+L["Show attack icon for units that are not tapped by you or your group, but still give kill credit when attacked."]=true;
+L["Show class icon for units."]=true;
+L["Above Minimap"]=true;
+L["Location Digits"]=true;
+L["Number of digits for map location."]=true;
+L["Hide minimap while in combat."]=true;
+L["FadeIn Delay"]=true;
+L["The time to wait before fading the minimap back in after combat hide. (0 = Disabled)"]=true;
+L["Minimap Button Bar"]=true;
+L["Style Buttons"]=true;
+L["Customize the minimap buttons in SVUI style."]=true;
+L["SVUI Style"]=true;
+L["Change settings for how the minimap buttons are styled."]=true;
+L["The size of the minimap buttons."]=true;
+L["No Anchor Bar"]=true;
+L["Horizontal Anchor Bar"]=true;
+L["Vertical Anchor Bar"]=true;
+L["Layout Direction"]=true;
+L["Normal is right to left or top to bottom, or select reversed to switch directions."]=true;
+L["Normal"]=true;
+L["Reversed"]=true;
+L["PvP Autorelease"]=true;
+L["Automatically release body when killed inside a battleground."]=true;
+L["Track Reputation"]=true;
+L["Automatically change your watched faction on the reputation bar to the faction you got reputation points for."]=true;
+L["Select Quest Reward"]=true;
+L["Automatically select the quest reward with the highest vendor sell value."]=true;
+L["Item Level"]=true;
+L["Target Range"]=true;
+L["Distance"]=true;
+L["Actionbar1DataPanel"]='Actionbar 1'
+L["Actionbar3DataPanel"]='Actionbar 3'
+L["Actionbar5DataPanel"]='Actionbar 5'
+L["Sunsong Ranch"]="Rancho Cantosol"
+L["The Halfhill Market"]="El Mercado del Alcor"
+L["Tilled Soil"]="Tierra labrada"
+L["Right-click to drop the item."]=true;
+L["Toolbox"]=true;
+L["COMIX_DESC"]="Toggle the comic popups during combat"
+L["FARMING_MODE_DESC"]="Adjust the settings for the tools that help your farming and professions."
+L["SNACKS_DESC"]="Adjust the settings for the consumables bar."
+L["Toolbox Bars"]=true;
+L["Toolbox Portal Bar"]=true;
+L["Toolbox Seed Bar"]=true;
+L["Toolbox Tools Bar"]=true;
+L["Enable/Disable the laborer bars."]=true;
+L["Only active buttons"]=true;
+L["Only show the buttons for the seeds, portals, tools you have in your bags."]=true;
+L["Drop Tools"]=true;
+L["Automatically drop tools from your bags when leaving the farming area."]=true;
+L["Seed Bar Direction"]=true;
+L["The direction of the seed bar buttons (Horizontal or Vertical)."]=true;
+L["Threat Text"]=true;
+L["Display threat level as text on targeted, boss or mouseover nameplate."]=true;
+L["Target Count"]=true;
+L["Display the number of party / raid members targetting the nameplate unit."]=true;
+L["Heal Glow"]=true;
+L["Direct AoE heals will let the unit frames of the affected party / raid members glow for the defined time period."]=true;
+L["Glow Duration"]=true;
+L["The amount of time the unit frames of party / raid members will glow when affected by a direct AoE heal."]=true;
+L["Glow Color"]=true;
+L["Raid Marker Bar"]=true;
+L["Display a quick action bar for raid targets and world markers."]=true;
+L["Modifier Key"]=true;
+L["Set the modifier key for placing world markers."]=true;
+L["Shift Key"]=true;
+L["Ctrl Key"]=true;
+L["Alt Key"]=true;
+L["Raid Markers"]=true;
+L["Click to clear the mark."]=true;
+L["Click to mark the target."]=true;
+L["%sClick to remove all worldmarkers."]=true;
+L["%sClick to place a worldmarker."]=true;
+L["WatchFrame"]=true;
+L["WATCHFRAME_DESC"]="Adjust the settings for the visibility of the watchframe (questlog) to your personal preference."
+L["Hidden"]=true;
+L["Collapsed"]=true;
+L["Settings"]=true;
+L["City (Resting)"]=true;
+L["PvP"]=true;
+L["Arena"]=true;
+L["Party"]=true;
+L["Raid"]=true;
+L["Progression Info"]=true;
+L["Display the players raid progression in the tooltip, this may not immediately update when mousing over a unit."]=true
\ No newline at end of file
diff --git a/SVUI_!Core/language/taiwanese_ui.lua b/SVUI_!Core/language/taiwanese_ui.lua
new file mode 100644
index 0000000..52e7873
--- /dev/null
+++ b/SVUI_!Core/language/taiwanese_ui.lua
@@ -0,0 +1,593 @@
+local L = Librarian("Linguist"):Lang("zhTW");
+if not L then return; end
+L["Conversation"]    = "對話"
+L["General"]         = "綜合"
+L["LocalDefense"]    = "本地防務"
+L["LookingForGroup"] = "尋求組隊"
+L["Trade"]           = "交易"
+L["WorldDefense"]    = "世界防務"
+L["S_Conversation"]    = "話"
+L["S_General"]        = "綜"
+L["S_LocalDefense"]    = "本"
+L["S_LookingForGroup"] = "尋"
+L["S_Trade"]          = "交"
+L["S_WorldDefense"]    = "世"
+L["Hearthstone"] = true;
+--[[LOGIN MESSAGE]]--
+L["LOGIN_MSG"] = "歡迎使用 |cffFFFF1ASVUI|r! 让您的 %s 和你 %s."
+L["LOGIN_MSG2"] = "|cffAA78FF%s|r 版, 請輸入/sv 進入設定介面."
+--[[OPTION MESSAGES]]--
+L["AURAS_DESC"] = "小地圖旁的光環圖示設定."
+L["BAGS_DESC"] = "調整 SVUI 背包設定."
+L["CHAT_DESC"] = "對話框架設定."
+L["STATS_DESC"] = "Configure docked stat panels.";
+L["SVUI_DESC"] = "SVUI 為一套功能完整, 可用來替換 WOW 原始介面的 UI 套件"
+L["NAMEPLATE_DESC"] = "修改血條設定."
+L["PANEL_DESC"] = "調整左、右對話框的尺寸, 此設定將會影響對話與背包框架的尺寸."
+L["ART_DESC"] = "調整外觀設定."
+L["TOGGLEART_DESC"] = "啟用 / 停用此外觀."
+L["TOOLTIP_DESC"] = "浮動提示資訊設定選項."
+L["TEXT_FORMAT_DESC"] = "Select the formatting of this text"
+L["import"] = "現有的設定檔"
+L["import_desc"] = "你可以通過在文本框內輸入一個名字創立一個新的設定檔,也可以選擇一個已經存在的設定檔。"
+L["import_sub"] = "從當前可用的設定檔裏面選擇一個。"
+L["copy_name"] = "複製自"
+L["copy_desc"] = "從當前某個已保存的設定檔複製到當前正使用的設定檔。"
+L["current"] = "Current Profile:"
+L["default"] = "預設"
+L["delete"] = "刪除一個設定檔"
+L["delete_confirm"] = "你確定要刪除所選擇的設定檔嗎?"
+L["delete_desc"] = "從資料庫裏刪除不再使用的設定檔,以節省空間,並且清理SavedVariables檔。"
+L["delete_sub"] = "從資料庫裏刪除一個設定檔。"
+L["intro"] = "你可以選擇一個活動的資料設定檔,這樣你的每個角色就可以擁有不同的設定值,可以給你的插件設定帶來極大的靈活性。"
+L["export"] = "新建"
+L["export_sub"] = "新建一個空的設定檔。"
+L["profiles"] = "設定檔"
+L["profiles_sub"] = "管理設定檔"
+L["reset"] = "重置設定檔"
+L["reset_desc"] = "將當前的設定檔恢復到它的預設值,用於你的設定檔損壞,或者你只是想重來的情況。"
+L["reset_sub"] = "將當前的設定檔恢復為預設值"
+L["SVUI_DockBottomCenter"] = "Bottom Data Dock"
+L["SVUI_DockTopCenter"] = "Top Data Dock"
+--[[REACTION TEXTS]]--
+L[" is drinking."] = true;
+L["Leeeeeroy!"] = true;
+L["No Food: "] = "缺少食物Buff: "
+L["No Flask: "] = "缺少精煉藥劑: "
+L["All Buffed!"] = "已獲得所有增益!"
+L["Check food and flask"] = "檢查食物和精煉"
+L["Thanks for "] = "謝謝你的 "
+L[" received from "] = " 收到來自于 "
+L["GO!"] = "開始!"
+L["Pulling %s in %s.."] = "正在拉: %s, 倒數 %s.."
+L["Pull ABORTED!"] = "取消拉怪!"
+L["%s has prepared a %s - [%s]."] = "%s 放置了 %s - [%s]."
+L["%s has prepared a %s."] = "%s 放置了 %s"
+L["%s has put down a %s."] = "%s 放置了 %s"
+L["%s is casting %s."] = "%s 開啟了 %s"
+L["%s is casting %s. Click!"] = "%s 正在開啟 %s... 請點擊!"
+L["%s used a %s."] = "%s 使用了 %s."
+--[[FORMATTED INSTALLER TEXTS]]--
+L["|cffD3CF00Recommended|r"] = true;
+L["Recommended: |cff99FF00Kaboom!|r"] = true;
+L["Recommended: |cff99FF00Super|r"] = true;
+L["Recommended: |cffFF0000Small Row!|r"] = true;
+L["Recommended: |cffFF0000Icon Lovers!|r"] = true;
+L["|cffFF9F00KABOOOOM!|r"] = true;
+L["|cffAF30FFThe Darkest Night|r"] = true;
+L["|cff00FFFFPlain and Simple|r"] = true;
+L["|cff00FFFFLets Do This|r"] = true;
+L["|cff00FFFFSimply Simple|r"] = true;
+L["|cff00FFFFEl Compacto|r"] = true;
+L["|cff00FFFFHealer Extraordinaire|r"] = true;
+L["|cff00FFFFLean And Clean|r"] = true;
+L["|cff00FFFFMore For Less|r"] = true;
+L["|cff00FFFFWhat Big Buttons You Have|r"] = true;
+L["|cff00FFFFThe Double Down|r"] = true;
+--[[NORMAL INSTALLER TEXTS]]--
+L["This is SVUI version %s!"] = true;
+L["Before I can turn you loose, persuing whatever villainy you feel will advance your professional career ... I need to ask some questions and turn a few screws first."] = true;
+L["At any time you can get to the config options by typing the command /sv. For quick changes to frame, bar or color sets, call your henchman by clicking the button on the bottom right of your screen. (Its the one with his stupid face on it)"] = true;
+L["CHOOSE_OR_DIE"] = CHOOSE_FACTION.." "..OR_CAPS.." "..HIT.." "..CONTINUE;
+L["Whether you want to or not, you will be needing a communicator so other villains can either update you on their doings-of-evil or inform you about the MANY abilities of Chuck Norris"] = true;
+L["The chat windows function the same as standard chat windows, you can right click the tabs and drag them, rename them, slap them around, you know... whatever. Clickity-click to setup your chat windows."] = true;
+L["Your current resolution is %s, this is considered a %s resolution."] = true;
+L["This resolution requires that you change some settings to get everything to fit on your screen."] = true;
+L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."] = true;
+L["You may need to further alter these settings depending how low you resolution is."] = true;
+L["This resolution doesn't require that you change settings for the UI to fit on your screen."] = true;
+L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."] = true;
+L["This is completely optional."] = true;
+L["So what you think your better than me with your big monitor? HUH?!?!"] = true;
+L["Dont forget whos in charge here! But enjoy the incredible detail."] = true;
+L["Why are you playing this on what I would assume is a calculator display?"] = true;
+L["Enjoy the ONE incredible pixel that fits on this screen."] = true;
+L["Choose a theme layout you wish to use for your initial setup."] = true;
+L["You can always change fonts and colors of any element of SVUI from the in-game configuration."] = true;
+L["This theme tells the world that you are a villain who can put on a show "] = true;
+L["or better yet, you ARE the show!"] = true;
+L["Kaboom!"] = true;
+L["This theme indicates that you have no interest in wasting time"] = true;
+L["the dying begins NOW!"] = true;
+L["Darkness"] = true;
+L["This theme is for villains who take pride in their class"] = true;
+L["villains know how to reprezent!"] = true;
+L["This theme is for any villain who sticks to their traditions"] = true;
+L["you don't need fancyness to kick some ass!"] = true;
+L["Vintage"] = true;
+L["Layout"] = true;
+L["You can now choose what primary unitframe style you wish to use."] = true;
+L["This will change the layout of your unitframes (ie.. Player, Target, Pet, Party, Raid ...etc)."] = true;
+L["This layout is anything but minimal! Using this is like being at a rock concert"] = true;
+L["then annihilating the crowd with frickin lazer beams!"] = true;
+L["Super"] = true;
+L["This layout is for the villain who just wants to get things done!"] = true;
+L["But he still wants to see your face before he hits you!"] = true;
+L["Simple"] = true;
+L["Just the necessities so you can see more of the world around you."] = true;
+L["You dont need no fanciness getting in the way of world domination do you?"] = true;
+L["Compact"] = true;
+L["This has all the pizzaz of Super frames but uses Compact party and raid frames."] = true;
+L["Sometimes a little fifty-fifty goes a long way."] = true;
+L["Healer"] = true;
+L["Bar Setup"] = true;
+L["Choose a layout for your action bars."] = true;
+L["Sometimes you need big buttons, sometimes you don't. Your choice here."] = true;
+L["Lets keep it slim and deadly, not unlike a ninja sword."] = true;
+L["You dont ever even look at your bar hardly, so pick this one!"] = true;
+L["Small Row"] = true;
+L["Granted, you dont REALLY need the buttons due to your hotkey-leetness, you just like watching cooldowns!"] = true;
+L["Sure thing cowboy, your secret is safe with me!"] = true;
+L["Small X2"] = true;
+L["The better to PEW-PEW you with my dear!"] = true;
+L["When you have little time for mouse accuracy, choose this set!"] = true;
+L["Big Row"] = true;
+L["It's like dual-wielding two big reasons for your enemies to back the **** up!"] = true;
+L["Double your bars then double their size for maximum button goodness!"] = true;
+L["Big X2"] = true;
+L["Auras System"] = true;
+L["Select the type of aura system you want to use with SVUI's unitframes. The Icon Lovers set will display only icons and aurabars won't be used. The Vintage set will use the original game style and the Gimme Everything set does just what it says.... icons, bars and awesomeness."] = true;
+L["If you have an icon or aurabar that you don't want to display simply hold down shift and right click the icon for it to suffer a painful death."] = true;
+L["Vintage"] = true;
+L["Icon Lovers"] = true;
+L["The Works!"] = true;
+L["Installation Complete"] = true;
+L["Thats it! All done! Now we just need to hand these choices off to the henchmen so they can get you ready to (..insert evil tasks here..)!"] = true;
+L["Click the button below to reload and get on your way! Good luck villain!"] = true;
+L["THE_BUTTON_BELOW"] = "THE\nBUTTON\nBELOW";
+--[[UI TEXTS]]--
+L["Meanwhile"]=true;
+L["..at "]=true;
+L["A taint has occured that is preventing you from using the queue system. Please reload your user interface and try again."]="發生一個錯誤導致你無法使用隊列系統,請重新加載你的用戶界面,然後再試一次."
+L["Binding"]="綁定"
+L["Key"]="鍵"
+L["KEY_ALT"]="A"
+L["KEY_CTRL"]="C"
+L["KEY_DELETE"]="Del"
+L["KEY_HOME"]="Hm"
+L["KEY_INSERT"]="Ins"
+L["KEY_MOUSEBUTTON"]="M"
+L["KEY_MOUSEWHEELDOWN"]="MwD"
+L["KEY_MOUSEWHEELUP"]="MwU"
+L["KEY_NUMPAD"]="N"
+L["KEY_PAGEDOWN"]="PD"
+L["KEY_PAGEUP"]="PU"
+L["KEY_SHIFT"]="S"
+L["KEY_SPACE"]="SpB"
+L["No bindings set."]="未設定快捷綁定."
+L["Remove Bar %d Action Page"]="移除第 %d 快捷列"
+L["Trigger"]="觸發器"
+L["Delete Grays"]="刪除灰色物品"
+L["Hold Control + Right Click:"]='按住 Ctrl 並按滑鼠右鍵:'
+L["Hold Shift + Drag:"]='按住 Shift 並拖曳:'
+L["Hold Shift:"]="按住 Shift:"
+L["Purchase"]="購買銀行欄位"
+L["Reset Position"]='重設位置'
+L["Sort Bags"]="整理背包"
+L["Sort Tab"]=true;
+L["Stack Bags to Bank"]='物品堆疊至銀行'
+L["Stack Bank to Bags"]='物品堆疊至背包'
+L["Stack Items"]="堆疊物品"
+L["Temporary Move"]='移動背包'
+L["Toggle Bags"]='開啟/關閉背包'
+L["Vendor Grays"]="出售灰色物品"
+L["AFK"]="離開"
+L["DND"]="忙碌"
+L["G"]="公會"
+L["I"]='副本'
+L["IL"]='副本隊長'
+L["Invalid Target"]="無效的目標"
+L["O"]="幹部"
+L["P"]="隊伍"
+L["PL"]="隊長"
+L["R"]="團隊"
+L["RL"]="團隊隊長"
+L["RW"]="團隊警告"
+L["says"]="說"
+L["whispers"]="密語"
+L["yells"]="大喊"
+L["(Hold Shift) Memory Usage"]="(按住Shift) 記憶體使用量"
+L["AP"]="攻擊強度"
+L["AVD: "]="免傷: "
+L["Avoidance Breakdown"]="免傷統計"
+L["Bandwidth"]="頻寬"
+L["Bases Assaulted"]="已佔領基地"
+L["Bases Defended"]="已守住基地"
+L["Carts Controlled"]="已操控乘載器具"
+L["Character: "]="角色: "
+L["Chest"]="胸部"
+L["Combat Time"]="戰斗時間"
+L["copperabbrev"]="|cffeda55f銅|r"
+L["Defeated"]="已擊殺"
+L["Deficit:"]="赤字:"
+L["Demolishers Destroyed"]="已摧毀攻城器具"
+L["Download"]="下載"
+L["DPS"]="傷害輸出"
+L["Earned:"]="賺取:"
+L["Feet"]="腳部"
+L["Flags Captured"]="已奪取旗幟"
+L["Flags Returned"]="已交還旗幟"
+L["Friends List"]="好友列表"
+L["Friends"]="好友"
+L["Galleon"]="帆船"
+L["Gates Destroyed"]="已摧毀城門"
+L["goldabbrev"]="|cffffd700金|r"
+L["Graveyards Assaulted"]="已佔領墓地"
+L["Graveyards Defended"]="已守住墓地"
+L["Hands"]="手部"
+L["Head"]="頭部"
+L["Hit"]="命中"
+L["Home Latency:"]="本機延遲:"
+L["HP"]="生命值"
+L["HPS"]="治療輸出"
+L["Legs"]="腿部"
+L["lvl"]="等級"
+L["Main Hand"]="主手"
+L["Mitigation By Level: "]="等級減傷: "
+L["Nalak"]="納拉卡"
+L["No Guild"]="沒有公會"
+L["Offhand"]="副手"
+L["Oondasta"]="烏達斯塔"
+L["Orb Possessions"]="寶珠屬地"
+L["Profit:"]="利潤: "
+L["Reset Data: Hold Shift + Right Click"]="重置數據: 按住 Shift + 右鍵點擊"
+L["Saved Raid(s)"]="已有進度的副本"
+L["Server: "]="伺服器: "
+L["Session:"]="本次登入:"
+L["Sha of Anger"]="憤怒之煞"
+L["Shoulder"]="肩部"
+L["silverabbrev"]="|cffc7c7cf銀|r"
+L["SP"]="法術能量"
+L["Spent:"]="花費:"
+L["Stats For:"]="統計:"
+L["Total CPU:"]="CPU佔用"
+L["Total Memory:"]="總記憶體:"
+L["Total: "]="合計: "
+L["Towers Assaulted"]="已佔領哨塔"
+L["Towers Defended"]="已守住哨塔"
+L["Undefeated"]="未擊殺"
+L["Unhittable:"]="未命中:"
+L["Victory Points"]="勝利點數"
+L["Waist"]="腰部"
+L["World Boss(s)"]="世界首領"
+L["Wrist"]="護腕"
+L["%s: %s tried to call the protected function '%s'."]="%s: %s 嘗試調用保護函數'%s'."
+L["No locals to dump"]="沒有本地文件"
+L["%s is attempting to share his filters with you. Would you like to accept the request?"]="%s 試圖與你分享過濾器配置. 你是否接受?"
+L["%s is attempting to share the profile %s with you. Would you like to accept the request?"]="%s 試圖與你分享配置文件 %s. 你是否接受?"
+L["Data From: %s"]="數據來源: %s"
+L["Filter download complete from %s, would you like to apply changes now?"]="過濾器配置下載於 %s, 你是否現在變更?"
+L["Lord! It's a miracle! The download up and vanished like a fart in the wind! Try Again!"]="天啊! 太奇葩啦! 下載消失了! 就像是在風中放了個屁... 再試一次吧!"
+L["Profile download complete from %s, but the profile %s already exists. Change the name or else it will overwrite the existing profile."]="配置文件從 %s 下載完成, 但是配置文件 %s 已存在. 請更改名稱, 否則它會覆蓋你的現有配置文件."
+L["Profile download complete from %s, would you like to load the profile %s now?"]="配置文件從 %s 下載完成, 你是否要加載配置文件 %s?"
+L["Profile request sent. Waiting for response from player."]="已發送文件請求. 等待對方響應."
+L["Request was denied by user."]="請求被對方拒絕."
+L["Your profile was successfully recieved by the player."]="你的配置文件已被其他玩家成功接收."
+L["Auras Set"]="光環樣式設定"
+L["Auras System"]="光環樣式"
+L["Caster DPS"]="法系輸出"
+L["Chat Set"]="對話设置"
+L["Chat"]="對話"
+L["Choose a theme layout you wish to use for your initial setup."]="為你的個人設定選擇一個你喜歡的皮膚主題."
+L["Vintage"]="經典"
+L["Classic"]="經典"
+L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."]="點擊下面的按鈕調整對話框、單位框架的尺寸, 以及移動快捷列位置."
+L["Config Mode:"]="設定模式:"
+L["CVars Set"]="參數設定"
+L["CVars"]="參數"
+L["Gloom & Doom"]="黑暗"
+L["Disable"]="禁用"
+L["SVUI Installation"]="安裝 SVUI"
+L["Finished"]="設定完畢"
+L["Grid Size:"]="網格尺寸:"
+L["Healer"]="補師"
+L["High Resolution"]="高解析度"
+L["high"]="高"
+L["Icons Only"]="圖示"
+L["If you have an icon or aurabar that you don't want to display simply hold down shift and right click the icon for it to disapear."]="如果你有不想顯示的圖示或光環條, 你可以簡單的通過按住Shift右鍵點擊使它隱藏."
+L["Importance: |cff07D400High|r"]="重要性: |cff07D400高|r"
+L["Importance: |cffD3CF00Medium|r"]="重要性: |cffD3CF00中|r"
+L["Importance: |cffFF0000Low|r"]="重要性: |cffFF0000低|r"
+L["Installation Complete"]="安裝完畢"
+L["Integrated"]="整合"
+L["Layout Set"]="版面配置設定"
+L["Layout"]="介面佈局"
+L["Lock"]="鎖定"
+L["Low Resolution"]="低解析度"
+L["low"]="低"
+L["Frames unlocked. Move them now and click Lock when you are done."]="解除框架移動鎖定. 現在可以移動它們, 移好後請點擊「鎖定」."
+L["Nudge"]="微調"
+L["Physical DPS"]="物理輸出"
+L["Pixel Perfect Set"]="像素設置"
+L["Pixel Perfect"]="像素完美"
+L["Please click the button below so you can setup variables and ReloadUI."]="請按下方按鈕設定變數並重載介面."
+L["Please click the button below to setup your CVars."]="請按下方按鈕設定參數."
+L["Please press the continue button to go onto the next step."]="請按「繼續」按鈕,執行下一個步驟."
+L["Resolution Style Set"]="解析度樣式設定"
+L["Resolution"]="解析度"
+L["Select the type of aura system you want to use with SVUI's unitframes. The integrated system utilizes both aura-bars and aura-icons. The icons only system will display only icons and aurabars won't be used. The classic system will configure your auras to be default."]="選擇你想在頭像框架上使用的光環樣式. 集成樣式包含了光環條和圖示. 圖示樣式只包含圖示, 並且光環條將不再顯示."
+L["Setup Chat"]="設定對話視窗"
+L["Setup CVars"]="設定參數"
+L["Skip Process"]="略過"
+L["Sticky Frames"]="框架依附"
+L["Tank"]="坦克"
+L["The chat windows function the same as Blizzard standard chat windows, you can right click the tabs and drag them around, rename, etc. Please click the button below to setup your chat windows."]="對話視窗與WOW 原始對話視窗的操作方式相同, 你可以拖拉、移動分頁或重新命名分頁. 請按下方按鈕以設定對話視窗."
+L["The in-game configuration menu can be accesses by typing the /sv command or by clicking the 'C' button on the minimap. Press the button below if you wish to skip the installation process."]="若要進入內建設定選單, 請輸入/sv, 或者按一下小地圖旁的「C」按鈕.若要略過安裝程序, 請按下方按鈕."
+L["The Pixel Perfect option will change the overall apperance of your UI. Using Pixel Perfect is a slight performance increase over the traditional layout."]="像素完美選項將改變你的整體用戶界面, 使用像素完美能輕微提升傳統界面的性能."
+L["Theme Set"]="主題設置"
+L["Theme Setup"]="主題安裝"
+L["This install process will help you learn some of the features in SVUI has to offer and also prepare your user interface for usage."]="此安裝程序有助你瞭解SVUI 部份功能, 並可協助你預先設定UI."
+L["This is completely optional."]="此為選擇性功能."
+L["This part of the installation process sets up your chat windows names, positions and colors."]="此安裝步驟將會設定對話視窗的名稱、位置和顏色."
+L["This part of the installation process sets up your World of Warcraft default options it is recommended you should do this step for everything to behave properly."]="此安裝步驟將會設定 WOW 預設選項, 建議你執行此步驟, 以確保功能均可正常運作."
+L["This resolution doesn't require that you change settings for the UI to fit on your screen."]="這個解析度不需要你改動任何設定以適應你的屏幕."
+L["This resolution requires that you change some settings to get everything to fit on your screen."]="這個解析度需要你改變一些設定才能適應你的屏幕."
+L["This will change the layout of your unitframes, raidframes, and statistics."]="此材質適用於對話框架、下拉式選單等物件上."
+L["Trade"]="拾取/交易"
+L["Using this option will cause your borders around frames to be 1 pixel wide instead of 3 pixel. You may have to finish the installation to notice a differance. By default this is enable."]="此安裝步驟將會使你的周圍邊框幀是1像素寬而不是3像素, 你可能在安裝時已經注意到這一差異, 這是一個默認的啓用."
+L["Welcome to SVUI version %s!"]="歡迎使用 SVUI %s 版!"
+L["You are now finished with the installation process. If you are in need of technical support please visit us at http://www.wowinterface.com."]="已完成安裝程序. 小提示: 若想開啟微型選單, 請在小地圖按滑鼠中鍵. 如果沒有中鍵按鈕, 請按住Shift鍵, 並在小地圖按滑鼠右鍵. 如需技術支援請至http://www.wowinterface.com"
+L["You can always change fonts and colors of any element of SVUI from the in-game configuration."]="你可以在遊戲內的設定選項內更改SVUI的字體、顏色等設定."
+L["You can now choose what layout you wish to use based on your combat role."]="你現在可以根據你的戰鬥角色選擇合適的佈局."
+L["You may need to further alter these settings depending how low you resolution is."]="根據你的解析度你可能需要改動這些設定."
+L["Your current resolution is %s, this is considered a %s resolution."]="你當前的解析度是%s, 這被認為是個%s 解析度."
+L["Bars"]="條"
+L["Calendar"]="日曆"
+L["Can't Roll"]="無法需求此裝備"
+L["Disband Group"]="解散隊伍"
+L["Empty Slot"]="空欄位"
+L["Enable"]="啟用"
+L["Experience"]="經驗/聲望條"
+L["Fishy Loot"]="貪婪"
+L["Left Click:"]="滑鼠左鍵:"
+L["Raid Menu"]="團隊選單"
+L["Remaining:"]="剩餘:"
+L["Rested:"]="休息:"
+L["Right Click:"]="滑鼠右鍵:"
+L["Show BG Texts"]="顯示戰場資訊文字"
+L["Toggle Chat Frame"]="開關對話框架"
+L["Toggle Configuration"]="開啟/關閉設定"
+L["XP:"]="經驗:"
+L["You don't have permission to mark targets."]="你沒有標記目標的權限."
+L["ABOVE_THREAT_FORMAT"]='%s: %.0f%% [%.0f%% 以上 |cff%02x%02x%02x%s|r]'
+L[" Frames"]="框架"
+L["Alternative Power"]="特殊能量條框架"
+L["Arena Frames"]="競技場框架"
+L["Auras Frame"]="增益/減益 框架"
+L["Bags"]="背包"
+L["Bar "]="快捷列 "
+L["BNet Frame"]="戰網提示資訊"
+L["Special Ability Button"]="特殊技能鍵"
+L["Boss Frames"]="首領框架"
+L["Experience Bar"]="經驗條"
+L["Focus Castbar"]="焦點目標施法條"
+L["Focus Frame"]="焦點目標框架"
+L["FocusTarget Frame"]="焦點目標的目標框架"
+L["GM Ticket Frame"]="GM 對話框"
+L["Left Dock"]="左側對話框"
+L["Loot / Alert Frames"]="拾取 / 提醒框架"
+L["Loot Frame"]="拾取框架"
+L["Loss Control Icon"]="失去控制圖示"
+L["MA Frames"]="主助理框架"
+L["Micromenu"]="微型系統菜單"
+L["Minimap"]="小地圖"
+L["MT Frames"]="主坦克框架"
+L["Party Frames"]="隊伍框架"
+L["Pet Bar"]="寵物快捷列"
+L["Pet Frame"]="寵物框架"
+L["PetTarget Frame"]="寵物目標框架"
+L["Player Castbar"]="玩家施法條"
+L["Player Frame"]="玩家框架"
+L["Raid 1-"]="團隊 1-"
+L["Reputation Bar"]="聲望條"
+L["Right Dock"]="右側對話框"
+L["Stance Bar"]="姿態列"
+L["Target Castbar"]="目標施法條"
+L["Target Frame"]="目標框架"
+L["TargetTarget Frame"]="目標的目標框架"
+L["Tooltip"]="浮動提示"
+L["Totems"]="圖騰列"
+L["Vehicle Seat Frame"]="載具座位框"
+L["Watch Frame"]="任務追蹤框架"
+L["Weapons"]="武器(毒藥/強化等)"
+L["Discipline"]="戒律"
+L["Holy"]="神聖"
+L["Mistweaver"]='織霧'
+L["Restoration"]="恢復"
+L[" |cff00ff00bound to |r"]=" |cff00ff00綁定到 |r"
+L["%s frame(s) has a conflicting anchor point, please change either the buff or debuff anchor point so they are not attached to each other. Forcing the debuffs to be attached to the main unitframe until fixed."]=" %s 個框架錨點衝突, 請移動buff或者debuff錨點讓他們彼此不依附. 暫時強制debuff依附到主框架."
+L["All keybindings cleared for |cff00ff00%s|r."]="取消|cff00ff00%s|r 所有綁定的快捷​​鍵."
+L["Already Running.. Bailing Out!"]='正在運行'
+L["Battleground statistics temporarily hidden, to show type /bgstats."]='戰場資訊暫時隱藏, 你可以通過輸入/bgstats 或右鍵點擊小地圖旁「C」按鈕顯示.'
+L["Battleground statistics will now show again if you are inside a battleground."]="當你處於戰場時戰場資訊將再次顯示."
+L["Binds Discarded"]="取消綁定"
+L["Binds Saved"]="儲存綁定"
+L["Confused.. Try Again!"]='請再試一次!'
+L["Deleted %d gray items. Total Worth: %s"]="已刪除%d 個灰色物品. 總價值: %s"
+L["No gray items to delete."]="沒有可刪除的灰色物品."
+L["No gray items to sell."]="沒有可出售的灰色物品."
+L["The spell '%s' has been added to the BlackList unitframe aura filter."]='法術"%s"已經被添加到單位框架的光環過濾器中.'
+L["Vendored gray items for:"]="已售出灰色物品,共得:"
+L["You don't have enough money to repair."]="沒有足夠的資金來修復."
+L["You must be at a vendor."]="你必須與商人對話."
+L["Your items have been repaired for: "]="裝備已修復,共支出:"
+L["Your items have been repaired using guild bank funds for: "]="已使用公會資金修復裝備,共支出:"
+L["Your version of SVUI is out of date. You can download the latest version from http://www.wowinterface.com"]="SVUI 版本已過期, 請至http://www.wowinterface.com 下載最新版"
+L["|cFFE30000Lua error recieved. You can view the error message when you exit combat."]="|cFFE30000LUA錯誤已接收, 你可以在脫離戰鬥後檢查.|r"
+L["A setting you have changed will change an option for this character only. This setting that you have changed will be uneffected by changing user profiles. Changing this setting requires that you reload your User Interface."]="你所做的改動只會影響到使用這個插件的本角色, 你需要重新加載介面才能使改動生效."
+L["Are you sure you want to delete all your gray items?"]="是否確定要刪除所有灰色物品?"
+L["Are you sure you want to disband the group?"]="確定要解散隊伍?"
+L["Are you sure you want to reset every mover back to it's default position?"]="確定需要重置所有框架至默認位置?"
+L["Because of the mass confusion caused by the new aura system I've implemented a new step to the installation process. This is optional. If you like how your auras are setup go to the last step and click finished to not be prompted again. If for some reason you are prompted repeatedly please restart your game."]="由於大量的問題導致光環系統需要一個新的安裝過程. 這是可選的, 最後一步將設置你的光環. 點擊「完成」將不再提示. 如果由於某些原因反復提示, 請重新開啟遊戲."
+L["Can't buy anymore slots!"]="無法再購買更多銀行欄位!"
+L["Disable Warning"]='停用警告'
+L["Discard"]="取消"
+L["Do you swear not to post in technical support about something not working without first disabling the addon/package combination first?"]=true;
+L["Hover your mouse over any actionbutton or spellbook button to bind it. Press the escape key or right click to clear the current actionbutton's keybinding."]="移動滑鼠到快捷列或技能書按鈕上綁定快捷鍵.按ESC或滑鼠右鍵取消目前快捷鍵."
+L["I Swear"]='我承諾'
+L["Oh lord, you have got SVUI and Tukui both enable at the same time. Select an addon to disable."]="你不能同時啓用SVUI和Tukui, 請選擇一個禁用."
+L["One or more of the changes you have made require a ReloadUI."]="已變更一或多個設定, 需重載介面."
+L["One or more of the changes you have made will effect all characters using this addon. You will have to reload the user interface to see the changes you have made."]="你所做的改動可能會影響到使用這個插件的所有角色, 你需要重新加載介面才能使改動生效."
+L["Save"]="儲存"
+L["Using the healer layout it is highly recommended you download the addon Clique if you wish to have the click-to-heal function."]=true;
+L["You have changed the pixel perfect option. You will have to complete the installation process to remove any graphical bugs."]="你已改變了像素完美中的選項, 你必須完成安裝過程以消除任何圖形錯誤."
+L["You have changed your UIScale, however you still have the AutoScale option enable in SV. Press accept if you would like to disable the Auto Scale option."]="你改變了介面縮放比例, 然而SVUI的自動縮放選項是開啟的. 點擊接受以關閉SVUI的自動縮放."
+L["You must purchase a bank slot first!"]="你必需購買一個銀行背包欄位!"
+L["Count"]="計數"
+L["Targeted By:"]="同目標的有:"
+L["A raid marker feature is available by pressing Escape -> Keybinds scroll to the bottom under SVUI and setting a keybind for the raid marker."]="你可以通過按ESC鍵-> 按鍵設定, 滾動到SVUI設定下方設定一個快速標記的快捷鍵."
+L["SVUI has a dual spec feature which allows you to load different profiles based on your current spec on the fly. You can enable this from the profiles tab."]="SVUI可以根據你所使用的天賦自動套用不同的設定檔. 你可以在配置文件中使用此功能."
+L["For technical support visit us at http://www.wowinterface.com."]="如需技術支援請至http://www.wowinterface.com."
+L["If you accidently remove a chat frame you can always go the in-game configuration menu, press install, go to the chat portion and reset them."]="如果你不慎移除了對話框, 你可以重新安裝一次重置他們."
+L["If you are experiencing issues with SVUI try disabling all your addons except SVUI, remember SVUI is a full UI replacement addon, you cannot run two addons that do the same thing."]="如果你遇到問題, SVUI會嘗試禁用你除了SVUI之外的插件. 請記住你不能用不同的插件實現同一功能."
+L["The buff panel to the right of minimap is a list of your consolidated buffs. You can disable it in Buffs and Debuffs options of SV."]="小地圖右側的光環條是你的整合Buff條, 你可以在你的SVUI光環設定中關閉此功能."
+L["The focus unit can be set by typing /focus when you are targeting the unit you want to focus. It is recommended you make a macro to do this."]="你可以通過/focus 命令設定焦點目標."
+L["To move abilities on the actionbars by default hold shift + drag. You can change the modifier key from the actionbar options menu."]="你可以通過按住Shift拖動技能條中的按鍵. 你可以在Blizzard的快捷列設定中更改按鍵."
+L["To setup which channels appear in which chat frame, right click the chat tab and go to settings."]="你可以通過右鍵點擊對話框標籤欄設定你需要在對話框內顯示的頻道."
+L["Using the /farmmode <size> command will spawn a larger minimap on your screen that can be moved around, very useful when farming."]="使用/farmmode 命令可以切換小地圖的顯示模式為大型可移動小地圖, 這在你Farm的時候會很有用."
+L["You can access copy chat and chat menu functions by mouse over the top right corner of chat panel and left/right click on the button that will appear."]="你可以通過滑鼠滑過對話框右上角點擊複製圖示打開對話復制窗口."
+L["You can see someones average item level of their gear by holding shift and mousing over them. It should appear inside the tooltip."]="你可以通過按住Shift並將滑鼠滑過目標看到目標的裝備等級, 這將顯示在你的滑鼠提示框內."
+L["You can set your keybinds quickly by typing /kb."]="你可以通過輸入/kb 快速綁定按鍵."
+L["You can toggle the microbar by using your middle mouse button on the minimap you can also accomplish this by enabling the actual microbar located in the actionbar settings."]="你可以通過滑鼠中鍵點擊小地圖或在快捷列設定內選擇打開微型系統欄."
+L["You can use the /resetui command to reset all of your moveables. You can also use the command to reset a specific mover, /resetui <mover name>.\nExample: /resetui Player Frame"]="使用/resetui命令可以重置你的所有框架位置. 你也可以通過命令/resetui <框架名稱> 單獨重置某個框架.\n例如: /resetui Player Frame"
+L["Ghost"]="鬼魂"
+L["Offline"]="離線"
+L["ENH_LOGIN_MSG"]="您正在使用 |cff1784d1SVUI Enhanced|r version %s%s|r."
+L["Your version of SVUI is to old. Please, download the latest version from http://www.wowinterface.com."]="您的SVUI版本過低(需要 v6.51 或更高), 請前往http://www.wowinterface.com下載最新版本."
+L["Equipment"]="自動換裝"
+L["EQUIPMENT_DESC"]="當你切換專精或進入戰場時自動更換裝備, 你可以在選項中選擇相關的裝備模組."
+L["No Change"]="不改變"
+L["Specialization"]="專精"
+L["Enable/Disable the specialization switch."]="開啓/關閉 專精切換"
+L["Primary Talent"]="主專精"
+L["Choose the equipment set to use for your primary specialization."]="選擇當你使用主專精時的裝備模組."
+L["Secondary Talent"]="副專精"
+L["Choose the equipment set to use for your secondary specialization."]="選擇當你使用副專精時的裝備模組."
+L["Battleground"]="戰場"
+L["Enable/Disable the battleground switch."]="開啓/關閉 戰場切換"
+L["Equipment Set"]="裝備模組"
+L["Choose the equipment set to use when you enter a battleground or arena."]="選擇當你進入戰場時的裝備模組."
+L["You have equipped equipment set: "]="你已裝備此模組: "
+L["DURABILITY_DESC"]="調整設置人物窗口裝備耐久度顯示."
+L["Enable/Disable the display of durability information on the character screen."]="開啓/關閉 人物窗口裝備耐久度顯示."
+L["Damaged Only"]="受損顯示"
+L["Only show durabitlity information for items that are damaged."]="只在裝備受損時顯示耐久度."
+L["ITEMLEVEL_DESC"]="調整在角色資訊上顯示物品裝等的各種設定."
+L["Enable/Disable the display of item levels on the character screen."]="在角色資訊上顯示各裝備裝等"
+L["Miscellaneous"]="雜項"
+L["Equipment Set Overlay"]=true;
+L["Show the associated equipment sets for the items in your bags (or bank)."]="在你包包或銀行中顯示相關的套裝設定"
+L["Layout Transparency"]="定位器透明度"
+L["Changes the transparency of all the moveables."]="改變所有定位器的透明度"
+L["Automatic Role Assignment"]="自動設定角色定位"
+L["Enables the automatic role assignment based on specialization for party / raid members (only work when you are group leader or group assist)."]="當你是隊長或助理時根據隊員天賦自動指定其角色定位"
+L["Hide Role Icon in combat"]=true;
+L["All role icons (Damage/Healer/Tank) on the unit frames are hidden when you go into combat."]=true;
+L["GPS"]="GPS定位"
+L["Show the direction and distance to the selected party or raid member."]="顯示你與當前隊伍或團隊成員的方向与距離."
+L["Attack Icon"]="戰鬥標記"
+L["Show attack icon for units that are not tapped by you or your group, but still give kill credit when attacked."]="當目標不是被你或你的隊伍所開,但是可以取得任務道具,獎勵,道具時顯示一個戰鬥標記"
+L["Show class icon for units."]="顯是職業圖標"
+L["Above Minimap"]="小地圖之上"
+L["Location Digits"]="坐標位數"
+L["Number of digits for map location."]="坐標顯示的小數位數"
+L["Hide minimap while in combat."]="戰鬥中隱藏小地圖"
+L["FadeIn Delay"]="隱藏延遲"
+L["The time to wait before fading the minimap back in after combat hide. (0 = Disabled)"]="戰鬥開始後隱藏小地圖前的延遲時間 (0=停用)"
+L["Minimap Button Bar"]="小地圖按鈕整合列"
+L["Style Buttons"]="美化按鈕"
+L["Customize the minimap buttons in SVUI style."]="將小地圖圖標美化成SVUI風格."
+L["SVUI Style"]="美化風格"
+L["Change settings for how the minimap buttons are styled."]="改變美化設定."
+L["The size of the minimap buttons."]="小地圖圖標尺寸."
+L["No Anchor Bar"]="沒有錨點"
+L["Horizontal Anchor Bar"]="水平狀"
+L["Vertical Anchor Bar"]="垂直狀"
+L["Layout Direction"]=true;
+L["Normal is right to left or top to bottom, or select reversed to switch directions."]=true;
+L["Normal"]=true;
+L["Reversed"]=true;
+L["PvP Autorelease"]="PVP自動釋放靈魂"
+L["Automatically release body when killed inside a battleground."]="在戰場死亡後自動釋放靈魂."
+L["Track Reputation"]="聲望追蹤"
+L["Automatically change your watched faction on the reputation bar to the faction you got reputation points for."]="當你獲得某個陣營的聲望時, 將自動追蹤此陣營的聲望至經驗值欄位."
+L["Select Quest Reward"]="自動選取任務獎勵"
+L["Automatically select the quest reward with the highest vendor sell value."]="自動選取有最高賣價的任務獎勵物品"
+L["Item Level"]="物品等級"
+L["Target Range"]="目標距離"
+L["Distance"]="距離"
+L["Actionbar1DataPanel"]='快捷列 1 資訊框'
+L["Actionbar3DataPanel"]='快捷列 3 資訊框'
+L["Actionbar5DataPanel"]='快捷列 5 資訊框'
+L["Sunsong Ranch"]="日歌農莊"
+L["The Halfhill Market"]="半丘市集"
+L["Tilled Soil"]="開墾過的沃土"
+L["Right-click to drop the item."]="右鍵點擊需刪除的項目."
+L["Toolbox"]="農夫"
+L["Toolbox Portal Bar"]="農夫列:傳送"
+L["Toolbox Seed Bar"]="農夫列:種子"
+L["Toolbox Tools Bar"]="農夫列:工具"
+L["COMIX_DESC"]="Toggle the comic popups during combat"
+L["FARMING_MODE_DESC"]="調整設置以便你在日歌農莊更有效的耕作."
+L["SNACKS_DESC"]=""
+L["Toolbox Bars"]="農夫列"
+L["Enable/Disable the laborer bars."]="開啓/關閉 農夫快捷列."
+L["Only active buttons"]="只顯示有效的按鈕"
+L["Only show the buttons for the seeds, portals, tools you have in your bags."]="只顯示你背包中有的種子, 傳送和工具."
+L["Drop Tools"]="刪除工具"
+L["Automatically drop tools from your bags when leaving the farming area."]="當你離開農莊範圍時, 自動刪除背包中的工具."
+L["Seed Bar Direction"]="種子條方向"
+L["The direction of the seed bar buttons (Horizontal or Vertical)."]="種子條的方向 (水平或垂直)"
+L["Threat Text"]="威脅值文字"
+L["Display threat level as text on targeted, boss or mouseover nameplate."]="在首領或鼠標懸停的血條上顯示威脅等級文字."
+L["Target Count"]="目標記數"
+L["Display the number of party / raid members targetting the nameplate unit."]="在血調旁邊顯示隊伍/團隊成員中以其為目標的個數"
+L["Heal Glow"]="高亮治療"
+L["Direct AoE heals will let the unit frames of the affected party / raid members glow for the defined time period."]="受到直接性的範圍治療法術影響的隊伍/團隊成員會被高亮指定的時間"
+L["Glow Duration"]="高量持續時間"
+L["The amount of time the unit frames of party / raid members will glow when affected by a direct AoE heal."]="當隊伍/團隊成員受到直接性範圍治療法術石高亮持續的時間"
+L["Glow Color"]="高亮顏色"
+L["Raid Marker Bar"]="團隊標記列"
+L["Display a quick action bar for raid targets and world markers."]="顯示一個可以快速設定團隊標記與光柱的快捷列"
+L["Modifier Key"]="組合鍵"
+L["Set the modifier key for placing world markers."]="設定標示團隊光柱的組合鍵"
+L["Shift Key"]="Shift鍵"
+L["Ctrl Key"]="Ctrl鍵"
+L["Alt Key"]="Alt鍵"
+L["Raid Markers"]="團隊標記"
+L["Click to clear the mark."]="點選清除所有標記"
+L["Click to mark the target."]="點選以標記目標"
+L["%sClick to remove all worldmarkers."]="%s 清除了所有光柱"
+L["%sClick to place a worldmarker."]="%s 放置了一個光柱"
+L["WatchFrame"]="追蹤器"
+L["WATCHFRAME_DESC"]="Adjust the settings for the visibility of the watchframe (questlog) to your personal preference."
+L["Hidden"]="隱藏"
+L["Collapsed"]="收起"
+L["Settings"]="設定"
+L["City (Resting)"]="城市 (休息)"
+L["PvP"]=true;
+L["Arena"]="競技場"
+L["Party"]="隊伍"
+L["Raid"]="團隊"
+L["Progression Info"]=true;
+L["Display the players raid progression in the tooltip, this may not immediately update when mousing over a unit."]=true
\ No newline at end of file
diff --git a/SVUI_!Core/libs/AceConfig-3.0/AceConfig-3.0.lua b/SVUI_!Core/libs/AceConfig-3.0/AceConfig-3.0.lua
new file mode 100644
index 0000000..3bedf8c
--- /dev/null
+++ b/SVUI_!Core/libs/AceConfig-3.0/AceConfig-3.0.lua
@@ -0,0 +1,57 @@
+--- AceConfig-3.0 wrapper library.
+-- Provides an API to register an options table with the config registry,
+-- as well as associate it with a slash command.
+-- @class file
+-- @name AceConfig-3.0
+-- @release $Id: AceConfig-3.0.lua 969 2010-10-07 02:11:48Z shefki $
+
+--[[
+AceConfig-3.0
+
+Very light wrapper library that combines all the AceConfig subcomponents into one more easily used whole.
+
+]]
+
+local MAJOR, MINOR = "AceConfig-3.0", 2
+local AceConfig = LibStub:NewLibrary(MAJOR, MINOR)
+
+if not AceConfig then return end
+
+local cfgreg = LibStub("AceConfigRegistry-3.0")
+local cfgcmd = LibStub("AceConfigCmd-3.0")
+--TODO: local cfgdlg = LibStub("AceConfigDialog-3.0", true)
+--TODO: local cfgdrp = LibStub("AceConfigDropdown-3.0", true)
+
+-- Lua APIs
+local pcall, error, type, pairs = pcall, error, type, pairs
+
+-- -------------------------------------------------------------------
+-- :RegisterOptionsTable(appName, options, slashcmd, persist)
+--
+-- - appName - (string) application name
+-- - options - table or function ref, see AceConfigRegistry
+-- - slashcmd - slash command (string) or table with commands, or nil to NOT create a slash command
+
+--- Register a option table with the AceConfig registry.
+-- You can supply a slash command (or a table of slash commands) to register with AceConfigCmd directly.
+-- @paramsig appName, options [, slashcmd]
+-- @param appName The application name for the config table.
+-- @param options The option table (or a function to generate one on demand).  http://www.wowace.com/addons/ace3/pages/ace-config-3-0-options-tables/
+-- @param slashcmd A slash command to register for the option table, or a table of slash commands.
+-- @usage
+-- local AceConfig = LibStub("AceConfig-3.0")
+-- AceConfig:RegisterOptionsTable("MyAddon", myOptions, {"/myslash", "/my"})
+function AceConfig:RegisterOptionsTable(appName, options, slashcmd)
+	local ok,msg = pcall(cfgreg.RegisterOptionsTable, self, appName, options)
+	if not ok then error(msg, 2) end
+
+	if slashcmd then
+		if type(slashcmd) == "table" then
+			for _,cmd in pairs(slashcmd) do
+				cfgcmd:CreateChatCommand(cmd, appName)
+			end
+		else
+			cfgcmd:CreateChatCommand(slashcmd, appName)
+		end
+	end
+end
diff --git a/SVUI_!Core/libs/AceConfig-3.0/AceConfig-3.0.xml b/SVUI_!Core/libs/AceConfig-3.0/AceConfig-3.0.xml
new file mode 100644
index 0000000..87972ad
--- /dev/null
+++ b/SVUI_!Core/libs/AceConfig-3.0/AceConfig-3.0.xml
@@ -0,0 +1,8 @@
+<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="AceConfigRegistry-3.0\AceConfigRegistry-3.0.xml"/>
+	<Include file="AceConfigCmd-3.0\AceConfigCmd-3.0.xml"/>
+	<Include file="AceConfigDialog-3.0\AceConfigDialog-3.0.xml"/>
+	<!--<Include file="AceConfigDropdown-3.0\AceConfigDropdown-3.0.xml"/>-->
+	<Script file="AceConfig-3.0.lua"/>
+</Ui>
\ No newline at end of file
diff --git a/SVUI_!Core/libs/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.lua b/SVUI_!Core/libs/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.lua
new file mode 100644
index 0000000..2023981
--- /dev/null
+++ b/SVUI_!Core/libs/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.lua
@@ -0,0 +1,794 @@
+--- AceConfigCmd-3.0 handles access to an options table through the "command line" interface via the ChatFrames.
+-- @class file
+-- @name AceConfigCmd-3.0
+-- @release $Id: AceConfigCmd-3.0.lua 1045 2011-12-09 17:58:40Z nevcairiel $
+
+--[[
+AceConfigCmd-3.0
+
+Handles commandline optionstable access
+
+REQUIRES: AceConsole-3.0 for command registration (loaded on demand)
+
+]]
+
+-- TODO: plugin args
+
+
+local MAJOR, MINOR = "AceConfigCmd-3.0", 13
+local AceConfigCmd = LibStub:NewLibrary(MAJOR, MINOR)
+
+if not AceConfigCmd then return end
+
+AceConfigCmd.commands = AceConfigCmd.commands or {}
+local commands = AceConfigCmd.commands
+
+local cfgreg = LibStub("AceConfigRegistry-3.0")
+local AceConsole -- LoD
+local AceConsoleName = "AceConsole-3.0"
+
+-- Lua APIs
+local strsub, strsplit, strlower, strmatch, strtrim = string.sub, string.split, string.lower, string.match, string.trim
+local format, tonumber, tostring = string.format, tonumber, tostring
+local tsort, tinsert = table.sort, table.insert
+local select, pairs, next, type = select, pairs, next, type
+local error, assert = error, assert
+
+-- WoW APIs
+local _G = _G
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: LibStub, SELECTED_CHAT_FRAME, DEFAULT_CHAT_FRAME
+
+
+local L = setmetatable({}, {	-- TODO: replace with proper locale
+	__index = function(self,k) return k end
+})
+
+
+
+local function print(msg)
+	(SELECTED_CHAT_FRAME or DEFAULT_CHAT_FRAME):AddMessage(msg)
+end
+
+-- constants used by getparam() calls below
+
+local handlertypes = {["table"]=true}
+local handlermsg = "expected a table"
+
+local functypes = {["function"]=true, ["string"]=true}
+local funcmsg = "expected function or member name"
+
+
+-- pickfirstset() - picks the first non-nil value and returns it
+
+local function pickfirstset(...)
+	for i=1,select("#",...) do
+		if select(i,...)~=nil then
+			return select(i,...)
+		end
+	end
+end
+
+
+-- err() - produce real error() regarding malformed options tables etc
+
+local function err(info,inputpos,msg )
+	local cmdstr=" "..strsub(info.input, 1, inputpos-1)
+	error(MAJOR..": /" ..info[0] ..cmdstr ..": "..(msg or "malformed options table"), 2)
+end
+
+
+-- usererr() - produce chatframe message regarding bad slash syntax etc
+
+local function usererr(info,inputpos,msg )
+	local cmdstr=strsub(info.input, 1, inputpos-1);
+	print("/" ..info[0] .. " "..cmdstr ..": "..(msg or "malformed options table"))
+end
+
+
+-- callmethod() - call a given named method (e.g. "get", "set") with given arguments
+
+local function callmethod(info, inputpos, tab, methodtype, ...)
+	local method = info[methodtype]
+	if not method then
+		err(info, inputpos, "'"..methodtype.."': not set")
+	end
+
+	info.arg = tab.arg
+	info.option = tab
+	info.type = tab.type
+
+	if type(method)=="function" then
+		return method(info, ...)
+	elseif type(method)=="string" then
+		if type(info.handler[method])~="function" then
+			err(info, inputpos, "'"..methodtype.."': '"..method.."' is not a member function of "..tostring(info.handler))
+		end
+		return info.handler[method](info.handler, info, ...)
+	else
+		assert(false)	-- type should have already been checked on read
+	end
+end
+
+-- callfunction() - call a given named function (e.g. "name", "desc") with given arguments
+
+local function callfunction(info, tab, methodtype, ...)
+	local method = tab[methodtype]
+
+	info.arg = tab.arg
+	info.option = tab
+	info.type = tab.type
+
+	if type(method)=="function" then
+		return method(info, ...)
+	else
+		assert(false) -- type should have already been checked on read
+	end
+end
+
+-- do_final() - do the final step (set/execute) along with validation and confirmation
+
+local function do_final(info, inputpos, tab, methodtype, ...)
+	if info.validate then
+		local res = callmethod(info,inputpos,tab,"validate",...)
+		if type(res)=="string" then
+			usererr(info, inputpos, "'"..strsub(info.input, inputpos).."' - "..res)
+			return
+		end
+	end
+	-- console ignores .confirm
+
+	callmethod(info,inputpos,tab,methodtype, ...)
+end
+
+
+-- getparam() - used by handle() to retreive and store "handler", "get", "set", etc
+
+local function getparam(info, inputpos, tab, depth, paramname, types, errormsg)
+	local old,oldat = info[paramname], info[paramname.."_at"]
+	local val=tab[paramname]
+	if val~=nil then
+		if val==false then
+			val=nil
+		elseif not types[type(val)] then
+			err(info, inputpos, "'" .. paramname.. "' - "..errormsg)
+		end
+		info[paramname] = val
+		info[paramname.."_at"] = depth
+	end
+	return old,oldat
+end
+
+
+-- iterateargs(tab) - custom iterator that iterates both t.args and t.plugins.*
+local dummytable={}
+
+local function iterateargs(tab)
+	if not tab.plugins then
+		return pairs(tab.args)
+	end
+
+	local argtabkey,argtab=next(tab.plugins)
+	local v
+
+	return function(_, k)
+		while argtab do
+			k,v = next(argtab, k)
+			if k then return k,v end
+			if argtab==tab.args then
+				argtab=nil
+			else
+				argtabkey,argtab = next(tab.plugins, argtabkey)
+				if not argtabkey then
+					argtab=tab.args
+				end
+			end
+		end
+	end
+end
+
+local function checkhidden(info, inputpos, tab)
+	if tab.cmdHidden~=nil then
+		return tab.cmdHidden
+	end
+	local hidden = tab.hidden
+	if type(hidden) == "function" or type(hidden) == "string" then
+		info.hidden = hidden
+		hidden = callmethod(info, inputpos, tab, 'hidden')
+		info.hidden = nil
+	end
+	return hidden
+end
+
+local function showhelp(info, inputpos, tab, depth, noHead)
+	if not noHead then
+		print("|cff33ff99"..info.appName.."|r: Arguments to |cffffff78/"..info[0].."|r "..strsub(info.input,1,inputpos-1)..":")
+	end
+
+	local sortTbl = {}	-- [1..n]=name
+	local refTbl = {}   -- [name]=tableref
+
+	for k,v in iterateargs(tab) do
+		if not refTbl[k] then	-- a plugin overriding something in .args
+			tinsert(sortTbl, k)
+			refTbl[k] = v
+		end
+	end
+
+	tsort(sortTbl, function(one, two)
+		local o1 = refTbl[one].order or 100
+		local o2 = refTbl[two].order or 100
+		if type(o1) == "function" or type(o1) == "string" then
+			info.order = o1
+			info[#info+1] = one
+			o1 = callmethod(info, inputpos, refTbl[one], "order")
+			info[#info] = nil
+			info.order = nil
+		end
+		if type(o2) == "function" or type(o1) == "string" then
+			info.order = o2
+			info[#info+1] = two
+			o2 = callmethod(info, inputpos, refTbl[two], "order")
+			info[#info] = nil
+			info.order = nil
+		end
+		if o1<0 and o2<0 then return o1<o2 end
+		if o2<0 then return true end
+		if o1<0 then return false end
+		if o1==o2 then return tostring(one)<tostring(two) end   -- compare names
+		return o1<o2
+	end)
+
+	for i = 1, #sortTbl do
+		local k = sortTbl[i]
+		local v = refTbl[k]
+		if not checkhidden(info, inputpos, v) then
+			if v.type ~= "description" and v.type ~= "header" then
+				-- recursively show all inline groups
+				local name, desc = v.name, v.desc
+				if type(name) == "function" then
+					name = callfunction(info, v, 'name')
+				end
+				if type(desc) == "function" then
+					desc = callfunction(info, v, 'desc')
+				end
+				if v.type == "group" and pickfirstset(v.cmdInline, v.inline, false) then
+					print("  "..(desc or name)..":")
+					local oldhandler,oldhandler_at = getparam(info, inputpos, v, depth, "handler", handlertypes, handlermsg)
+					showhelp(info, inputpos, v, depth, true)
+					info.handler,info.handler_at = oldhandler,oldhandler_at
+				else
+					local key = k:gsub(" ", "_")
+					print("  |cffffff78"..key.."|r - "..(desc or name or ""))
+				end
+			end
+		end
+	end
+end
+
+
+local function keybindingValidateFunc(text)
+	if text == nil or text == "NONE" then
+		return nil
+	end
+	text = 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 text == "" then
+		return false
+	end
+	if not text:find("^F%d+$") and text ~= "CAPSLOCK" and text:len() ~= 1 and (text:byte() < 128 or text:len() > 4) and not _G["KEY_" .. text] then
+		return false
+	end
+	local s = text
+	if shift then
+		s = "SHIFT-" .. s
+	end
+	if ctrl then
+		s = "CTRL-" .. s
+	end
+	if alt then
+		s = "ALT-" .. s
+	end
+	return s
+end
+
+-- handle() - selfrecursing function that processes input->optiontable
+-- - depth - starts at 0
+-- - retfalse - return false rather than produce error if a match is not found (used by inlined groups)
+
+local function handle(info, inputpos, tab, depth, retfalse)
+
+	if not(type(tab)=="table" and type(tab.type)=="string") then err(info,inputpos) end
+
+	-------------------------------------------------------------------
+	-- Grab hold of handler,set,get,func,etc if set (and remember old ones)
+	-- Note that we do NOT validate if method names are correct at this stage,
+	-- the handler may change before they're actually used!
+
+	local oldhandler,oldhandler_at = getparam(info,inputpos,tab,depth,"handler",handlertypes,handlermsg)
+	local oldset,oldset_at = getparam(info,inputpos,tab,depth,"set",functypes,funcmsg)
+	local oldget,oldget_at = getparam(info,inputpos,tab,depth,"get",functypes,funcmsg)
+	local oldfunc,oldfunc_at = getparam(info,inputpos,tab,depth,"func",functypes,funcmsg)
+	local oldvalidate,oldvalidate_at = getparam(info,inputpos,tab,depth,"validate",functypes,funcmsg)
+	--local oldconfirm,oldconfirm_at = getparam(info,inputpos,tab,depth,"confirm",functypes,funcmsg)
+
+	-------------------------------------------------------------------
+	-- Act according to .type of this table
+
+	if tab.type=="group" then
+		------------ group --------------------------------------------
+
+		if type(tab.args)~="table" then err(info, inputpos) end
+		if tab.plugins and type(tab.plugins)~="table" then err(info,inputpos) end
+
+		-- grab next arg from input
+		local _,nextpos,arg = (info.input):find(" *([^ ]+) *", inputpos)
+		if not arg then
+			showhelp(info, inputpos, tab, depth)
+			return
+		end
+		nextpos=nextpos+1
+
+		-- loop .args and try to find a key with a matching name
+		for k,v in iterateargs(tab) do
+			if not(type(k)=="string" and type(v)=="table" and type(v.type)=="string") then err(info,inputpos, "options table child '"..tostring(k).."' is malformed") end
+
+			-- is this child an inline group? if so, traverse into it
+			if v.type=="group" and pickfirstset(v.cmdInline, v.inline, false) then
+				info[depth+1] = k
+				if handle(info, inputpos, v, depth+1, true)==false then
+					info[depth+1] = nil
+					-- wasn't found in there, but that's ok, we just keep looking down here
+				else
+					return	-- done, name was found in inline group
+				end
+			-- matching name and not a inline group
+			elseif strlower(arg)==strlower(k:gsub(" ", "_")) then
+				info[depth+1] = k
+				return handle(info,nextpos,v,depth+1)
+			end
+		end
+
+		-- no match
+		if retfalse then
+			-- restore old infotable members and return false to indicate failure
+			info.handler,info.handler_at = oldhandler,oldhandler_at
+			info.set,info.set_at = oldset,oldset_at
+			info.get,info.get_at = oldget,oldget_at
+			info.func,info.func_at = oldfunc,oldfunc_at
+			info.validate,info.validate_at = oldvalidate,oldvalidate_at
+			--info.confirm,info.confirm_at = oldconfirm,oldconfirm_at
+			return false
+		end
+
+		-- couldn't find the command, display error
+		usererr(info, inputpos, "'"..arg.."' - " .. L["unknown argument"])
+		return
+	end
+
+	local str = strsub(info.input,inputpos);
+
+	if tab.type=="execute" then
+		------------ execute --------------------------------------------
+		do_final(info, inputpos, tab, "func")
+
+
+
+	elseif tab.type=="input" then
+		------------ input --------------------------------------------
+
+		local res = true
+		if tab.pattern then
+			if not(type(tab.pattern)=="string") then err(info, inputpos, "'pattern' - expected a string") end
+			if not strmatch(str, tab.pattern) then
+				usererr(info, inputpos, "'"..str.."' - " .. L["invalid input"])
+				return
+			end
+		end
+
+		do_final(info, inputpos, tab, "set", str)
+
+
+
+	elseif tab.type=="toggle" then
+		------------ toggle --------------------------------------------
+		local b
+		local str = strtrim(strlower(str))
+		if str=="" then
+			b = callmethod(info, inputpos, tab, "get")
+
+			if tab.tristate then
+				--cycle in true, nil, false order
+				if b then
+					b = nil
+				elseif b == nil then
+					b = false
+				else
+					b = true
+				end
+			else
+				b = not b
+			end
+
+		elseif str==L["on"] then
+			b = true
+		elseif str==L["off"] then
+			b = false
+		elseif tab.tristate and str==L["default"] then
+			b = nil
+		else
+			if tab.tristate then
+				usererr(info, inputpos, format(L["'%s' - expected 'on', 'off' or 'default', or no argument to toggle."], str))
+			else
+				usererr(info, inputpos, format(L["'%s' - expected 'on' or 'off', or no argument to toggle."], str))
+			end
+			return
+		end
+
+		do_final(info, inputpos, tab, "set", b)
+
+
+	elseif tab.type=="range" then
+		------------ range --------------------------------------------
+		local val = tonumber(str)
+		if not val then
+			usererr(info, inputpos, "'"..str.."' - "..L["expected number"])
+			return
+		end
+		if type(info.step)=="number" then
+			val = val- (val % info.step)
+		end
+		if type(info.min)=="number" and val<info.min then
+			usererr(info, inputpos, val.." - "..format(L["must be equal to or higher than %s"], tostring(info.min)) )
+			return
+		end
+		if type(info.max)=="number" and val>info.max then
+			usererr(info, inputpos, val.." - "..format(L["must be equal to or lower than %s"], tostring(info.max)) )
+			return
+		end
+
+		do_final(info, inputpos, tab, "set", val)
+
+
+	elseif tab.type=="select" then
+		------------ select ------------------------------------
+		local str = strtrim(strlower(str))
+
+		local values = tab.values
+		if type(values) == "function" or type(values) == "string" then
+			info.values = values
+			values = callmethod(info, inputpos, tab, "values")
+			info.values = nil
+		end
+
+		if str == "" then
+			local b = callmethod(info, inputpos, tab, "get")
+			local fmt = "|cffffff78- [%s]|r %s"
+			local fmt_sel = "|cffffff78- [%s]|r %s |cffff0000*|r"
+			print(L["Options for |cffffff78"..info[#info].."|r:"])
+			for k, v in pairs(values) do
+				if b == k then
+					print(fmt_sel:format(k, v))
+				else
+					print(fmt:format(k, v))
+				end
+			end
+			return
+		end
+
+		local ok
+		for k,v in pairs(values) do
+			if strlower(k)==str then
+				str = k	-- overwrite with key (in case of case mismatches)
+				ok = true
+				break
+			end
+		end
+		if not ok then
+			usererr(info, inputpos, "'"..str.."' - "..L["unknown selection"])
+			return
+		end
+
+		do_final(info, inputpos, tab, "set", str)
+
+	elseif tab.type=="multiselect" then
+		------------ multiselect -------------------------------------------
+		local str = strtrim(strlower(str))
+
+		local values = tab.values
+		if type(values) == "function" or type(values) == "string" then
+			info.values = values
+			values = callmethod(info, inputpos, tab, "values")
+			info.values = nil
+		end
+
+		if str == "" then
+			local fmt = "|cffffff78- [%s]|r %s"
+			local fmt_sel = "|cffffff78- [%s]|r %s |cffff0000*|r"
+			print(L["Options for |cffffff78"..info[#info].."|r (multiple possible):"])
+			for k, v in pairs(values) do
+				if callmethod(info, inputpos, tab, "get", k) then
+					print(fmt_sel:format(k, v))
+				else
+					print(fmt:format(k, v))
+				end
+			end
+			return
+		end
+
+		--build a table of the selections, checking that they exist
+		--parse for =on =off =default in the process
+		--table will be key = true for options that should toggle, key = [on|off|default] for options to be set
+		local sels = {}
+		for v in str:gmatch("[^ ]+") do
+			--parse option=on etc
+			local opt, val = v:match('(.+)=(.+)')
+			--get option if toggling
+			if not opt then
+				opt = v
+			end
+
+			--check that the opt is valid
+			local ok
+			for k,v in pairs(values) do
+				if strlower(k)==opt then
+					opt = k	-- overwrite with key (in case of case mismatches)
+					ok = true
+					break
+				end
+			end
+
+			if not ok then
+				usererr(info, inputpos, "'"..opt.."' - "..L["unknown selection"])
+				return
+			end
+
+			--check that if val was supplied it is valid
+			if val then
+				if val == L["on"] or val == L["off"] or (tab.tristate and val == L["default"]) then
+					--val is valid insert it
+					sels[opt] = val
+				else
+					if tab.tristate then
+						usererr(info, inputpos, format(L["'%s' '%s' - expected 'on', 'off' or 'default', or no argument to toggle."], v, val))
+					else
+						usererr(info, inputpos, format(L["'%s' '%s' - expected 'on' or 'off', or no argument to toggle."], v, val))
+					end
+					return
+				end
+			else
+				-- no val supplied, toggle
+				sels[opt] = true
+			end
+		end
+
+		for opt, val in pairs(sels) do
+			local newval
+
+			if (val == true) then
+				--toggle the option
+				local b = callmethod(info, inputpos, tab, "get", opt)
+
+				if tab.tristate then
+					--cycle in true, nil, false order
+					if b then
+						b = nil
+					elseif b == nil then
+						b = false
+					else
+						b = true
+					end
+				else
+					b = not b
+				end
+				newval = b
+			else
+				--set the option as specified
+				if val==L["on"] then
+					newval = true
+				elseif val==L["off"] then
+					newval = false
+				elseif val==L["default"] then
+					newval = nil
+				end
+			end
+
+			do_final(info, inputpos, tab, "set", opt, newval)
+		end
+
+
+	elseif tab.type=="color" then
+		------------ color --------------------------------------------
+		local str = strtrim(strlower(str))
+		if str == "" then
+			--TODO: Show current value
+			return
+		end
+
+		local r, g, b, a
+
+		local hasAlpha = tab.hasAlpha
+		if type(hasAlpha) == "function" or type(hasAlpha) == "string" then
+			info.hasAlpha = hasAlpha
+			hasAlpha = callmethod(info, inputpos, tab, 'hasAlpha')
+			info.hasAlpha = nil
+		end
+
+		if hasAlpha then
+			if str:len() == 8 and str:find("^%x*$")  then
+				--parse a hex string
+				r,g,b,a = tonumber(str:sub(1, 2), 16) / 255, tonumber(str:sub(3, 4), 16) / 255, tonumber(str:sub(5, 6), 16) / 255, tonumber(str:sub(7, 8), 16) / 255
+			else
+				--parse seperate values
+				r,g,b,a = str:match("^([%d%.]+) ([%d%.]+) ([%d%.]+) ([%d%.]+)$")
+				r,g,b,a = tonumber(r), tonumber(g), tonumber(b), tonumber(a)
+			end
+			if not (r and g and b and a) then
+				usererr(info, inputpos, format(L["'%s' - expected 'RRGGBBAA' or 'r g b a'."], str))
+				return
+			end
+
+			if r >= 0.0 and r <= 1.0 and g >= 0.0 and g <= 1.0 and b >= 0.0 and b <= 1.0 and a >= 0.0 and a <= 1.0 then
+				--values are valid
+			elseif r >= 0 and r <= 255 and g >= 0 and g <= 255 and b >= 0 and b <= 255 and a >= 0 and a <= 255 then
+				--values are valid 0..255, convert to 0..1
+				r = r / 255
+				g = g / 255
+				b = b / 255
+				a = a / 255
+			else
+				--values are invalid
+				usererr(info, inputpos, format(L["'%s' - values must all be either in the range 0..1 or 0..255."], str))
+			end
+		else
+			a = 1.0
+			if str:len() == 6 and str:find("^%x*$") then
+				--parse a hex string
+				r,g,b = tonumber(str:sub(1, 2), 16) / 255, tonumber(str:sub(3, 4), 16) / 255, tonumber(str:sub(5, 6), 16) / 255
+			else
+				--parse seperate values
+				r,g,b = str:match("^([%d%.]+) ([%d%.]+) ([%d%.]+)$")
+				r,g,b = tonumber(r), tonumber(g), tonumber(b)
+			end
+			if not (r and g and b) then
+				usererr(info, inputpos, format(L["'%s' - expected 'RRGGBB' or 'r g b'."], str))
+				return
+			end
+			if r >= 0.0 and r <= 1.0 and g >= 0.0 and g <= 1.0 and b >= 0.0 and b <= 1.0 then
+				--values are valid
+			elseif r >= 0 and r <= 255 and g >= 0 and g <= 255 and b >= 0 and b <= 255 then
+				--values are valid 0..255, convert to 0..1
+				r = r / 255
+				g = g / 255
+				b = b / 255
+			else
+				--values are invalid
+				usererr(info, inputpos, format(L["'%s' - values must all be either in the range 0-1 or 0-255."], str))
+			end
+		end
+
+		do_final(info, inputpos, tab, "set", r,g,b,a)
+
+	elseif tab.type=="keybinding" then
+		------------ keybinding --------------------------------------------
+		local str = strtrim(strlower(str))
+		if str == "" then
+			--TODO: Show current value
+			return
+		end
+		local value = keybindingValidateFunc(str:upper())
+		if value == false then
+			usererr(info, inputpos, format(L["'%s' - Invalid Keybinding."], str))
+			return
+		end
+
+		do_final(info, inputpos, tab, "set", value)
+
+	elseif tab.type=="description" then
+		------------ description --------------------
+		-- ignore description, GUI config only
+	else
+		err(info, inputpos, "unknown options table item type '"..tostring(tab.type).."'")
+	end
+end
+
+--- Handle the chat command.
+-- This is usually called from a chat command handler to parse the command input as operations on an aceoptions table.\\
+-- AceConfigCmd uses this function internally when a slash command is registered with `:CreateChatCommand`
+-- @param slashcmd The slash command WITHOUT leading slash (only used for error output)
+-- @param appName The application name as given to `:RegisterOptionsTable()`
+-- @param input The commandline input (as given by the WoW handler, i.e. without the command itself)
+-- @usage
+-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon", "AceConsole-3.0")
+-- -- Use AceConsole-3.0 to register a Chat Command
+-- MyAddon:RegisterChatCommand("mychat", "ChatCommand")
+--
+-- -- Show the GUI if no input is supplied, otherwise handle the chat input.
+-- function MyAddon:ChatCommand(input)
+--   -- Assuming "MyOptions" is the appName of a valid options table
+--   if not input or input:trim() == "" then
+--     LibStub("AceConfigDialog-3.0"):Open("MyOptions")
+--   else
+--     LibStub("AceConfigCmd-3.0").HandleCommand(MyAddon, "mychat", "MyOptions", input)
+--   end
+-- end
+function AceConfigCmd:HandleCommand(slashcmd, appName, input)
+
+	local optgetter = cfgreg:GetOptionsTable(appName)
+	if not optgetter then
+		error([[Usage: HandleCommand("slashcmd", "appName", "input"): 'appName' - no options table "]]..tostring(appName)..[[" has been registered]], 2)
+	end
+	local options = assert( optgetter("cmd", MAJOR) )
+
+	local info = {   -- Don't try to recycle this, it gets handed off to callbacks and whatnot
+		[0] = slashcmd,
+		appName = appName,
+		options = options,
+		input = input,
+		self = self,
+		handler = self,
+		uiType = "cmd",
+		uiName = MAJOR,
+	}
+
+	handle(info, 1, options, 0)  -- (info, inputpos, table, depth)
+end
+
+--- Utility function to create a slash command handler.
+-- Also registers tab completion with AceTab
+-- @param slashcmd The slash command WITHOUT leading slash (only used for error output)
+-- @param appName The application name as given to `:RegisterOptionsTable()`
+function AceConfigCmd:CreateChatCommand(slashcmd, appName)
+	if not AceConsole then
+		AceConsole = LibStub(AceConsoleName)
+	end
+	if AceConsole.RegisterChatCommand(self, slashcmd, function(input)
+				AceConfigCmd.HandleCommand(self, slashcmd, appName, input)	-- upgradable
+		end,
+	true) then -- succesfully registered so lets get the command -> app table in
+		commands[slashcmd] = appName
+	end
+end
+
+--- Utility function that returns the options table that belongs to a slashcommand.
+-- Designed to be used for the AceTab interface.
+-- @param slashcmd The slash command WITHOUT leading slash (only used for error output)
+-- @return The options table associated with the slash command (or nil if the slash command was not registered)
+function AceConfigCmd:GetChatCommandOptions(slashcmd)
+	return commands[slashcmd]
+end
diff --git a/SVUI_!Core/libs/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.xml b/SVUI_!Core/libs/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.xml
new file mode 100644
index 0000000..188d354
--- /dev/null
+++ b/SVUI_!Core/libs/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.xml
@@ -0,0 +1,4 @@
+<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="AceConfigCmd-3.0.lua"/>
+</Ui>
\ No newline at end of file
diff --git a/SVUI_!Core/libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua b/SVUI_!Core/libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua
new file mode 100644
index 0000000..820aea8
--- /dev/null
+++ b/SVUI_!Core/libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua
@@ -0,0 +1,1955 @@
+--- AceConfigDialog-3.0 generates AceGUI-3.0 based windows based on option tables.
+-- @class file
+-- @name AceConfigDialog-3.0
+-- @release $Id: AceConfigDialog-3.0.lua 1126 2014-11-10 06:38:01Z nevcairiel $
+
+local LibStub = LibStub
+local MAJOR, MINOR = "AceConfigDialog-3.0", 60
+local AceConfigDialog, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
+
+if not AceConfigDialog then return end
+
+AceConfigDialog.OpenFrames = AceConfigDialog.OpenFrames or {}
+AceConfigDialog.Status = AceConfigDialog.Status or {}
+AceConfigDialog.frame = AceConfigDialog.frame or CreateFrame("Frame")
+
+AceConfigDialog.frame.apps = AceConfigDialog.frame.apps or {}
+AceConfigDialog.frame.closing = AceConfigDialog.frame.closing or {}
+AceConfigDialog.frame.closeAllOverride = AceConfigDialog.frame.closeAllOverride or {}
+
+local gui = LibStub("AceGUI-3.0")
+local reg = LibStub("AceConfigRegistry-3.0")
+
+-- Lua APIs
+local tconcat, tinsert, tsort, tremove, tsort = table.concat, table.insert, table.sort, table.remove, table.sort
+local strmatch, format = string.match, string.format
+local assert, loadstring, error = assert, loadstring, error
+local pairs, next, select, type, unpack, wipe, ipairs = pairs, next, select, type, unpack, wipe, ipairs
+local rawset, tostring, tonumber = rawset, tostring, tonumber
+local math_min, math_max, math_floor = math.min, math.max, math.floor
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: NORMAL_FONT_COLOR, GameTooltip, StaticPopupDialogs, ACCEPT, CANCEL, StaticPopup_Show
+-- GLOBALS: PlaySound, GameFontHighlight, GameFontHighlightSmall, GameFontHighlightLarge
+-- GLOBALS: CloseSpecialWindows, InterfaceOptions_AddCategory, geterrorhandler
+
+local emptyTbl = {}
+
+--[[
+	 xpcall safecall implementation
+]]
+local xpcall = xpcall
+
+local function errorhandler(err)
+	return geterrorhandler()(err)
+end
+
+local function CreateDispatcher(argCount)
+	local code = [[
+		local xpcall, eh = ...
+		local method, ARGS
+		local function call() return method(ARGS) end
+
+		local function dispatch(func, ...)
+			 method = func
+			 if not method then return end
+			 ARGS = ...
+			 return xpcall(call, eh)
+		end
+
+		return dispatch
+	]]
+
+	local ARGS = {}
+	for i = 1, argCount do ARGS[i] = "arg"..i end
+	code = code:gsub("ARGS", tconcat(ARGS, ", "))
+	return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler)
+end
+
+local Dispatchers = setmetatable({}, {__index=function(self, argCount)
+	local dispatcher = CreateDispatcher(argCount)
+	rawset(self, argCount, dispatcher)
+	return dispatcher
+end})
+Dispatchers[0] = function(func)
+	return xpcall(func, errorhandler)
+end
+
+local function safecall(func, ...)
+	return Dispatchers[select("#", ...)](func, ...)
+end
+
+local width_multiplier = 170
+
+--[[
+Group Types
+  Tree 	- All Descendant Groups will all become nodes on the tree, direct child options will appear above the tree
+  		- Descendant Groups with inline=true and thier children will not become nodes
+
+  Tab	- Direct Child Groups will become tabs, direct child options will appear above the tab control
+  		- Grandchild groups will default to inline unless specified otherwise
+
+  Select- Same as Tab but with entries in a dropdown rather than tabs
+
+
+  Inline Groups
+  	- Will not become nodes of a select group, they will be effectivly part of thier parent group seperated by a border
+  	- If declared on a direct child of a root node of a select group, they will appear above the group container control
+  	- When a group is displayed inline, all descendants will also be inline members of the group
+
+]]
+
+-- Recycling functions
+local new, del, copy
+--newcount, delcount,createdcount,cached = 0,0,0
+do
+	local pool = setmetatable({},{__mode="k"})
+	function new()
+		--newcount = newcount + 1
+		local t = next(pool)
+		if t then
+			pool[t] = nil
+			return t
+		else
+			--createdcount = createdcount + 1
+			return {}
+		end
+	end
+	function copy(t)
+		local c = new()
+		for k, v in pairs(t) do
+			c[k] = v
+		end
+		return c
+	end
+	function del(t)
+		--delcount = delcount + 1
+		wipe(t)
+		pool[t] = true
+	end
+--	function cached()
+--		local n = 0
+--		for k in pairs(pool) do
+--			n = n + 1
+--		end
+--		return n
+--	end
+end
+
+-- picks the first non-nil value and returns it
+local function pickfirstset(...)
+  for i=1,select("#",...) do
+    if select(i,...)~=nil then
+      return select(i,...)
+    end
+  end
+end
+
+--gets an option from a given group, checking plugins
+local function GetSubOption(group, key)
+	if group.plugins then
+		for plugin, t in pairs(group.plugins) do
+			if t[key] then
+				return t[key]
+			end
+		end
+	end
+
+	return group.args[key]
+end
+
+--Option member type definitions, used to decide how to access it
+
+--Is the member Inherited from parent options
+local isInherited = {
+	set = true,
+	get = true,
+	func = true,
+	confirm = true,
+	validate = true,
+	disabled = true,
+	hidden = true
+}
+
+--Does a string type mean a literal value, instead of the default of a method of the handler
+local stringIsLiteral = {
+	name = true,
+	desc = true,
+	icon = true,
+	usage = true,
+	width = true,
+	image = true,
+	fontSize = true,
+}
+
+--Is Never a function or method
+local allIsLiteral = {
+	type = true,
+	descStyle = true,
+	imageWidth = true,
+	imageHeight = true,
+}
+
+--gets the value for a member that could be a function
+--function refs are called with an info arg
+--every other type is returned
+local function GetOptionsMemberValue(membername, option, options, path, appName, ...)
+	--get definition for the member
+	local inherits = isInherited[membername]
+
+
+	--get the member of the option, traversing the tree if it can be inherited
+	local member
+
+	if inherits then
+		local group = options
+		if group[membername] ~= nil then
+			member = group[membername]
+		end
+		for i = 1, #path do
+			group = GetSubOption(group, path[i])
+			if group[membername] ~= nil then
+				member = group[membername]
+			end
+		end
+	else
+		member = option[membername]
+	end
+
+	--check if we need to call a functon, or if we have a literal value
+	if ( not allIsLiteral[membername] ) and ( type(member) == "function" or ((not stringIsLiteral[membername]) and type(member) == "string") ) then
+		--We have a function to call
+		local info = new()
+		--traverse the options table, picking up the handler and filling the info with the path
+		local handler
+		local group = options
+		handler = group.handler or handler
+
+		for i = 1, #path do
+			group = GetSubOption(group, path[i])
+			info[i] = path[i]
+			handler = group.handler or handler
+		end
+
+		info.options = options
+		info.appName = appName
+		info[0] = appName
+		info.arg = option.arg
+		info.handler = handler
+		info.option = option
+		info.type = option.type
+		info.uiType = "dialog"
+		info.uiName = MAJOR
+
+		local a, b, c ,d
+		--using 4 returns for the get of a color type, increase if a type needs more
+		if type(member) == "function" then
+			--Call the function
+			a,b,c,d = member(info, ...)
+		else
+			--Call the method
+			if handler and handler[member] then
+				a,b,c,d = handler[member](handler, info, ...)
+			else
+				error(format("Method %s doesn't exist in handler for type %s", member, membername))
+			end
+		end
+		del(info)
+		return a,b,c,d
+	else
+		--The value isnt a function to call, return it
+		return member
+	end
+end
+
+--[[calls an options function that could be inherited, method name or function ref
+local function CallOptionsFunction(funcname ,option, options, path, appName, ...)
+	local info = new()
+
+	local func
+	local group = options
+	local handler
+
+	--build the info table containing the path
+	-- pick up functions while traversing the tree
+	if group[funcname] ~= nil then
+		func = group[funcname]
+	end
+	handler = group.handler or handler
+
+	for i, v in ipairs(path) do
+		group = GetSubOption(group, v)
+		info[i] = v
+		if group[funcname] ~= nil then
+			func =  group[funcname]
+		end
+		handler = group.handler or handler
+	end
+
+	info.options = options
+	info[0] = appName
+	info.arg = option.arg
+
+	local a, b, c ,d
+	if type(func) == "string" then
+		if handler and handler[func] then
+			a,b,c,d = handler[func](handler, info, ...)
+		else
+			error(string.format("Method %s doesn't exist in handler for type func", func))
+		end
+	elseif type(func) == "function" then
+		a,b,c,d = func(info, ...)
+	end
+	del(info)
+	return a,b,c,d
+end
+--]]
+
+--tables to hold orders and names for options being sorted, will be created with new()
+--prevents needing to call functions repeatedly while sorting
+local tempOrders
+local tempNames
+
+local function compareOptions(a,b)
+	if not a then
+		return true
+	end
+	if not b then
+		return false
+	end
+	local OrderA, OrderB = tempOrders[a] or 100, tempOrders[b] or 100
+	if OrderA == OrderB then
+		local NameA = (type(tempNames[a]) == "string") and tempNames[a] or ""
+		local NameB = (type(tempNames[b]) == "string") and tempNames[b] or ""
+		return NameA:upper() < NameB:upper()
+	end
+	if OrderA < 0 then
+		if OrderB > 0 then
+			return false
+		end
+	else
+		if OrderB < 0 then
+			return true
+		end
+	end
+	return OrderA < OrderB
+end
+
+
+
+--builds 2 tables out of an options group
+-- keySort, sorted keys
+-- opts, combined options from .plugins and args
+local function BuildSortedOptionsTable(group, keySort, opts, options, path, appName)
+	tempOrders = new()
+	tempNames = new()
+
+	if group.plugins then
+		for plugin, t in pairs(group.plugins) do
+			for k, v in pairs(t) do
+				if not opts[k] then
+					tinsert(keySort, k)
+					opts[k] = v
+
+					path[#path+1] = k
+					tempOrders[k] = GetOptionsMemberValue("order", v, options, path, appName)
+					tempNames[k] = GetOptionsMemberValue("name", v, options, path, appName)
+					path[#path] = nil
+				end
+			end
+		end
+	end
+
+	for k, v in pairs(group.args) do
+		if not opts[k] then
+			tinsert(keySort, k)
+			opts[k] = v
+
+			path[#path+1] = k
+			tempOrders[k] = GetOptionsMemberValue("order", v, options, path, appName)
+			tempNames[k] = GetOptionsMemberValue("name", v, options, path, appName)
+			path[#path] = nil
+		end
+	end
+
+	tsort(keySort, compareOptions)
+
+	del(tempOrders)
+	del(tempNames)
+end
+
+local function DelTree(tree)
+	if tree.children then
+		local childs = tree.children
+		for i = 1, #childs do
+			DelTree(childs[i])
+			del(childs[i])
+		end
+		del(childs)
+	end
+end
+
+local function CleanUserData(widget, event)
+
+	local user = widget:GetUserDataTable()
+
+	if user.path then
+		del(user.path)
+	end
+
+	if widget.type == "TreeGroup" then
+		local tree = user.tree
+		widget:SetTree(nil)
+		if tree then
+			for i = 1, #tree do
+				DelTree(tree[i])
+				del(tree[i])
+			end
+			del(tree)
+		end
+	end
+
+	if widget.type == "TabGroup" then
+		widget:SetTabs(nil)
+		if user.tablist then
+			del(user.tablist)
+		end
+	end
+
+	if widget.type == "DropdownGroup" then
+		widget:SetGroupList(nil)
+		if user.grouplist then
+			del(user.grouplist)
+		end
+		if user.orderlist then
+			del(user.orderlist)
+		end
+	end
+end
+
+-- - Gets a status table for the given appname and options path.
+-- @param appName The application name as given to `:RegisterOptionsTable()`
+-- @param path The path to the options (a table with all group keys)
+-- @return
+function AceConfigDialog:GetStatusTable(appName, path)
+	local status = self.Status
+
+	if not status[appName] then
+		status[appName] = {}
+		status[appName].status = {}
+		status[appName].children = {}
+	end
+
+	status = status[appName]
+
+	if path then
+		for i = 1, #path do
+			local v = path[i]
+			if not status.children[v] then
+				status.children[v] = {}
+				status.children[v].status = {}
+				status.children[v].children = {}
+			end
+			status = status.children[v]
+		end
+	end
+
+	return status.status
+end
+
+--- Selects the specified path in the options window.
+-- The path specified has to match the keys of the groups in the table.
+-- @param appName The application name as given to `:RegisterOptionsTable()`
+-- @param ... The path to the key that should be selected
+function AceConfigDialog:SelectGroup(appName, ...)
+	local path = new()
+
+
+	local app = reg:GetOptionsTable(appName)
+	if not app then
+		error(("%s isn't registed with AceConfigRegistry, unable to open config"):format(appName), 2)
+	end
+	local options = app("dialog", MAJOR)
+	local group = options
+	local status = self:GetStatusTable(appName, path)
+	if not status.groups then
+		status.groups = {}
+	end
+	status = status.groups
+	local treevalue
+	local treestatus
+
+	for n = 1, select("#",...) do
+		local key = select(n, ...)
+
+		if group.childGroups == "tab" or group.childGroups == "select" then
+			--if this is a tab or select group, select the group
+			status.selected = key
+			--children of this group are no longer extra levels of a tree
+			treevalue = nil
+		else
+			--tree group by default
+			if treevalue then
+				--this is an extra level of a tree group, build a uniquevalue for it
+				treevalue = treevalue.."\001"..key
+			else
+				--this is the top level of a tree group, the uniquevalue is the same as the key
+				treevalue = key
+				if not status.groups then
+					status.groups = {}
+				end
+				--save this trees status table for any extra levels or groups
+				treestatus = status
+			end
+			--make sure that the tree entry is open, and select it.
+			--the selected group will be overwritten if a child is the final target but still needs to be open
+			treestatus.selected = treevalue
+			treestatus.groups[treevalue] = true
+
+		end
+
+		--move to the next group in the path
+		group = GetSubOption(group, key)
+		if not group then
+			break
+		end
+		tinsert(path, key)
+		status = self:GetStatusTable(appName, path)
+		if not status.groups then
+			status.groups = {}
+		end
+		status = status.groups
+	end
+
+	del(path)
+	reg:NotifyChange(appName)
+end
+
+local function OptionOnMouseOver(widget, event)
+	--show a tooltip/set the status bar to the desc text
+	local user = widget:GetUserDataTable()
+	local opt = user.option
+	local options = user.options
+	local path = user.path
+	local appName = user.appName
+
+	GameTooltip:SetOwner(widget.frame, "ANCHOR_TOPRIGHT")
+	local name = GetOptionsMemberValue("name", opt, options, path, appName)
+	local desc = GetOptionsMemberValue("desc", opt, options, path, appName)
+	local usage = GetOptionsMemberValue("usage", opt, options, path, appName)
+	local descStyle = opt.descStyle
+
+	if descStyle and descStyle ~= "tooltip" then return end
+
+	GameTooltip:SetText(name, 1, .82, 0, true)
+
+	if opt.type == "multiselect" then
+		GameTooltip:AddLine(user.text, 0.5, 0.5, 0.8, true)
+	end
+	if type(desc) == "string" then
+		GameTooltip:AddLine(desc, 1, 1, 1, true)
+	end
+	if type(usage) == "string" then
+		GameTooltip:AddLine("Usage: "..usage, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, true)
+	end
+
+	GameTooltip:Show()
+end
+
+local function OptionOnMouseLeave(widget, event)
+	GameTooltip:Hide()
+end
+
+local function GetFuncName(option)
+	local type = option.type
+	if type == "execute" then
+		return "func"
+	else
+		return "set"
+	end
+end
+local function confirmPopup(appName, rootframe, basepath, info, message, func, ...)
+	if not StaticPopupDialogs["ACECONFIGDIALOG30_CONFIRM_DIALOG"] then
+		StaticPopupDialogs["ACECONFIGDIALOG30_CONFIRM_DIALOG"] = {}
+	end
+	local t = StaticPopupDialogs["ACECONFIGDIALOG30_CONFIRM_DIALOG"]
+	for k in pairs(t) do
+		t[k] = nil
+	end
+	t.text = message
+	t.button1 = ACCEPT
+	t.button2 = CANCEL
+	t.preferredIndex = STATICPOPUP_NUMDIALOGS
+	local dialog, oldstrata
+	t.OnAccept = function()
+		safecall(func, unpack(t))
+		if dialog and oldstrata then
+			dialog:SetFrameStrata(oldstrata)
+		end
+		AceConfigDialog:Open(appName, rootframe, unpack(basepath or emptyTbl))
+		del(info)
+	end
+	t.OnCancel = function()
+		if dialog and oldstrata then
+			dialog:SetFrameStrata(oldstrata)
+		end
+		AceConfigDialog:Open(appName, rootframe, unpack(basepath or emptyTbl))
+		del(info)
+	end
+	for i = 1, select("#", ...) do
+		t[i] = select(i, ...) or false
+	end
+	t.timeout = 0
+	t.whileDead = 1
+	t.hideOnEscape = 1
+
+	dialog = StaticPopup_Show("ACECONFIGDIALOG30_CONFIRM_DIALOG")
+	if dialog then
+		oldstrata = dialog:GetFrameStrata()
+		dialog:SetFrameStrata("TOOLTIP")
+	end
+end
+
+local function ActivateControl(widget, event, ...)
+	--This function will call the set / execute handler for the widget
+	--widget:GetUserDataTable() contains the needed info
+	local user = widget:GetUserDataTable()
+	local option = user.option
+	local options = user.options
+	local path = user.path
+	local info = new()
+
+	local func
+	local group = options
+	local funcname = GetFuncName(option)
+	local handler
+	local confirm
+	local validate
+	--build the info table containing the path
+	-- pick up functions while traversing the tree
+	if group[funcname] ~= nil then
+		func =  group[funcname]
+	end
+	handler = group.handler or handler
+	confirm = group.confirm
+	validate = group.validate
+	for i = 1, #path do
+		local v = path[i]
+		group = GetSubOption(group, v)
+		info[i] = v
+		if group[funcname] ~= nil then
+			func =  group[funcname]
+		end
+		handler = group.handler or handler
+		if group.confirm ~= nil then
+			confirm = group.confirm
+		end
+		if group.validate ~= nil then
+			validate = group.validate
+		end
+	end
+
+	info.options = options
+	info.appName = user.appName
+	info.arg = option.arg
+	info.handler = handler
+	info.option = option
+	info.type = option.type
+	info.uiType = "dialog"
+	info.uiName = MAJOR
+
+	local name
+	if type(option.name) == "function" then
+		name = option.name(info)
+	elseif type(option.name) == "string" then
+		name = option.name
+	else
+		name = ""
+	end
+	local usage = option.usage
+	local pattern = option.pattern
+
+	local validated = true
+
+	if option.type == "input" then
+		if type(pattern)=="string" then
+			if not strmatch(..., pattern) then
+				validated = false
+			end
+		end
+	end
+
+	local success
+	if validated and option.type ~= "execute" then
+		if type(validate) == "string" then
+			if handler and handler[validate] then
+				success, validated = safecall(handler[validate], handler, info, ...)
+				if not success then validated = false end
+			else
+				error(format("Method %s doesn't exist in handler for type execute", validate))
+			end
+		elseif type(validate) == "function" then
+			success, validated = safecall(validate, info, ...)
+			if not success then validated = false end
+		end
+	end
+
+	local rootframe = user.rootframe
+	if type(validated) == "string" then
+		--validate function returned a message to display
+		if rootframe.SetStatusText then
+			rootframe:SetStatusText(validated)
+		else
+			-- TODO: do something else.
+		end
+		PlaySound("igPlayerInviteDecline")
+		del(info)
+		return true
+	elseif not validated then
+		--validate returned false
+		if rootframe.SetStatusText then
+			if usage then
+				rootframe:SetStatusText(name..": "..usage)
+			else
+				if pattern then
+					rootframe:SetStatusText(name..": Expected "..pattern)
+				else
+					rootframe:SetStatusText(name..": Invalid Value")
+				end
+			end
+		else
+			-- TODO: do something else
+		end
+		PlaySound("igPlayerInviteDecline")
+		del(info)
+		return true
+	else
+
+		local confirmText = option.confirmText
+		--call confirm func/method
+		if type(confirm) == "string" then
+			if handler and handler[confirm] then
+				success, confirm = safecall(handler[confirm], handler, info, ...)
+				if success and type(confirm) == "string" then
+					confirmText = confirm
+					confirm = true
+				elseif not success then
+					confirm = false
+				end
+			else
+				error(format("Method %s doesn't exist in handler for type confirm", confirm))
+			end
+		elseif type(confirm) == "function" then
+			success, confirm = safecall(confirm, info, ...)
+			if success and type(confirm) == "string" then
+				confirmText = confirm
+				confirm = true
+			elseif not success then
+				confirm = false
+			end
+		end
+
+		--confirm if needed
+		if type(confirm) == "boolean" then
+			if confirm then
+				if not confirmText then
+					local name, desc = option.name, option.desc
+					if type(name) == "function" then
+						name = name(info)
+					end
+					if type(desc) == "function" then
+						desc = desc(info)
+					end
+					confirmText = name
+					if desc then
+						confirmText = confirmText.." - "..desc
+					end
+				end
+
+				local iscustom = user.rootframe:GetUserData("iscustom")
+				local rootframe
+
+				if iscustom then
+					rootframe = user.rootframe
+				end
+				local basepath = user.rootframe:GetUserData("basepath")
+				if type(func) == "string" then
+					if handler and handler[func] then
+						confirmPopup(user.appName, rootframe, basepath, info, confirmText, handler[func], handler, info, ...)
+					else
+						error(format("Method %s doesn't exist in handler for type func", func))
+					end
+				elseif type(func) == "function" then
+					confirmPopup(user.appName, rootframe, basepath, info, confirmText, func, info, ...)
+				end
+				--func will be called and info deleted when the confirm dialog is responded to
+				return
+			end
+		end
+
+		--call the function
+		if type(func) == "string" then
+			if handler and handler[func] then
+				safecall(handler[func],handler, info, ...)
+			else
+				error(format("Method %s doesn't exist in handler for type func", func))
+			end
+		elseif type(func) == "function" then
+			safecall(func,info, ...)
+		end
+
+
+
+		local iscustom = user.rootframe:GetUserData("iscustom")
+		local basepath = user.rootframe:GetUserData("basepath") or emptyTbl
+		--full refresh of the frame, some controls dont cause this on all events
+		if option.type == "color" then
+			if event == "OnValueConfirmed" then
+
+				if iscustom then
+					AceConfigDialog:Open(user.appName, user.rootframe, unpack(basepath))
+				else
+					AceConfigDialog:Open(user.appName, unpack(basepath))
+				end
+			end
+		elseif option.type == "range" then
+			if event == "OnMouseUp" then
+				if iscustom then
+					AceConfigDialog:Open(user.appName, user.rootframe, unpack(basepath))
+				else
+					AceConfigDialog:Open(user.appName, unpack(basepath))
+				end
+			end
+		--multiselects don't cause a refresh on 'OnValueChanged' only 'OnClosed'
+		elseif option.type == "multiselect" then
+			user.valuechanged = true
+		else
+			if iscustom then
+				AceConfigDialog:Open(user.appName, user.rootframe, unpack(basepath))
+			else
+				AceConfigDialog:Open(user.appName, unpack(basepath))
+			end
+		end
+
+	end
+	del(info)
+end
+
+local function ActivateSlider(widget, event, value)
+	local option = widget:GetUserData("option")
+	local min, max, step = option.min or (not option.softMin and 0 or nil), option.max or (not option.softMax and 100 or nil), option.step
+	if min then
+		if step then
+			value = math_floor((value - min) / step + 0.5) * step + min
+		end
+		value = math_max(value, min)
+	end
+	if max then
+		value = math_min(value, max)
+	end
+	ActivateControl(widget,event,value)
+end
+
+--called from a checkbox that is part of an internally created multiselect group
+--this type is safe to refresh on activation of one control
+local function ActivateMultiControl(widget, event, ...)
+	ActivateControl(widget, event, widget:GetUserData("value"), ...)
+	local user = widget:GetUserDataTable()
+	local iscustom = user.rootframe:GetUserData("iscustom")
+	local basepath = user.rootframe:GetUserData("basepath") or emptyTbl
+	if iscustom then
+		AceConfigDialog:Open(user.appName, user.rootframe, unpack(basepath))
+	else
+		AceConfigDialog:Open(user.appName, unpack(basepath))
+	end
+end
+
+local function MultiControlOnClosed(widget, event, ...)
+	local user = widget:GetUserDataTable()
+	if user.valuechanged then
+		local iscustom = user.rootframe:GetUserData("iscustom")
+		local basepath = user.rootframe:GetUserData("basepath") or emptyTbl
+		if iscustom then
+			AceConfigDialog:Open(user.appName, user.rootframe, unpack(basepath))
+		else
+			AceConfigDialog:Open(user.appName, unpack(basepath))
+		end
+	end
+end
+
+local function FrameOnClose(widget, event)
+	local appName = widget:GetUserData("appName")
+	AceConfigDialog.OpenFrames[appName] = nil
+	gui:Release(widget)
+end
+
+local function CheckOptionHidden(option, options, path, appName)
+	--check for a specific boolean option
+	local hidden = pickfirstset(option.dialogHidden,option.guiHidden)
+	if hidden ~= nil then
+		return hidden
+	end
+
+	return GetOptionsMemberValue("hidden", option, options, path, appName)
+end
+
+local function CheckOptionDisabled(option, options, path, appName)
+	--check for a specific boolean option
+	local disabled = pickfirstset(option.dialogDisabled,option.guiDisabled)
+	if disabled ~= nil then
+		return disabled
+	end
+
+	return GetOptionsMemberValue("disabled", option, options, path, appName)
+end
+--[[
+local function BuildTabs(group, options, path, appName)
+	local tabs = new()
+	local text = new()
+	local keySort = new()
+	local opts = new()
+
+	BuildSortedOptionsTable(group, keySort, opts, options, path, appName)
+
+	for i = 1, #keySort do
+		local k = keySort[i]
+		local v = opts[k]
+		if v.type == "group" then
+			path[#path+1] = k
+			local inline = pickfirstset(v.dialogInline,v.guiInline,v.inline, false)
+			local hidden = CheckOptionHidden(v, options, path, appName)
+			if not inline and not hidden then
+				tinsert(tabs, k)
+				text[k] = GetOptionsMemberValue("name", v, options, path, appName)
+			end
+			path[#path] = nil
+		end
+	end
+
+	del(keySort)
+	del(opts)
+
+	return tabs, text
+end
+]]
+local function BuildSelect(group, options, path, appName)
+	local groups = new()
+	local order = new()
+	local keySort = new()
+	local opts = new()
+
+	BuildSortedOptionsTable(group, keySort, opts, options, path, appName)
+
+	for i = 1, #keySort do
+		local k = keySort[i]
+		local v = opts[k]
+		if v.type == "group" then
+			path[#path+1] = k
+			local inline = pickfirstset(v.dialogInline,v.guiInline,v.inline, false)
+			local hidden = CheckOptionHidden(v, options, path, appName)
+			if not inline and not hidden then
+				groups[k] = GetOptionsMemberValue("name", v, options, path, appName)
+				tinsert(order, k)
+			end
+			path[#path] = nil
+		end
+	end
+
+	del(opts)
+	del(keySort)
+
+	return groups, order
+end
+
+local function BuildSubGroups(group, tree, options, path, appName)
+	local keySort = new()
+	local opts = new()
+
+	BuildSortedOptionsTable(group, keySort, opts, options, path, appName)
+
+	for i = 1, #keySort do
+		local k = keySort[i]
+		local v = opts[k]
+		if v.type == "group" then
+			path[#path+1] = k
+			local inline = pickfirstset(v.dialogInline,v.guiInline,v.inline, false)
+			local hidden = CheckOptionHidden(v, options, path, appName)
+			if not inline and not hidden then
+				local entry = new()
+				entry.value = k
+				entry.text = GetOptionsMemberValue("name", v, options, path, appName)
+				entry.icon = GetOptionsMemberValue("icon", v, options, path, appName)
+				entry.iconCoords = GetOptionsMemberValue("iconCoords", v, options, path, appName)
+				entry.disabled = CheckOptionDisabled(v, options, path, appName)
+				if not tree.children then tree.children = new() end
+				tinsert(tree.children,entry)
+				if (v.childGroups or "tree") == "tree" then
+					BuildSubGroups(v,entry, options, path, appName)
+				end
+			end
+			path[#path] = nil
+		end
+	end
+
+	del(keySort)
+	del(opts)
+end
+
+local function BuildGroups(group, options, path, appName, recurse)
+	local tree = new()
+	local keySort = new()
+	local opts = new()
+
+	BuildSortedOptionsTable(group, keySort, opts, options, path, appName)
+
+	for i = 1, #keySort do
+		local k = keySort[i]
+		local v = opts[k]
+		if v.type == "group" then
+			path[#path+1] = k
+			local inline = pickfirstset(v.dialogInline,v.guiInline,v.inline, false)
+			local hidden = CheckOptionHidden(v, options, path, appName)
+			if not inline and not hidden then
+				local entry = new()
+				entry.value = k
+				entry.text = GetOptionsMemberValue("name", v, options, path, appName)
+				entry.icon = GetOptionsMemberValue("icon", v, options, path, appName)
+				entry.disabled = CheckOptionDisabled(v, options, path, appName)
+				tinsert(tree,entry)
+				if recurse and (v.childGroups or "tree") == "tree" then
+					BuildSubGroups(v,entry, options, path, appName)
+				end
+			end
+			path[#path] = nil
+		end
+	end
+	del(keySort)
+	del(opts)
+	return tree
+end
+
+local function InjectInfo(control, options, option, path, rootframe, appName)
+	local user = control:GetUserDataTable()
+	for i = 1, #path do
+		user[i] = path[i]
+	end
+	user.rootframe = rootframe
+	user.option = option
+	user.options = options
+	user.path = copy(path)
+	user.appName = appName
+	control:SetCallback("OnRelease", CleanUserData)
+	control:SetCallback("OnLeave", OptionOnMouseLeave)
+	control:SetCallback("OnEnter", OptionOnMouseOver)
+end
+
+
+--[[
+	options - root of the options table being fed
+	container - widget that controls will be placed in
+	rootframe - Frame object the options are in
+	path - table with the keys to get to the group being fed
+--]]
+
+local function FeedOptions(appName, options,container,rootframe,path,group,inline)
+	local keySort = new()
+	local opts = new()
+
+	BuildSortedOptionsTable(group, keySort, opts, options, path, appName)
+
+	for i = 1, #keySort do
+		local k = keySort[i]
+		local v = opts[k]
+		tinsert(path, k)
+		local hidden = CheckOptionHidden(v, options, path, appName)
+		local name = GetOptionsMemberValue("name", v, options, path, appName)
+		if not hidden then
+			if v.type == "group" then
+				if inline or pickfirstset(v.dialogInline,v.guiInline,v.inline, false) then
+					--Inline group
+					local GroupContainer
+					if name and name ~= "" then
+						GroupContainer = gui:Create("InlineGroup")
+						GroupContainer:SetTitle(name or "")
+					else
+						GroupContainer = gui:Create("SimpleGroup")
+					end
+
+					GroupContainer.width = "fill"
+					GroupContainer:SetLayout("flow")
+					container:AddChild(GroupContainer)
+					FeedOptions(appName,options,GroupContainer,rootframe,path,v,true)
+				end
+			else
+				--Control to feed
+				local control
+
+				local name = GetOptionsMemberValue("name", v, options, path, appName)
+
+				if v.type == "execute" then
+
+					local imageCoords = GetOptionsMemberValue("imageCoords",v, options, path, appName)
+					local image, width, height = GetOptionsMemberValue("image",v, options, path, appName)
+
+					if type(image) == "string" then
+						control = gui:Create("Icon")
+						if not width then
+							width = GetOptionsMemberValue("imageWidth",v, options, path, appName)
+						end
+						if not height then
+							height = GetOptionsMemberValue("imageHeight",v, options, path, appName)
+						end
+						if type(imageCoords) == "table" then
+							control:SetImage(image, unpack(imageCoords))
+						else
+							control:SetImage(image)
+						end
+						if type(width) ~= "number" then
+							width = 32
+						end
+						if type(height) ~= "number" then
+							height = 32
+						end
+						control:SetImageSize(width, height)
+						control:SetLabel(name)
+					else
+						control = gui:Create("Button")
+						control:SetText(name)
+					end
+					control:SetCallback("OnClick",ActivateControl)
+
+				elseif v.type == "input" then
+					local controlType = v.dialogControl or v.control or (v.multiline and "MultiLineEditBox") or "EditBox"
+					control = gui:Create(controlType)
+					if not control then
+						geterrorhandler()(("Invalid Custom Control Type - %s"):format(tostring(controlType)))
+						control = gui:Create(v.multiline and "MultiLineEditBox" or "EditBox")
+					end
+
+					if v.multiline and control.SetNumLines then
+						control:SetNumLines(tonumber(v.multiline) or 4)
+					end
+					control:SetLabel(name)
+					control:SetCallback("OnEnterPressed",ActivateControl)
+					local text = GetOptionsMemberValue("get",v, options, path, appName)
+					if type(text) ~= "string" then
+						text = ""
+					end
+					control:SetText(text)
+
+				elseif v.type == "toggle" then
+					control = gui:Create("CheckBox")
+					control:SetLabel(name)
+					control:SetTriState(v.tristate)
+					local value = GetOptionsMemberValue("get",v, options, path, appName)
+					control:SetValue(value)
+					control:SetCallback("OnValueChanged",ActivateControl)
+
+					if v.descStyle == "inline" then
+						local desc = GetOptionsMemberValue("desc", v, options, path, appName)
+						control:SetDescription(desc)
+					end
+
+					local image = GetOptionsMemberValue("image", v, options, path, appName)
+					local imageCoords = GetOptionsMemberValue("imageCoords", v, options, path, appName)
+
+					if type(image) == "string" then
+						if type(imageCoords) == "table" then
+							control:SetImage(image, unpack(imageCoords))
+						else
+							control:SetImage(image)
+						end
+					end
+				elseif v.type == "range" then
+					control = gui:Create("Slider")
+					control:SetLabel(name)
+					control:SetSliderValues(v.softMin or v.min or 0, v.softMax or v.max or 100, v.bigStep or v.step or 0)
+					control:SetIsPercent(v.isPercent)
+					local value = GetOptionsMemberValue("get",v, options, path, appName)
+					if type(value) ~= "number" then
+						value = 0
+					end
+					control:SetValue(value)
+					control:SetCallback("OnValueChanged",ActivateSlider)
+					control:SetCallback("OnMouseUp",ActivateSlider)
+
+				elseif v.type == "select" then
+					local values = GetOptionsMemberValue("values", v, options, path, appName)
+					if v.style == "radio" then
+						local disabled = CheckOptionDisabled(v, options, path, appName)
+						local width = GetOptionsMemberValue("width",v,options,path,appName)
+						control = gui:Create("InlineGroup")
+						control:SetLayout("Flow")
+						control:SetTitle(name)
+						control.width = "fill"
+
+						control:PauseLayout()
+						local optionValue = GetOptionsMemberValue("get",v, options, path, appName)
+						local t = {}
+						for value, text in pairs(values) do
+							t[#t+1]=value
+						end
+						tsort(t)
+						for k, value in ipairs(t) do
+							local text = values[value]
+							local radio = gui:Create("CheckBox")
+							radio:SetLabel(text)
+							radio:SetUserData("value", value)
+							radio:SetUserData("text", text)
+							radio:SetDisabled(disabled)
+							radio:SetType("radio")
+							radio:SetValue(optionValue == value)
+							radio:SetCallback("OnValueChanged", ActivateMultiControl)
+							InjectInfo(radio, options, v, path, rootframe, appName)
+							control:AddChild(radio)
+							if width == "double" then
+								radio:SetWidth(width_multiplier * 2)
+							elseif width == "half" then
+								radio:SetWidth(width_multiplier / 2)
+							elseif width == "full" then
+								radio.width = "fill"
+							else
+								radio:SetWidth(width_multiplier)
+							end
+						end
+						control:ResumeLayout()
+						control:DoLayout()
+					else
+						local controlType = v.dialogControl or v.control or "Dropdown"
+						control = gui:Create(controlType)
+						if not control then
+							geterrorhandler()(("Invalid Custom Control Type - %s"):format(tostring(controlType)))
+							control = gui:Create("Dropdown")
+						end
+						local itemType = v.itemControl
+						if itemType and not gui:GetWidgetVersion(itemType) then
+							geterrorhandler()(("Invalid Custom Item Type - %s"):format(tostring(itemType)))
+							itemType = nil
+						end
+						control:SetLabel(name)
+						control:SetList(values, nil, itemType)
+						local value = GetOptionsMemberValue("get",v, options, path, appName)
+						if not values[value] then
+							value = nil
+						end
+						control:SetValue(value)
+						control:SetCallback("OnValueChanged", ActivateControl)
+					end
+
+				elseif v.type == "multiselect" then
+					local values = GetOptionsMemberValue("values", v, options, path, appName)
+					local disabled = CheckOptionDisabled(v, options, path, appName)
+
+					local controlType = v.dialogControl or v.control
+
+					local valuesort = new()
+					if values then
+						for value, text in pairs(values) do
+							tinsert(valuesort, value)
+						end
+					end
+					tsort(valuesort)
+
+					if controlType then
+						control = gui:Create(controlType)
+						if not control then
+							geterrorhandler()(("Invalid Custom Control Type - %s"):format(tostring(controlType)))
+						end
+					end
+					if control then
+						control:SetMultiselect(true)
+						control:SetLabel(name)
+						control:SetList(values)
+						control:SetDisabled(disabled)
+						control:SetCallback("OnValueChanged",ActivateControl)
+						control:SetCallback("OnClosed", MultiControlOnClosed)
+						local width = GetOptionsMemberValue("width",v,options,path,appName)
+						if width == "double" then
+							control:SetWidth(width_multiplier * 2)
+						elseif width == "half" then
+							control:SetWidth(width_multiplier / 2)
+						elseif width == "full" then
+							control.width = "fill"
+						else
+							control:SetWidth(width_multiplier)
+						end
+						--check:SetTriState(v.tristate)
+						for i = 1, #valuesort do
+							local key = valuesort[i]
+							local value = GetOptionsMemberValue("get",v, options, path, appName, key)
+							control:SetItemValue(key,value)
+						end
+					else
+						control = gui:Create("InlineGroup")
+						control:SetLayout("Flow")
+						control:SetTitle(name)
+						control.width = "fill"
+
+						control:PauseLayout()
+						local width = GetOptionsMemberValue("width",v,options,path,appName)
+						for i = 1, #valuesort do
+							local value = valuesort[i]
+							local text = values[value]
+							local check = gui:Create("CheckBox")
+							check:SetLabel(text)
+							check:SetUserData("value", value)
+							check:SetUserData("text", text)
+							check:SetDisabled(disabled)
+							check:SetTriState(v.tristate)
+							check:SetValue(GetOptionsMemberValue("get",v, options, path, appName, value))
+							check:SetCallback("OnValueChanged",ActivateMultiControl)
+							InjectInfo(check, options, v, path, rootframe, appName)
+							control:AddChild(check)
+							if width == "double" then
+								check:SetWidth(width_multiplier * 2)
+							elseif width == "half" then
+								check:SetWidth(width_multiplier / 2)
+							elseif width == "full" then
+								check.width = "fill"
+							else
+								check:SetWidth(width_multiplier)
+							end
+						end
+						control:ResumeLayout()
+						control:DoLayout()
+
+
+					end
+
+					del(valuesort)
+
+				elseif v.type == "color" then
+					control = gui:Create("ColorPicker")
+					control:SetLabel(name)
+					control:SetHasAlpha(GetOptionsMemberValue("hasAlpha",v, options, path, appName))
+					control:SetColor(GetOptionsMemberValue("get",v, options, path, appName))
+					control:SetCallback("OnValueChanged",ActivateControl)
+					control:SetCallback("OnValueConfirmed",ActivateControl)
+
+				elseif v.type == "keybinding" then
+					control = gui:Create("Keybinding")
+					control:SetLabel(name)
+					control:SetKey(GetOptionsMemberValue("get",v, options, path, appName))
+					control:SetCallback("OnKeyChanged",ActivateControl)
+
+				elseif v.type == "header" then
+					control = gui:Create("Heading")
+					control:SetText(name)
+					control.width = "fill"
+
+				elseif v.type == "description" then
+					control = gui:Create("Label")
+					control:SetText(name)
+
+					local fontSize = GetOptionsMemberValue("fontSize",v, options, path, appName)
+					if fontSize == "medium" then
+						control:SetFontObject(GameFontHighlight)
+					elseif fontSize == "large" then
+						control:SetFontObject(GameFontHighlightLarge)
+					else -- small or invalid
+						control:SetFontObject(GameFontHighlightSmall)
+					end
+
+					local imageCoords = GetOptionsMemberValue("imageCoords",v, options, path, appName)
+					local image, width, height = GetOptionsMemberValue("image",v, options, path, appName)
+
+					if type(image) == "string" then
+						if not width then
+							width = GetOptionsMemberValue("imageWidth",v, options, path, appName)
+						end
+						if not height then
+							height = GetOptionsMemberValue("imageHeight",v, options, path, appName)
+						end
+						if type(imageCoords) == "table" then
+							control:SetImage(image, unpack(imageCoords))
+						else
+							control:SetImage(image)
+						end
+						if type(width) ~= "number" then
+							width = 32
+						end
+						if type(height) ~= "number" then
+							height = 32
+						end
+						control:SetImageSize(width, height)
+					end
+					local width = GetOptionsMemberValue("width",v,options,path,appName)
+					control.width = not width and "fill"
+				end
+
+				--Common Init
+				if control then
+					if control.width ~= "fill" then
+						local width = GetOptionsMemberValue("width",v,options,path,appName)
+						if width == "double" then
+							control:SetWidth(width_multiplier * 2)
+						elseif width == "half" then
+							control:SetWidth(width_multiplier / 2)
+						elseif width == "full" then
+							control.width = "fill"
+						else
+							control:SetWidth(width_multiplier)
+						end
+					end
+					if control.SetDisabled then
+						local disabled = CheckOptionDisabled(v, options, path, appName)
+						control:SetDisabled(disabled)
+					end
+
+					InjectInfo(control, options, v, path, rootframe, appName)
+					container:AddChild(control)
+				end
+
+			end
+		end
+		tremove(path)
+	end
+	container:ResumeLayout()
+	container:DoLayout()
+	del(keySort)
+	del(opts)
+end
+
+local function BuildPath(path, ...)
+	for i = 1, select("#",...)  do
+		tinsert(path, (select(i,...)))
+	end
+end
+
+
+local function TreeOnButtonEnter(widget, event, uniquevalue, button)
+	local user = widget:GetUserDataTable()
+	if not user then return end
+	local options = user.options
+	local option = user.option
+	local path = user.path
+	local appName = user.appName
+
+	local feedpath = new()
+	for i = 1, #path do
+		feedpath[i] = path[i]
+	end
+
+	BuildPath(feedpath, ("\001"):split(uniquevalue))
+	local group = options
+	for i = 1, #feedpath do
+		if not group then return end
+		group = GetSubOption(group, feedpath[i])
+	end
+
+	local name = GetOptionsMemberValue("name", group, options, feedpath, appName)
+	local desc = GetOptionsMemberValue("desc", group, options, feedpath, appName)
+
+	GameTooltip:SetOwner(button, "ANCHOR_NONE")
+	if widget.type == "TabGroup" then
+		GameTooltip:SetPoint("BOTTOM",button,"TOP")
+	else
+		GameTooltip:SetPoint("LEFT",button,"RIGHT")
+	end
+
+	GameTooltip:SetText(name, 1, .82, 0, true)
+
+	if type(desc) == "string" then
+		GameTooltip:AddLine(desc, 1, 1, 1, true)
+	end
+
+	GameTooltip:Show()
+end
+
+local function TreeOnButtonLeave(widget, event, value, button)
+	GameTooltip:Hide()
+end
+
+
+local function GroupExists(appName, options, path, uniquevalue)
+	if not uniquevalue then return false end
+
+	local feedpath = new()
+	local temppath = new()
+	for i = 1, #path do
+		feedpath[i] = path[i]
+	end
+
+	BuildPath(feedpath, ("\001"):split(uniquevalue))
+
+	local group = options
+	for i = 1, #feedpath do
+		local v = feedpath[i]
+		temppath[i] = v
+		group = GetSubOption(group, v)
+
+		if not group or group.type ~= "group" or CheckOptionHidden(group, options, temppath, appName) then
+			del(feedpath)
+			del(temppath)
+			return false
+		end
+	end
+	del(feedpath)
+	del(temppath)
+	return true
+end
+
+local function GroupSelected(widget, event, uniquevalue)
+
+	local user = widget:GetUserDataTable()
+
+	local options = user.options
+	local option = user.option
+	local path = user.path
+	local rootframe = user.rootframe
+
+	local feedpath = new()
+	for i = 1, #path do
+		feedpath[i] = path[i]
+	end
+
+	BuildPath(feedpath, ("\001"):split(uniquevalue))
+	local group = options
+	for i = 1, #feedpath do
+		group = GetSubOption(group, feedpath[i])
+	end
+	widget:ReleaseChildren()
+	AceConfigDialog:FeedGroup(user.appName,options,widget,rootframe,feedpath)
+
+	del(feedpath)
+end
+
+
+
+--[[
+-- INTERNAL --
+This function will feed one group, and any inline child groups into the given container
+Select Groups will only have the selection control (tree, tabs, dropdown) fed in
+and have a group selected, this event will trigger the feeding of child groups
+
+Rules:
+	If the group is Inline, FeedOptions
+	If the group has no child groups, FeedOptions
+
+	If the group is a tab or select group, FeedOptions then add the Group Control
+	If the group is a tree group FeedOptions then
+		its parent isnt a tree group:  then add the tree control containing this and all child tree groups
+		if its parent is a tree group, its already a node on a tree
+--]]
+
+function AceConfigDialog:FeedGroup(appName,options,container,rootframe,path, isRoot)
+	local group = options
+	--follow the path to get to the curent group
+	local inline
+	local grouptype, parenttype = options.childGroups, "none"
+
+
+	for i = 1, #path do
+		local v = path[i]
+		group = GetSubOption(group, v)
+		inline = inline or pickfirstset(v.dialogInline,v.guiInline,v.inline, false)
+		parenttype = grouptype
+		grouptype = group.childGroups
+	end
+
+	if not parenttype then
+		parenttype = "tree"
+	end
+
+	--check if the group has child groups
+	local hasChildGroups
+	for k, v in pairs(group.args) do
+		if v.type == "group" and not pickfirstset(v.dialogInline,v.guiInline,v.inline, false) and not CheckOptionHidden(v, options, path, appName) then
+			hasChildGroups = true
+		end
+	end
+	if group.plugins then
+		for plugin, t in pairs(group.plugins) do
+			for k, v in pairs(t) do
+				if v.type == "group" and not pickfirstset(v.dialogInline,v.guiInline,v.inline, false) and not CheckOptionHidden(v, options, path, appName) then
+					hasChildGroups = true
+				end
+			end
+		end
+	end
+
+	container:SetLayout("flow")
+	local scroll
+
+	--Add a scrollframe if we are not going to add a group control, this is the inverse of the conditions for that later on
+	if (not (hasChildGroups and not inline)) or (grouptype ~= "tab" and grouptype ~= "select" and (parenttype == "tree" and not isRoot)) then
+		if container.type ~= "InlineGroup" and container.type ~= "SimpleGroup" then
+			scroll = gui:Create("ScrollFrame")
+			scroll:SetLayout("flow")
+			scroll.width = "fill"
+			scroll.height = "fill"
+			container:SetLayout("fill")
+			container:AddChild(scroll)
+			container = scroll
+		end
+	end
+
+	FeedOptions(appName,options,container,rootframe,path,group,nil)
+
+	if scroll then
+		container:PerformLayout()
+		local status = self:GetStatusTable(appName, path)
+		if not status.scroll then
+			status.scroll = {}
+		end
+		scroll:SetStatusTable(status.scroll)
+	end
+
+	if hasChildGroups and not inline then
+		local name = GetOptionsMemberValue("name", group, options, path, appName)
+		if grouptype == "tab" then
+
+			local tab = gui:Create("TabGroup")
+			InjectInfo(tab, options, group, path, rootframe, appName)
+			tab:SetCallback("OnGroupSelected", GroupSelected)
+			tab:SetCallback("OnTabEnter", TreeOnButtonEnter)
+			tab:SetCallback("OnTabLeave", TreeOnButtonLeave)
+
+			local status = AceConfigDialog:GetStatusTable(appName, path)
+			if not status.groups then
+				status.groups = {}
+			end
+			tab:SetStatusTable(status.groups)
+			tab.width = "fill"
+			tab.height = "fill"
+
+			local tabs = BuildGroups(group, options, path, appName)
+			tab:SetTabs(tabs)
+			tab:SetUserData("tablist", tabs)
+
+			for i = 1, #tabs do
+				local entry = tabs[i]
+				if not entry.disabled then
+					tab:SelectTab((GroupExists(appName, options, path,status.groups.selected) and status.groups.selected) or entry.value)
+					break
+				end
+			end
+
+			container:AddChild(tab)
+
+		elseif grouptype == "select" then
+
+			local select = gui:Create("DropdownGroup")
+			select:SetTitle(name)
+			InjectInfo(select, options, group, path, rootframe, appName)
+			select:SetCallback("OnGroupSelected", GroupSelected)
+			local status = AceConfigDialog:GetStatusTable(appName, path)
+			if not status.groups then
+				status.groups = {}
+			end
+			select:SetStatusTable(status.groups)
+			local grouplist, orderlist = BuildSelect(group, options, path, appName)
+			select:SetGroupList(grouplist, orderlist)
+			select:SetUserData("grouplist", grouplist)
+			select:SetUserData("orderlist", orderlist)
+
+			local firstgroup = orderlist[1]
+			if firstgroup then
+				select:SetGroup((GroupExists(appName, options, path,status.groups.selected) and status.groups.selected) or firstgroup)
+			end
+
+			select.width = "fill"
+			select.height = "fill"
+
+			container:AddChild(select)
+
+		--assume tree group by default
+		--if parenttype is tree then this group is already a node on that tree
+		elseif (parenttype ~= "tree") or isRoot then
+			local tree = gui:Create("TreeGroup")
+			InjectInfo(tree, options, group, path, rootframe, appName)
+			tree:EnableButtonTooltips(false)
+
+			tree.width = "fill"
+			tree.height = "fill"
+
+			tree:SetCallback("OnGroupSelected", GroupSelected)
+			tree:SetCallback("OnButtonEnter", TreeOnButtonEnter)
+			tree:SetCallback("OnButtonLeave", TreeOnButtonLeave)
+
+			local status = AceConfigDialog:GetStatusTable(appName, path)
+			if not status.groups then
+				status.groups = {}
+			end
+			local treedefinition = BuildGroups(group, options, path, appName, true)
+			tree:SetStatusTable(status.groups)
+
+			tree:SetTree(treedefinition)
+			tree:SetUserData("tree",treedefinition)
+
+			for i = 1, #treedefinition do
+				local entry = treedefinition[i]
+				if not entry.disabled then
+					tree:SelectByValue((GroupExists(appName, options, path,status.groups.selected) and status.groups.selected) or entry.value)
+					break
+				end
+			end
+
+			container:AddChild(tree)
+		end
+	end
+end
+
+local old_CloseSpecialWindows
+
+
+local function RefreshOnUpdate(this)
+	for appName in pairs(this.closing) do
+		if AceConfigDialog.OpenFrames[appName] then
+			AceConfigDialog.OpenFrames[appName]:Hide()
+		end
+		if AceConfigDialog.BlizOptions and AceConfigDialog.BlizOptions[appName] then
+			for key, widget in pairs(AceConfigDialog.BlizOptions[appName]) do
+				if not widget:IsVisible() then
+					widget:ReleaseChildren()
+				end
+			end
+		end
+		this.closing[appName] = nil
+	end
+
+	if this.closeAll then
+		for k, v in pairs(AceConfigDialog.OpenFrames) do
+			if not this.closeAllOverride[k] then
+				v:Hide()
+			end
+		end
+		this.closeAll = nil
+		wipe(this.closeAllOverride)
+	end
+
+	for appName in pairs(this.apps) do
+		if AceConfigDialog.OpenFrames[appName] then
+			local user = AceConfigDialog.OpenFrames[appName]:GetUserDataTable()
+			AceConfigDialog:Open(appName, unpack(user.basepath or emptyTbl))
+		end
+		if AceConfigDialog.BlizOptions and AceConfigDialog.BlizOptions[appName] then
+			for key, widget in pairs(AceConfigDialog.BlizOptions[appName]) do
+				local user = widget:GetUserDataTable()
+				if widget:IsVisible() then
+					AceConfigDialog:Open(widget:GetUserData("appName"), widget, unpack(user.basepath or emptyTbl))
+				end
+			end
+		end
+		this.apps[appName] = nil
+	end
+	this:SetScript("OnUpdate", nil)
+end
+
+-- Upgrade the OnUpdate script as well, if needed.
+if AceConfigDialog.frame:GetScript("OnUpdate") then
+	AceConfigDialog.frame:SetScript("OnUpdate", RefreshOnUpdate)
+end
+
+--- Close all open options windows
+function AceConfigDialog:CloseAll()
+	AceConfigDialog.frame.closeAll = true
+	AceConfigDialog.frame:SetScript("OnUpdate", RefreshOnUpdate)
+	if next(self.OpenFrames) then
+		return true
+	end
+end
+
+--- Close a specific options window.
+-- @param appName The application name as given to `:RegisterOptionsTable()`
+function AceConfigDialog:Close(appName)
+	if self.OpenFrames[appName] then
+		AceConfigDialog.frame.closing[appName] = true
+		AceConfigDialog.frame:SetScript("OnUpdate", RefreshOnUpdate)
+		return true
+	end
+end
+
+-- Internal -- Called by AceConfigRegistry
+function AceConfigDialog:ConfigTableChanged(event, appName)
+	AceConfigDialog.frame.apps[appName] = true
+	AceConfigDialog.frame:SetScript("OnUpdate", RefreshOnUpdate)
+end
+
+reg.RegisterCallback(AceConfigDialog, "ConfigTableChange", "ConfigTableChanged")
+
+--- Sets the default size of the options window for a specific application.
+-- @param appName The application name as given to `:RegisterOptionsTable()`
+-- @param width The default width
+-- @param height The default height
+function AceConfigDialog:SetDefaultSize(appName, width, height)
+	local status = AceConfigDialog:GetStatusTable(appName)
+	if type(width) == "number" and type(height) == "number" then
+		status.width = width
+		status.height = height
+	end
+end
+
+--- Open an option window at the specified path (if any).
+-- This function can optionally feed the group into a pre-created container
+-- instead of creating a new container frame.
+-- @paramsig appName [, container][, ...]
+-- @param appName The application name as given to `:RegisterOptionsTable()`
+-- @param container An optional container frame to feed the options into
+-- @param ... The path to open after creating the options window (see `:SelectGroup` for details)
+function AceConfigDialog:Open(appName, container, ...)
+	if not old_CloseSpecialWindows then
+		old_CloseSpecialWindows = CloseSpecialWindows
+		CloseSpecialWindows = function()
+			local found = old_CloseSpecialWindows()
+			return self:CloseAll() or found
+		end
+	end
+	local app = reg:GetOptionsTable(appName)
+	if not app then
+		error(("%s isn't registed with AceConfigRegistry, unable to open config"):format(appName), 2)
+	end
+	local options = app("dialog", MAJOR)
+
+	local f
+
+	local path = new()
+	local name = GetOptionsMemberValue("name", options, options, path, appName)
+
+	--If an optional path is specified add it to the path table before feeding the options
+	--as container is optional as well it may contain the first element of the path
+	if type(container) == "string" then
+		tinsert(path, container)
+		container = nil
+	end
+	for n = 1, select("#",...) do
+		tinsert(path, (select(n, ...)))
+	end
+
+	local option = options
+	if type(container) == "table" and container.type == "BlizOptionsGroup" and #path > 0 then
+		for i = 1, #path do
+			option = options.args[path[i]]
+		end
+		name = format("%s - %s", name, GetOptionsMemberValue("name", option, options, path, appName))
+	end
+
+	--if a container is given feed into that
+	if container then
+		f = container
+		f:ReleaseChildren()
+		f:SetUserData("appName", appName)
+		f:SetUserData("iscustom", true)
+		if #path > 0 then
+			f:SetUserData("basepath", copy(path))
+		end
+		local status = AceConfigDialog:GetStatusTable(appName)
+		if not status.width then
+			status.width =  700
+		end
+		if not status.height then
+			status.height = 500
+		end
+		if f.SetStatusTable then
+			f:SetStatusTable(status)
+		end
+		if f.SetTitle then
+			f:SetTitle(name or "")
+		end
+	else
+		if not self.OpenFrames[appName] then
+			f = gui:Create("Frame")
+			self.OpenFrames[appName] = f
+		else
+			f = self.OpenFrames[appName]
+		end
+		f:ReleaseChildren()
+		f:SetCallback("OnClose", FrameOnClose)
+		f:SetUserData("appName", appName)
+		if #path > 0 then
+			f:SetUserData("basepath", copy(path))
+		end
+		f:SetTitle(name or "")
+		local status = AceConfigDialog:GetStatusTable(appName)
+		f:SetStatusTable(status)
+	end
+
+	self:FeedGroup(appName,options,f,f,path,true)
+	if f.Show then
+		f:Show()
+	end
+	del(path)
+
+	if AceConfigDialog.frame.closeAll then
+		-- close all is set, but thats not good, since we're just opening here, so force it
+		AceConfigDialog.frame.closeAllOverride[appName] = true
+	end
+end
+
+-- convert pre-39 BlizOptions structure to the new format
+if oldminor and oldminor < 39 and AceConfigDialog.BlizOptions then
+	local old = AceConfigDialog.BlizOptions
+	local new = {}
+	for key, widget in pairs(old) do
+		local appName = widget:GetUserData("appName")
+		if not new[appName] then new[appName] = {} end
+		new[appName][key] = widget
+	end
+	AceConfigDialog.BlizOptions = new
+else
+	AceConfigDialog.BlizOptions = AceConfigDialog.BlizOptions or {}
+end
+
+local function FeedToBlizPanel(widget, event)
+	local path = widget:GetUserData("path")
+	AceConfigDialog:Open(widget:GetUserData("appName"), widget, unpack(path or emptyTbl))
+end
+
+local function ClearBlizPanel(widget, event)
+	local appName = widget:GetUserData("appName")
+	AceConfigDialog.frame.closing[appName] = true
+	AceConfigDialog.frame:SetScript("OnUpdate", RefreshOnUpdate)
+end
+
+--- Add an option table into the Blizzard Interface Options panel.
+-- You can optionally supply a descriptive name to use and a parent frame to use,
+-- as well as a path in the options table.\\
+-- If no name is specified, the appName will be used instead.
+--
+-- If you specify a proper `parent` (by name), the interface options will generate a
+-- tree layout. Note that only one level of children is supported, so the parent always
+-- has to be a head-level note.
+--
+-- This function returns a reference to the container frame registered with the Interface
+-- Options. You can use this reference to open the options with the API function
+-- `InterfaceOptionsFrame_OpenToCategory`.
+-- @param appName The application name as given to `:RegisterOptionsTable()`
+-- @param name A descriptive name to display in the options tree (defaults to appName)
+-- @param parent The parent to use in the interface options tree.
+-- @param ... The path in the options table to feed into the interface options panel.
+-- @return The reference to the frame registered into the Interface Options.
+function AceConfigDialog:AddToBlizOptions(appName, name, parent, ...)
+	local BlizOptions = AceConfigDialog.BlizOptions
+
+	local key = appName
+	for n = 1, select("#", ...) do
+		key = key.."\001"..select(n, ...)
+	end
+
+	if not BlizOptions[appName] then
+		BlizOptions[appName] = {}
+	end
+
+	if not BlizOptions[appName][key] then
+		local group = gui:Create("BlizOptionsGroup")
+		BlizOptions[appName][key] = group
+		group:SetName(name or appName, parent)
+
+		group:SetTitle(name or appName)
+		group:SetUserData("appName", appName)
+		if select("#", ...) > 0 then
+			local path = {}
+			for n = 1, select("#",...) do
+				tinsert(path, (select(n, ...)))
+			end
+			group:SetUserData("path", path)
+		end
+		group:SetCallback("OnShow", FeedToBlizPanel)
+		group:SetCallback("OnHide", ClearBlizPanel)
+		InterfaceOptions_AddCategory(group.frame)
+		return group.frame
+	else
+		error(("%s has already been added to the Blizzard Options Window with the given path"):format(appName), 2)
+	end
+end
diff --git a/SVUI_!Core/libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.xml b/SVUI_!Core/libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.xml
new file mode 100644
index 0000000..86ce057
--- /dev/null
+++ b/SVUI_!Core/libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.xml
@@ -0,0 +1,4 @@
+<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="AceConfigDialog-3.0.lua"/>
+</Ui>
\ No newline at end of file
diff --git a/SVUI_!Core/libs/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.lua b/SVUI_!Core/libs/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.lua
new file mode 100644
index 0000000..d684d66
--- /dev/null
+++ b/SVUI_!Core/libs/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.lua
@@ -0,0 +1,348 @@
+--- AceConfigRegistry-3.0 handles central registration of options tables in use by addons and modules.\\
+-- Options tables can be registered as raw tables, OR as function refs that return a table.\\
+-- Such functions receive three arguments: "uiType", "uiName", "appName". \\
+-- * Valid **uiTypes**: "cmd", "dropdown", "dialog". This is verified by the library at call time. \\
+-- * The **uiName** field is expected to contain the full name of the calling addon, including version, e.g. "FooBar-1.0". This is verified by the library at call time.\\
+-- * The **appName** field is the options table name as given at registration time \\
+--
+-- :IterateOptionsTables() (and :GetOptionsTable() if only given one argument) return a function reference that the requesting config handling addon must call with valid "uiType", "uiName".
+-- @class file
+-- @name AceConfigRegistry-3.0
+-- @release $Id: AceConfigRegistry-3.0.lua 1105 2013-12-08 22:11:58Z nevcairiel $
+local MAJOR, MINOR = "AceConfigRegistry-3.0", 15
+local AceConfigRegistry = LibStub:NewLibrary(MAJOR, MINOR)
+
+if not AceConfigRegistry then return end
+
+AceConfigRegistry.tables = AceConfigRegistry.tables or {}
+
+local CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0")
+
+if not AceConfigRegistry.callbacks then
+	AceConfigRegistry.callbacks = CallbackHandler:New(AceConfigRegistry)
+end
+
+-- Lua APIs
+local tinsert, tconcat = table.insert, table.concat
+local strfind, strmatch = string.find, string.match
+local type, tostring, select, pairs = type, tostring, select, pairs
+local error, assert = error, assert
+
+-----------------------------------------------------------------------
+-- Validating options table consistency:
+
+
+AceConfigRegistry.validated = {
+	-- list of options table names ran through :ValidateOptionsTable automatically.
+	-- CLEARED ON PURPOSE, since newer versions may have newer validators
+	cmd = {},
+	dropdown = {},
+	dialog = {},
+}
+
+
+
+local function err(msg, errlvl, ...)
+	local t = {}
+	for i=select("#",...),1,-1 do
+		tinsert(t, (select(i, ...)))
+	end
+	error(MAJOR..":ValidateOptionsTable(): "..tconcat(t,".")..msg, errlvl+2)
+end
+
+
+local isstring={["string"]=true, _="string"}
+local isstringfunc={["string"]=true,["function"]=true, _="string or funcref"}
+local istable={["table"]=true,   _="table"}
+local ismethodtable={["table"]=true,["string"]=true,["function"]=true,   _="methodname, funcref or table"}
+local optstring={["nil"]=true,["string"]=true, _="string"}
+local optstringfunc={["nil"]=true,["string"]=true,["function"]=true, _="string or funcref"}
+local optnumber={["nil"]=true,["number"]=true, _="number"}
+local optmethod={["nil"]=true,["string"]=true,["function"]=true, _="methodname or funcref"}
+local optmethodfalse={["nil"]=true,["string"]=true,["function"]=true,["boolean"]={[false]=true},  _="methodname, funcref or false"}
+local optmethodnumber={["nil"]=true,["string"]=true,["function"]=true,["number"]=true,  _="methodname, funcref or number"}
+local optmethodtable={["nil"]=true,["string"]=true,["function"]=true,["table"]=true,  _="methodname, funcref or table"}
+local optmethodbool={["nil"]=true,["string"]=true,["function"]=true,["boolean"]=true,  _="methodname, funcref or boolean"}
+local opttable={["nil"]=true,["table"]=true,  _="table"}
+local optbool={["nil"]=true,["boolean"]=true,  _="boolean"}
+local optboolnumber={["nil"]=true,["boolean"]=true,["number"]=true,  _="boolean or number"}
+
+local basekeys={
+	type=isstring,
+	name=isstringfunc,
+	desc=optstringfunc,
+	descStyle=optstring,
+	order=optmethodnumber,
+	validate=optmethodfalse,
+	confirm=optmethodbool,
+	confirmText=optstring,
+	disabled=optmethodbool,
+	hidden=optmethodbool,
+		guiHidden=optmethodbool,
+		dialogHidden=optmethodbool,
+		dropdownHidden=optmethodbool,
+	cmdHidden=optmethodbool,
+	icon=optstringfunc,
+	iconCoords=optmethodtable,
+	handler=opttable,
+	get=optmethodfalse,
+	set=optmethodfalse,
+	func=optmethodfalse,
+	arg={["*"]=true},
+	width=optstring,
+}
+
+local typedkeys={
+	header={},
+	description={
+		image=optstringfunc,
+		imageCoords=optmethodtable,
+		imageHeight=optnumber,
+		imageWidth=optnumber,
+		fontSize=optstringfunc,
+	},
+	group={
+		args=istable,
+		plugins=opttable,
+		inline=optbool,
+			cmdInline=optbool,
+			guiInline=optbool,
+			dropdownInline=optbool,
+			dialogInline=optbool,
+		childGroups=optstring,
+	},
+	execute={
+		image=optstringfunc,
+		imageCoords=optmethodtable,
+		imageHeight=optnumber,
+		imageWidth=optnumber,
+	},
+	input={
+		pattern=optstring,
+		usage=optstring,
+		control=optstring,
+		dialogControl=optstring,
+		dropdownControl=optstring,
+		multiline=optboolnumber,
+	},
+	toggle={
+		tristate=optbool,
+		image=optstringfunc,
+		imageCoords=optmethodtable,
+	},
+	tristate={
+	},
+	range={
+		min=optnumber,
+		softMin=optnumber,
+		max=optnumber,
+		softMax=optnumber,
+		step=optnumber,
+		bigStep=optnumber,
+		isPercent=optbool,
+	},
+	select={
+		values=ismethodtable,
+		style={
+			["nil"]=true,
+			["string"]={dropdown=true,radio=true},
+			_="string: 'dropdown' or 'radio'"
+		},
+		control=optstring,
+		dialogControl=optstring,
+		dropdownControl=optstring,
+		itemControl=optstring,
+	},
+	multiselect={
+		values=ismethodtable,
+		style=optstring,
+		tristate=optbool,
+		control=optstring,
+		dialogControl=optstring,
+		dropdownControl=optstring,
+	},
+	color={
+		hasAlpha=optmethodbool,
+	},
+	keybinding={
+		-- TODO
+	},
+}
+
+local function validateKey(k,errlvl,...)
+	errlvl=(errlvl or 0)+1
+	if type(k)~="string" then
+		err("["..tostring(k).."] - key is not a string", errlvl,...)
+	end
+	if strfind(k, "[%c\127]") then
+		err("["..tostring(k).."] - key name contained control characters", errlvl,...)
+	end
+end
+
+local function validateVal(v, oktypes, errlvl,...)
+	errlvl=(errlvl or 0)+1
+	local isok=oktypes[type(v)] or oktypes["*"]
+
+	if not isok then
+		err(": expected a "..oktypes._..", got '"..tostring(v).."'", errlvl,...)
+	end
+	if type(isok)=="table" then		-- isok was a table containing specific values to be tested for!
+		if not isok[v] then
+			err(": did not expect "..type(v).." value '"..tostring(v).."'", errlvl,...)
+		end
+	end
+end
+
+local function validate(options,errlvl,...)
+	errlvl=(errlvl or 0)+1
+	-- basic consistency
+	if type(options)~="table" then
+		err(": expected a table, got a "..type(options), errlvl,...)
+	end
+	if type(options.type)~="string" then
+		err(".type: expected a string, got a "..type(options.type), errlvl,...)
+	end
+
+	-- get type and 'typedkeys' member
+	local tk = typedkeys[options.type]
+	if not tk then
+		err(".type: unknown type '"..options.type.."'", errlvl,...)
+	end
+
+	-- make sure that all options[] are known parameters
+	for k,v in pairs(options) do
+		if not (tk[k] or basekeys[k]) then
+			err(": unknown parameter", errlvl,tostring(k),...)
+		end
+	end
+
+	-- verify that required params are there, and that everything is the right type
+	for k,oktypes in pairs(basekeys) do
+		validateVal(options[k], oktypes, errlvl,k,...)
+	end
+	for k,oktypes in pairs(tk) do
+		validateVal(options[k], oktypes, errlvl,k,...)
+	end
+
+	-- extra logic for groups
+	if options.type=="group" then
+		for k,v in pairs(options.args) do
+			validateKey(k,errlvl,"args",...)
+			validate(v, errlvl,k,"args",...)
+		end
+		if options.plugins then
+			for plugname,plugin in pairs(options.plugins) do
+				if type(plugin)~="table" then
+					err(": expected a table, got '"..tostring(plugin).."'", errlvl,tostring(plugname),"plugins",...)
+				end
+				for k,v in pairs(plugin) do
+					validateKey(k,errlvl,tostring(plugname),"plugins",...)
+					validate(v, errlvl,k,tostring(plugname),"plugins",...)
+				end
+			end
+		end
+	end
+end
+
+
+--- Validates basic structure and integrity of an options table \\
+-- Does NOT verify that get/set etc actually exist, since they can be defined at any depth
+-- @param options The table to be validated
+-- @param name The name of the table to be validated (shown in any error message)
+-- @param errlvl (optional number) error level offset, default 0 (=errors point to the function calling :ValidateOptionsTable)
+function AceConfigRegistry:ValidateOptionsTable(options,name,errlvl)
+	errlvl=(errlvl or 0)+1
+	name = name or "Optionstable"
+	if not options.name then
+		options.name=name	-- bit of a hack, the root level doesn't really need a .name :-/
+	end
+	validate(options,errlvl,name)
+end
+
+--- Fires a "ConfigTableChange" callback for those listening in on it, allowing config GUIs to refresh.
+-- You should call this function if your options table changed from any outside event, like a game event
+-- or a timer.
+-- @param appName The application name as given to `:RegisterOptionsTable()`
+function AceConfigRegistry:NotifyChange(appName)
+	if not AceConfigRegistry.tables[appName] then return end
+	AceConfigRegistry.callbacks:Fire("ConfigTableChange", appName)
+end
+
+-- -------------------------------------------------------------------
+-- Registering and retreiving options tables:
+
+
+-- validateGetterArgs: helper function for :GetOptionsTable (or, rather, the getter functions returned by it)
+
+local function validateGetterArgs(uiType, uiName, errlvl)
+	errlvl=(errlvl or 0)+2
+	if uiType~="cmd" and uiType~="dropdown" and uiType~="dialog" then
+		error(MAJOR..": Requesting options table: 'uiType' - invalid configuration UI type, expected 'cmd', 'dropdown' or 'dialog'", errlvl)
+	end
+	if not strmatch(uiName, "[A-Za-z]%-[0-9]") then	-- Expecting e.g. "MyLib-1.2"
+		error(MAJOR..": Requesting options table: 'uiName' - badly formatted or missing version number. Expected e.g. 'MyLib-1.2'", errlvl)
+	end
+end
+
+--- Register an options table with the config registry.
+-- @param appName The application name as given to `:RegisterOptionsTable()`
+-- @param options The options table, OR a function reference that generates it on demand. \\
+-- See the top of the page for info on arguments passed to such functions.
+-- @param skipValidation Skip options table validation (primarily useful for extremely huge options, with a noticeable slowdown)
+function AceConfigRegistry:RegisterOptionsTable(appName, options, skipValidation)
+	if type(options)=="table" then
+		if options.type~="group" then	-- quick sanity checker
+			error(MAJOR..": RegisterOptionsTable(appName, options): 'options' - missing type='group' member in root group", 2)
+		end
+		AceConfigRegistry.tables[appName] = function(uiType, uiName, errlvl)
+			errlvl=(errlvl or 0)+1
+			validateGetterArgs(uiType, uiName, errlvl)
+			if not AceConfigRegistry.validated[uiType][appName] and not skipValidation then
+				AceConfigRegistry:ValidateOptionsTable(options, appName, errlvl)	-- upgradable
+				AceConfigRegistry.validated[uiType][appName] = true
+			end
+			return options
+		end
+	elseif type(options)=="function" then
+		AceConfigRegistry.tables[appName] = function(uiType, uiName, errlvl)
+			errlvl=(errlvl or 0)+1
+			validateGetterArgs(uiType, uiName, errlvl)
+			local tab = assert(options(uiType, uiName, appName))
+			if not AceConfigRegistry.validated[uiType][appName] and not skipValidation then
+				AceConfigRegistry:ValidateOptionsTable(tab, appName, errlvl)	-- upgradable
+				AceConfigRegistry.validated[uiType][appName] = true
+			end
+			return tab
+		end
+	else
+		error(MAJOR..": RegisterOptionsTable(appName, options): 'options' - expected table or function reference", 2)
+	end
+end
+
+--- Returns an iterator of ["appName"]=funcref pairs
+function AceConfigRegistry:IterateOptionsTables()
+	return pairs(AceConfigRegistry.tables)
+end
+
+
+
+
+--- Query the registry for a specific options table.
+-- If only appName is given, a function is returned which you
+-- can call with (uiType,uiName) to get the table.\\
+-- If uiType&uiName are given, the table is returned.
+-- @param appName The application name as given to `:RegisterOptionsTable()`
+-- @param uiType The type of UI to get the table for, one of "cmd", "dropdown", "dialog"
+-- @param uiName The name of the library/addon querying for the table, e.g. "MyLib-1.0"
+function AceConfigRegistry:GetOptionsTable(appName, uiType, uiName)
+	local f = AceConfigRegistry.tables[appName]
+	if not f then
+		return nil
+	end
+
+	if uiType then
+		return f(uiType,uiName,1)	-- get the table for us
+	else
+		return f	-- return the function
+	end
+end
diff --git a/SVUI_!Core/libs/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.xml b/SVUI_!Core/libs/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.xml
new file mode 100644
index 0000000..101bfda
--- /dev/null
+++ b/SVUI_!Core/libs/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.xml
@@ -0,0 +1,4 @@
+<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="AceConfigRegistry-3.0.lua"/>
+</Ui>
\ No newline at end of file
diff --git a/SVUI_!Core/libs/AceGUI-3.0/AceGUI-3.0.lua b/SVUI_!Core/libs/AceGUI-3.0/AceGUI-3.0.lua
new file mode 100644
index 0000000..9853644
--- /dev/null
+++ b/SVUI_!Core/libs/AceGUI-3.0/AceGUI-3.0.lua
@@ -0,0 +1,813 @@
+--- **AceGUI-3.0** provides access to numerous widgets which can be used to create GUIs.
+-- AceGUI is used by AceConfigDialog to create the option GUIs, but you can use it by itself
+-- to create any custom GUI. There are more extensive examples in the test suite in the Ace3
+-- stand-alone distribution.
+--
+-- **Note**: When using AceGUI-3.0 directly, please do not modify the frames of the widgets directly,
+-- as any "unknown" change to the widgets will cause addons that get your widget out of the widget pool
+-- to misbehave. If you think some part of a widget should be modifiable, please open a ticket, and we"ll
+-- implement a proper API to modify it.
+-- @usage
+-- local AceGUI = LibStub("AceGUI-3.0")
+-- -- Create a container frame
+-- local f = AceGUI:Create("Frame")
+-- f:SetCallback("OnClose",function(widget) AceGUI:Release(widget) end)
+-- f:SetTitle("AceGUI-3.0 Example")
+-- f:SetStatusText("Status Bar")
+-- f:SetLayout("Flow")
+-- -- Create a button
+-- local btn = AceGUI:Create("Button")
+-- btn:SetWidth(170)
+-- btn:SetText("Button !")
+-- btn:SetCallback("OnClick", function() print("Click!") end)
+-- -- Add the button to the container
+-- f:AddChild(btn)
+-- @class file
+-- @name AceGUI-3.0
+-- @release $Id: AceGUI-3.0.lua 1102 2013-10-25 14:15:23Z nevcairiel $
+local ACEGUI_MAJOR, ACEGUI_MINOR = "AceGUI-3.0", 34
+local AceGUI, oldminor = LibStub:NewLibrary(ACEGUI_MAJOR, ACEGUI_MINOR)
+
+if not AceGUI then return end -- No upgrade needed
+
+-- Lua APIs
+local tconcat, tremove, tinsert = table.concat, table.remove, table.insert
+local select, pairs, next, type = select, pairs, next, type
+local error, assert, loadstring = error, assert, loadstring
+local setmetatable, rawget, rawset = setmetatable, rawget, rawset
+local math_max = math.max
+
+-- WoW APIs
+local UIParent = UIParent
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: geterrorhandler, LibStub
+
+--local con = LibStub("AceConsole-3.0",true)
+
+AceGUI.WidgetRegistry = AceGUI.WidgetRegistry or {}
+AceGUI.LayoutRegistry = AceGUI.LayoutRegistry or {}
+AceGUI.WidgetBase = AceGUI.WidgetBase or {}
+AceGUI.WidgetContainerBase = AceGUI.WidgetContainerBase or {}
+AceGUI.WidgetVersions = AceGUI.WidgetVersions or {}
+
+-- local upvalues
+local WidgetRegistry = AceGUI.WidgetRegistry
+local LayoutRegistry = AceGUI.LayoutRegistry
+local WidgetVersions = AceGUI.WidgetVersions
+
+--[[
+	 xpcall safecall implementation
+]]
+local xpcall = xpcall
+
+local function errorhandler(err)
+	return geterrorhandler()(err)
+end
+
+local function CreateDispatcher(argCount)
+	local code = [[
+		local xpcall, eh = ...
+		local method, ARGS
+		local function call() return method(ARGS) end
+
+		local function dispatch(func, ...)
+			method = func
+			if not method then return end
+			ARGS = ...
+			return xpcall(call, eh)
+		end
+
+		return dispatch
+	]]
+
+	local ARGS = {}
+	for i = 1, argCount do ARGS[i] = "arg"..i end
+	code = code:gsub("ARGS", tconcat(ARGS, ", "))
+	return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler)
+end
+
+local Dispatchers = setmetatable({}, {__index=function(self, argCount)
+	local dispatcher = CreateDispatcher(argCount)
+	rawset(self, argCount, dispatcher)
+	return dispatcher
+end})
+Dispatchers[0] = function(func)
+	return xpcall(func, errorhandler)
+end
+
+local function safecall(func, ...)
+	return Dispatchers[select("#", ...)](func, ...)
+end
+
+-- Recycling functions
+local newWidget, delWidget
+do
+	-- Version Upgrade in Minor 29
+	-- Internal Storage of the objects changed, from an array table
+	-- to a hash table, and additionally we introduced versioning on
+	-- the widgets which would discard all widgets from a pre-29 version
+	-- anyway, so we just clear the storage now, and don't try to
+	-- convert the storage tables to the new format.
+	-- This should generally not cause *many* widgets to end up in trash,
+	-- since once dialogs are opened, all addons should be loaded already
+	-- and AceGUI should be on the latest version available on the users
+	-- setup.
+	-- -- nevcairiel - Nov 2nd, 2009
+	if oldminor and oldminor < 29 and AceGUI.objPools then
+		AceGUI.objPools = nil
+	end
+
+	AceGUI.objPools = AceGUI.objPools or {}
+	local objPools = AceGUI.objPools
+	--Returns a new instance, if none are available either returns a new table or calls the given contructor
+	function newWidget(type)
+		if not WidgetRegistry[type] then
+			error("Attempt to instantiate unknown widget type", 2)
+		end
+
+		if not objPools[type] then
+			objPools[type] = {}
+		end
+
+		local newObj = next(objPools[type])
+		if not newObj then
+			newObj = WidgetRegistry[type]()
+			newObj.AceGUIWidgetVersion = WidgetVersions[type]
+		else
+			objPools[type][newObj] = nil
+			-- if the widget is older then the latest, don't even try to reuse it
+			-- just forget about it, and grab a new one.
+			if not newObj.AceGUIWidgetVersion or newObj.AceGUIWidgetVersion < WidgetVersions[type] then
+				return newWidget(type)
+			end
+		end
+		return newObj
+	end
+	-- Releases an instance to the Pool
+	function delWidget(obj,type)
+		if not objPools[type] then
+			objPools[type] = {}
+		end
+		if objPools[type][obj] then
+			error("Attempt to Release Widget that is already released", 2)
+		end
+		objPools[type][obj] = true
+	end
+end
+
+
+-------------------
+-- API Functions --
+-------------------
+
+-- Gets a widget Object
+
+--- Create a new Widget of the given type.
+-- This function will instantiate a new widget (or use one from the widget pool), and call the
+-- OnAcquire function on it, before returning.
+-- @param type The type of the widget.
+-- @return The newly created widget.
+function AceGUI:Create(type)
+	if WidgetRegistry[type] then
+		local widget = newWidget(type)
+
+		if rawget(widget, "Acquire") then
+			widget.OnAcquire = widget.Acquire
+			widget.Acquire = nil
+		elseif rawget(widget, "Aquire") then
+			widget.OnAcquire = widget.Aquire
+			widget.Aquire = nil
+		end
+
+		if rawget(widget, "Release") then
+			widget.OnRelease = rawget(widget, "Release")
+			widget.Release = nil
+		end
+
+		if widget.OnAcquire then
+			widget:OnAcquire()
+		else
+			error(("Widget type %s doesn't supply an OnAcquire Function"):format(type))
+		end
+		-- Set the default Layout ("List")
+		safecall(widget.SetLayout, widget, "List")
+		safecall(widget.ResumeLayout, widget)
+		return widget
+	end
+end
+
+--- Releases a widget Object.
+-- This function calls OnRelease on the widget and places it back in the widget pool.
+-- Any data on the widget is being erased, and the widget will be hidden.\\
+-- If this widget is a Container-Widget, all of its Child-Widgets will be releases as well.
+-- @param widget The widget to release
+function AceGUI:Release(widget)
+	safecall(widget.PauseLayout, widget)
+	widget:Fire("OnRelease")
+	safecall(widget.ReleaseChildren, widget)
+
+	if widget.OnRelease then
+		widget:OnRelease()
+--	else
+--		error(("Widget type %s doesn't supply an OnRelease Function"):format(widget.type))
+	end
+	for k in pairs(widget.userdata) do
+		widget.userdata[k] = nil
+	end
+	for k in pairs(widget.events) do
+		widget.events[k] = nil
+	end
+	widget.width = nil
+	widget.relWidth = nil
+	widget.height = nil
+	widget.relHeight = nil
+	widget.noAutoHeight = nil
+	widget.frame:ClearAllPoints()
+	widget.frame:Hide()
+	widget.frame:SetParent(UIParent)
+	widget.frame.width = nil
+	widget.frame.height = nil
+	if widget.content then
+		widget.content.width = nil
+		widget.content.height = nil
+	end
+	delWidget(widget, widget.type)
+end
+
+-----------
+-- Focus --
+-----------
+
+
+--- Called when a widget has taken focus.
+-- e.g. Dropdowns opening, Editboxes gaining kb focus
+-- @param widget The widget that should be focused
+function AceGUI:SetFocus(widget)
+	if self.FocusedWidget and self.FocusedWidget ~= widget then
+		safecall(self.FocusedWidget.ClearFocus, self.FocusedWidget)
+	end
+	self.FocusedWidget = widget
+end
+
+
+--- Called when something has happened that could cause widgets with focus to drop it
+-- e.g. titlebar of a frame being clicked
+function AceGUI:ClearFocus()
+	if self.FocusedWidget then
+		safecall(self.FocusedWidget.ClearFocus, self.FocusedWidget)
+		self.FocusedWidget = nil
+	end
+end
+
+-------------
+-- Widgets --
+-------------
+--[[
+	Widgets must provide the following functions
+		OnAcquire() - Called when the object is acquired, should set everything to a default hidden state
+
+	And the following members
+		frame - the frame or derivitive object that will be treated as the widget for size and anchoring purposes
+		type - the type of the object, same as the name given to :RegisterWidget()
+
+	Widgets contain a table called userdata, this is a safe place to store data associated with the wigdet
+	It will be cleared automatically when a widget is released
+	Placing values directly into a widget object should be avoided
+
+	If the Widget can act as a container for other Widgets the following
+		content - frame or derivitive that children will be anchored to
+
+	The Widget can supply the following Optional Members
+		:OnRelease() - Called when the object is Released, should remove any additional anchors and clear any data
+		:OnWidthSet(width) - Called when the width of the widget is changed
+		:OnHeightSet(height) - Called when the height of the widget is changed
+			Widgets should not use the OnSizeChanged events of thier frame or content members, use these methods instead
+			AceGUI already sets a handler to the event
+		:LayoutFinished(width, height) - called after a layout has finished, the width and height will be the width and height of the
+			area used for controls. These can be nil if the layout used the existing size to layout the controls.
+
+]]
+
+--------------------------
+-- Widget Base Template --
+--------------------------
+do
+	local WidgetBase = AceGUI.WidgetBase
+
+	WidgetBase.SetParent = function(self, parent)
+		local frame = self.frame
+		frame:SetParent(nil)
+		frame:SetParent(parent.content)
+		self.parent = parent
+	end
+
+	WidgetBase.SetCallback = function(self, name, func)
+		if type(func) == "function" then
+			self.events[name] = func
+		end
+	end
+
+	WidgetBase.Fire = function(self, name, ...)
+		if self.events[name] then
+			local success, ret = safecall(self.events[name], self, name, ...)
+			if success then
+				return ret
+			end
+		end
+	end
+
+	WidgetBase.SetWidth = function(self, width)
+		self.frame:SetWidth(width)
+		self.frame.width = width
+		if self.OnWidthSet then
+			self:OnWidthSet(width)
+		end
+	end
+
+	WidgetBase.SetRelativeWidth = function(self, width)
+		if width <= 0 or width > 1 then
+			error(":SetRelativeWidth(width): Invalid relative width.", 2)
+		end
+		self.relWidth = width
+		self.width = "relative"
+	end
+
+	WidgetBase.SetHeight = function(self, height)
+		self.frame:SetHeight(height)
+		self.frame.height = height
+		if self.OnHeightSet then
+			self:OnHeightSet(height)
+		end
+	end
+
+	--[[ WidgetBase.SetRelativeHeight = function(self, height)
+		if height <= 0 or height > 1 then
+			error(":SetRelativeHeight(height): Invalid relative height.", 2)
+		end
+		self.relHeight = height
+		self.height = "relative"
+	end ]]
+
+	WidgetBase.IsVisible = function(self)
+		return self.frame:IsVisible()
+	end
+
+	WidgetBase.IsShown= function(self)
+		return self.frame:IsShown()
+	end
+
+	WidgetBase.Release = function(self)
+		AceGUI:Release(self)
+	end
+
+	WidgetBase.SetPoint = function(self, ...)
+		return self.frame:SetPoint(...)
+	end
+
+	WidgetBase.ClearAllPoints = function(self)
+		return self.frame:ClearAllPoints()
+	end
+
+	WidgetBase.GetNumPoints = function(self)
+		return self.frame:GetNumPoints()
+	end
+
+	WidgetBase.GetPoint = function(self, ...)
+		return self.frame:GetPoint(...)
+	end
+
+	WidgetBase.GetUserDataTable = function(self)
+		return self.userdata
+	end
+
+	WidgetBase.SetUserData = function(self, key, value)
+		self.userdata[key] = value
+	end
+
+	WidgetBase.GetUserData = function(self, key)
+		return self.userdata[key]
+	end
+
+	WidgetBase.IsFullHeight = function(self)
+		return self.height == "fill"
+	end
+
+	WidgetBase.SetFullHeight = function(self, isFull)
+		if isFull then
+			self.height = "fill"
+		else
+			self.height = nil
+		end
+	end
+
+	WidgetBase.IsFullWidth = function(self)
+		return self.width == "fill"
+	end
+
+	WidgetBase.SetFullWidth = function(self, isFull)
+		if isFull then
+			self.width = "fill"
+		else
+			self.width = nil
+		end
+	end
+
+--	local function LayoutOnUpdate(this)
+--		this:SetScript("OnUpdate",nil)
+--		this.obj:PerformLayout()
+--	end
+
+	local WidgetContainerBase = AceGUI.WidgetContainerBase
+
+	WidgetContainerBase.PauseLayout = function(self)
+		self.LayoutPaused = true
+	end
+
+	WidgetContainerBase.ResumeLayout = function(self)
+		self.LayoutPaused = nil
+	end
+
+	WidgetContainerBase.PerformLayout = function(self)
+		if self.LayoutPaused then
+			return
+		end
+		safecall(self.LayoutFunc, self.content, self.children)
+	end
+
+	--call this function to layout, makes sure layed out objects get a frame to get sizes etc
+	WidgetContainerBase.DoLayout = function(self)
+		self:PerformLayout()
+--		if not self.parent then
+--			self.frame:SetScript("OnUpdate", LayoutOnUpdate)
+--		end
+	end
+
+	WidgetContainerBase.AddChild = function(self, child, beforeWidget)
+		if beforeWidget then
+			local siblingIndex = 1
+			for _, widget in pairs(self.children) do
+				if widget == beforeWidget then
+					break
+				end
+				siblingIndex = siblingIndex + 1
+			end
+			tinsert(self.children, siblingIndex, child)
+		else
+			tinsert(self.children, child)
+		end
+		child:SetParent(self)
+		child.frame:Show()
+		self:DoLayout()
+	end
+
+	WidgetContainerBase.AddChildren = function(self, ...)
+		for i = 1, select("#", ...) do
+			local child = select(i, ...)
+			tinsert(self.children, child)
+			child:SetParent(self)
+			child.frame:Show()
+		end
+		self:DoLayout()
+	end
+
+	WidgetContainerBase.ReleaseChildren = function(self)
+		local children = self.children
+		for i = 1,#children do
+			AceGUI:Release(children[i])
+			children[i] = nil
+		end
+	end
+
+	WidgetContainerBase.SetLayout = function(self, Layout)
+		self.LayoutFunc = AceGUI:GetLayout(Layout)
+	end
+
+	WidgetContainerBase.SetAutoAdjustHeight = function(self, adjust)
+		if adjust then
+			self.noAutoHeight = nil
+		else
+			self.noAutoHeight = true
+		end
+	end
+
+	local function FrameResize(this)
+		local self = this.obj
+		if this:GetWidth() and this:GetHeight() then
+			if self.OnWidthSet then
+				self:OnWidthSet(this:GetWidth())
+			end
+			if self.OnHeightSet then
+				self:OnHeightSet(this:GetHeight())
+			end
+		end
+	end
+
+	local function ContentResize(this)
+		if this:GetWidth() and this:GetHeight() then
+			this.width = this:GetWidth()
+			this.height = this:GetHeight()
+			this.obj:DoLayout()
+		end
+	end
+
+	setmetatable(WidgetContainerBase, {__index=WidgetBase})
+
+	--One of these function should be called on each Widget Instance as part of its creation process
+
+	--- Register a widget-class as a container for newly created widgets.
+	-- @param widget The widget class
+	function AceGUI:RegisterAsContainer(widget)
+		widget.children = {}
+		widget.userdata = {}
+		widget.events = {}
+		widget.base = WidgetContainerBase
+		widget.content.obj = widget
+		widget.frame.obj = widget
+		widget.content:SetScript("OnSizeChanged", ContentResize)
+		widget.frame:SetScript("OnSizeChanged", FrameResize)
+		setmetatable(widget, {__index = WidgetContainerBase})
+		widget:SetLayout("List")
+		return widget
+	end
+
+	--- Register a widget-class as a widget.
+	-- @param widget The widget class
+	function AceGUI:RegisterAsWidget(widget)
+		widget.userdata = {}
+		widget.events = {}
+		widget.base = WidgetBase
+		widget.frame.obj = widget
+		widget.frame:SetScript("OnSizeChanged", FrameResize)
+		setmetatable(widget, {__index = WidgetBase})
+		return widget
+	end
+end
+
+
+
+
+------------------
+-- Widget API   --
+------------------
+
+--- Registers a widget Constructor, this function returns a new instance of the Widget
+-- @param Name The name of the widget
+-- @param Constructor The widget constructor function
+-- @param Version The version of the widget
+function AceGUI:RegisterWidgetType(Name, Constructor, Version)
+	assert(type(Constructor) == "function")
+	assert(type(Version) == "number")
+
+	local oldVersion = WidgetVersions[Name]
+	if oldVersion and oldVersion >= Version then return end
+
+	WidgetVersions[Name] = Version
+	WidgetRegistry[Name] = Constructor
+end
+
+--- Registers a Layout Function
+-- @param Name The name of the layout
+-- @param LayoutFunc Reference to the layout function
+function AceGUI:RegisterLayout(Name, LayoutFunc)
+	assert(type(LayoutFunc) == "function")
+	if type(Name) == "string" then
+		Name = Name:upper()
+	end
+	LayoutRegistry[Name] = LayoutFunc
+end
+
+--- Get a Layout Function from the registry
+-- @param Name The name of the layout
+function AceGUI:GetLayout(Name)
+	if type(Name) == "string" then
+		Name = Name:upper()
+	end
+	return LayoutRegistry[Name]
+end
+
+AceGUI.counts = AceGUI.counts or {}
+
+--- A type-based counter to count the number of widgets created.
+-- This is used by widgets that require a named frame, e.g. when a Blizzard
+-- Template requires it.
+-- @param type The widget type
+function AceGUI:GetNextWidgetNum(type)
+	if not self.counts[type] then
+		self.counts[type] = 0
+	end
+	self.counts[type] = self.counts[type] + 1
+	return self.counts[type]
+end
+
+--- Return the number of created widgets for this type.
+-- In contrast to GetNextWidgetNum, the number is not incremented.
+-- @param type The widget type
+function AceGUI:GetWidgetCount(type)
+	return self.counts[type] or 0
+end
+
+--- Return the version of the currently registered widget type.
+-- @param type The widget type
+function AceGUI:GetWidgetVersion(type)
+	return WidgetVersions[type]
+end
+
+-------------
+-- Layouts --
+-------------
+
+--[[
+	A Layout is a func that takes 2 parameters
+		content - the frame that widgets will be placed inside
+		children - a table containing the widgets to layout
+]]
+
+-- Very simple Layout, Children are stacked on top of each other down the left side
+AceGUI:RegisterLayout("List",
+	function(content, children)
+		local height = 0
+		local width = content.width or content:GetWidth() or 0
+		for i = 1, #children do
+			local child = children[i]
+
+			local frame = child.frame
+			frame:ClearAllPoints()
+			frame:Show()
+			if i == 1 then
+				frame:SetPoint("TOPLEFT", content)
+			else
+				frame:SetPoint("TOPLEFT", children[i-1].frame, "BOTTOMLEFT")
+			end
+
+			if child.width == "fill" then
+				child:SetWidth(width)
+				frame:SetPoint("RIGHT", content)
+
+				if child.DoLayout then
+					child:DoLayout()
+				end
+			elseif child.width == "relative" then
+				child:SetWidth(width * child.relWidth)
+
+				if child.DoLayout then
+					child:DoLayout()
+				end
+			end
+
+			height = height + (frame.height or frame:GetHeight() or 0)
+		end
+		safecall(content.obj.LayoutFinished, content.obj, nil, height)
+	end)
+
+-- A single control fills the whole content area
+AceGUI:RegisterLayout("Fill",
+	function(content, children)
+		if children[1] then
+			children[1]:SetWidth(content:GetWidth() or 0)
+			children[1]:SetHeight(content:GetHeight() or 0)
+			children[1].frame:SetAllPoints(content)
+			children[1].frame:Show()
+			safecall(content.obj.LayoutFinished, content.obj, nil, children[1].frame:GetHeight())
+		end
+	end)
+
+local layoutrecursionblock = nil
+local function safelayoutcall(object, func, ...)
+	layoutrecursionblock = true
+	object[func](object, ...)
+	layoutrecursionblock = nil
+end
+
+AceGUI:RegisterLayout("Flow",
+	function(content, children)
+		if layoutrecursionblock then return end
+		--used height so far
+		local height = 0
+		--width used in the current row
+		local usedwidth = 0
+		--height of the current row
+		local rowheight = 0
+		local rowoffset = 0
+		local lastrowoffset
+
+		local width = content.width or content:GetWidth() or 0
+
+		--control at the start of the row
+		local rowstart
+		local rowstartoffset
+		local lastrowstart
+		local isfullheight
+
+		local frameoffset
+		local lastframeoffset
+		local oversize
+		for i = 1, #children do
+			local child = children[i]
+			oversize = nil
+			local frame = child.frame
+			local frameheight = frame.height or frame:GetHeight() or 0
+			local framewidth = frame.width or frame:GetWidth() or 0
+			lastframeoffset = frameoffset
+			-- HACK: Why did we set a frameoffset of (frameheight / 2) ?
+			-- That was moving all widgets half the widgets size down, is that intended?
+			-- Actually, it seems to be neccessary for many cases, we'll leave it in for now.
+			-- If widgets seem to anchor weirdly with this, provide a valid alignoffset for them.
+			-- TODO: Investigate moar!
+			frameoffset = child.alignoffset or (frameheight / 2)
+
+			if child.width == "relative" then
+				framewidth = width * child.relWidth
+			end
+
+			frame:Show()
+			frame:ClearAllPoints()
+			if i == 1 then
+				-- anchor the first control to the top left
+				frame:SetPoint("TOPLEFT", content)
+				rowheight = frameheight
+				rowoffset = frameoffset
+				rowstart = frame
+				rowstartoffset = frameoffset
+				usedwidth = framewidth
+				if usedwidth > width then
+					oversize = true
+				end
+			else
+				-- if there isn't available width for the control start a new row
+				-- if a control is "fill" it will be on a row of its own full width
+				if usedwidth == 0 or ((framewidth) + usedwidth > width) or child.width == "fill" then
+					if isfullheight then
+						-- a previous row has already filled the entire height, there's nothing we can usefully do anymore
+						-- (maybe error/warn about this?)
+						break
+					end
+					--anchor the previous row, we will now know its height and offset
+					rowstart:SetPoint("TOPLEFT", content, "TOPLEFT", 0, -(height + (rowoffset - rowstartoffset) + 3))
+					height = height + rowheight + 3
+					--save this as the rowstart so we can anchor it after the row is complete and we have the max height and offset of controls in it
+					rowstart = frame
+					rowstartoffset = frameoffset
+					rowheight = frameheight
+					rowoffset = frameoffset
+					usedwidth = framewidth
+					if usedwidth > width then
+						oversize = true
+					end
+				-- put the control on the current row, adding it to the width and checking if the height needs to be increased
+				else
+					--handles cases where the new height is higher than either control because of the offsets
+					--math.max(rowheight-rowoffset+frameoffset, frameheight-frameoffset+rowoffset)
+
+					--offset is always the larger of the two offsets
+					rowoffset = math_max(rowoffset, frameoffset)
+					rowheight = math_max(rowheight, rowoffset + (frameheight / 2))
+
+					frame:SetPoint("TOPLEFT", children[i-1].frame, "TOPRIGHT", 0, frameoffset - lastframeoffset)
+					usedwidth = framewidth + usedwidth
+				end
+			end
+
+			if child.width == "fill" then
+				safelayoutcall(child, "SetWidth", width)
+				frame:SetPoint("RIGHT", content)
+
+				usedwidth = 0
+				rowstart = frame
+				rowstartoffset = frameoffset
+
+				if child.DoLayout then
+					child:DoLayout()
+				end
+				rowheight = frame.height or frame:GetHeight() or 0
+				rowoffset = child.alignoffset or (rowheight / 2)
+				rowstartoffset = rowoffset
+			elseif child.width == "relative" then
+				safelayoutcall(child, "SetWidth", width * child.relWidth)
+
+				if child.DoLayout then
+					child:DoLayout()
+				end
+			elseif oversize then
+				if width > 1 then
+					frame:SetPoint("RIGHT", content)
+				end
+			end
+
+			if child.height == "fill" then
+				frame:SetPoint("BOTTOM", content)
+				isfullheight = true
+			end
+		end
+
+		--anchor the last row, if its full height needs a special case since  its height has just been changed by the anchor
+		if isfullheight then
+			rowstart:SetPoint("TOPLEFT", content, "TOPLEFT", 0, -height)
+		elseif rowstart then
+			rowstart:SetPoint("TOPLEFT", content, "TOPLEFT", 0, -(height + (rowoffset - rowstartoffset) + 3))
+		end
+
+		height = height + rowheight + 3
+		safecall(content.obj.LayoutFinished, content.obj, nil, height)
+	end)
diff --git a/SVUI_!Core/libs/AceGUI-3.0/AceGUI-3.0.xml b/SVUI_!Core/libs/AceGUI-3.0/AceGUI-3.0.xml
new file mode 100644
index 0000000..b515077
--- /dev/null
+++ b/SVUI_!Core/libs/AceGUI-3.0/AceGUI-3.0.xml
@@ -0,0 +1,28 @@
+<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="AceGUI-3.0.lua"/>
+	<!-- Container -->
+	<Script file="widgets\AceGUIContainer-BlizOptionsGroup.lua"/>
+	<Script file="widgets\AceGUIContainer-DropDownGroup.lua"/>
+	<Script file="widgets\AceGUIContainer-Frame.lua"/>
+	<Script file="widgets\AceGUIContainer-InlineGroup.lua"/>
+	<Script file="widgets\AceGUIContainer-ScrollFrame.lua"/>
+	<Script file="widgets\AceGUIContainer-SimpleGroup.lua"/>
+	<Script file="widgets\AceGUIContainer-TabGroup.lua"/>
+	<Script file="widgets\AceGUIContainer-TreeGroup.lua"/>
+	<Script file="widgets\AceGUIContainer-Window.lua"/>
+	<!-- Widgets -->
+	<Script file="widgets\AceGUIWidget-Button.lua"/>
+	<Script file="widgets\AceGUIWidget-CheckBox.lua"/>
+	<Script file="widgets\AceGUIWidget-ColorPicker.lua"/>
+	<Script file="widgets\AceGUIWidget-DropDown.lua"/>
+	<Script file="widgets\AceGUIWidget-DropDown-Items.lua"/>
+	<Script file="widgets\AceGUIWidget-EditBox.lua"/>
+	<Script file="widgets\AceGUIWidget-Heading.lua"/>
+	<Script file="widgets\AceGUIWidget-Icon.lua"/>
+	<Script file="widgets\AceGUIWidget-InteractiveLabel.lua"/>
+	<Script file="widgets\AceGUIWidget-Keybinding.lua"/>
+	<Script file="widgets\AceGUIWidget-Label.lua"/>
+	<Script file="widgets\AceGUIWidget-MultiLineEditBox.lua"/>
+	<Script file="widgets\AceGUIWidget-Slider.lua"/>
+</Ui>
diff --git a/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-BlizOptionsGroup.lua b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-BlizOptionsGroup.lua
new file mode 100644
index 0000000..9a48f8b
--- /dev/null
+++ b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-BlizOptionsGroup.lua
@@ -0,0 +1,138 @@
+--[[-----------------------------------------------------------------------------
+BlizOptionsGroup Container
+Simple container widget for the integration of AceGUI into the Blizzard Interface Options
+-------------------------------------------------------------------------------]]
+local Type, Version = "BlizOptionsGroup", 21
+local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
+if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
+
+-- Lua APIs
+local pairs = pairs
+
+-- WoW APIs
+local CreateFrame = CreateFrame
+
+--[[-----------------------------------------------------------------------------
+Scripts
+-------------------------------------------------------------------------------]]
+
+local function OnShow(frame)
+	frame.obj:Fire("OnShow")
+end
+
+local function OnHide(frame)
+	frame.obj:Fire("OnHide")
+end
+
+--[[-----------------------------------------------------------------------------
+Support functions
+-------------------------------------------------------------------------------]]
+
+local function okay(frame)
+	frame.obj:Fire("okay")
+end
+
+local function cancel(frame)
+	frame.obj:Fire("cancel")
+end
+
+local function default(frame)
+	frame.obj:Fire("default")
+end
+
+local function refresh(frame)
+	frame.obj:Fire("refresh")
+end
+
+--[[-----------------------------------------------------------------------------
+Methods
+-------------------------------------------------------------------------------]]
+
+local methods = {
+	["OnAcquire"] = function(self)
+		self:SetName()
+		self:SetTitle()
+	end,
+
+	-- ["OnRelease"] = nil,
+
+	["OnWidthSet"] = function(self, width)
+		local content = self.content
+		local contentwidth = width - 63
+		if contentwidth < 0 then
+			contentwidth = 0
+		end
+		content:SetWidth(contentwidth)
+		content.width = contentwidth
+	end,
+
+	["OnHeightSet"] = function(self, height)
+		local content = self.content
+		local contentheight = height - 26
+		if contentheight < 0 then
+			contentheight = 0
+		end
+		content:SetHeight(contentheight)
+		content.height = contentheight
+	end,
+
+	["SetName"] = function(self, name, parent)
+		self.frame.name = name
+		self.frame.parent = parent
+	end,
+
+	["SetTitle"] = function(self, title)
+		local content = self.content
+		content:ClearAllPoints()
+		if not title or title == "" then
+			content:SetPoint("TOPLEFT", 10, -10)
+			self.label:SetText("")
+		else
+			content:SetPoint("TOPLEFT", 10, -40)
+			self.label:SetText(title)
+		end
+		content:SetPoint("BOTTOMRIGHT", -10, 10)
+	end
+}
+
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+local function Constructor()
+	local frame = CreateFrame("Frame")
+	frame:Hide()
+
+	-- support functions for the Blizzard Interface Options
+	frame.okay = okay
+	frame.cancel = cancel
+	frame.default = default
+	frame.refresh = refresh
+
+	frame:SetScript("OnHide", OnHide)
+	frame:SetScript("OnShow", OnShow)
+
+	local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
+	label:SetPoint("TOPLEFT", 10, -15)
+	label:SetPoint("BOTTOMRIGHT", frame, "TOPRIGHT", 10, -45)
+	label:SetJustifyH("LEFT")
+	label:SetJustifyV("TOP")
+
+	--Container Support
+	local content = CreateFrame("Frame", nil, frame)
+	content:SetPoint("TOPLEFT", 10, -10)
+	content:SetPoint("BOTTOMRIGHT", -10, 10)
+
+	local widget = {
+		label   = label,
+		frame   = frame,
+		content = content,
+		type    = Type
+	}
+	for method, func in pairs(methods) do
+		widget[method] = func
+	end
+
+	return AceGUI:RegisterAsContainer(widget)
+end
+
+AceGUI:RegisterWidgetType(Type, Constructor, Version)
diff --git a/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-DropDownGroup.lua b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-DropDownGroup.lua
new file mode 100644
index 0000000..b0f81b7
--- /dev/null
+++ b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-DropDownGroup.lua
@@ -0,0 +1,157 @@
+--[[-----------------------------------------------------------------------------
+DropdownGroup Container
+Container controlled by a dropdown on the top.
+-------------------------------------------------------------------------------]]
+local Type, Version = "DropdownGroup", 21
+local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
+if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
+
+-- Lua APIs
+local assert, pairs, type = assert, pairs, type
+
+-- WoW APIs
+local CreateFrame = CreateFrame
+
+--[[-----------------------------------------------------------------------------
+Scripts
+-------------------------------------------------------------------------------]]
+local function SelectedGroup(self, event, value)
+	local group = self.parentgroup
+	local status = group.status or group.localstatus
+	status.selected = value
+	self.parentgroup:Fire("OnGroupSelected", value)
+end
+
+--[[-----------------------------------------------------------------------------
+Methods
+-------------------------------------------------------------------------------]]
+local methods = {
+	["OnAcquire"] = function(self)
+		self.dropdown:SetText("")
+		self:SetDropdownWidth(200)
+		self:SetTitle("")
+	end,
+
+	["OnRelease"] = function(self)
+		self.dropdown.list = nil
+		self.status = nil
+		for k in pairs(self.localstatus) do
+			self.localstatus[k] = nil
+		end
+	end,
+
+	["SetTitle"] = function(self, title)
+		self.titletext:SetText(title)
+		self.dropdown.frame:ClearAllPoints()
+		if title and title ~= "" then
+			self.dropdown.frame:SetPoint("TOPRIGHT", -2, 0)
+		else
+			self.dropdown.frame:SetPoint("TOPLEFT", -1, 0)
+		end
+	end,
+
+	["SetGroupList"] = function(self,list,order)
+		self.dropdown:SetList(list,order)
+	end,
+
+	["SetStatusTable"] = function(self, status)
+		assert(type(status) == "table")
+		self.status = status
+	end,
+
+	["SetGroup"] = function(self,group)
+		self.dropdown:SetValue(group)
+		local status = self.status or self.localstatus
+		status.selected = group
+		self:Fire("OnGroupSelected", group)
+	end,
+
+	["OnWidthSet"] = function(self, width)
+		local content = self.content
+		local contentwidth = width - 26
+		if contentwidth < 0 then
+			contentwidth = 0
+		end
+		content:SetWidth(contentwidth)
+		content.width = contentwidth
+	end,
+
+	["OnHeightSet"] = function(self, height)
+		local content = self.content
+		local contentheight = height - 63
+		if contentheight < 0 then
+			contentheight = 0
+		end
+		content:SetHeight(contentheight)
+		content.height = contentheight
+	end,
+
+	["LayoutFinished"] = function(self, width, height)
+		self:SetHeight((height or 0) + 63)
+	end,
+
+	["SetDropdownWidth"] = function(self, width)
+		self.dropdown:SetWidth(width)
+	end
+}
+
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+local PaneBackdrop  = {
+	bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
+	edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
+	tile = true, tileSize = 16, edgeSize = 16,
+	insets = { left = 3, right = 3, top = 5, bottom = 3 }
+}
+
+local function Constructor()
+	local frame = CreateFrame("Frame")
+	frame:SetHeight(100)
+	frame:SetWidth(100)
+	frame:SetFrameStrata("FULLSCREEN_DIALOG")
+
+	local titletext = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
+	titletext:SetPoint("TOPLEFT", 4, -5)
+	titletext:SetPoint("TOPRIGHT", -4, -5)
+	titletext:SetJustifyH("LEFT")
+	titletext:SetHeight(18)
+
+	local dropdown = AceGUI:Create("Dropdown")
+	dropdown.frame:SetParent(frame)
+	dropdown.frame:SetFrameLevel(dropdown.frame:GetFrameLevel() + 2)
+	dropdown:SetCallback("OnValueChanged", SelectedGroup)
+	dropdown.frame:SetPoint("TOPLEFT", -1, 0)
+	dropdown.frame:Show()
+	dropdown:SetLabel("")
+
+	local border = CreateFrame("Frame", nil, frame)
+	border:SetPoint("TOPLEFT", 0, -26)
+	border:SetPoint("BOTTOMRIGHT", 0, 3)
+	border:SetBackdrop(PaneBackdrop)
+	border:SetBackdropColor(0.1,0.1,0.1,0.5)
+	border:SetBackdropBorderColor(0.4,0.4,0.4)
+
+	--Container Support
+	local content = CreateFrame("Frame", nil, border)
+	content:SetPoint("TOPLEFT", 10, -10)
+	content:SetPoint("BOTTOMRIGHT", -10, 10)
+
+	local widget = {
+		frame       = frame,
+		localstatus = {},
+		titletext   = titletext,
+		dropdown    = dropdown,
+		border      = border,
+		content     = content,
+		type        = Type
+	}
+	for method, func in pairs(methods) do
+		widget[method] = func
+	end
+	dropdown.parentgroup = widget
+
+	return AceGUI:RegisterAsContainer(widget)
+end
+
+AceGUI:RegisterWidgetType(Type, Constructor, Version)
diff --git a/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-Frame.lua b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-Frame.lua
new file mode 100644
index 0000000..0dae68c
--- /dev/null
+++ b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-Frame.lua
@@ -0,0 +1,311 @@
+--[[-----------------------------------------------------------------------------
+Frame Container
+-------------------------------------------------------------------------------]]
+local Type, Version = "Frame", 24
+local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
+if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
+
+-- Lua APIs
+local pairs, assert, type = pairs, assert, type
+local wipe = table.wipe
+
+-- WoW APIs
+local PlaySound = PlaySound
+local CreateFrame, UIParent = CreateFrame, UIParent
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: CLOSE
+
+--[[-----------------------------------------------------------------------------
+Scripts
+-------------------------------------------------------------------------------]]
+local function Button_OnClick(frame)
+	PlaySound("gsTitleOptionExit")
+	frame.obj:Hide()
+end
+
+local function Frame_OnClose(frame)
+	frame.obj:Fire("OnClose")
+end
+
+local function Frame_OnMouseDown(frame)
+	AceGUI:ClearFocus()
+end
+
+local function Title_OnMouseDown(frame)
+	frame:GetParent():StartMoving()
+	AceGUI:ClearFocus()
+end
+
+local function MoverSizer_OnMouseUp(mover)
+	local frame = mover:GetParent()
+	frame:StopMovingOrSizing()
+	local self = frame.obj
+	local status = self.status or self.localstatus
+	status.width = frame:GetWidth()
+	status.height = frame:GetHeight()
+	status.top = frame:GetTop()
+	status.left = frame:GetLeft()
+end
+
+local function SizerSE_OnMouseDown(frame)
+	frame:GetParent():StartSizing("BOTTOMRIGHT")
+	AceGUI:ClearFocus()
+end
+
+local function SizerS_OnMouseDown(frame)
+	frame:GetParent():StartSizing("BOTTOM")
+	AceGUI:ClearFocus()
+end
+
+local function SizerE_OnMouseDown(frame)
+	frame:GetParent():StartSizing("RIGHT")
+	AceGUI:ClearFocus()
+end
+
+local function StatusBar_OnEnter(frame)
+	frame.obj:Fire("OnEnterStatusBar")
+end
+
+local function StatusBar_OnLeave(frame)
+	frame.obj:Fire("OnLeaveStatusBar")
+end
+
+--[[-----------------------------------------------------------------------------
+Methods
+-------------------------------------------------------------------------------]]
+local methods = {
+	["OnAcquire"] = function(self)
+		self.frame:SetParent(UIParent)
+		self.frame:SetFrameStrata("FULLSCREEN_DIALOG")
+		self:SetTitle()
+		self:SetStatusText()
+		self:ApplyStatus()
+		self:Show()
+        self:EnableResize(true)
+	end,
+
+	["OnRelease"] = function(self)
+		self.status = nil
+		wipe(self.localstatus)
+	end,
+
+	["OnWidthSet"] = function(self, width)
+		local content = self.content
+		local contentwidth = width - 34
+		if contentwidth < 0 then
+			contentwidth = 0
+		end
+		content:SetWidth(contentwidth)
+		content.width = contentwidth
+	end,
+
+	["OnHeightSet"] = function(self, height)
+		local content = self.content
+		local contentheight = height - 57
+		if contentheight < 0 then
+			contentheight = 0
+		end
+		content:SetHeight(contentheight)
+		content.height = contentheight
+	end,
+
+	["SetTitle"] = function(self, title)
+		self.titletext:SetText(title)
+		self.titlebg:SetWidth((self.titletext:GetWidth() or 0) + 10)
+	end,
+
+	["SetStatusText"] = function(self, text)
+		self.statustext:SetText(text)
+	end,
+
+	["Hide"] = function(self)
+		self.frame:Hide()
+	end,
+
+	["Show"] = function(self)
+		self.frame:Show()
+	end,
+
+	["EnableResize"] = function(self, state)
+		local func = state and "Show" or "Hide"
+		self.sizer_se[func](self.sizer_se)
+		self.sizer_s[func](self.sizer_s)
+		self.sizer_e[func](self.sizer_e)
+	end,
+
+	-- called to set an external table to store status in
+	["SetStatusTable"] = function(self, status)
+		assert(type(status) == "table")
+		self.status = status
+		self:ApplyStatus()
+	end,
+
+	["ApplyStatus"] = function(self)
+		local status = self.status or self.localstatus
+		local frame = self.frame
+		self:SetWidth(status.width or 700)
+		self:SetHeight(status.height or 500)
+		frame:ClearAllPoints()
+		if status.top and status.left then
+			frame:SetPoint("TOP", UIParent, "BOTTOM", 0, status.top)
+			frame:SetPoint("LEFT", UIParent, "LEFT", status.left, 0)
+		else
+			frame:SetPoint("CENTER")
+		end
+	end
+}
+
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+local FrameBackdrop = {
+	bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
+	edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
+	tile = true, tileSize = 32, edgeSize = 32,
+	insets = { left = 8, right = 8, top = 8, bottom = 8 }
+}
+
+local PaneBackdrop  = {
+	bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
+	edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
+	tile = true, tileSize = 16, edgeSize = 16,
+	insets = { left = 3, right = 3, top = 5, bottom = 3 }
+}
+
+local function Constructor()
+	local frame = CreateFrame("Frame", nil, UIParent)
+	frame:Hide()
+
+	frame:EnableMouse(true)
+	frame:SetMovable(true)
+	frame:SetResizable(true)
+	frame:SetFrameStrata("FULLSCREEN_DIALOG")
+	frame:SetBackdrop(FrameBackdrop)
+	frame:SetBackdropColor(0, 0, 0, 1)
+	frame:SetMinResize(400, 200)
+	frame:SetToplevel(true)
+	frame:SetScript("OnHide", Frame_OnClose)
+	frame:SetScript("OnMouseDown", Frame_OnMouseDown)
+
+	local closebutton = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
+	closebutton:SetScript("OnClick", Button_OnClick)
+	closebutton:SetPoint("BOTTOMRIGHT", -27, 17)
+	closebutton:SetHeight(20)
+	closebutton:SetWidth(100)
+	closebutton:SetText(CLOSE)
+
+	local statusbg = CreateFrame("Button", nil, frame)
+	statusbg:SetPoint("BOTTOMLEFT", 15, 15)
+	statusbg:SetPoint("BOTTOMRIGHT", -132, 15)
+	statusbg:SetHeight(24)
+	statusbg:SetBackdrop(PaneBackdrop)
+	statusbg:SetBackdropColor(0.1,0.1,0.1)
+	statusbg:SetBackdropBorderColor(0.4,0.4,0.4)
+	statusbg:SetScript("OnEnter", StatusBar_OnEnter)
+	statusbg:SetScript("OnLeave", StatusBar_OnLeave)
+
+	local statustext = statusbg:CreateFontString(nil, "OVERLAY", "GameFontNormal")
+	statustext:SetPoint("TOPLEFT", 7, -2)
+	statustext:SetPoint("BOTTOMRIGHT", -7, 2)
+	statustext:SetHeight(20)
+	statustext:SetJustifyH("LEFT")
+	statustext:SetText("")
+
+	local titlebg = frame:CreateTexture(nil, "OVERLAY")
+	titlebg:SetTexture("Interface\\DialogFrame\\UI-DialogBox-Header")
+	titlebg:SetTexCoord(0.31, 0.67, 0, 0.63)
+	titlebg:SetPoint("TOP", 0, 12)
+	titlebg:SetWidth(100)
+	titlebg:SetHeight(40)
+
+	local title = CreateFrame("Frame", nil, frame)
+	title:EnableMouse(true)
+	title:SetScript("OnMouseDown", Title_OnMouseDown)
+	title:SetScript("OnMouseUp", MoverSizer_OnMouseUp)
+	title:SetAllPoints(titlebg)
+
+	local titletext = title:CreateFontString(nil, "OVERLAY", "GameFontNormal")
+	titletext:SetPoint("TOP", titlebg, "TOP", 0, -14)
+
+	local titlebg_l = frame:CreateTexture(nil, "OVERLAY")
+	titlebg_l:SetTexture("Interface\\DialogFrame\\UI-DialogBox-Header")
+	titlebg_l:SetTexCoord(0.21, 0.31, 0, 0.63)
+	titlebg_l:SetPoint("RIGHT", titlebg, "LEFT")
+	titlebg_l:SetWidth(30)
+	titlebg_l:SetHeight(40)
+
+	local titlebg_r = frame:CreateTexture(nil, "OVERLAY")
+	titlebg_r:SetTexture("Interface\\DialogFrame\\UI-DialogBox-Header")
+	titlebg_r:SetTexCoord(0.67, 0.77, 0, 0.63)
+	titlebg_r:SetPoint("LEFT", titlebg, "RIGHT")
+	titlebg_r:SetWidth(30)
+	titlebg_r:SetHeight(40)
+
+	local sizer_se = CreateFrame("Frame", nil, frame)
+	sizer_se:SetPoint("BOTTOMRIGHT")
+	sizer_se:SetWidth(25)
+	sizer_se:SetHeight(25)
+	sizer_se:EnableMouse()
+	sizer_se:SetScript("OnMouseDown",SizerSE_OnMouseDown)
+	sizer_se:SetScript("OnMouseUp", MoverSizer_OnMouseUp)
+
+	local line1 = sizer_se:CreateTexture(nil, "BACKGROUND")
+	line1:SetWidth(14)
+	line1:SetHeight(14)
+	line1:SetPoint("BOTTOMRIGHT", -8, 8)
+	line1:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border")
+	local x = 0.1 * 14/17
+	line1:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5)
+
+	local line2 = sizer_se:CreateTexture(nil, "BACKGROUND")
+	line2:SetWidth(8)
+	line2:SetHeight(8)
+	line2:SetPoint("BOTTOMRIGHT", -8, 8)
+	line2:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border")
+	local x = 0.1 * 8/17
+	line2:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5)
+
+	local sizer_s = CreateFrame("Frame", nil, frame)
+	sizer_s:SetPoint("BOTTOMRIGHT", -25, 0)
+	sizer_s:SetPoint("BOTTOMLEFT")
+	sizer_s:SetHeight(25)
+	sizer_s:EnableMouse(true)
+	sizer_s:SetScript("OnMouseDown", SizerS_OnMouseDown)
+	sizer_s:SetScript("OnMouseUp", MoverSizer_OnMouseUp)
+
+	local sizer_e = CreateFrame("Frame", nil, frame)
+	sizer_e:SetPoint("BOTTOMRIGHT", 0, 25)
+	sizer_e:SetPoint("TOPRIGHT")
+	sizer_e:SetWidth(25)
+	sizer_e:EnableMouse(true)
+	sizer_e:SetScript("OnMouseDown", SizerE_OnMouseDown)
+	sizer_e:SetScript("OnMouseUp", MoverSizer_OnMouseUp)
+
+	--Container Support
+	local content = CreateFrame("Frame", nil, frame)
+	content:SetPoint("TOPLEFT", 17, -27)
+	content:SetPoint("BOTTOMRIGHT", -17, 40)
+
+	local widget = {
+		localstatus = {},
+		titletext   = titletext,
+		statustext  = statustext,
+		titlebg     = titlebg,
+		sizer_se    = sizer_se,
+		sizer_s     = sizer_s,
+		sizer_e     = sizer_e,
+		content     = content,
+		frame       = frame,
+		type        = Type
+	}
+	for method, func in pairs(methods) do
+		widget[method] = func
+	end
+	closebutton.obj, statusbg.obj = widget, widget
+
+	return AceGUI:RegisterAsContainer(widget)
+end
+
+AceGUI:RegisterWidgetType(Type, Constructor, Version)
diff --git a/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-InlineGroup.lua b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-InlineGroup.lua
new file mode 100644
index 0000000..f3db7d6
--- /dev/null
+++ b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-InlineGroup.lua
@@ -0,0 +1,103 @@
+--[[-----------------------------------------------------------------------------
+InlineGroup Container
+Simple container widget that creates a visible "box" with an optional title.
+-------------------------------------------------------------------------------]]
+local Type, Version = "InlineGroup", 21
+local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
+if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
+
+-- Lua APIs
+local pairs = pairs
+
+-- WoW APIs
+local CreateFrame, UIParent = CreateFrame, UIParent
+
+--[[-----------------------------------------------------------------------------
+Methods
+-------------------------------------------------------------------------------]]
+local methods = {
+	["OnAcquire"] = function(self)
+		self:SetWidth(300)
+		self:SetHeight(100)
+		self:SetTitle("")
+	end,
+
+	-- ["OnRelease"] = nil,
+
+	["SetTitle"] = function(self,title)
+		self.titletext:SetText(title)
+	end,
+
+
+	["LayoutFinished"] = function(self, width, height)
+		if self.noAutoHeight then return end
+		self:SetHeight((height or 0) + 40)
+	end,
+
+	["OnWidthSet"] = function(self, width)
+		local content = self.content
+		local contentwidth = width - 20
+		if contentwidth < 0 then
+			contentwidth = 0
+		end
+		content:SetWidth(contentwidth)
+		content.width = contentwidth
+	end,
+
+	["OnHeightSet"] = function(self, height)
+		local content = self.content
+		local contentheight = height - 20
+		if contentheight < 0 then
+			contentheight = 0
+		end
+		content:SetHeight(contentheight)
+		content.height = contentheight
+	end
+}
+
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+local PaneBackdrop  = {
+	bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
+	edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
+	tile = true, tileSize = 16, edgeSize = 16,
+	insets = { left = 3, right = 3, top = 5, bottom = 3 }
+}
+
+local function Constructor()
+	local frame = CreateFrame("Frame", nil, UIParent)
+	frame:SetFrameStrata("FULLSCREEN_DIALOG")
+
+	local titletext = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
+	titletext:SetPoint("TOPLEFT", 14, 0)
+	titletext:SetPoint("TOPRIGHT", -14, 0)
+	titletext:SetJustifyH("LEFT")
+	titletext:SetHeight(18)
+
+	local border = CreateFrame("Frame", nil, frame)
+	border:SetPoint("TOPLEFT", 0, -17)
+	border:SetPoint("BOTTOMRIGHT", -1, 3)
+	border:SetBackdrop(PaneBackdrop)
+	border:SetBackdropColor(0.1, 0.1, 0.1, 0.5)
+	border:SetBackdropBorderColor(0.4, 0.4, 0.4)
+
+	--Container Support
+	local content = CreateFrame("Frame", nil, border)
+	content:SetPoint("TOPLEFT", 10, -10)
+	content:SetPoint("BOTTOMRIGHT", -10, 10)
+
+	local widget = {
+		frame     = frame,
+		content   = content,
+		titletext = titletext,
+		type      = Type
+	}
+	for method, func in pairs(methods) do
+		widget[method] = func
+	end
+
+	return AceGUI:RegisterAsContainer(widget)
+end
+
+AceGUI:RegisterWidgetType(Type, Constructor, Version)
diff --git a/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-ScrollFrame.lua b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-ScrollFrame.lua
new file mode 100644
index 0000000..a1c6a57
--- /dev/null
+++ b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-ScrollFrame.lua
@@ -0,0 +1,204 @@
+--[[-----------------------------------------------------------------------------
+ScrollFrame Container
+Plain container that scrolls its content and doesn't grow in height.
+-------------------------------------------------------------------------------]]
+local Type, Version = "ScrollFrame", 23
+local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
+if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
+
+-- Lua APIs
+local pairs, assert, type = pairs, assert, type
+local min, max, floor, abs = math.min, math.max, math.floor, math.abs
+
+-- WoW APIs
+local CreateFrame, UIParent = CreateFrame, UIParent
+
+--[[-----------------------------------------------------------------------------
+Support functions
+-------------------------------------------------------------------------------]]
+local function FixScrollOnUpdate(frame)
+	frame:SetScript("OnUpdate", nil)
+	frame.obj:FixScroll()
+end
+
+--[[-----------------------------------------------------------------------------
+Scripts
+-------------------------------------------------------------------------------]]
+local function ScrollFrame_OnMouseWheel(frame, value)
+	frame.obj:MoveScroll(value)
+end
+
+local function ScrollFrame_OnSizeChanged(frame)
+	frame:SetScript("OnUpdate", FixScrollOnUpdate)
+end
+
+local function ScrollBar_OnScrollValueChanged(frame, value)
+	frame.obj:SetScroll(value)
+end
+
+--[[-----------------------------------------------------------------------------
+Methods
+-------------------------------------------------------------------------------]]
+local methods = {
+	["OnAcquire"] = function(self)
+		self:SetScroll(0)
+		self.scrollframe:SetScript("OnUpdate", FixScrollOnUpdate)
+	end,
+
+	["OnRelease"] = function(self)
+		self.status = nil
+		for k in pairs(self.localstatus) do
+			self.localstatus[k] = nil
+		end
+		self.scrollframe:SetPoint("BOTTOMRIGHT")
+		self.scrollbar:Hide()
+		self.scrollBarShown = nil
+		self.content.height, self.content.width = nil, nil
+	end,
+
+	["SetScroll"] = function(self, value)
+		local status = self.status or self.localstatus
+		local viewheight = self.scrollframe:GetHeight()
+		local height = self.content:GetHeight()
+		local offset
+
+		if viewheight > height then
+			offset = 0
+		else
+			offset = floor((height - viewheight) / 1000.0 * value)
+		end
+		self.content:ClearAllPoints()
+		self.content:SetPoint("TOPLEFT", 0, offset)
+		self.content:SetPoint("TOPRIGHT", 0, offset)
+		status.offset = offset
+		status.scrollvalue = value
+	end,
+
+	["MoveScroll"] = function(self, value)
+		local status = self.status or self.localstatus
+		local height, viewheight = self.scrollframe:GetHeight(), self.content:GetHeight()
+
+		if self.scrollBarShown then
+			local diff = height - viewheight
+			local delta = 1
+			if value < 0 then
+				delta = -1
+			end
+			self.scrollbar:SetValue(min(max(status.scrollvalue + delta*(1000/(diff/45)),0), 1000))
+		end
+	end,
+
+	["FixScroll"] = function(self)
+		if self.updateLock then return end
+		self.updateLock = true
+		local status = self.status or self.localstatus
+		local height, viewheight = self.scrollframe:GetHeight(), self.content:GetHeight()
+		local offset = status.offset or 0
+		local curvalue = self.scrollbar:GetValue()
+		-- Give us a margin of error of 2 pixels to stop some conditions that i would blame on floating point inaccuracys
+		-- No-one is going to miss 2 pixels at the bottom of the frame, anyhow!
+		if viewheight < height + 2 then
+			if self.scrollBarShown then
+				self.scrollBarShown = nil
+				self.scrollbar:Hide()
+				self.scrollbar:SetValue(0)
+				self.scrollframe:SetPoint("BOTTOMRIGHT")
+				self:DoLayout()
+			end
+		else
+			if not self.scrollBarShown then
+				self.scrollBarShown = true
+				self.scrollbar:Show()
+				self.scrollframe:SetPoint("BOTTOMRIGHT", -20, 0)
+				self:DoLayout()
+			end
+			local value = (offset / (viewheight - height) * 1000)
+			if value > 1000 then value = 1000 end
+			self.scrollbar:SetValue(value)
+			self:SetScroll(value)
+			if value < 1000 then
+				self.content:ClearAllPoints()
+				self.content:SetPoint("TOPLEFT", 0, offset)
+				self.content:SetPoint("TOPRIGHT", 0, offset)
+				status.offset = offset
+			end
+		end
+		self.updateLock = nil
+	end,
+
+	["LayoutFinished"] = function(self, width, height)
+		self.content:SetHeight(height or 0 + 20)
+		self.scrollframe:SetScript("OnUpdate", FixScrollOnUpdate)
+	end,
+
+	["SetStatusTable"] = function(self, status)
+		assert(type(status) == "table")
+		self.status = status
+		if not status.scrollvalue then
+			status.scrollvalue = 0
+		end
+	end,
+
+	["OnWidthSet"] = function(self, width)
+		local content = self.content
+		content.width = width
+	end,
+
+	["OnHeightSet"] = function(self, height)
+		local content = self.content
+		content.height = height
+	end
+}
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+local function Constructor()
+	local frame = CreateFrame("Frame", nil, UIParent)
+	local num = AceGUI:GetNextWidgetNum(Type)
+
+	local scrollframe = CreateFrame("ScrollFrame", nil, frame)
+	scrollframe:SetPoint("TOPLEFT")
+	scrollframe:SetPoint("BOTTOMRIGHT")
+	scrollframe:EnableMouseWheel(true)
+	scrollframe:SetScript("OnMouseWheel", ScrollFrame_OnMouseWheel)
+	scrollframe:SetScript("OnSizeChanged", ScrollFrame_OnSizeChanged)
+
+	local scrollbar = CreateFrame("Slider", ("AceConfigDialogScrollFrame%dScrollBar"):format(num), scrollframe, "UIPanelScrollBarTemplate")
+	scrollbar:SetPoint("TOPLEFT", scrollframe, "TOPRIGHT", 4, -16)
+	scrollbar:SetPoint("BOTTOMLEFT", scrollframe, "BOTTOMRIGHT", 4, 16)
+	scrollbar:SetMinMaxValues(0, 1000)
+	scrollbar:SetValueStep(1)
+	scrollbar:SetValue(0)
+	scrollbar:SetWidth(16)
+	scrollbar:Hide()
+	-- set the script as the last step, so it doesn't fire yet
+	scrollbar:SetScript("OnValueChanged", ScrollBar_OnScrollValueChanged)
+
+	local scrollbg = scrollbar:CreateTexture(nil, "BACKGROUND")
+	scrollbg:SetAllPoints(scrollbar)
+	scrollbg:SetColorTexture(0, 0, 0, 0.4)
+
+	--Container Support
+	local content = CreateFrame("Frame", nil, scrollframe)
+	content:SetPoint("TOPLEFT")
+	content:SetPoint("TOPRIGHT")
+	content:SetHeight(400)
+	scrollframe:SetScrollChild(content)
+
+	local widget = {
+		localstatus = { scrollvalue = 0 },
+		scrollframe = scrollframe,
+		scrollbar   = scrollbar,
+		content     = content,
+		frame       = frame,
+		type        = Type
+	}
+	for method, func in pairs(methods) do
+		widget[method] = func
+	end
+	scrollframe.obj, scrollbar.obj = widget, widget
+
+	return AceGUI:RegisterAsContainer(widget)
+end
+
+AceGUI:RegisterWidgetType(Type, Constructor, Version)
diff --git a/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-SimpleGroup.lua b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-SimpleGroup.lua
new file mode 100644
index 0000000..57512c3
--- /dev/null
+++ b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-SimpleGroup.lua
@@ -0,0 +1,69 @@
+--[[-----------------------------------------------------------------------------
+SimpleGroup Container
+Simple container widget that just groups widgets.
+-------------------------------------------------------------------------------]]
+local Type, Version = "SimpleGroup", 20
+local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
+if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
+
+-- Lua APIs
+local pairs = pairs
+
+-- WoW APIs
+local CreateFrame, UIParent = CreateFrame, UIParent
+
+
+--[[-----------------------------------------------------------------------------
+Methods
+-------------------------------------------------------------------------------]]
+local methods = {
+	["OnAcquire"] = function(self)
+		self:SetWidth(300)
+		self:SetHeight(100)
+	end,
+
+	-- ["OnRelease"] = nil,
+
+	["LayoutFinished"] = function(self, width, height)
+		if self.noAutoHeight then return end
+		self:SetHeight(height or 0)
+	end,
+
+	["OnWidthSet"] = function(self, width)
+		local content = self.content
+		content:SetWidth(width)
+		content.width = width
+	end,
+
+	["OnHeightSet"] = function(self, height)
+		local content = self.content
+		content:SetHeight(height)
+		content.height = height
+	end
+}
+
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+local function Constructor()
+	local frame = CreateFrame("Frame", nil, UIParent)
+	frame:SetFrameStrata("FULLSCREEN_DIALOG")
+
+	--Container Support
+	local content = CreateFrame("Frame", nil, frame)
+	content:SetPoint("TOPLEFT")
+	content:SetPoint("BOTTOMRIGHT")
+
+	local widget = {
+		frame     = frame,
+		content   = content,
+		type      = Type
+	}
+	for method, func in pairs(methods) do
+		widget[method] = func
+	end
+
+	return AceGUI:RegisterAsContainer(widget)
+end
+
+AceGUI:RegisterWidgetType(Type, Constructor, Version)
diff --git a/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-TabGroup.lua b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-TabGroup.lua
new file mode 100644
index 0000000..00be129
--- /dev/null
+++ b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-TabGroup.lua
@@ -0,0 +1,350 @@
+--[[-----------------------------------------------------------------------------
+TabGroup Container
+Container that uses tabs on top to switch between groups.
+-------------------------------------------------------------------------------]]
+local Type, Version = "TabGroup", 35
+local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
+if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
+
+-- Lua APIs
+local pairs, ipairs, assert, type, wipe = pairs, ipairs, assert, type, wipe
+
+-- WoW APIs
+local PlaySound = PlaySound
+local CreateFrame, UIParent = CreateFrame, UIParent
+local _G = _G
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: PanelTemplates_TabResize, PanelTemplates_SetDisabledTabState, PanelTemplates_SelectTab, PanelTemplates_DeselectTab
+
+-- local upvalue storage used by BuildTabs
+local widths = {}
+local rowwidths = {}
+local rowends = {}
+
+--[[-----------------------------------------------------------------------------
+Support functions
+-------------------------------------------------------------------------------]]
+local function UpdateTabLook(frame)
+	if frame.disabled then
+		PanelTemplates_SetDisabledTabState(frame)
+	elseif frame.selected then
+		PanelTemplates_SelectTab(frame)
+	else
+		PanelTemplates_DeselectTab(frame)
+	end
+end
+
+local function Tab_SetText(frame, text)
+	frame:_SetText(text)
+	local width = frame.obj.frame.width or frame.obj.frame:GetWidth() or 0
+	PanelTemplates_TabResize(frame, 0, nil, nil, width, frame:GetFontString():GetStringWidth())
+end
+
+local function Tab_SetSelected(frame, selected)
+	frame.selected = selected
+	UpdateTabLook(frame)
+end
+
+local function Tab_SetDisabled(frame, disabled)
+	frame.disabled = disabled
+	UpdateTabLook(frame)
+end
+
+local function BuildTabsOnUpdate(frame)
+	local self = frame.obj
+	self:BuildTabs()
+	frame:SetScript("OnUpdate", nil)
+end
+
+--[[-----------------------------------------------------------------------------
+Scripts
+-------------------------------------------------------------------------------]]
+local function Tab_OnClick(frame)
+	if not (frame.selected or frame.disabled) then
+		PlaySound("igCharacterInfoTab")
+		frame.obj:SelectTab(frame.value)
+	end
+end
+
+local function Tab_OnEnter(frame)
+	local self = frame.obj
+	self:Fire("OnTabEnter", self.tabs[frame.id].value, frame)
+end
+
+local function Tab_OnLeave(frame)
+	local self = frame.obj
+	self:Fire("OnTabLeave", self.tabs[frame.id].value, frame)
+end
+
+local function Tab_OnShow(frame)
+	_G[frame:GetName().."HighlightTexture"]:SetWidth(frame:GetTextWidth() + 30)
+end
+
+--[[-----------------------------------------------------------------------------
+Methods
+-------------------------------------------------------------------------------]]
+local methods = {
+	["OnAcquire"] = function(self)
+		self:SetTitle()
+	end,
+
+	["OnRelease"] = function(self)
+		self.status = nil
+		for k in pairs(self.localstatus) do
+			self.localstatus[k] = nil
+		end
+		self.tablist = nil
+		for _, tab in pairs(self.tabs) do
+			tab:Hide()
+		end
+	end,
+
+	["CreateTab"] = function(self, id)
+		local tabname = ("AceGUITabGroup%dTab%d"):format(self.num, id)
+		local tab = CreateFrame("Button", tabname, self.border, "OptionsFrameTabButtonTemplate")
+		tab.obj = self
+		tab.id = id
+
+		tab.text = _G[tabname .. "Text"]
+		tab.text:ClearAllPoints()
+		tab.text:SetPoint("LEFT", 14, -3)
+		tab.text:SetPoint("RIGHT", -12, -3)
+
+		tab:SetScript("OnClick", Tab_OnClick)
+		tab:SetScript("OnEnter", Tab_OnEnter)
+		tab:SetScript("OnLeave", Tab_OnLeave)
+		tab:SetScript("OnShow", Tab_OnShow)
+
+		tab._SetText = tab.SetText
+		tab.SetText = Tab_SetText
+		tab.SetSelected = Tab_SetSelected
+		tab.SetDisabled = Tab_SetDisabled
+
+		return tab
+	end,
+
+	["SetTitle"] = function(self, text)
+		self.titletext:SetText(text or "")
+		if text and text ~= "" then
+			self.alignoffset = 25
+		else
+			self.alignoffset = 18
+		end
+		self:BuildTabs()
+	end,
+
+	["SetStatusTable"] = function(self, status)
+		assert(type(status) == "table")
+		self.status = status
+	end,
+
+	["SelectTab"] = function(self, value)
+		local status = self.status or self.localstatus
+		local found
+		for i, v in ipairs(self.tabs) do
+			if v.value == value then
+				v:SetSelected(true)
+				found = true
+			else
+				v:SetSelected(false)
+			end
+		end
+		status.selected = value
+		if found then
+			self:Fire("OnGroupSelected",value)
+		end
+	end,
+
+	["SetTabs"] = function(self, tabs)
+		self.tablist = tabs
+		self:BuildTabs()
+	end,
+
+
+	["BuildTabs"] = function(self)
+		local hastitle = (self.titletext:GetText() and self.titletext:GetText() ~= "")
+		local status = self.status or self.localstatus
+		local tablist = self.tablist
+		local tabs = self.tabs
+
+		if not tablist then return end
+
+		local width = self.frame.width or self.frame:GetWidth() or 0
+
+		wipe(widths)
+		wipe(rowwidths)
+		wipe(rowends)
+
+		--Place Text into tabs and get thier initial width
+		for i, v in ipairs(tablist) do
+			local tab = tabs[i]
+			if not tab then
+				tab = self:CreateTab(i)
+				tabs[i] = tab
+			end
+
+			tab:Show()
+			tab:SetText(v.text)
+			tab:SetDisabled(v.disabled)
+			tab.value = v.value
+
+			widths[i] = tab:GetWidth() - 6 --tabs are anchored 10 pixels from the right side of the previous one to reduce spacing, but add a fixed 4px padding for the text
+		end
+
+		for i = (#tablist)+1, #tabs, 1 do
+			tabs[i]:Hide()
+		end
+
+		--First pass, find the minimum number of rows needed to hold all tabs and the initial tab layout
+		local numtabs = #tablist
+		local numrows = 1
+		local usedwidth = 0
+
+		for i = 1, #tablist do
+			--If this is not the first tab of a row and there isn't room for it
+			if usedwidth ~= 0 and (width - usedwidth - widths[i]) < 0 then
+				rowwidths[numrows] = usedwidth + 10 --first tab in each row takes up an extra 10px
+				rowends[numrows] = i - 1
+				numrows = numrows + 1
+				usedwidth = 0
+			end
+			usedwidth = usedwidth + widths[i]
+		end
+		rowwidths[numrows] = usedwidth + 10 --first tab in each row takes up an extra 10px
+		rowends[numrows] = #tablist
+
+		--Fix for single tabs being left on the last row, move a tab from the row above if applicable
+		if numrows > 1 then
+			--if the last row has only one tab
+			if rowends[numrows-1] == numtabs-1 then
+				--if there are more than 2 tabs in the 2nd last row
+				if (numrows == 2 and rowends[numrows-1] > 2) or (rowends[numrows] - rowends[numrows-1] > 2) then
+					--move 1 tab from the second last row to the last, if there is enough space
+					if (rowwidths[numrows] + widths[numtabs-1]) <= width then
+						rowends[numrows-1] = rowends[numrows-1] - 1
+						rowwidths[numrows] = rowwidths[numrows] + widths[numtabs-1]
+						rowwidths[numrows-1] = rowwidths[numrows-1] - widths[numtabs-1]
+					end
+				end
+			end
+		end
+
+		--anchor the rows as defined and resize tabs to fill thier row
+		local starttab = 1
+		for row, endtab in ipairs(rowends) do
+			local first = true
+			for tabno = starttab, endtab do
+				local tab = tabs[tabno]
+				tab:ClearAllPoints()
+				if first then
+					tab:SetPoint("TOPLEFT", self.frame, "TOPLEFT", 0, -(hastitle and 14 or 7)-(row-1)*20 )
+					first = false
+				else
+					tab:SetPoint("LEFT", tabs[tabno-1], "RIGHT", -10, 0)
+				end
+			end
+
+			-- equal padding for each tab to fill the available width,
+			-- if the used space is above 75% already
+			-- the 18 pixel is the typical width of a scrollbar, so we can have a tab group inside a scrolling frame,
+			-- and not have the tabs jump around funny when switching between tabs that need scrolling and those that don't
+			local padding = 0
+			if not (numrows == 1 and rowwidths[1] < width*0.75 - 18) then
+				padding = (width - rowwidths[row]) / (endtab - starttab+1)
+			end
+
+			for i = starttab, endtab do
+				PanelTemplates_TabResize(tabs[i], padding + 4, nil, nil, width, tabs[i]:GetFontString():GetStringWidth())
+			end
+			starttab = endtab + 1
+		end
+
+		self.borderoffset = (hastitle and 17 or 10)+((numrows)*20)
+		self.border:SetPoint("TOPLEFT", 1, -self.borderoffset)
+	end,
+
+	["OnWidthSet"] = function(self, width)
+		local content = self.content
+		local contentwidth = width - 60
+		if contentwidth < 0 then
+			contentwidth = 0
+		end
+		content:SetWidth(contentwidth)
+		content.width = contentwidth
+		self:BuildTabs(self)
+		self.frame:SetScript("OnUpdate", BuildTabsOnUpdate)
+	end,
+
+	["OnHeightSet"] = function(self, height)
+		local content = self.content
+		local contentheight = height - (self.borderoffset + 23)
+		if contentheight < 0 then
+			contentheight = 0
+		end
+		content:SetHeight(contentheight)
+		content.height = contentheight
+	end,
+
+	["LayoutFinished"] = function(self, width, height)
+		if self.noAutoHeight then return end
+		self:SetHeight((height or 0) + (self.borderoffset + 23))
+	end
+}
+
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+local PaneBackdrop  = {
+	bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
+	edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
+	tile = true, tileSize = 16, edgeSize = 16,
+	insets = { left = 3, right = 3, top = 5, bottom = 3 }
+}
+
+local function Constructor()
+	local num = AceGUI:GetNextWidgetNum(Type)
+	local frame = CreateFrame("Frame",nil,UIParent)
+	frame:SetHeight(100)
+	frame:SetWidth(100)
+	frame:SetFrameStrata("FULLSCREEN_DIALOG")
+
+	local titletext = frame:CreateFontString(nil,"OVERLAY","GameFontNormal")
+	titletext:SetPoint("TOPLEFT", 14, 0)
+	titletext:SetPoint("TOPRIGHT", -14, 0)
+	titletext:SetJustifyH("LEFT")
+	titletext:SetHeight(18)
+	titletext:SetText("")
+
+	local border = CreateFrame("Frame", nil, frame)
+	border:SetPoint("TOPLEFT", 1, -27)
+	border:SetPoint("BOTTOMRIGHT", -1, 3)
+	border:SetBackdrop(PaneBackdrop)
+	border:SetBackdropColor(0.1, 0.1, 0.1, 0.5)
+	border:SetBackdropBorderColor(0.4, 0.4, 0.4)
+
+	local content = CreateFrame("Frame", nil, border)
+	content:SetPoint("TOPLEFT", 10, -7)
+	content:SetPoint("BOTTOMRIGHT", -10, 7)
+
+	local widget = {
+		num          = num,
+		frame        = frame,
+		localstatus  = {},
+		alignoffset  = 18,
+		titletext    = titletext,
+		border       = border,
+		borderoffset = 27,
+		tabs         = {},
+		content      = content,
+		type         = Type
+	}
+	for method, func in pairs(methods) do
+		widget[method] = func
+	end
+
+	return AceGUI:RegisterAsContainer(widget)
+end
+
+AceGUI:RegisterWidgetType(Type, Constructor, Version)
diff --git a/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-TreeGroup.lua b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-TreeGroup.lua
new file mode 100644
index 0000000..bddeee7
--- /dev/null
+++ b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-TreeGroup.lua
@@ -0,0 +1,709 @@
+--[[-----------------------------------------------------------------------------
+TreeGroup Container
+Container that uses a tree control to switch between groups.
+-------------------------------------------------------------------------------]]
+local Type, Version = "TreeGroup", 38
+local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
+if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
+
+-- Lua APIs
+local next, pairs, ipairs, assert, type = next, pairs, ipairs, assert, type
+local math_min, math_max, floor = math.min, math.max, floor
+local select, tremove, unpack, tconcat = select, table.remove, unpack, table.concat
+
+-- WoW APIs
+local CreateFrame, UIParent = CreateFrame, UIParent
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: GameTooltip, FONT_COLOR_CODE_CLOSE
+
+-- Recycling functions
+local new, del
+do
+	local pool = setmetatable({},{__mode='k'})
+	function new()
+		local t = next(pool)
+		if t then
+			pool[t] = nil
+			return t
+		else
+			return {}
+		end
+	end
+	function del(t)
+		for k in pairs(t) do
+			t[k] = nil
+		end
+		pool[t] = true
+	end
+end
+
+local DEFAULT_TREE_WIDTH = 175
+local DEFAULT_TREE_SIZABLE = true
+
+--[[-----------------------------------------------------------------------------
+Support functions
+-------------------------------------------------------------------------------]]
+local function GetButtonUniqueValue(line)
+	local parent = line.parent
+	if parent and parent.value then
+		return GetButtonUniqueValue(parent).."\001"..line.value
+	else
+		return line.value
+	end
+end
+
+local function UpdateButton(button, treeline, selected, canExpand, isExpanded)
+	local self = button.obj
+	local toggle = button.toggle
+	local frame = self.frame
+	local text = treeline.text or ""
+	local icon = treeline.icon
+	local iconCoords = treeline.iconCoords
+	local level = treeline.level
+	local value = treeline.value
+	local uniquevalue = treeline.uniquevalue
+	local disabled = treeline.disabled
+
+	button.treeline = treeline
+	button.value = value
+	button.uniquevalue = uniquevalue
+	if selected then
+		button:LockHighlight()
+		button.selected = true
+	else
+		button:UnlockHighlight()
+		button.selected = false
+	end
+	local normalTexture = button:GetNormalTexture()
+	local line = button.line
+	button.level = level
+	if ( level == 1 ) then
+		button:SetNormalFontObject("GameFontNormal")
+		button:SetHighlightFontObject("GameFontHighlight")
+		button.text:SetPoint("LEFT", (icon and 16 or 0) + 8, 2)
+	else
+		button:SetNormalFontObject("GameFontHighlightSmall")
+		button:SetHighlightFontObject("GameFontHighlightSmall")
+		button.text:SetPoint("LEFT", (icon and 16 or 0) + 8 * level, 2)
+	end
+
+	if disabled then
+		button:EnableMouse(false)
+		button.text:SetText("|cff808080"..text..FONT_COLOR_CODE_CLOSE)
+	else
+		button.text:SetText(text)
+		button:EnableMouse(true)
+	end
+
+	if icon then
+		button.icon:SetTexture(icon)
+		button.icon:SetPoint("LEFT", 8 * level, (level == 1) and 0 or 1)
+	else
+		button.icon:SetTexture(nil)
+	end
+
+	if iconCoords then
+		button.icon:SetTexCoord(unpack(iconCoords))
+	else
+		button.icon:SetTexCoord(0, 1, 0, 1)
+	end
+
+	if canExpand then
+		if not isExpanded then
+			toggle:SetNormalTexture("Interface\\Buttons\\UI-PlusButton-UP")
+			toggle:SetPushedTexture("Interface\\Buttons\\UI-PlusButton-DOWN")
+		else
+			toggle:SetNormalTexture("Interface\\Buttons\\UI-MinusButton-UP")
+			toggle:SetPushedTexture("Interface\\Buttons\\UI-MinusButton-DOWN")
+		end
+		toggle:Show()
+	else
+		toggle:Hide()
+	end
+end
+
+local function ShouldDisplayLevel(tree)
+	local result = false
+	for k, v in ipairs(tree) do
+		if v.children == nil and v.visible ~= false then
+			result = true
+		elseif v.children then
+			result = result or ShouldDisplayLevel(v.children)
+		end
+		if result then return result end
+	end
+	return false
+end
+
+local function addLine(self, v, tree, level, parent)
+	local line = new()
+	line.value = v.value
+	line.text = v.text
+	line.icon = v.icon
+	line.iconCoords = v.iconCoords
+	line.disabled = v.disabled
+	line.tree = tree
+	line.level = level
+	line.parent = parent
+	line.visible = v.visible
+	line.uniquevalue = GetButtonUniqueValue(line)
+	if v.children then
+		line.hasChildren = true
+	else
+		line.hasChildren = nil
+	end
+	self.lines[#self.lines+1] = line
+	return line
+end
+
+--fire an update after one frame to catch the treeframes height
+local function FirstFrameUpdate(frame)
+	local self = frame.obj
+	frame:SetScript("OnUpdate", nil)
+	self:RefreshTree()
+end
+
+local function BuildUniqueValue(...)
+	local n = select('#', ...)
+	if n == 1 then
+		return ...
+	else
+		return (...).."\001"..BuildUniqueValue(select(2,...))
+	end
+end
+
+--[[-----------------------------------------------------------------------------
+Scripts
+-------------------------------------------------------------------------------]]
+local function Expand_OnClick(frame)
+	local button = frame.button
+	local self = button.obj
+	local status = (self.status or self.localstatus).groups
+	status[button.uniquevalue] = not status[button.uniquevalue]
+	self:RefreshTree()
+end
+
+local function Button_OnClick(frame)
+	local self = frame.obj
+	self:Fire("OnClick", frame.uniquevalue, frame.selected)
+	if not frame.selected then
+		self:SetSelected(frame.uniquevalue)
+		frame.selected = true
+		frame:LockHighlight()
+		self:RefreshTree()
+	end
+	AceGUI:ClearFocus()
+end
+
+local function Button_OnDoubleClick(button)
+	local self = button.obj
+	local status = self.status or self.localstatus
+	local status = (self.status or self.localstatus).groups
+	status[button.uniquevalue] = not status[button.uniquevalue]
+	self:RefreshTree()
+end
+
+local function Button_OnEnter(frame)
+	local self = frame.obj
+	self:Fire("OnButtonEnter", frame.uniquevalue, frame)
+
+	if self.enabletooltips then
+		GameTooltip:SetOwner(frame, "ANCHOR_NONE")
+		GameTooltip:SetPoint("LEFT",frame,"RIGHT")
+		GameTooltip:SetText(frame.text:GetText() or "", 1, .82, 0, true)
+
+		GameTooltip:Show()
+	end
+end
+
+local function Button_OnLeave(frame)
+	local self = frame.obj
+	self:Fire("OnButtonLeave", frame.uniquevalue, frame)
+
+	if self.enabletooltips then
+		GameTooltip:Hide()
+	end
+end
+
+local function OnScrollValueChanged(frame, value)
+	if frame.obj.noupdate then return end
+	local self = frame.obj
+	local status = self.status or self.localstatus
+	status.scrollvalue = floor(value + 0.5)
+	self:RefreshTree()
+	AceGUI:ClearFocus()
+end
+
+local function Tree_OnSizeChanged(frame)
+	frame.obj:RefreshTree()
+end
+
+local function Tree_OnMouseWheel(frame, delta)
+	local self = frame.obj
+	if self.showscroll then
+		local scrollbar = self.scrollbar
+		local min, max = scrollbar:GetMinMaxValues()
+		local value = scrollbar:GetValue()
+		local newvalue = math_min(max,math_max(min,value - delta))
+		if value ~= newvalue then
+			scrollbar:SetValue(newvalue)
+		end
+	end
+end
+
+local function Dragger_OnLeave(frame)
+	frame:SetBackdropColor(1, 1, 1, 0)
+end
+
+local function Dragger_OnEnter(frame)
+	frame:SetBackdropColor(1, 1, 1, 0.8)
+end
+
+local function Dragger_OnMouseDown(frame)
+	local treeframe = frame:GetParent()
+	treeframe:StartSizing("RIGHT")
+end
+
+local function Dragger_OnMouseUp(frame)
+	local treeframe = frame:GetParent()
+	local self = treeframe.obj
+	local frame = treeframe:GetParent()
+	treeframe:StopMovingOrSizing()
+	--treeframe:SetScript("OnUpdate", nil)
+	treeframe:SetUserPlaced(false)
+	--Without this :GetHeight will get stuck on the current height, causing the tree contents to not resize
+	treeframe:SetHeight(0)
+	treeframe:SetPoint("TOPLEFT", frame, "TOPLEFT",0,0)
+	treeframe:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT",0,0)
+
+	local status = self.status or self.localstatus
+	status.treewidth = treeframe:GetWidth()
+
+	treeframe.obj:Fire("OnTreeResize",treeframe:GetWidth())
+	-- recalculate the content width
+	treeframe.obj:OnWidthSet(status.fullwidth)
+	-- update the layout of the content
+	treeframe.obj:DoLayout()
+end
+
+--[[-----------------------------------------------------------------------------
+Methods
+-------------------------------------------------------------------------------]]
+local methods = {
+	["OnAcquire"] = function(self)
+		self:SetTreeWidth(DEFAULT_TREE_WIDTH, DEFAULT_TREE_SIZABLE)
+		self:EnableButtonTooltips(true)
+	end,
+
+	["OnRelease"] = function(self)
+		self.status = nil
+		for k, v in pairs(self.localstatus) do
+			if k == "groups" then
+				for k2 in pairs(v) do
+					v[k2] = nil
+				end
+			else
+				self.localstatus[k] = nil
+			end
+		end
+		self.localstatus.scrollvalue = 0
+		self.localstatus.treewidth = DEFAULT_TREE_WIDTH
+		self.localstatus.treesizable = DEFAULT_TREE_SIZABLE
+	end,
+
+	["EnableButtonTooltips"] = function(self, enable)
+		self.enabletooltips = enable
+	end,
+
+	["CreateButton"] = function(self)
+		local num = AceGUI:GetNextWidgetNum("TreeGroupButton")
+		local button = CreateFrame("Button", ("AceGUI30TreeButton%d"):format(num), self.treeframe, "OptionsListButtonTemplate")
+		button.obj = self
+
+		local icon = button:CreateTexture(nil, "OVERLAY")
+		icon:SetWidth(14)
+		icon:SetHeight(14)
+		button.icon = icon
+
+		button:SetScript("OnClick",Button_OnClick)
+		button:SetScript("OnDoubleClick", Button_OnDoubleClick)
+		button:SetScript("OnEnter",Button_OnEnter)
+		button:SetScript("OnLeave",Button_OnLeave)
+
+		button.toggle.button = button
+		button.toggle:SetScript("OnClick",Expand_OnClick)
+
+		button.text:SetHeight(14) -- Prevents text wrapping
+
+		return button
+	end,
+
+	["SetStatusTable"] = function(self, status)
+		assert(type(status) == "table")
+		self.status = status
+		if not status.groups then
+			status.groups = {}
+		end
+		if not status.scrollvalue then
+			status.scrollvalue = 0
+		end
+		if not status.treewidth then
+			status.treewidth = DEFAULT_TREE_WIDTH
+		end
+		if status.treesizable == nil then
+			status.treesizable = DEFAULT_TREE_SIZABLE
+		end
+		self:SetTreeWidth(status.treewidth,status.treesizable)
+		self:RefreshTree()
+	end,
+
+	--sets the tree to be displayed
+	["SetTree"] = function(self, tree, filter)
+		self.filter = filter
+		if tree then
+			assert(type(tree) == "table")
+		end
+		self.tree = tree
+		self:RefreshTree()
+	end,
+
+	["BuildLevel"] = function(self, tree, level, parent)
+		local groups = (self.status or self.localstatus).groups
+		local hasChildren = self.hasChildren
+
+		for i, v in ipairs(tree) do
+			if v.children then
+				if not self.filter or ShouldDisplayLevel(v.children) then
+					local line = addLine(self, v, tree, level, parent)
+					if groups[line.uniquevalue] then
+						self:BuildLevel(v.children, level+1, line)
+					end
+				end
+			elseif v.visible ~= false or not self.filter then
+				addLine(self, v, tree, level, parent)
+			end
+		end
+	end,
+
+	["RefreshTree"] = function(self,scrollToSelection)
+		local buttons = self.buttons
+		local lines = self.lines
+
+		for i, v in ipairs(buttons) do
+			v:Hide()
+		end
+		while lines[1] do
+			local t = tremove(lines)
+			for k in pairs(t) do
+				t[k] = nil
+			end
+			del(t)
+		end
+
+		if not self.tree then return end
+		--Build the list of visible entries from the tree and status tables
+		local status = self.status or self.localstatus
+		local groupstatus = status.groups
+		local tree = self.tree
+
+		local treeframe = self.treeframe
+
+		status.scrollToSelection = status.scrollToSelection or scrollToSelection	-- needs to be cached in case the control hasn't been drawn yet (code bails out below)
+
+		self:BuildLevel(tree, 1)
+
+		local numlines = #lines
+
+		local maxlines = (floor(((self.treeframe:GetHeight()or 0) - 20 ) / 18))
+		if maxlines <= 0 then return end
+
+		local first, last
+
+		scrollToSelection = status.scrollToSelection
+		status.scrollToSelection = nil
+
+		if numlines <= maxlines then
+			--the whole tree fits in the frame
+			status.scrollvalue = 0
+			self:ShowScroll(false)
+			first, last = 1, numlines
+		else
+			self:ShowScroll(true)
+			--scrolling will be needed
+			self.noupdate = true
+			self.scrollbar:SetMinMaxValues(0, numlines - maxlines)
+			--check if we are scrolled down too far
+			if numlines - status.scrollvalue < maxlines then
+				status.scrollvalue = numlines - maxlines
+			end
+			self.noupdate = nil
+			first, last = status.scrollvalue+1, status.scrollvalue + maxlines
+			--show selection?
+			if scrollToSelection and status.selected then
+				local show
+				for i,line in ipairs(lines) do	-- find the line number
+					if line.uniquevalue==status.selected then
+						show=i
+					end
+				end
+				if not show then
+					-- selection was deleted or something?
+				elseif show>=first and show<=last then
+					-- all good
+				else
+					-- scrolling needed!
+					if show<first then
+						status.scrollvalue = show-1
+					else
+						status.scrollvalue = show-maxlines
+					end
+					first, last = status.scrollvalue+1, status.scrollvalue + maxlines
+				end
+			end
+			if self.scrollbar:GetValue() ~= status.scrollvalue then
+				self.scrollbar:SetValue(status.scrollvalue)
+			end
+		end
+
+		local buttonnum = 1
+		for i = first, last do
+			local line = lines[i]
+			local button = buttons[buttonnum]
+			if not button then
+				button = self:CreateButton()
+
+				buttons[buttonnum] = button
+				button:SetParent(treeframe)
+				button:SetFrameLevel(treeframe:GetFrameLevel()+1)
+				button:ClearAllPoints()
+				if buttonnum == 1 then
+					if self.showscroll then
+						button:SetPoint("TOPRIGHT", -22, -10)
+						button:SetPoint("TOPLEFT", 0, -10)
+					else
+						button:SetPoint("TOPRIGHT", 0, -10)
+						button:SetPoint("TOPLEFT", 0, -10)
+					end
+				else
+					button:SetPoint("TOPRIGHT", buttons[buttonnum-1], "BOTTOMRIGHT",0,0)
+					button:SetPoint("TOPLEFT", buttons[buttonnum-1], "BOTTOMLEFT",0,0)
+				end
+			end
+
+			UpdateButton(button, line, status.selected == line.uniquevalue, line.hasChildren, groupstatus[line.uniquevalue] )
+			button:Show()
+			buttonnum = buttonnum + 1
+		end
+
+	end,
+
+	["SetSelected"] = function(self, value)
+		local status = self.status or self.localstatus
+		if status.selected ~= value then
+			status.selected = value
+			self:Fire("OnGroupSelected", value)
+		end
+	end,
+
+	["Select"] = function(self, uniquevalue, ...)
+		self.filter = false
+		local status = self.status or self.localstatus
+		local groups = status.groups
+		local path = {...}
+		for i = 1, #path do
+			groups[tconcat(path, "\001", 1, i)] = true
+		end
+		status.selected = uniquevalue
+		self:RefreshTree(true)
+		self:Fire("OnGroupSelected", uniquevalue)
+	end,
+
+	["SelectByPath"] = function(self, ...)
+		self:Select(BuildUniqueValue(...), ...)
+	end,
+
+	["SelectByValue"] = function(self, uniquevalue)
+		self:Select(uniquevalue, ("\001"):split(uniquevalue))
+	end,
+
+	["ShowScroll"] = function(self, show)
+		self.showscroll = show
+		if show then
+			self.scrollbar:Show()
+			if self.buttons[1] then
+				self.buttons[1]:SetPoint("TOPRIGHT", self.treeframe,"TOPRIGHT",-22,-10)
+			end
+		else
+			self.scrollbar:Hide()
+			if self.buttons[1] then
+				self.buttons[1]:SetPoint("TOPRIGHT", self.treeframe,"TOPRIGHT",0,-10)
+			end
+		end
+	end,
+
+	["OnWidthSet"] = function(self, width)
+		local content = self.content
+		local treeframe = self.treeframe
+		local status = self.status or self.localstatus
+		status.fullwidth = width
+
+		local contentwidth = width - status.treewidth - 20
+		if contentwidth < 0 then
+			contentwidth = 0
+		end
+		content:SetWidth(contentwidth)
+		content.width = contentwidth
+
+		local maxtreewidth = math_min(400, width - 50)
+
+		if maxtreewidth > 100 and status.treewidth > maxtreewidth then
+			self:SetTreeWidth(maxtreewidth, status.treesizable)
+		end
+		treeframe:SetMaxResize(maxtreewidth, 1600)
+	end,
+
+	["OnHeightSet"] = function(self, height)
+		local content = self.content
+		local contentheight = height - 20
+		if contentheight < 0 then
+			contentheight = 0
+		end
+		content:SetHeight(contentheight)
+		content.height = contentheight
+	end,
+
+	["SetTreeWidth"] = function(self, treewidth, resizable)
+		if not resizable then
+			if type(treewidth) == 'number' then
+				resizable = false
+			elseif type(treewidth) == 'boolean' then
+				resizable = treewidth
+				treewidth = DEFAULT_TREE_WIDTH
+			else
+				resizable = false
+				treewidth = DEFAULT_TREE_WIDTH
+			end
+		end
+		self.treeframe:SetWidth(treewidth)
+		self.dragger:EnableMouse(resizable)
+
+		local status = self.status or self.localstatus
+		status.treewidth = treewidth
+		status.treesizable = resizable
+
+		-- recalculate the content width
+		if status.fullwidth then
+			self:OnWidthSet(status.fullwidth)
+		end
+	end,
+
+	["GetTreeWidth"] = function(self)
+		local status = self.status or self.localstatus
+		return status.treewidth or DEFAULT_TREE_WIDTH
+	end,
+
+	["LayoutFinished"] = function(self, width, height)
+		if self.noAutoHeight then return end
+		self:SetHeight((height or 0) + 20)
+	end
+}
+
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+local PaneBackdrop  = {
+	bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
+	edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
+	tile = true, tileSize = 16, edgeSize = 16,
+	insets = { left = 3, right = 3, top = 5, bottom = 3 }
+}
+
+local DraggerBackdrop  = {
+	bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
+	edgeFile = nil,
+	tile = true, tileSize = 16, edgeSize = 0,
+	insets = { left = 3, right = 3, top = 7, bottom = 7 }
+}
+
+local function Constructor()
+	local num = AceGUI:GetNextWidgetNum(Type)
+	local frame = CreateFrame("Frame", nil, UIParent)
+
+	local treeframe = CreateFrame("Frame", nil, frame)
+	treeframe:SetPoint("TOPLEFT")
+	treeframe:SetPoint("BOTTOMLEFT")
+	treeframe:SetWidth(DEFAULT_TREE_WIDTH)
+	treeframe:EnableMouseWheel(true)
+	treeframe:SetBackdrop(PaneBackdrop)
+	treeframe:SetBackdropColor(0.1, 0.1, 0.1, 0.5)
+	treeframe:SetBackdropBorderColor(0.4, 0.4, 0.4)
+	treeframe:SetResizable(true)
+	treeframe:SetMinResize(100, 1)
+	treeframe:SetMaxResize(400, 1600)
+	treeframe:SetScript("OnUpdate", FirstFrameUpdate)
+	treeframe:SetScript("OnSizeChanged", Tree_OnSizeChanged)
+	treeframe:SetScript("OnMouseWheel", Tree_OnMouseWheel)
+
+	local dragger = CreateFrame("Frame", nil, treeframe)
+	dragger:SetWidth(8)
+	dragger:SetPoint("TOP", treeframe, "TOPRIGHT")
+	dragger:SetPoint("BOTTOM", treeframe, "BOTTOMRIGHT")
+	dragger:SetBackdrop(DraggerBackdrop)
+	dragger:SetBackdropColor(1, 1, 1, 0)
+	dragger:SetScript("OnEnter", Dragger_OnEnter)
+	dragger:SetScript("OnLeave", Dragger_OnLeave)
+	dragger:SetScript("OnMouseDown", Dragger_OnMouseDown)
+	dragger:SetScript("OnMouseUp", Dragger_OnMouseUp)
+
+	local scrollbar = CreateFrame("Slider", ("AceConfigDialogTreeGroup%dScrollBar"):format(num), treeframe, "UIPanelScrollBarTemplate")
+	scrollbar:SetScript("OnValueChanged", nil)
+	scrollbar:SetPoint("TOPRIGHT", -10, -26)
+	scrollbar:SetPoint("BOTTOMRIGHT", -10, 26)
+	scrollbar:SetMinMaxValues(0,0)
+	scrollbar:SetValueStep(1)
+	scrollbar:SetValue(0)
+	scrollbar:SetWidth(16)
+	scrollbar:SetScript("OnValueChanged", OnScrollValueChanged)
+
+	local scrollbg = scrollbar:CreateTexture(nil, "BACKGROUND")
+	scrollbg:SetAllPoints(scrollbar)
+	scrollbg:SetColorTexture(0,0,0,0.4)
+
+	local border = CreateFrame("Frame",nil,frame)
+	border:SetPoint("TOPLEFT", treeframe, "TOPRIGHT")
+	border:SetPoint("BOTTOMRIGHT")
+	border:SetBackdrop(PaneBackdrop)
+	border:SetBackdropColor(0.1, 0.1, 0.1, 0.5)
+	border:SetBackdropBorderColor(0.4, 0.4, 0.4)
+
+	--Container Support
+	local content = CreateFrame("Frame", nil, border)
+	content:SetPoint("TOPLEFT", 10, -10)
+	content:SetPoint("BOTTOMRIGHT", -10, 10)
+
+	local widget = {
+		frame        = frame,
+		lines        = {},
+		levels       = {},
+		buttons      = {},
+		hasChildren  = {},
+		localstatus  = { groups = {}, scrollvalue = 0 },
+		filter       = false,
+		treeframe    = treeframe,
+		dragger      = dragger,
+		scrollbar    = scrollbar,
+		border       = border,
+		content      = content,
+		type         = Type
+	}
+	for method, func in pairs(methods) do
+		widget[method] = func
+	end
+	treeframe.obj, dragger.obj, scrollbar.obj = widget, widget, widget
+
+	return AceGUI:RegisterAsContainer(widget)
+end
+
+AceGUI:RegisterWidgetType(Type, Constructor, Version)
diff --git a/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-Window.lua b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-Window.lua
new file mode 100644
index 0000000..bb0a2a2
--- /dev/null
+++ b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIContainer-Window.lua
@@ -0,0 +1,331 @@
+local AceGUI = LibStub("AceGUI-3.0")
+
+-- Lua APIs
+local pairs, assert, type = pairs, assert, type
+
+-- WoW APIs
+local PlaySound = PlaySound
+local CreateFrame, UIParent = CreateFrame, UIParent
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: GameFontNormal
+
+----------------
+-- Main Frame --
+----------------
+--[[
+	Events :
+		OnClose
+
+]]
+do
+	local Type = "Window"
+	local Version = 4
+
+	local function frameOnClose(this)
+		this.obj:Fire("OnClose")
+	end
+
+	local function closeOnClick(this)
+		PlaySound("gsTitleOptionExit")
+		this.obj:Hide()
+	end
+
+	local function frameOnMouseDown(this)
+		AceGUI:ClearFocus()
+	end
+
+	local function titleOnMouseDown(this)
+		this:GetParent():StartMoving()
+		AceGUI:ClearFocus()
+	end
+
+	local function frameOnMouseUp(this)
+		local frame = this:GetParent()
+		frame:StopMovingOrSizing()
+		local self = frame.obj
+		local status = self.status or self.localstatus
+		status.width = frame:GetWidth()
+		status.height = frame:GetHeight()
+		status.top = frame:GetTop()
+		status.left = frame:GetLeft()
+	end
+
+	local function sizerseOnMouseDown(this)
+		this:GetParent():StartSizing("BOTTOMRIGHT")
+		AceGUI:ClearFocus()
+	end
+
+	local function sizersOnMouseDown(this)
+		this:GetParent():StartSizing("BOTTOM")
+		AceGUI:ClearFocus()
+	end
+
+	local function sizereOnMouseDown(this)
+		this:GetParent():StartSizing("RIGHT")
+		AceGUI:ClearFocus()
+	end
+
+	local function sizerOnMouseUp(this)
+		this:GetParent():StopMovingOrSizing()
+	end
+
+	local function SetTitle(self,title)
+		self.titletext:SetText(title)
+	end
+
+	local function SetStatusText(self,text)
+		-- self.statustext:SetText(text)
+	end
+
+	local function Hide(self)
+		self.frame:Hide()
+	end
+
+	local function Show(self)
+		self.frame:Show()
+	end
+
+	local function OnAcquire(self)
+		self.frame:SetParent(UIParent)
+		self.frame:SetFrameStrata("FULLSCREEN_DIALOG")
+		self:ApplyStatus()
+		self:EnableResize(true)
+		self:Show()
+	end
+
+	local function OnRelease(self)
+		self.status = nil
+		for k in pairs(self.localstatus) do
+			self.localstatus[k] = nil
+		end
+	end
+
+	-- called to set an external table to store status in
+	local function SetStatusTable(self, status)
+		assert(type(status) == "table")
+		self.status = status
+		self:ApplyStatus()
+	end
+
+	local function ApplyStatus(self)
+		local status = self.status or self.localstatus
+		local frame = self.frame
+		self:SetWidth(status.width or 700)
+		self:SetHeight(status.height or 500)
+		if status.top and status.left then
+			frame:SetPoint("TOP",UIParent,"BOTTOM",0,status.top)
+			frame:SetPoint("LEFT",UIParent,"LEFT",status.left,0)
+		else
+			frame:SetPoint("CENTER",UIParent,"CENTER")
+		end
+	end
+
+	local function OnWidthSet(self, width)
+		local content = self.content
+		local contentwidth = width - 34
+		if contentwidth < 0 then
+			contentwidth = 0
+		end
+		content:SetWidth(contentwidth)
+		content.width = contentwidth
+	end
+
+
+	local function OnHeightSet(self, height)
+		local content = self.content
+		local contentheight = height - 57
+		if contentheight < 0 then
+			contentheight = 0
+		end
+		content:SetHeight(contentheight)
+		content.height = contentheight
+	end
+
+	local function EnableResize(self, state)
+		local func = state and "Show" or "Hide"
+		self.sizer_se[func](self.sizer_se)
+		self.sizer_s[func](self.sizer_s)
+		self.sizer_e[func](self.sizer_e)
+	end
+
+	local function Constructor()
+		local frame = CreateFrame("Frame",nil,UIParent)
+		local self = {}
+		self.type = "Window"
+
+		self.Hide = Hide
+		self.Show = Show
+		self.SetTitle =  SetTitle
+		self.OnRelease = OnRelease
+		self.OnAcquire = OnAcquire
+		self.SetStatusText = SetStatusText
+		self.SetStatusTable = SetStatusTable
+		self.ApplyStatus = ApplyStatus
+		self.OnWidthSet = OnWidthSet
+		self.OnHeightSet = OnHeightSet
+		self.EnableResize = EnableResize
+
+		self.localstatus = {}
+
+		self.frame = frame
+		frame.obj = self
+		frame:SetWidth(700)
+		frame:SetHeight(500)
+		frame:SetPoint("CENTER",UIParent,"CENTER",0,0)
+		frame:EnableMouse()
+		frame:SetMovable(true)
+		frame:SetResizable(true)
+		frame:SetFrameStrata("FULLSCREEN_DIALOG")
+		frame:SetScript("OnMouseDown", frameOnMouseDown)
+
+		frame:SetScript("OnHide",frameOnClose)
+		frame:SetMinResize(240,240)
+		frame:SetToplevel(true)
+
+		local titlebg = frame:CreateTexture(nil, "BACKGROUND")
+		titlebg:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Title-Background]])
+		titlebg:SetPoint("TOPLEFT", 9, -6)
+		titlebg:SetPoint("BOTTOMRIGHT", frame, "TOPRIGHT", -28, -24)
+
+		local dialogbg = frame:CreateTexture(nil, "BACKGROUND")
+		dialogbg:SetTexture([[Interface\Tooltips\UI-Tooltip-Background]])
+		dialogbg:SetPoint("TOPLEFT", 8, -24)
+		dialogbg:SetPoint("BOTTOMRIGHT", -6, 8)
+		dialogbg:SetVertexColor(0, 0, 0, .75)
+
+		local topleft = frame:CreateTexture(nil, "BORDER")
+		topleft:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
+		topleft:SetWidth(64)
+		topleft:SetHeight(64)
+		topleft:SetPoint("TOPLEFT")
+		topleft:SetTexCoord(0.501953125, 0.625, 0, 1)
+
+		local topright = frame:CreateTexture(nil, "BORDER")
+		topright:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
+		topright:SetWidth(64)
+		topright:SetHeight(64)
+		topright:SetPoint("TOPRIGHT")
+		topright:SetTexCoord(0.625, 0.75, 0, 1)
+
+		local top = frame:CreateTexture(nil, "BORDER")
+		top:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
+		top:SetHeight(64)
+		top:SetPoint("TOPLEFT", topleft, "TOPRIGHT")
+		top:SetPoint("TOPRIGHT", topright, "TOPLEFT")
+		top:SetTexCoord(0.25, 0.369140625, 0, 1)
+
+		local bottomleft = frame:CreateTexture(nil, "BORDER")
+		bottomleft:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
+		bottomleft:SetWidth(64)
+		bottomleft:SetHeight(64)
+		bottomleft:SetPoint("BOTTOMLEFT")
+		bottomleft:SetTexCoord(0.751953125, 0.875, 0, 1)
+
+		local bottomright = frame:CreateTexture(nil, "BORDER")
+		bottomright:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
+		bottomright:SetWidth(64)
+		bottomright:SetHeight(64)
+		bottomright:SetPoint("BOTTOMRIGHT")
+		bottomright:SetTexCoord(0.875, 1, 0, 1)
+
+		local bottom = frame:CreateTexture(nil, "BORDER")
+		bottom:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
+		bottom:SetHeight(64)
+		bottom:SetPoint("BOTTOMLEFT", bottomleft, "BOTTOMRIGHT")
+		bottom:SetPoint("BOTTOMRIGHT", bottomright, "BOTTOMLEFT")
+		bottom:SetTexCoord(0.376953125, 0.498046875, 0, 1)
+
+		local left = frame:CreateTexture(nil, "BORDER")
+		left:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
+		left:SetWidth(64)
+		left:SetPoint("TOPLEFT", topleft, "BOTTOMLEFT")
+		left:SetPoint("BOTTOMLEFT", bottomleft, "TOPLEFT")
+		left:SetTexCoord(0.001953125, 0.125, 0, 1)
+
+		local right = frame:CreateTexture(nil, "BORDER")
+		right:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
+		right:SetWidth(64)
+		right:SetPoint("TOPRIGHT", topright, "BOTTOMRIGHT")
+		right:SetPoint("BOTTOMRIGHT", bottomright, "TOPRIGHT")
+		right:SetTexCoord(0.1171875, 0.2421875, 0, 1)
+
+		local close = CreateFrame("Button", nil, frame, "UIPanelCloseButton")
+		close:SetPoint("TOPRIGHT", 2, 1)
+		close:SetScript("OnClick", closeOnClick)
+		self.closebutton = close
+		close.obj = self
+
+		local titletext = frame:CreateFontString(nil, "ARTWORK")
+		titletext:SetFontObject(GameFontNormal)
+		titletext:SetPoint("TOPLEFT", 12, -8)
+		titletext:SetPoint("TOPRIGHT", -32, -8)
+		self.titletext = titletext
+
+		local title = CreateFrame("Button", nil, frame)
+		title:SetPoint("TOPLEFT", titlebg)
+		title:SetPoint("BOTTOMRIGHT", titlebg)
+		title:EnableMouse()
+		title:SetScript("OnMouseDown",titleOnMouseDown)
+		title:SetScript("OnMouseUp", frameOnMouseUp)
+		self.title = title
+
+		local sizer_se = CreateFrame("Frame",nil,frame)
+		sizer_se:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,0)
+		sizer_se:SetWidth(25)
+		sizer_se:SetHeight(25)
+		sizer_se:EnableMouse()
+		sizer_se:SetScript("OnMouseDown",sizerseOnMouseDown)
+		sizer_se:SetScript("OnMouseUp", sizerOnMouseUp)
+		self.sizer_se = sizer_se
+
+		local line1 = sizer_se:CreateTexture(nil, "BACKGROUND")
+		self.line1 = line1
+		line1:SetWidth(14)
+		line1:SetHeight(14)
+		line1:SetPoint("BOTTOMRIGHT", -8, 8)
+		line1:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border")
+		local x = 0.1 * 14/17
+		line1:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5)
+
+		local line2 = sizer_se:CreateTexture(nil, "BACKGROUND")
+		self.line2 = line2
+		line2:SetWidth(8)
+		line2:SetHeight(8)
+		line2:SetPoint("BOTTOMRIGHT", -8, 8)
+		line2:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border")
+		local x = 0.1 * 8/17
+		line2:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5)
+
+		local sizer_s = CreateFrame("Frame",nil,frame)
+		sizer_s:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-25,0)
+		sizer_s:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",0,0)
+		sizer_s:SetHeight(25)
+		sizer_s:EnableMouse()
+		sizer_s:SetScript("OnMouseDown",sizersOnMouseDown)
+		sizer_s:SetScript("OnMouseUp", sizerOnMouseUp)
+		self.sizer_s = sizer_s
+
+		local sizer_e = CreateFrame("Frame",nil,frame)
+		sizer_e:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,25)
+		sizer_e:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,0)
+		sizer_e:SetWidth(25)
+		sizer_e:EnableMouse()
+		sizer_e:SetScript("OnMouseDown",sizereOnMouseDown)
+		sizer_e:SetScript("OnMouseUp", sizerOnMouseUp)
+		self.sizer_e = sizer_e
+
+		--Container Support
+		local content = CreateFrame("Frame",nil,frame)
+		self.content = content
+		content.obj = self
+		content:SetPoint("TOPLEFT",frame,"TOPLEFT",12,-32)
+		content:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-12,13)
+
+		AceGUI:RegisterAsContainer(self)
+		return self
+	end
+
+	AceGUI:RegisterWidgetType(Type,Constructor,Version)
+end
diff --git a/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-Button.lua b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-Button.lua
new file mode 100644
index 0000000..028e524
--- /dev/null
+++ b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-Button.lua
@@ -0,0 +1,109 @@
+--[[-----------------------------------------------------------------------------
+Button Widget
+Graphical Button.
+-------------------------------------------------------------------------------]]
+local Type, Version = "Button", 23
+local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
+if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
+
+-- Lua APIs
+local pairs = pairs
+
+-- WoW APIs
+local _G = _G
+local PlaySound, CreateFrame, UIParent = PlaySound, CreateFrame, UIParent
+
+local wowMoP
+do
+	local _, _, _, interface = GetBuildInfo()
+	wowMoP = (interface >= 50000)
+end
+
+--[[-----------------------------------------------------------------------------
+Scripts
+-------------------------------------------------------------------------------]]
+local function Button_OnClick(frame, ...)
+	AceGUI:ClearFocus()
+	PlaySound("igMainMenuOption")
+	frame.obj:Fire("OnClick", ...)
+end
+
+local function Control_OnEnter(frame)
+	frame.obj:Fire("OnEnter")
+end
+
+local function Control_OnLeave(frame)
+	frame.obj:Fire("OnLeave")
+end
+
+--[[-----------------------------------------------------------------------------
+Methods
+-------------------------------------------------------------------------------]]
+local methods = {
+	["OnAcquire"] = function(self)
+		-- restore default values
+		self:SetHeight(24)
+		self:SetWidth(200)
+		self:SetDisabled(false)
+		self:SetAutoWidth(false)
+		self:SetText()
+	end,
+
+	-- ["OnRelease"] = nil,
+
+	["SetText"] = function(self, text)
+		self.text:SetText(text)
+		if self.autoWidth then
+			self:SetWidth(self.text:GetStringWidth() + 30)
+		end
+	end,
+
+	["SetAutoWidth"] = function(self, autoWidth)
+		self.autoWidth = autoWidth
+		if self.autoWidth then
+			self:SetWidth(self.text:GetStringWidth() + 30)
+		end
+	end,
+
+	["SetDisabled"] = function(self, disabled)
+		self.disabled = disabled
+		if disabled then
+			self.frame:Disable()
+		else
+			self.frame:Enable()
+		end
+	end
+}
+
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+local function Constructor()
+	local name = "AceGUI30Button" .. AceGUI:GetNextWidgetNum(Type)
+	local frame = CreateFrame("Button", name, UIParent, wowMoP and "UIPanelButtonTemplate" or "UIPanelButtonTemplate2")
+	frame:Hide()
+
+	frame:EnableMouse(true)
+	frame:SetScript("OnClick", Button_OnClick)
+	frame:SetScript("OnEnter", Control_OnEnter)
+	frame:SetScript("OnLeave", Control_OnLeave)
+
+	local text = frame:GetFontString()
+	text:ClearAllPoints()
+	text:SetPoint("TOPLEFT", 15, -1)
+	text:SetPoint("BOTTOMRIGHT", -15, 1)
+	text:SetJustifyV("MIDDLE")
+
+	local widget = {
+		text  = text,
+		frame = frame,
+		type  = Type
+	}
+	for method, func in pairs(methods) do
+		widget[method] = func
+	end
+
+	return AceGUI:RegisterAsWidget(widget)
+end
+
+AceGUI:RegisterWidgetType(Type, Constructor, Version)
diff --git a/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-CheckBox.lua b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-CheckBox.lua
new file mode 100644
index 0000000..8847ebc
--- /dev/null
+++ b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-CheckBox.lua
@@ -0,0 +1,295 @@
+--[[-----------------------------------------------------------------------------
+Checkbox Widget
+-------------------------------------------------------------------------------]]
+local Type, Version = "CheckBox", 22
+local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
+if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
+
+-- Lua APIs
+local select, pairs = select, pairs
+
+-- WoW APIs
+local PlaySound = PlaySound
+local CreateFrame, UIParent = CreateFrame, UIParent
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: SetDesaturation, GameFontHighlight
+
+--[[-----------------------------------------------------------------------------
+Support functions
+-------------------------------------------------------------------------------]]
+local function AlignImage(self)
+	local img = self.image:GetTexture()
+	self.text:ClearAllPoints()
+	if not img then
+		self.text:SetPoint("LEFT", self.checkbg, "RIGHT")
+		self.text:SetPoint("RIGHT")
+	else
+		self.text:SetPoint("LEFT", self.image,"RIGHT", 1, 0)
+		self.text:SetPoint("RIGHT")
+	end
+end
+
+--[[-----------------------------------------------------------------------------
+Scripts
+-------------------------------------------------------------------------------]]
+local function Control_OnEnter(frame)
+	frame.obj:Fire("OnEnter")
+end
+
+local function Control_OnLeave(frame)
+	frame.obj:Fire("OnLeave")
+end
+
+local function CheckBox_OnMouseDown(frame)
+	local self = frame.obj
+	if not self.disabled then
+		if self.image:GetTexture() then
+			self.text:SetPoint("LEFT", self.image,"RIGHT", 2, -1)
+		else
+			self.text:SetPoint("LEFT", self.checkbg, "RIGHT", 1, -1)
+		end
+	end
+	AceGUI:ClearFocus()
+end
+
+local function CheckBox_OnMouseUp(frame)
+	local self = frame.obj
+	if not self.disabled then
+		self:ToggleChecked()
+
+		if self.checked then
+			PlaySound("igMainMenuOptionCheckBoxOn")
+		else -- for both nil and false (tristate)
+			PlaySound("igMainMenuOptionCheckBoxOff")
+		end
+
+		self:Fire("OnValueChanged", self.checked)
+		AlignImage(self)
+	end
+end
+
+--[[-----------------------------------------------------------------------------
+Methods
+-------------------------------------------------------------------------------]]
+local methods = {
+	["OnAcquire"] = function(self)
+		self:SetType()
+		self:SetValue(false)
+		self:SetTriState(nil)
+		-- height is calculated from the width and required space for the description
+		self:SetWidth(200)
+		self:SetImage()
+		self:SetDisabled(nil)
+		self:SetDescription(nil)
+	end,
+
+	-- ["OnRelease"] = nil,
+
+	["OnWidthSet"] = function(self, width)
+		if self.desc then
+			self.desc:SetWidth(width - 30)
+			if self.desc:GetText() and self.desc:GetText() ~= "" then
+				self:SetHeight(28 + self.desc:GetHeight())
+			end
+		end
+	end,
+
+	["SetDisabled"] = function(self, disabled)
+		self.disabled = disabled
+		if disabled then
+			self.frame:Disable()
+			self.text:SetTextColor(0.5, 0.5, 0.5)
+			SetDesaturation(self.check, true)
+			if self.desc then
+				self.desc:SetTextColor(0.5, 0.5, 0.5)
+			end
+		else
+			self.frame:Enable()
+			self.text:SetTextColor(1, 1, 1)
+			if self.tristate and self.checked == nil then
+				SetDesaturation(self.check, true)
+			else
+				SetDesaturation(self.check, false)
+			end
+			if self.desc then
+				self.desc:SetTextColor(1, 1, 1)
+			end
+		end
+	end,
+
+	["SetValue"] = function(self,value)
+		local check = self.check
+		self.checked = value
+		if value then
+			SetDesaturation(self.check, false)
+			self.check:Show()
+		else
+			--Nil is the unknown tristate value
+			if self.tristate and value == nil then
+				SetDesaturation(self.check, true)
+				self.check:Show()
+			else
+				SetDesaturation(self.check, false)
+				self.check:Hide()
+			end
+		end
+		self:SetDisabled(self.disabled)
+	end,
+
+	["GetValue"] = function(self)
+		return self.checked
+	end,
+
+	["SetTriState"] = function(self, enabled)
+		self.tristate = enabled
+		self:SetValue(self:GetValue())
+	end,
+
+	["SetType"] = function(self, type)
+		local checkbg = self.checkbg
+		local check = self.check
+		local highlight = self.highlight
+
+		local size
+		if type == "radio" then
+			size = 16
+			checkbg:SetTexture("Interface\\Buttons\\UI-RadioButton")
+			checkbg:SetTexCoord(0, 0.25, 0, 1)
+			check:SetTexture("Interface\\Buttons\\UI-RadioButton")
+			check:SetTexCoord(0.25, 0.5, 0, 1)
+			check:SetBlendMode("ADD")
+			highlight:SetTexture("Interface\\Buttons\\UI-RadioButton")
+			highlight:SetTexCoord(0.5, 0.75, 0, 1)
+		else
+			size = 24
+			checkbg:SetTexture("Interface\\Buttons\\UI-CheckBox-Up")
+			checkbg:SetTexCoord(0, 1, 0, 1)
+			check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
+			check:SetTexCoord(0, 1, 0, 1)
+			check:SetBlendMode("BLEND")
+			highlight:SetTexture("Interface\\Buttons\\UI-CheckBox-Highlight")
+			highlight:SetTexCoord(0, 1, 0, 1)
+		end
+		checkbg:SetHeight(size)
+		checkbg:SetWidth(size)
+	end,
+
+	["ToggleChecked"] = function(self)
+		local value = self:GetValue()
+		if self.tristate then
+			--cycle in true, nil, false order
+			if value then
+				self:SetValue(nil)
+			elseif value == nil then
+				self:SetValue(false)
+			else
+				self:SetValue(true)
+			end
+		else
+			self:SetValue(not self:GetValue())
+		end
+	end,
+
+	["SetLabel"] = function(self, label)
+		self.text:SetText(label)
+	end,
+
+	["SetDescription"] = function(self, desc)
+		if desc then
+			if not self.desc then
+				local desc = self.frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
+				desc:ClearAllPoints()
+				desc:SetPoint("TOPLEFT", self.checkbg, "TOPRIGHT", 5, -21)
+				desc:SetWidth(self.frame.width - 30)
+				desc:SetJustifyH("LEFT")
+				desc:SetJustifyV("TOP")
+				self.desc = desc
+			end
+			self.desc:Show()
+			--self.text:SetFontObject(GameFontNormal)
+			self.desc:SetText(desc)
+			self:SetHeight(28 + self.desc:GetHeight())
+		else
+			if self.desc then
+				self.desc:SetText("")
+				self.desc:Hide()
+			end
+			--self.text:SetFontObject(GameFontHighlight)
+			self:SetHeight(24)
+		end
+	end,
+
+	["SetImage"] = function(self, path, ...)
+		local image = self.image
+		image:SetTexture(path)
+
+		if image:GetTexture() then
+			local n = select("#", ...)
+			if n == 4 or n == 8 then
+				image:SetTexCoord(...)
+			else
+				image:SetTexCoord(0, 1, 0, 1)
+			end
+		end
+		AlignImage(self)
+	end
+}
+
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+local function Constructor()
+	local frame = CreateFrame("Button", nil, UIParent)
+	frame:Hide()
+
+	frame:EnableMouse(true)
+	frame:SetScript("OnEnter", Control_OnEnter)
+	frame:SetScript("OnLeave", Control_OnLeave)
+	frame:SetScript("OnMouseDown", CheckBox_OnMouseDown)
+	frame:SetScript("OnMouseUp", CheckBox_OnMouseUp)
+
+	local checkbg = frame:CreateTexture(nil, "ARTWORK")
+	checkbg:SetWidth(24)
+	checkbg:SetHeight(24)
+	checkbg:SetPoint("TOPLEFT")
+	checkbg:SetTexture("Interface\\Buttons\\UI-CheckBox-Up")
+
+	local check = frame:CreateTexture(nil, "OVERLAY")
+	check:SetAllPoints(checkbg)
+	check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
+
+	local text = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
+	text:SetJustifyH("LEFT")
+	text:SetHeight(18)
+	text:SetPoint("LEFT", checkbg, "RIGHT")
+	text:SetPoint("RIGHT")
+
+	local highlight = frame:CreateTexture(nil, "HIGHLIGHT")
+	highlight:SetTexture("Interface\\Buttons\\UI-CheckBox-Highlight")
+	highlight:SetBlendMode("ADD")
+	highlight:SetAllPoints(checkbg)
+
+	local image = frame:CreateTexture(nil, "OVERLAY")
+	image:SetHeight(16)
+	image:SetWidth(16)
+	image:SetPoint("LEFT", checkbg, "RIGHT", 1, 0)
+
+	local widget = {
+		checkbg   = checkbg,
+		check     = check,
+		text      = text,
+		highlight = highlight,
+		image     = image,
+		frame     = frame,
+		type      = Type
+	}
+	for method, func in pairs(methods) do
+		widget[method] = func
+	end
+
+	return AceGUI:RegisterAsWidget(widget)
+end
+
+AceGUI:RegisterWidgetType(Type, Constructor, Version)
diff --git a/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-ColorPicker.lua b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-ColorPicker.lua
new file mode 100644
index 0000000..59f8d60
--- /dev/null
+++ b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-ColorPicker.lua
@@ -0,0 +1,188 @@
+--[[-----------------------------------------------------------------------------
+ColorPicker Widget
+-------------------------------------------------------------------------------]]
+local Type, Version = "ColorPicker", 22
+local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
+if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
+
+-- Lua APIs
+local pairs = pairs
+
+-- WoW APIs
+local CreateFrame, UIParent = CreateFrame, UIParent
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: ShowUIPanel, HideUIPanel, ColorPickerFrame, OpacitySliderFrame
+
+--[[-----------------------------------------------------------------------------
+Support functions
+-------------------------------------------------------------------------------]]
+local function ColorCallback(self, r, g, b, a, isAlpha)
+	if not self.HasAlpha then
+		a = 1
+	end
+	self:SetColor(r, g, b, a)
+	if ColorPickerFrame:IsVisible() then
+		--colorpicker is still open
+		self:Fire("OnValueChanged", r, g, b, a)
+	else
+		--colorpicker is closed, color callback is first, ignore it,
+		--alpha callback is the final call after it closes so confirm now
+		if isAlpha then
+			self:Fire("OnValueConfirmed", r, g, b, a)
+		end
+	end
+end
+
+--[[-----------------------------------------------------------------------------
+Scripts
+-------------------------------------------------------------------------------]]
+local function Control_OnEnter(frame)
+	frame.obj:Fire("OnEnter")
+end
+
+local function Control_OnLeave(frame)
+	frame.obj:Fire("OnLeave")
+end
+
+local function ColorSwatch_OnClick(frame)
+	HideUIPanel(ColorPickerFrame)
+	local self = frame.obj
+	if not self.disabled then
+		ColorPickerFrame:SetFrameStrata("FULLSCREEN_DIALOG")
+		ColorPickerFrame:SetFrameLevel(frame:GetFrameLevel() + 10)
+		ColorPickerFrame:SetClampedToScreen(true)
+
+		ColorPickerFrame.func = function()
+			local r, g, b = ColorPickerFrame:GetColorRGB()
+			local a = 1 - OpacitySliderFrame:GetValue()
+			ColorCallback(self, r, g, b, a)
+		end
+
+		ColorPickerFrame.hasOpacity = self.HasAlpha
+		ColorPickerFrame.opacityFunc = function()
+			local r, g, b = ColorPickerFrame:GetColorRGB()
+			local a = 1 - OpacitySliderFrame:GetValue()
+			ColorCallback(self, r, g, b, a, true)
+		end
+
+		local r, g, b, a = self.r, self.g, self.b, self.a
+		if self.HasAlpha then
+			ColorPickerFrame.opacity = 1 - (a or 0)
+		end
+		ColorPickerFrame:SetColorRGB(r, g, b)
+
+		ColorPickerFrame.cancelFunc = function()
+			ColorCallback(self, r, g, b, a, true)
+		end
+
+		ShowUIPanel(ColorPickerFrame)
+	end
+	AceGUI:ClearFocus()
+end
+
+--[[-----------------------------------------------------------------------------
+Methods
+-------------------------------------------------------------------------------]]
+local methods = {
+	["OnAcquire"] = function(self)
+		self:SetHeight(24)
+		self:SetWidth(200)
+		self:SetHasAlpha(false)
+		self:SetColor(0, 0, 0, 1)
+		self:SetDisabled(nil)
+		self:SetLabel(nil)
+	end,
+
+	-- ["OnRelease"] = nil,
+
+	["SetLabel"] = function(self, text)
+		self.text:SetText(text)
+	end,
+
+	["SetColor"] = function(self, r, g, b, a)
+		self.r = r
+		self.g = g
+		self.b = b
+		self.a = a or 1
+		self.colorSwatch:SetVertexColor(r, g, b, a)
+	end,
+
+	["SetHasAlpha"] = function(self, HasAlpha)
+		self.HasAlpha = HasAlpha
+	end,
+
+	["SetDisabled"] = function(self, disabled)
+		self.disabled = disabled
+		if self.disabled then
+			self.frame:Disable()
+			self.text:SetTextColor(0.5, 0.5, 0.5)
+		else
+			self.frame:Enable()
+			self.text:SetTextColor(1, 1, 1)
+		end
+	end
+}
+
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+local function Constructor()
+	local frame = CreateFrame("Button", nil, UIParent)
+	frame:Hide()
+
+	frame:EnableMouse(true)
+	frame:SetScript("OnEnter", Control_OnEnter)
+	frame:SetScript("OnLeave", Control_OnLeave)
+	frame:SetScript("OnClick", ColorSwatch_OnClick)
+
+	local colorSwatch = frame:CreateTexture(nil, "OVERLAY")
+	colorSwatch:SetWidth(19)
+	colorSwatch:SetHeight(19)
+	colorSwatch:SetTexture("Interface\\ChatFrame\\ChatFrameColorSwatch")
+	colorSwatch:SetPoint("LEFT")
+
+	local texture = frame:CreateTexture(nil, "BACKGROUND")
+	texture:SetWidth(16)
+	texture:SetHeight(16)
+	texture:SetColorTexture(1, 1, 1)
+	texture:SetPoint("CENTER", colorSwatch)
+	texture:Show()
+
+	local checkers = frame:CreateTexture(nil, "BACKGROUND")
+	checkers:SetWidth(14)
+	checkers:SetHeight(14)
+	checkers:SetTexture("Tileset\\Generic\\Checkers")
+	checkers:SetTexCoord(.25, 0, 0.5, .25)
+	checkers:SetDesaturated(true)
+	checkers:SetVertexColor(1, 1, 1, 0.75)
+	checkers:SetPoint("CENTER", colorSwatch)
+	checkers:Show()
+
+	local text = frame:CreateFontString(nil,"OVERLAY","GameFontHighlight")
+	text:SetHeight(24)
+	text:SetJustifyH("LEFT")
+	text:SetTextColor(1, 1, 1)
+	text:SetPoint("LEFT", colorSwatch, "RIGHT", 2, 0)
+	text:SetPoint("RIGHT")
+
+	--local highlight = frame:CreateTexture(nil, "HIGHLIGHT")
+	--highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
+	--highlight:SetBlendMode("ADD")
+	--highlight:SetAllPoints(frame)
+
+	local widget = {
+		colorSwatch = colorSwatch,
+		text        = text,
+		frame       = frame,
+		type        = Type
+	}
+	for method, func in pairs(methods) do
+		widget[method] = func
+	end
+
+	return AceGUI:RegisterAsWidget(widget)
+end
+
+AceGUI:RegisterWidgetType(Type, Constructor, Version)
diff --git a/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown-Items.lua b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown-Items.lua
new file mode 100644
index 0000000..1d80f11
--- /dev/null
+++ b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown-Items.lua
@@ -0,0 +1,471 @@
+--[[ $Id: AceGUIWidget-DropDown-Items.lua 996 2010-12-01 18:34:17Z nevcairiel $ ]]--
+
+local AceGUI = LibStub("AceGUI-3.0")
+
+-- Lua APIs
+local select, assert = select, assert
+
+-- WoW APIs
+local PlaySound = PlaySound
+local CreateFrame = CreateFrame
+
+local function fixlevels(parent,...)
+	local i = 1
+	local child = select(i, ...)
+	while child do
+		child:SetFrameLevel(parent:GetFrameLevel()+1)
+		fixlevels(child, child:GetChildren())
+		i = i + 1
+		child = select(i, ...)
+	end
+end
+
+local function fixstrata(strata, parent, ...)
+	local i = 1
+	local child = select(i, ...)
+	parent:SetFrameStrata(strata)
+	while child do
+		fixstrata(strata, child, child:GetChildren())
+		i = i + 1
+		child = select(i, ...)
+	end
+end
+
+-- ItemBase is the base "class" for all dropdown items.
+-- Each item has to use ItemBase.Create(widgetType) to
+-- create an initial 'self' value.
+-- ItemBase will add common functions and ui event handlers.
+-- Be sure to keep basic usage when you override functions.
+
+local ItemBase = {
+	-- NOTE: The ItemBase version is added to each item's version number
+	--       to ensure proper updates on ItemBase changes.
+	--       Use at least 1000er steps.
+	version = 1000,
+	counter = 0,
+}
+
+function ItemBase.Frame_OnEnter(this)
+	local self = this.obj
+
+	if self.useHighlight then
+		self.highlight:Show()
+	end
+	self:Fire("OnEnter")
+
+	if self.specialOnEnter then
+		self.specialOnEnter(self)
+	end
+end
+
+function ItemBase.Frame_OnLeave(this)
+	local self = this.obj
+
+	self.highlight:Hide()
+	self:Fire("OnLeave")
+
+	if self.specialOnLeave then
+		self.specialOnLeave(self)
+	end
+end
+
+-- exported, AceGUI callback
+function ItemBase.OnAcquire(self)
+	self.frame:SetToplevel(true)
+	self.frame:SetFrameStrata("FULLSCREEN_DIALOG")
+end
+
+-- exported, AceGUI callback
+function ItemBase.OnRelease(self)
+	self:SetDisabled(false)
+	self.pullout = nil
+	self.frame:SetParent(nil)
+	self.frame:ClearAllPoints()
+	self.frame:Hide()
+end
+
+-- exported
+-- NOTE: this is called by a Dropdown-Pullout.
+--       Do not call this method directly
+function ItemBase.SetPullout(self, pullout)
+	self.pullout = pullout
+
+	self.frame:SetParent(nil)
+	self.frame:SetParent(pullout.itemFrame)
+	self.parent = pullout.itemFrame
+	fixlevels(pullout.itemFrame, pullout.itemFrame:GetChildren())
+end
+
+-- exported
+function ItemBase.SetText(self, text)
+	self.text:SetText(text or "")
+end
+
+-- exported
+function ItemBase.GetText(self)
+	return self.text:GetText()
+end
+
+-- exported
+function ItemBase.SetPoint(self, ...)
+	self.frame:SetPoint(...)
+end
+
+-- exported
+function ItemBase.Show(self)
+	self.frame:Show()
+end
+
+-- exported
+function ItemBase.Hide(self)
+	self.frame:Hide()
+end
+
+-- exported
+function ItemBase.SetDisabled(self, disabled)
+	self.disabled = disabled
+	if disabled then
+		self.useHighlight = false
+		self.text:SetTextColor(.5, .5, .5)
+	else
+		self.useHighlight = true
+		self.text:SetTextColor(1, 1, 1)
+	end
+end
+
+-- exported
+-- NOTE: this is called by a Dropdown-Pullout.
+--       Do not call this method directly
+function ItemBase.SetOnLeave(self, func)
+	self.specialOnLeave = func
+end
+
+-- exported
+-- NOTE: this is called by a Dropdown-Pullout.
+--       Do not call this method directly
+function ItemBase.SetOnEnter(self, func)
+	self.specialOnEnter = func
+end
+
+function ItemBase.Create(type)
+	-- NOTE: Most of the following code is copied from AceGUI-3.0/Dropdown widget
+	local count = AceGUI:GetNextWidgetNum(type)
+	local frame = CreateFrame("Button", "AceGUI30DropDownItem"..count)
+	local self = {}
+	self.frame = frame
+	frame.obj = self
+	self.type = type
+
+	self.useHighlight = true
+
+	frame:SetHeight(17)
+	frame:SetFrameStrata("FULLSCREEN_DIALOG")
+
+	local text = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
+	text:SetTextColor(1,1,1)
+	text:SetJustifyH("LEFT")
+	text:SetPoint("TOPLEFT",frame,"TOPLEFT",18,0)
+	text:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-8,0)
+	self.text = text
+
+	local highlight = frame:CreateTexture(nil, "OVERLAY")
+	highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
+	highlight:SetBlendMode("ADD")
+	highlight:SetHeight(14)
+	highlight:ClearAllPoints()
+	highlight:SetPoint("RIGHT",frame,"RIGHT",-3,0)
+	highlight:SetPoint("LEFT",frame,"LEFT",5,0)
+	highlight:Hide()
+	self.highlight = highlight
+
+	local check = frame:CreateTexture("OVERLAY")
+	check:SetWidth(16)
+	check:SetHeight(16)
+	check:SetPoint("LEFT",frame,"LEFT",3,-1)
+	check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
+	check:Hide()
+	self.check = check
+
+	local sub = frame:CreateTexture("OVERLAY")
+	sub:SetWidth(16)
+	sub:SetHeight(16)
+	sub:SetPoint("RIGHT",frame,"RIGHT",-3,-1)
+	sub:SetTexture("Interface\\ChatFrame\\ChatFrameExpandArrow")
+	sub:Hide()
+	self.sub = sub
+
+	frame:SetScript("OnEnter", ItemBase.Frame_OnEnter)
+	frame:SetScript("OnLeave", ItemBase.Frame_OnLeave)
+
+	self.OnAcquire = ItemBase.OnAcquire
+	self.OnRelease = ItemBase.OnRelease
+
+	self.SetPullout = ItemBase.SetPullout
+	self.GetText    = ItemBase.GetText
+	self.SetText    = ItemBase.SetText
+	self.SetDisabled = ItemBase.SetDisabled
+
+	self.SetPoint   = ItemBase.SetPoint
+	self.Show       = ItemBase.Show
+	self.Hide       = ItemBase.Hide
+
+	self.SetOnLeave = ItemBase.SetOnLeave
+	self.SetOnEnter = ItemBase.SetOnEnter
+
+	return self
+end
+
+-- Register a dummy LibStub library to retrieve the ItemBase, so other addons can use it.
+local IBLib = LibStub:NewLibrary("AceGUI-3.0-DropDown-ItemBase", ItemBase.version)
+if IBLib then
+	IBLib.GetItemBase = function() return ItemBase end
+end
+
+--[[
+	Template for items:
+
+-- Item:
+--
+do
+	local widgetType = "Dropdown-Item-"
+	local widgetVersion = 1
+
+	local function Constructor()
+		local self = ItemBase.Create(widgetType)
+
+		AceGUI:RegisterAsWidget(self)
+		return self
+	end
+
+	AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
+end
+--]]
+
+-- Item: Header
+-- A single text entry.
+-- Special: Different text color and no highlight
+do
+	local widgetType = "Dropdown-Item-Header"
+	local widgetVersion = 1
+
+	local function OnEnter(this)
+		local self = this.obj
+		self:Fire("OnEnter")
+
+		if self.specialOnEnter then
+			self.specialOnEnter(self)
+		end
+	end
+
+	local function OnLeave(this)
+		local self = this.obj
+		self:Fire("OnLeave")
+
+		if self.specialOnLeave then
+			self.specialOnLeave(self)
+		end
+	end
+
+	-- exported, override
+	local function SetDisabled(self, disabled)
+		ItemBase.SetDisabled(self, disabled)
+		if not disabled then
+			self.text:SetTextColor(1, 1, 0)
+		end
+	end
+
+	local function Constructor()
+		local self = ItemBase.Create(widgetType)
+
+		self.SetDisabled = SetDisabled
+
+		self.frame:SetScript("OnEnter", OnEnter)
+		self.frame:SetScript("OnLeave", OnLeave)
+
+		self.text:SetTextColor(1, 1, 0)
+
+		AceGUI:RegisterAsWidget(self)
+		return self
+	end
+
+	AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
+end
+
+-- Item: Execute
+-- A simple button
+do
+	local widgetType = "Dropdown-Item-Execute"
+	local widgetVersion = 1
+
+	local function Frame_OnClick(this, button)
+		local self = this.obj
+		if self.disabled then return end
+		self:Fire("OnClick")
+		if self.pullout then
+			self.pullout:Close()
+		end
+	end
+
+	local function Constructor()
+		local self = ItemBase.Create(widgetType)
+
+		self.frame:SetScript("OnClick", Frame_OnClick)
+
+		AceGUI:RegisterAsWidget(self)
+		return self
+	end
+
+	AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
+end
+
+-- Item: Toggle
+-- Some sort of checkbox for dropdown menus.
+-- Does not close the pullout on click.
+do
+	local widgetType = "Dropdown-Item-Toggle"
+	local widgetVersion = 3
+
+	local function UpdateToggle(self)
+		if self.value then
+			self.check:Show()
+		else
+			self.check:Hide()
+		end
+	end
+
+	local function OnRelease(self)
+		ItemBase.OnRelease(self)
+		self:SetValue(nil)
+	end
+
+	local function Frame_OnClick(this, button)
+		local self = this.obj
+		if self.disabled then return end
+		self.value = not self.value
+		if self.value then
+			PlaySound("igMainMenuOptionCheckBoxOn")
+		else
+			PlaySound("igMainMenuOptionCheckBoxOff")
+		end
+		UpdateToggle(self)
+		self:Fire("OnValueChanged", self.value)
+	end
+
+	-- exported
+	local function SetValue(self, value)
+		self.value = value
+		UpdateToggle(self)
+	end
+
+	-- exported
+	local function GetValue(self)
+		return self.value
+	end
+
+	local function Constructor()
+		local self = ItemBase.Create(widgetType)
+
+		self.frame:SetScript("OnClick", Frame_OnClick)
+
+		self.SetValue = SetValue
+		self.GetValue = GetValue
+		self.OnRelease = OnRelease
+
+		AceGUI:RegisterAsWidget(self)
+		return self
+	end
+
+	AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
+end
+
+-- Item: Menu
+-- Shows a submenu on mouse over
+-- Does not close the pullout on click
+do
+	local widgetType = "Dropdown-Item-Menu"
+	local widgetVersion = 2
+
+	local function OnEnter(this)
+		local self = this.obj
+		self:Fire("OnEnter")
+
+		if self.specialOnEnter then
+			self.specialOnEnter(self)
+		end
+
+		self.highlight:Show()
+
+		if not self.disabled and self.submenu then
+			self.submenu:Open("TOPLEFT", self.frame, "TOPRIGHT", self.pullout:GetRightBorderWidth(), 0, self.frame:GetFrameLevel() + 100)
+		end
+	end
+
+	local function OnHide(this)
+		local self = this.obj
+		if self.submenu then
+			self.submenu:Close()
+		end
+	end
+
+	-- exported
+	local function SetMenu(self, menu)
+		assert(menu.type == "Dropdown-Pullout")
+		self.submenu = menu
+	end
+
+	-- exported
+	local function CloseMenu(self)
+		self.submenu:Close()
+	end
+
+	local function Constructor()
+		local self = ItemBase.Create(widgetType)
+
+		self.sub:Show()
+
+		self.frame:SetScript("OnEnter", OnEnter)
+		self.frame:SetScript("OnHide", OnHide)
+
+		self.SetMenu   = SetMenu
+		self.CloseMenu = CloseMenu
+
+		AceGUI:RegisterAsWidget(self)
+		return self
+	end
+
+	AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
+end
+
+-- Item: Separator
+-- A single line to separate items
+do
+	local widgetType = "Dropdown-Item-Separator"
+	local widgetVersion = 1
+
+	-- exported, override
+	local function SetDisabled(self, disabled)
+		ItemBase.SetDisabled(self, disabled)
+		self.useHighlight = false
+	end
+
+	local function Constructor()
+		local self = ItemBase.Create(widgetType)
+
+		self.SetDisabled = SetDisabled
+
+		local line = self.frame:CreateTexture(nil, "OVERLAY")
+		line:SetHeight(1)
+		line:SetColorTexture(.5, .5, .5)
+		line:SetPoint("LEFT", self.frame, "LEFT", 10, 0)
+		line:SetPoint("RIGHT", self.frame, "RIGHT", -10, 0)
+
+		self.text:Hide()
+
+		self.useHighlight = false
+
+		AceGUI:RegisterAsWidget(self)
+		return self
+	end
+
+	AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
+end
diff --git a/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown.lua b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown.lua
new file mode 100644
index 0000000..0dd3bff
--- /dev/null
+++ b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown.lua
@@ -0,0 +1,737 @@
+--[[ $Id: AceGUIWidget-DropDown.lua 1116 2014-10-12 08:15:46Z nevcairiel $ ]]--
+local AceGUI = LibStub("AceGUI-3.0")
+
+-- Lua APIs
+local min, max, floor = math.min, math.max, math.floor
+local select, pairs, ipairs, type = select, pairs, ipairs, type
+local tsort = table.sort
+
+-- WoW APIs
+local PlaySound = PlaySound
+local UIParent, CreateFrame = UIParent, CreateFrame
+local _G = _G
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: CLOSE
+
+local function fixlevels(parent,...)
+	local i = 1
+	local child = select(i, ...)
+	while child do
+		child:SetFrameLevel(parent:GetFrameLevel()+1)
+		fixlevels(child, child:GetChildren())
+		i = i + 1
+		child = select(i, ...)
+	end
+end
+
+local function fixstrata(strata, parent, ...)
+	local i = 1
+	local child = select(i, ...)
+	parent:SetFrameStrata(strata)
+	while child do
+		fixstrata(strata, child, child:GetChildren())
+		i = i + 1
+		child = select(i, ...)
+	end
+end
+
+do
+	local widgetType = "Dropdown-Pullout"
+	local widgetVersion = 3
+
+	--[[ Static data ]]--
+
+	local backdrop = {
+		bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
+		edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
+		edgeSize = 32,
+		tileSize = 32,
+		tile = true,
+		insets = { left = 11, right = 12, top = 12, bottom = 11 },
+	}
+	local sliderBackdrop  = {
+		bgFile = "Interface\\Buttons\\UI-SliderBar-Background",
+		edgeFile = "Interface\\Buttons\\UI-SliderBar-Border",
+		tile = true, tileSize = 8, edgeSize = 8,
+		insets = { left = 3, right = 3, top = 3, bottom = 3 }
+	}
+
+	local defaultWidth = 200
+	local defaultMaxHeight = 600
+
+	--[[ UI Event Handlers ]]--
+
+	-- HACK: This should be no part of the pullout, but there
+	--       is no other 'clean' way to response to any item-OnEnter
+	--       Used to close Submenus when an other item is entered
+	local function OnEnter(item)
+		local self = item.pullout
+		for k, v in ipairs(self.items) do
+			if v.CloseMenu and v ~= item then
+				v:CloseMenu()
+			end
+		end
+	end
+
+	-- See the note in Constructor() for each scroll related function
+	local function OnMouseWheel(this, value)
+		this.obj:MoveScroll(value)
+	end
+
+	local function OnScrollValueChanged(this, value)
+		this.obj:SetScroll(value)
+	end
+
+	local function OnSizeChanged(this)
+		this.obj:FixScroll()
+	end
+
+	--[[ Exported methods ]]--
+
+	-- exported
+	local function SetScroll(self, value)
+		local status = self.scrollStatus
+		local frame, child = self.scrollFrame, self.itemFrame
+		local height, viewheight = frame:GetHeight(), child:GetHeight()
+
+		local offset
+		if height > viewheight then
+			offset = 0
+		else
+			offset = floor((viewheight - height) / 1000 * value)
+		end
+		child:ClearAllPoints()
+		child:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, offset)
+		child:SetPoint("TOPRIGHT", frame, "TOPRIGHT", self.slider:IsShown() and -12 or 0, offset)
+		status.offset = offset
+		status.scrollvalue = value
+	end
+
+	-- exported
+	local function MoveScroll(self, value)
+		local status = self.scrollStatus
+		local frame, child = self.scrollFrame, self.itemFrame
+		local height, viewheight = frame:GetHeight(), child:GetHeight()
+
+		if height > viewheight then
+			self.slider:Hide()
+		else
+			self.slider:Show()
+			local diff = height - viewheight
+			local delta = 1
+			if value < 0 then
+				delta = -1
+			end
+			self.slider:SetValue(min(max(status.scrollvalue + delta*(1000/(diff/45)),0), 1000))
+		end
+	end
+
+	-- exported
+	local function FixScroll(self)
+		local status = self.scrollStatus
+		local frame, child = self.scrollFrame, self.itemFrame
+		local height, viewheight = frame:GetHeight(), child:GetHeight()
+		local offset = status.offset or 0
+
+		if viewheight < height then
+			self.slider:Hide()
+			child:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 0, offset)
+			self.slider:SetValue(0)
+		else
+			self.slider:Show()
+			local value = (offset / (viewheight - height) * 1000)
+			if value > 1000 then value = 1000 end
+			self.slider:SetValue(value)
+			self:SetScroll(value)
+			if value < 1000 then
+				child:ClearAllPoints()
+				child:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, offset)
+				child:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -12, offset)
+				status.offset = offset
+			end
+		end
+	end
+
+	-- exported, AceGUI callback
+	local function OnAcquire(self)
+		self.frame:SetParent(UIParent)
+		--self.itemFrame:SetToplevel(true)
+	end
+
+	-- exported, AceGUI callback
+	local function OnRelease(self)
+		self:Clear()
+		self.frame:ClearAllPoints()
+		self.frame:Hide()
+	end
+
+	-- exported
+	local function AddItem(self, item)
+		self.items[#self.items + 1] = item
+
+		local h = #self.items * 16
+		self.itemFrame:SetHeight(h)
+		self.frame:SetHeight(min(h + 34, self.maxHeight)) -- +34: 20 for scrollFrame placement (10 offset) and +14 for item placement
+
+		item.frame:SetPoint("LEFT", self.itemFrame, "LEFT")
+		item.frame:SetPoint("RIGHT", self.itemFrame, "RIGHT")
+
+		item:SetPullout(self)
+		item:SetOnEnter(OnEnter)
+	end
+
+	-- exported
+	local function Open(self, point, relFrame, relPoint, x, y)
+		local items = self.items
+		local frame = self.frame
+		local itemFrame = self.itemFrame
+
+		frame:SetPoint(point, relFrame, relPoint, x, y)
+
+
+		local height = 8
+		for i, item in pairs(items) do
+			if i == 1 then
+				item:SetPoint("TOP", itemFrame, "TOP", 0, -2)
+			else
+				item:SetPoint("TOP", items[i-1].frame, "BOTTOM", 0, 1)
+			end
+
+			item:Show()
+
+			height = height + 16
+		end
+		itemFrame:SetHeight(height)
+		fixstrata("TOOLTIP", frame, frame:GetChildren())
+		frame:Show()
+		self:Fire("OnOpen")
+	end
+
+	-- exported
+	local function Close(self)
+		self.frame:Hide()
+		self:Fire("OnClose")
+	end
+
+	-- exported
+	local function Clear(self)
+		local items = self.items
+		for i, item in pairs(items) do
+			AceGUI:Release(item)
+			items[i] = nil
+		end
+	end
+
+	-- exported
+	local function IterateItems(self)
+		return ipairs(self.items)
+	end
+
+	-- exported
+	local function SetHideOnLeave(self, val)
+		self.hideOnLeave = val
+	end
+
+	-- exported
+	local function SetMaxHeight(self, height)
+		self.maxHeight = height or defaultMaxHeight
+		if self.frame:GetHeight() > height then
+			self.frame:SetHeight(height)
+		elseif (self.itemFrame:GetHeight() + 34) < height then
+			self.frame:SetHeight(self.itemFrame:GetHeight() + 34) -- see :AddItem
+		end
+	end
+
+	-- exported
+	local function GetRightBorderWidth(self)
+		return 6 + (self.slider:IsShown() and 12 or 0)
+	end
+
+	-- exported
+	local function GetLeftBorderWidth(self)
+		return 6
+	end
+
+	--[[ Constructor ]]--
+
+	local function Constructor()
+		local count = AceGUI:GetNextWidgetNum(widgetType)
+		local frame = CreateFrame("Frame", "AceGUI30Pullout"..count, UIParent)
+		local self = {}
+		self.count = count
+		self.type = widgetType
+		self.frame = frame
+		frame.obj = self
+
+		self.OnAcquire = OnAcquire
+		self.OnRelease = OnRelease
+
+		self.AddItem = AddItem
+		self.Open    = Open
+		self.Close   = Close
+		self.Clear   = Clear
+		self.IterateItems = IterateItems
+		self.SetHideOnLeave = SetHideOnLeave
+
+		self.SetScroll  = SetScroll
+		self.MoveScroll = MoveScroll
+		self.FixScroll  = FixScroll
+
+		self.SetMaxHeight = SetMaxHeight
+		self.GetRightBorderWidth = GetRightBorderWidth
+		self.GetLeftBorderWidth = GetLeftBorderWidth
+
+		self.items = {}
+
+		self.scrollStatus = {
+			scrollvalue = 0,
+		}
+
+		self.maxHeight = defaultMaxHeight
+
+		frame:SetBackdrop(backdrop)
+		frame:SetBackdropColor(0, 0, 0)
+		frame:SetFrameStrata("FULLSCREEN_DIALOG")
+		frame:SetClampedToScreen(true)
+		frame:SetWidth(defaultWidth)
+		frame:SetHeight(self.maxHeight)
+		--frame:SetToplevel(true)
+
+		-- NOTE: The whole scroll frame code is copied from the AceGUI-3.0 widget ScrollFrame
+		local scrollFrame = CreateFrame("ScrollFrame", nil, frame)
+		local itemFrame = CreateFrame("Frame", nil, scrollFrame)
+
+		self.scrollFrame = scrollFrame
+		self.itemFrame = itemFrame
+
+		scrollFrame.obj = self
+		itemFrame.obj = self
+
+		local slider = CreateFrame("Slider", "AceGUI30PulloutScrollbar"..count, scrollFrame)
+		slider:SetOrientation("VERTICAL")
+		slider:SetHitRectInsets(0, 0, -10, 0)
+		slider:SetBackdrop(sliderBackdrop)
+		slider:SetWidth(8)
+		slider:SetThumbTexture("Interface\\Buttons\\UI-SliderBar-Button-Vertical")
+		slider:SetFrameStrata("FULLSCREEN_DIALOG")
+		self.slider = slider
+		slider.obj = self
+
+		scrollFrame:SetScrollChild(itemFrame)
+		scrollFrame:SetPoint("TOPLEFT", frame, "TOPLEFT", 6, -12)
+		scrollFrame:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -6, 12)
+		scrollFrame:EnableMouseWheel(true)
+		scrollFrame:SetScript("OnMouseWheel", OnMouseWheel)
+		scrollFrame:SetScript("OnSizeChanged", OnSizeChanged)
+		scrollFrame:SetToplevel(true)
+		scrollFrame:SetFrameStrata("FULLSCREEN_DIALOG")
+
+		itemFrame:SetPoint("TOPLEFT", scrollFrame, "TOPLEFT", 0, 0)
+		itemFrame:SetPoint("TOPRIGHT", scrollFrame, "TOPRIGHT", -12, 0)
+		itemFrame:SetHeight(400)
+		itemFrame:SetToplevel(true)
+		itemFrame:SetFrameStrata("FULLSCREEN_DIALOG")
+
+		slider:SetPoint("TOPLEFT", scrollFrame, "TOPRIGHT", -16, 0)
+		slider:SetPoint("BOTTOMLEFT", scrollFrame, "BOTTOMRIGHT", -16, 0)
+		slider:SetScript("OnValueChanged", OnScrollValueChanged)
+		slider:SetMinMaxValues(0, 1000)
+		slider:SetValueStep(1)
+		slider:SetValue(0)
+
+		scrollFrame:Show()
+		itemFrame:Show()
+		slider:Hide()
+
+		self:FixScroll()
+
+		AceGUI:RegisterAsWidget(self)
+		return self
+	end
+
+	AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion)
+end
+
+do
+	local widgetType = "Dropdown"
+	local widgetVersion = 30
+
+	--[[ Static data ]]--
+
+	--[[ UI event handler ]]--
+
+	local function Control_OnEnter(this)
+		this.obj.button:LockHighlight()
+		this.obj:Fire("OnEnter")
+	end
+
+	local function Control_OnLeave(this)
+		this.obj.button:UnlockHighlight()
+		this.obj:Fire("OnLeave")
+	end
+
+	local function Dropdown_OnHide(this)
+		local self = this.obj
+		if self.open then
+			self.pullout:Close()
+		end
+	end
+
+	local function Dropdown_TogglePullout(this)
+		local self = this.obj
+		PlaySound("igMainMenuOptionCheckBoxOn") -- missleading name, but the Blizzard code uses this sound
+		if self.open then
+			self.open = nil
+			self.pullout:Close()
+			AceGUI:ClearFocus()
+		else
+			self.open = true
+			self.pullout:SetWidth(self.pulloutWidth or self.frame:GetWidth())
+			self.pullout:Open("TOPLEFT", self.frame, "BOTTOMLEFT", 0, self.label:IsShown() and -2 or 0)
+			AceGUI:SetFocus(self)
+		end
+	end
+
+	local function OnPulloutOpen(this)
+		local self = this.userdata.obj
+		local value = self.value
+
+		if not self.multiselect then
+			for i, item in this:IterateItems() do
+				item:SetValue(item.userdata.value == value)
+			end
+		end
+
+		self.open = true
+		self:Fire("OnOpened")
+	end
+
+	local function OnPulloutClose(this)
+		local self = this.userdata.obj
+		self.open = nil
+		self:Fire("OnClosed")
+	end
+
+	local function ShowMultiText(self)
+		local text
+		for i, widget in self.pullout:IterateItems() do
+			if widget.type == "Dropdown-Item-Toggle" then
+				if widget:GetValue() then
+					if text then
+						text = text..", "..widget:GetText()
+					else
+						text = widget:GetText()
+					end
+				end
+			end
+		end
+		self:SetText(text)
+	end
+
+	local function OnItemValueChanged(this, event, checked)
+		local self = this.userdata.obj
+
+		if self.multiselect then
+			self:Fire("OnValueChanged", this.userdata.value, checked)
+			ShowMultiText(self)
+		else
+			if checked then
+				self:SetValue(this.userdata.value)
+				self:Fire("OnValueChanged", this.userdata.value)
+			else
+				this:SetValue(true)
+			end
+			if self.open then
+				self.pullout:Close()
+			end
+		end
+	end
+
+	--[[ Exported methods ]]--
+
+	-- exported, AceGUI callback
+	local function OnAcquire(self)
+		local pullout = AceGUI:Create("Dropdown-Pullout")
+		self.pullout = pullout
+		pullout.userdata.obj = self
+		pullout:SetCallback("OnClose", OnPulloutClose)
+		pullout:SetCallback("OnOpen", OnPulloutOpen)
+		self.pullout.frame:SetFrameLevel(self.frame:GetFrameLevel() + 1)
+		fixlevels(self.pullout.frame, self.pullout.frame:GetChildren())
+
+		self:SetHeight(44)
+		self:SetWidth(200)
+		self:SetLabel()
+		self:SetPulloutWidth(nil)
+	end
+
+	-- exported, AceGUI callback
+	local function OnRelease(self)
+		if self.open then
+			self.pullout:Close()
+		end
+		AceGUI:Release(self.pullout)
+		self.pullout = nil
+
+		self:SetText("")
+		self:SetDisabled(false)
+		self:SetMultiselect(false)
+
+		self.value = nil
+		self.list = nil
+		self.open = nil
+		self.hasClose = nil
+
+		self.frame:ClearAllPoints()
+		self.frame:Hide()
+	end
+
+	-- exported
+	local function SetDisabled(self, disabled)
+		self.disabled = disabled
+		if disabled then
+			self.text:SetTextColor(0.5,0.5,0.5)
+			self.button:Disable()
+			self.button_cover:Disable()
+			self.label:SetTextColor(0.5,0.5,0.5)
+		else
+			self.button:Enable()
+			self.button_cover:Enable()
+			self.label:SetTextColor(1,.82,0)
+			self.text:SetTextColor(1,1,1)
+		end
+	end
+
+	-- exported
+	local function ClearFocus(self)
+		if self.open then
+			self.pullout:Close()
+		end
+	end
+
+	-- exported
+	local function SetText(self, text)
+		self.text:SetText(text or "")
+	end
+
+	-- exported
+	local function SetLabel(self, text)
+		if text and text ~= "" then
+			self.label:SetText(text)
+			self.label:Show()
+			self.dropdown:SetPoint("TOPLEFT",self.frame,"TOPLEFT",-15,-14)
+			self:SetHeight(40)
+			self.alignoffset = 26
+		else
+			self.label:SetText("")
+			self.label:Hide()
+			self.dropdown:SetPoint("TOPLEFT",self.frame,"TOPLEFT",-15,0)
+			self:SetHeight(26)
+			self.alignoffset = 12
+		end
+	end
+
+	-- exported
+	local function SetValue(self, value)
+		if self.list then
+			self:SetText(self.list[value] or "")
+		end
+		self.value = value
+	end
+
+	-- exported
+	local function GetValue(self)
+		return self.value
+	end
+
+	-- exported
+	local function SetItemValue(self, item, value)
+		if not self.multiselect then return end
+		for i, widget in self.pullout:IterateItems() do
+			if widget.userdata.value == item then
+				if widget.SetValue then
+					widget:SetValue(value)
+				end
+			end
+		end
+		ShowMultiText(self)
+	end
+
+	-- exported
+	local function SetItemDisabled(self, item, disabled)
+		for i, widget in self.pullout:IterateItems() do
+			if widget.userdata.value == item then
+				widget:SetDisabled(disabled)
+			end
+		end
+	end
+
+	local function AddListItem(self, value, text, itemType)
+		if not itemType then itemType = "Dropdown-Item-Toggle" end
+		local exists = AceGUI:GetWidgetVersion(itemType)
+		if not exists then error(("The given item type, %q, does not exist within AceGUI-3.0"):format(tostring(itemType)), 2) end
+
+		local item = AceGUI:Create(itemType)
+		item:SetText(text)
+		item.userdata.obj = self
+		item.userdata.value = value
+		item:SetCallback("OnValueChanged", OnItemValueChanged)
+		self.pullout:AddItem(item)
+	end
+
+	local function AddCloseButton(self)
+		if not self.hasClose then
+			local close = AceGUI:Create("Dropdown-Item-Execute")
+			close:SetText(CLOSE)
+			self.pullout:AddItem(close)
+			self.hasClose = true
+		end
+	end
+
+	-- exported
+	local sortlist = {}
+	local function SetList(self, list, order, itemType)
+		self.list = list
+		self.pullout:Clear()
+		self.hasClose = nil
+		if not list then return end
+
+		if type(order) ~= "table" then
+			for v in pairs(list) do
+				sortlist[#sortlist + 1] = v
+			end
+			tsort(sortlist)
+
+			for i, key in ipairs(sortlist) do
+				AddListItem(self, key, list[key], itemType)
+				sortlist[i] = nil
+			end
+		else
+			for i, key in ipairs(order) do
+				AddListItem(self, key, list[key], itemType)
+			end
+		end
+		if self.multiselect then
+			ShowMultiText(self)
+			AddCloseButton(self)
+		end
+	end
+
+	-- exported
+	local function AddItem(self, value, text, itemType)
+		if self.list then
+			self.list[value] = text
+			AddListItem(self, value, text, itemType)
+		end
+	end
+
+	-- exported
+	local function SetMultiselect(self, multi)
+		self.multiselect = multi
+		if multi then
+			ShowMultiText(self)
+			AddCloseButton(self)
+		end
+	end
+
+	-- exported
+	local function GetMultiselect(self)
+		return self.multiselect
+	end
+
+	local function SetPulloutWidth(self, width)
+		self.pulloutWidth = width
+	end
+
+	--[[ Constructor ]]--
+
+	local function Constructor()
+		local count = AceGUI:GetNextWidgetNum(widgetType)
+		local frame = CreateFrame("Frame", nil, UIParent)
+		local dropdown = CreateFrame("Frame", "AceGUI30DropDown"..count, frame, "UIDropDownMenuTemplate")
+
+		local self = {}
+		self.type = widgetType
+		self.frame = frame
+		self.dropdown = dropdown
+		self.count = count
+		frame.obj = self
+		dropdown.obj = self
+
+		self.OnRelease   = OnRelease
+		self.OnAcquire   = OnAcquire
+
+		self.ClearFocus  = ClearFocus
+
+		self.SetText     = SetText
+		self.SetValue    = SetValue
+		self.GetValue    = GetValue
+		self.SetList     = SetList
+		self.SetLabel    = SetLabel
+		self.SetDisabled = SetDisabled
+		self.AddItem     = AddItem
+		self.SetMultiselect = SetMultiselect
+		self.GetMultiselect = GetMultiselect
+		self.SetItemValue = SetItemValue
+		self.SetItemDisabled = SetItemDisabled
+		self.SetPulloutWidth = SetPulloutWidth
+
+		self.alignoffset = 26
+
+		frame:SetScript("OnHide",Dropdown_OnHide)
+
+		dropdown:ClearAllPoints()
+		dropdown:SetPoint("TOPLEFT",frame,"TOPLEFT",-15,0)
+		dropdown:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",17,0)
+		dropdown:SetScript("OnHide", nil)
+
+		local left = _G[dropdown:GetName() .. "Left"]
+		local middle = _G[dropdown:GetName() .. "Middle"]
+		local right = _G[dropdown:GetName() .. "Right"]
+
+		middle:ClearAllPoints()
+		right:ClearAllPoints()
+
+		middle:SetPoint("LEFT", left, "RIGHT", 0, 0)
+		middle:SetPoint("RIGHT", right, "LEFT", 0, 0)
+		right:SetPoint("TOPRIGHT", dropdown, "TOPRIGHT", 0, 17)
+
+		local button = _G[dropdown:GetName() .. "Button"]
+		self.button = button
+		button.obj = self
+		button:SetScript("OnEnter",Control_OnEnter)
+		button:SetScript("OnLeave",Control_OnLeave)
+		button:SetScript("OnClick",Dropdown_TogglePullout)
+
+		local button_cover = CreateFrame("BUTTON",nil,self.frame)
+		self.button_cover = button_cover
+		button_cover.obj = self
+		button_cover:SetPoint("TOPLEFT",self.frame,"BOTTOMLEFT",0,25)
+		button_cover:SetPoint("BOTTOMRIGHT",self.frame,"BOTTOMRIGHT")
+		button_cover:SetScript("OnEnter",Control_OnEnter)
+		button_cover:SetScript("OnLeave",Control_OnLeave)
+		button_cover:SetScript("OnClick",Dropdown_TogglePullout)
+
+		local text = _G[dropdown:GetName() .. "Text"]
+		self.text = text
+		text.obj = self
+		text:ClearAllPoints()
+		text:SetPoint("RIGHT", right, "RIGHT" ,-43, 2)
+		text:SetPoint("LEFT", left, "LEFT", 25, 2)
+
+		local label = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
+		label:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
+		label:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,0)
+		label:SetJustifyH("LEFT")
+		label:SetHeight(18)
+		label:Hide()
+		self.label = label
+
+		AceGUI:RegisterAsWidget(self)
+		return self
+	end
+
+	AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion)
+end
diff --git a/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-EditBox.lua b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-EditBox.lua
new file mode 100644
index 0000000..c67902c
--- /dev/null
+++ b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-EditBox.lua
@@ -0,0 +1,261 @@
+--[[-----------------------------------------------------------------------------
+EditBox Widget
+-------------------------------------------------------------------------------]]
+local Type, Version = "EditBox", 25
+local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
+if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
+
+-- Lua APIs
+local tostring, pairs = tostring, pairs
+
+-- WoW APIs
+local PlaySound = PlaySound
+local GetCursorInfo, ClearCursor, GetSpellInfo = GetCursorInfo, ClearCursor, GetSpellInfo
+local CreateFrame, UIParent = CreateFrame, UIParent
+local _G = _G
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: AceGUIEditBoxInsertLink, ChatFontNormal, OKAY
+
+--[[-----------------------------------------------------------------------------
+Support functions
+-------------------------------------------------------------------------------]]
+if not AceGUIEditBoxInsertLink then
+	-- upgradeable hook
+	hooksecurefunc("ChatEdit_InsertLink", function(...) return _G.AceGUIEditBoxInsertLink(...) end)
+end
+
+function _G.AceGUIEditBoxInsertLink(text)
+	for i = 1, AceGUI:GetWidgetCount(Type) do
+		local editbox = _G["AceGUI-3.0EditBox"..i]
+		if editbox and editbox:IsVisible() and editbox:HasFocus() then
+			editbox:Insert(text)
+			return true
+		end
+	end
+end
+
+local function ShowButton(self)
+	if not self.disablebutton then
+		self.button:Show()
+		self.editbox:SetTextInsets(0, 20, 3, 3)
+	end
+end
+
+local function HideButton(self)
+	self.button:Hide()
+	self.editbox:SetTextInsets(0, 0, 3, 3)
+end
+
+--[[-----------------------------------------------------------------------------
+Scripts
+-------------------------------------------------------------------------------]]
+local function Control_OnEnter(frame)
+	frame.obj:Fire("OnEnter")
+end
+
+local function Control_OnLeave(frame)
+	frame.obj:Fire("OnLeave")
+end
+
+local function Frame_OnShowFocus(frame)
+	frame.obj.editbox:SetFocus()
+	frame:SetScript("OnShow", nil)
+end
+
+local function EditBox_OnEscapePressed(frame)
+	AceGUI:ClearFocus()
+end
+
+local function EditBox_OnEnterPressed(frame)
+	local self = frame.obj
+	local value = frame:GetText()
+	local cancel = self:Fire("OnEnterPressed", value)
+	if not cancel then
+		PlaySound("igMainMenuOptionCheckBoxOn")
+		HideButton(self)
+	end
+end
+
+local function EditBox_OnReceiveDrag(frame)
+	local self = frame.obj
+	local type, id, info = GetCursorInfo()
+	if type == "item" then
+		self:SetText(info)
+		self:Fire("OnEnterPressed", info)
+		ClearCursor()
+	elseif type == "spell" then
+		local name = GetSpellInfo(id, info)
+		self:SetText(name)
+		self:Fire("OnEnterPressed", name)
+		ClearCursor()
+	elseif type == "macro" then
+		local name = GetMacroInfo(id)
+		self:SetText(name)
+		self:Fire("OnEnterPressed", name)
+		ClearCursor()
+	end
+	HideButton(self)
+	AceGUI:ClearFocus()
+end
+
+local function EditBox_OnTextChanged(frame)
+	local self = frame.obj
+	local value = frame:GetText()
+	if tostring(value) ~= tostring(self.lasttext) then
+		self:Fire("OnTextChanged", value)
+		self.lasttext = value
+		ShowButton(self)
+	end
+end
+
+local function EditBox_OnFocusGained(frame)
+	AceGUI:SetFocus(frame.obj)
+end
+
+local function Button_OnClick(frame)
+	local editbox = frame.obj.editbox
+	editbox:ClearFocus()
+	EditBox_OnEnterPressed(editbox)
+end
+
+--[[-----------------------------------------------------------------------------
+Methods
+-------------------------------------------------------------------------------]]
+local methods = {
+	["OnAcquire"] = function(self)
+		-- height is controlled by SetLabel
+		self:SetWidth(200)
+		self:SetDisabled(false)
+		self:SetLabel()
+		self:SetText()
+		self:DisableButton(false)
+		self:SetMaxLetters(0)
+	end,
+
+	["OnRelease"] = function(self)
+		self:ClearFocus()
+	end,
+
+	["SetDisabled"] = function(self, disabled)
+		self.disabled = disabled
+		if disabled then
+			self.editbox:EnableMouse(false)
+			self.editbox:ClearFocus()
+			self.editbox:SetTextColor(0.5,0.5,0.5)
+			self.label:SetTextColor(0.5,0.5,0.5)
+		else
+			self.editbox:EnableMouse(true)
+			self.editbox:SetTextColor(1,1,1)
+			self.label:SetTextColor(1,.82,0)
+		end
+	end,
+
+	["SetText"] = function(self, text)
+		self.lasttext = text or ""
+		self.editbox:SetText(text or "")
+		self.editbox:SetCursorPosition(0)
+		HideButton(self)
+	end,
+
+	["GetText"] = function(self, text)
+		return self.editbox:GetText()
+	end,
+
+	["SetLabel"] = function(self, text)
+		if text and text ~= "" then
+			self.label:SetText(text)
+			self.label:Show()
+			self.editbox:SetPoint("TOPLEFT",self.frame,"TOPLEFT",7,-18)
+			self:SetHeight(44)
+			self.alignoffset = 30
+		else
+			self.label:SetText("")
+			self.label:Hide()
+			self.editbox:SetPoint("TOPLEFT",self.frame,"TOPLEFT",7,0)
+			self:SetHeight(26)
+			self.alignoffset = 12
+		end
+	end,
+
+	["DisableButton"] = function(self, disabled)
+		self.disablebutton = disabled
+		if disabled then
+			HideButton(self)
+		end
+	end,
+
+	["SetMaxLetters"] = function (self, num)
+		self.editbox:SetMaxLetters(num or 0)
+	end,
+
+	["ClearFocus"] = function(self)
+		self.editbox:ClearFocus()
+		self.frame:SetScript("OnShow", nil)
+	end,
+
+	["SetFocus"] = function(self)
+		self.editbox:SetFocus()
+		if not self.frame:IsShown() then
+			self.frame:SetScript("OnShow", Frame_OnShowFocus)
+		end
+	end
+}
+
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+local function Constructor()
+	local num  = AceGUI:GetNextWidgetNum(Type)
+	local frame = CreateFrame("Frame", nil, UIParent)
+	frame:Hide()
+
+	local editbox = CreateFrame("EditBox", "AceGUI-3.0EditBox"..num, frame, "InputBoxTemplate")
+	editbox:SetAutoFocus(false)
+	editbox:SetFontObject(ChatFontNormal)
+	editbox:SetScript("OnEnter", Control_OnEnter)
+	editbox:SetScript("OnLeave", Control_OnLeave)
+	editbox:SetScript("OnEscapePressed", EditBox_OnEscapePressed)
+	editbox:SetScript("OnEnterPressed", EditBox_OnEnterPressed)
+	editbox:SetScript("OnTextChanged", EditBox_OnTextChanged)
+	editbox:SetScript("OnReceiveDrag", EditBox_OnReceiveDrag)
+	editbox:SetScript("OnMouseDown", EditBox_OnReceiveDrag)
+	editbox:SetScript("OnEditFocusGained", EditBox_OnFocusGained)
+	editbox:SetTextInsets(0, 0, 3, 3)
+	editbox:SetMaxLetters(256)
+	editbox:SetPoint("BOTTOMLEFT", 6, 0)
+	editbox:SetPoint("BOTTOMRIGHT")
+	editbox:SetHeight(19)
+
+	local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
+	label:SetPoint("TOPLEFT", 0, -2)
+	label:SetPoint("TOPRIGHT", 0, -2)
+	label:SetJustifyH("LEFT")
+	label:SetHeight(18)
+
+	local button = CreateFrame("Button", nil, editbox, "UIPanelButtonTemplate")
+	button:SetWidth(40)
+	button:SetHeight(20)
+	button:SetPoint("RIGHT", -2, 0)
+	button:SetText(OKAY)
+	button:SetScript("OnClick", Button_OnClick)
+	button:Hide()
+
+	local widget = {
+		alignoffset = 30,
+		editbox     = editbox,
+		label       = label,
+		button      = button,
+		frame       = frame,
+		type        = Type
+	}
+	for method, func in pairs(methods) do
+		widget[method] = func
+	end
+	editbox.obj, button.obj = widget, widget
+
+	return AceGUI:RegisterAsWidget(widget)
+end
+
+AceGUI:RegisterWidgetType(Type, Constructor, Version)
diff --git a/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-Heading.lua b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-Heading.lua
new file mode 100644
index 0000000..1aaf3f5
--- /dev/null
+++ b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-Heading.lua
@@ -0,0 +1,78 @@
+--[[-----------------------------------------------------------------------------
+Heading Widget
+-------------------------------------------------------------------------------]]
+local Type, Version = "Heading", 20
+local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
+if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
+
+-- Lua APIs
+local pairs = pairs
+
+-- WoW APIs
+local CreateFrame, UIParent = CreateFrame, UIParent
+
+--[[-----------------------------------------------------------------------------
+Methods
+-------------------------------------------------------------------------------]]
+local methods = {
+	["OnAcquire"] = function(self)
+		self:SetText()
+		self:SetFullWidth()
+		self:SetHeight(18)
+	end,
+
+	-- ["OnRelease"] = nil,
+
+	["SetText"] = function(self, text)
+		self.label:SetText(text or "")
+		if text and text ~= "" then
+			self.left:SetPoint("RIGHT", self.label, "LEFT", -5, 0)
+			self.right:Show()
+		else
+			self.left:SetPoint("RIGHT", -3, 0)
+			self.right:Hide()
+		end
+	end
+}
+
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+local function Constructor()
+	local frame = CreateFrame("Frame", nil, UIParent)
+	frame:Hide()
+
+	local label = frame:CreateFontString(nil, "BACKGROUND", "GameFontNormal")
+	label:SetPoint("TOP")
+	label:SetPoint("BOTTOM")
+	label:SetJustifyH("CENTER")
+
+	local left = frame:CreateTexture(nil, "BACKGROUND")
+	left:SetHeight(8)
+	left:SetPoint("LEFT", 3, 0)
+	left:SetPoint("RIGHT", label, "LEFT", -5, 0)
+	left:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border")
+	left:SetTexCoord(0.81, 0.94, 0.5, 1)
+
+	local right = frame:CreateTexture(nil, "BACKGROUND")
+	right:SetHeight(8)
+	right:SetPoint("RIGHT", -3, 0)
+	right:SetPoint("LEFT", label, "RIGHT", 5, 0)
+	right:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border")
+	right:SetTexCoord(0.81, 0.94, 0.5, 1)
+
+	local widget = {
+		label = label,
+		left  = left,
+		right = right,
+		frame = frame,
+		type  = Type
+	}
+	for method, func in pairs(methods) do
+		widget[method] = func
+	end
+
+	return AceGUI:RegisterAsWidget(widget)
+end
+
+AceGUI:RegisterWidgetType(Type, Constructor, Version)
diff --git a/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-Icon.lua b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-Icon.lua
new file mode 100644
index 0000000..8d01b54
--- /dev/null
+++ b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-Icon.lua
@@ -0,0 +1,144 @@
+--[[-----------------------------------------------------------------------------
+Icon Widget
+-------------------------------------------------------------------------------]]
+local Type, Version = "Icon", 21
+local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
+if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
+
+-- Lua APIs
+local select, pairs, print = select, pairs, print
+
+-- WoW APIs
+local CreateFrame, UIParent, GetBuildInfo = CreateFrame, UIParent, GetBuildInfo
+
+--[[-----------------------------------------------------------------------------
+Scripts
+-------------------------------------------------------------------------------]]
+local function Control_OnEnter(frame)
+	frame.obj:Fire("OnEnter")
+end
+
+local function Control_OnLeave(frame)
+	frame.obj:Fire("OnLeave")
+end
+
+local function Button_OnClick(frame, button)
+	frame.obj:Fire("OnClick", button)
+	AceGUI:ClearFocus()
+end
+
+--[[-----------------------------------------------------------------------------
+Methods
+-------------------------------------------------------------------------------]]
+local methods = {
+	["OnAcquire"] = function(self)
+		self:SetHeight(110)
+		self:SetWidth(110)
+		self:SetLabel()
+		self:SetImage(nil)
+		self:SetImageSize(64, 64)
+		self:SetDisabled(false)
+	end,
+
+	-- ["OnRelease"] = nil,
+
+	["SetLabel"] = function(self, text)
+		if text and text ~= "" then
+			self.label:Show()
+			self.label:SetText(text)
+			self:SetHeight(self.image:GetHeight() + 25)
+		else
+			self.label:Hide()
+			self:SetHeight(self.image:GetHeight() + 10)
+		end
+	end,
+
+	["SetImage"] = function(self, path, ...)
+		local image = self.image
+		image:SetTexture(path)
+
+		if image:GetTexture() then
+			local n = select("#", ...)
+			if n == 4 or n == 8 then
+				image:SetTexCoord(...)
+			else
+				image:SetTexCoord(0, 1, 0, 1)
+			end
+		end
+	end,
+
+	["SetImageSize"] = function(self, width, height)
+		self.image:SetWidth(width)
+		self.image:SetHeight(height)
+		--self.frame:SetWidth(width + 30)
+		if self.label:IsShown() then
+			self:SetHeight(height + 25)
+		else
+			self:SetHeight(height + 10)
+		end
+	end,
+
+	["SetDisabled"] = function(self, disabled)
+		self.disabled = disabled
+		if disabled then
+			self.frame:Disable()
+			self.label:SetTextColor(0.5, 0.5, 0.5)
+			self.image:SetVertexColor(0.5, 0.5, 0.5, 0.5)
+		else
+			self.frame:Enable()
+			self.label:SetTextColor(1, 1, 1)
+			self.image:SetVertexColor(1, 1, 1, 1)
+		end
+	end
+}
+
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+local function Constructor()
+	local frame = CreateFrame("Button", nil, UIParent)
+	frame:Hide()
+
+	frame:EnableMouse(true)
+	frame:SetScript("OnEnter", Control_OnEnter)
+	frame:SetScript("OnLeave", Control_OnLeave)
+	frame:SetScript("OnClick", Button_OnClick)
+
+	local label = frame:CreateFontString(nil, "BACKGROUND", "GameFontHighlight")
+	label:SetPoint("BOTTOMLEFT")
+	label:SetPoint("BOTTOMRIGHT")
+	label:SetJustifyH("CENTER")
+	label:SetJustifyV("TOP")
+	label:SetHeight(18)
+
+	local image = frame:CreateTexture(nil, "BACKGROUND")
+	image:SetWidth(64)
+	image:SetHeight(64)
+	image:SetPoint("TOP", 0, -5)
+
+	local highlight = frame:CreateTexture(nil, "HIGHLIGHT")
+	highlight:SetAllPoints(image)
+	highlight:SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-Tab-Highlight")
+	highlight:SetTexCoord(0, 1, 0.23, 0.77)
+	highlight:SetBlendMode("ADD")
+
+	local widget = {
+		label = label,
+		image = image,
+		frame = frame,
+		type  = Type
+	}
+	for method, func in pairs(methods) do
+		widget[method] = func
+	end
+	-- SetText is deprecated, but keep it around for a while. (say, to WoW 4.0)
+	if (select(4, GetBuildInfo()) < 40000) then
+		widget.SetText = widget.SetLabel
+	else
+		widget.SetText = function(self, ...) print("AceGUI-3.0-Icon: SetText is deprecated! Use SetLabel instead!"); self:SetLabel(...) end
+	end
+
+	return AceGUI:RegisterAsWidget(widget)
+end
+
+AceGUI:RegisterWidgetType(Type, Constructor, Version)
diff --git a/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-InteractiveLabel.lua b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-InteractiveLabel.lua
new file mode 100644
index 0000000..9e06049
--- /dev/null
+++ b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-InteractiveLabel.lua
@@ -0,0 +1,101 @@
+--[[-----------------------------------------------------------------------------
+InteractiveLabel Widget
+-------------------------------------------------------------------------------]]
+local Type, Version = "InteractiveLabel", 20
+local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
+if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
+
+-- Lua APIs
+local select, pairs = select, pairs
+
+-- WoW APIs
+local CreateFrame, UIParent = CreateFrame, UIParent
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: GameFontHighlightSmall
+
+--[[-----------------------------------------------------------------------------
+Scripts
+-------------------------------------------------------------------------------]]
+local function Control_OnEnter(frame)
+	frame.obj:Fire("OnEnter")
+end
+
+local function Control_OnLeave(frame)
+	frame.obj:Fire("OnLeave")
+end
+
+local function Label_OnClick(frame, button)
+	frame.obj:Fire("OnClick", button)
+	AceGUI:ClearFocus()
+end
+
+--[[-----------------------------------------------------------------------------
+Methods
+-------------------------------------------------------------------------------]]
+local methods = {
+	["OnAcquire"] = function(self)
+		self:LabelOnAcquire()
+		self:SetHighlight()
+		self:SetHighlightTexCoord()
+		self:SetDisabled(false)
+	end,
+
+	-- ["OnRelease"] = nil,
+
+	["SetHighlight"] = function(self, ...)
+		self.highlight:SetTexture(...)
+	end,
+
+	["SetHighlightTexCoord"] = function(self, ...)
+		local c = select("#", ...)
+		if c == 4 or c == 8 then
+			self.highlight:SetTexCoord(...)
+		else
+			self.highlight:SetTexCoord(0, 1, 0, 1)
+		end
+	end,
+
+	["SetDisabled"] = function(self,disabled)
+		self.disabled = disabled
+		if disabled then
+			self.frame:EnableMouse(false)
+			self.label:SetTextColor(0.5, 0.5, 0.5)
+		else
+			self.frame:EnableMouse(true)
+			self.label:SetTextColor(1, 1, 1)
+		end
+	end
+}
+
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+local function Constructor()
+	-- create a Label type that we will hijack
+	local label = AceGUI:Create("Label")
+
+	local frame = label.frame
+	frame:EnableMouse(true)
+	frame:SetScript("OnEnter", Control_OnEnter)
+	frame:SetScript("OnLeave", Control_OnLeave)
+	frame:SetScript("OnMouseDown", Label_OnClick)
+
+	local highlight = frame:CreateTexture(nil, "HIGHLIGHT")
+	highlight:SetTexture(nil)
+	highlight:SetAllPoints()
+	highlight:SetBlendMode("ADD")
+
+	label.highlight = highlight
+	label.type = Type
+	label.LabelOnAcquire = label.OnAcquire
+	for method, func in pairs(methods) do
+		label[method] = func
+	end
+
+	return label
+end
+
+AceGUI:RegisterWidgetType(Type, Constructor, Version)
+
diff --git a/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-Keybinding.lua b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-Keybinding.lua
new file mode 100644
index 0000000..7dccc64
--- /dev/null
+++ b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-Keybinding.lua
@@ -0,0 +1,239 @@
+--[[-----------------------------------------------------------------------------
+Keybinding Widget
+Set Keybindings in the Config UI.
+-------------------------------------------------------------------------------]]
+local Type, Version = "Keybinding", 24
+local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
+if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
+
+-- Lua APIs
+local pairs = pairs
+
+-- WoW APIs
+local IsShiftKeyDown, IsControlKeyDown, IsAltKeyDown = IsShiftKeyDown, IsControlKeyDown, IsAltKeyDown
+local CreateFrame, UIParent = CreateFrame, UIParent
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: NOT_BOUND
+
+local wowMoP
+do
+	local _, _, _, interface = GetBuildInfo()
+	wowMoP = (interface >= 50000)
+end
+
+--[[-----------------------------------------------------------------------------
+Scripts
+-------------------------------------------------------------------------------]]
+
+local function Control_OnEnter(frame)
+	frame.obj:Fire("OnEnter")
+end
+
+local function Control_OnLeave(frame)
+	frame.obj:Fire("OnLeave")
+end
+
+local function Keybinding_OnClick(frame, button)
+	if button == "LeftButton" or button == "RightButton" then
+		local self = frame.obj
+		if self.waitingForKey then
+			frame:EnableKeyboard(false)
+			self.msgframe:Hide()
+			frame:UnlockHighlight()
+			self.waitingForKey = nil
+		else
+			frame:EnableKeyboard(true)
+			self.msgframe:Show()
+			frame:LockHighlight()
+			self.waitingForKey = true
+		end
+	end
+	AceGUI:ClearFocus()
+end
+
+local ignoreKeys = {
+	["BUTTON1"] = true, ["BUTTON2"] = true,
+	["UNKNOWN"] = true,
+	["LSHIFT"] = true, ["LCTRL"] = true, ["LALT"] = true,
+	["RSHIFT"] = true, ["RCTRL"] = true, ["RALT"] = true,
+}
+local function Keybinding_OnKeyDown(frame, key)
+	local self = frame.obj
+	if self.waitingForKey then
+		local keyPressed = key
+		if keyPressed == "ESCAPE" then
+			keyPressed = ""
+		else
+			if ignoreKeys[keyPressed] then return end
+			if IsShiftKeyDown() then
+				keyPressed = "SHIFT-"..keyPressed
+			end
+			if IsControlKeyDown() then
+				keyPressed = "CTRL-"..keyPressed
+			end
+			if IsAltKeyDown() then
+				keyPressed = "ALT-"..keyPressed
+			end
+		end
+
+		frame:EnableKeyboard(false)
+		self.msgframe:Hide()
+		frame:UnlockHighlight()
+		self.waitingForKey = nil
+
+		if not self.disabled then
+			self:SetKey(keyPressed)
+			self:Fire("OnKeyChanged", keyPressed)
+		end
+	end
+end
+
+local function Keybinding_OnMouseDown(frame, button)
+	if button == "LeftButton" or button == "RightButton" then
+		return
+	elseif button == "MiddleButton" then
+		button = "BUTTON3"
+	elseif button == "Button4" then
+		button = "BUTTON4"
+	elseif button == "Button5" then
+		button = "BUTTON5"
+	end
+	Keybinding_OnKeyDown(frame, button)
+end
+
+--[[-----------------------------------------------------------------------------
+Methods
+-------------------------------------------------------------------------------]]
+local methods = {
+	["OnAcquire"] = function(self)
+		self:SetWidth(200)
+		self:SetLabel("")
+		self:SetKey("")
+		self.waitingForKey = nil
+		self.msgframe:Hide()
+		self:SetDisabled(false)
+		self.button:EnableKeyboard(false)
+	end,
+
+	-- ["OnRelease"] = nil,
+
+	["SetDisabled"] = function(self, disabled)
+		self.disabled = disabled
+		if disabled then
+			self.button:Disable()
+			self.label:SetTextColor(0.5,0.5,0.5)
+		else
+			self.button:Enable()
+			self.label:SetTextColor(1,1,1)
+		end
+	end,
+
+	["SetKey"] = function(self, key)
+		if (key or "") == "" then
+			self.button:SetText(NOT_BOUND)
+			self.button:SetNormalFontObject("GameFontNormal")
+		else
+			self.button:SetText(key)
+			self.button:SetNormalFontObject("GameFontHighlight")
+		end
+	end,
+
+	["GetKey"] = function(self)
+		local key = self.button:GetText()
+		if key == NOT_BOUND then
+			key = nil
+		end
+		return key
+	end,
+
+	["SetLabel"] = function(self, label)
+		self.label:SetText(label or "")
+		if (label or "") == "" then
+			self.alignoffset = nil
+			self:SetHeight(24)
+		else
+			self.alignoffset = 30
+			self:SetHeight(44)
+		end
+	end,
+}
+
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+
+local ControlBackdrop  = {
+	bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
+	edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
+	tile = true, tileSize = 16, edgeSize = 16,
+	insets = { left = 3, right = 3, top = 3, bottom = 3 }
+}
+
+local function keybindingMsgFixWidth(frame)
+	frame:SetWidth(frame.msg:GetWidth() + 10)
+	frame:SetScript("OnUpdate", nil)
+end
+
+local function Constructor()
+	local name = "AceGUI30KeybindingButton" .. AceGUI:GetNextWidgetNum(Type)
+
+	local frame = CreateFrame("Frame", nil, UIParent)
+	local button = CreateFrame("Button", name, frame, wowMoP and "UIPanelButtonTemplate" or "UIPanelButtonTemplate2")
+
+	button:EnableMouse(true)
+	button:RegisterForClicks("AnyDown")
+	button:SetScript("OnEnter", Control_OnEnter)
+	button:SetScript("OnLeave", Control_OnLeave)
+	button:SetScript("OnClick", Keybinding_OnClick)
+	button:SetScript("OnKeyDown", Keybinding_OnKeyDown)
+	button:SetScript("OnMouseDown", Keybinding_OnMouseDown)
+	button:SetPoint("BOTTOMLEFT")
+	button:SetPoint("BOTTOMRIGHT")
+	button:SetHeight(24)
+	button:EnableKeyboard(false)
+
+	local text = button:GetFontString()
+	text:SetPoint("LEFT", 7, 0)
+	text:SetPoint("RIGHT", -7, 0)
+
+	local label = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
+	label:SetPoint("TOPLEFT")
+	label:SetPoint("TOPRIGHT")
+	label:SetJustifyH("CENTER")
+	label:SetHeight(18)
+
+	local msgframe = CreateFrame("Frame", nil, UIParent)
+	msgframe:SetHeight(30)
+	msgframe:SetBackdrop(ControlBackdrop)
+	msgframe:SetBackdropColor(0,0,0)
+	msgframe:SetFrameStrata("FULLSCREEN_DIALOG")
+	msgframe:SetFrameLevel(1000)
+	msgframe:SetToplevel(true)
+
+	local msg = msgframe:CreateFontString(nil, "OVERLAY", "GameFontNormal")
+	msg:SetText("Press a key to bind, ESC to clear the binding or click the button again to cancel.")
+	msgframe.msg = msg
+	msg:SetPoint("TOPLEFT", 5, -5)
+	msgframe:SetScript("OnUpdate", keybindingMsgFixWidth)
+	msgframe:SetPoint("BOTTOM", button, "TOP")
+	msgframe:Hide()
+
+	local widget = {
+		button      = button,
+		label       = label,
+		msgframe    = msgframe,
+		frame       = frame,
+		alignoffset = 30,
+		type        = Type
+	}
+	for method, func in pairs(methods) do
+		widget[method] = func
+	end
+	button.obj = widget
+
+	return AceGUI:RegisterAsWidget(widget)
+end
+
+AceGUI:RegisterWidgetType(Type, Constructor, Version)
diff --git a/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-Label.lua b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-Label.lua
new file mode 100644
index 0000000..23897d5
--- /dev/null
+++ b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-Label.lua
@@ -0,0 +1,166 @@
+--[[-----------------------------------------------------------------------------
+Label Widget
+Displays text and optionally an icon.
+-------------------------------------------------------------------------------]]
+local Type, Version = "Label", 23
+local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
+if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
+
+-- Lua APIs
+local max, select, pairs = math.max, select, pairs
+
+-- WoW APIs
+local CreateFrame, UIParent = CreateFrame, UIParent
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: GameFontHighlightSmall
+
+--[[-----------------------------------------------------------------------------
+Support functions
+-------------------------------------------------------------------------------]]
+
+local function UpdateImageAnchor(self)
+	if self.resizing then return end
+	local frame = self.frame
+	local width = frame.width or frame:GetWidth() or 0
+	local image = self.image
+	local label = self.label
+	local height
+
+	label:ClearAllPoints()
+	image:ClearAllPoints()
+
+	if self.imageshown then
+		local imagewidth = image:GetWidth()
+		if (width - imagewidth) < 200 or (label:GetText() or "") == "" then
+			-- image goes on top centered when less than 200 width for the text, or if there is no text
+			image:SetPoint("TOP")
+			label:SetPoint("TOP", image, "BOTTOM")
+			label:SetPoint("LEFT")
+			label:SetWidth(width)
+			height = image:GetHeight() + label:GetHeight()
+		else
+			-- image on the left
+			image:SetPoint("TOPLEFT")
+			if image:GetHeight() > label:GetHeight() then
+				label:SetPoint("LEFT", image, "RIGHT", 4, 0)
+			else
+				label:SetPoint("TOPLEFT", image, "TOPRIGHT", 4, 0)
+			end
+			label:SetWidth(width - imagewidth - 4)
+			height = max(image:GetHeight(), label:GetHeight())
+		end
+	else
+		-- no image shown
+		label:SetPoint("TOPLEFT")
+		label:SetWidth(width)
+		height = label:GetHeight()
+	end
+
+	self.resizing = true
+	frame:SetHeight(height)
+	frame.height = height
+	self.resizing = nil
+end
+
+--[[-----------------------------------------------------------------------------
+Methods
+-------------------------------------------------------------------------------]]
+local methods = {
+	["OnAcquire"] = function(self)
+		-- set the flag to stop constant size updates
+		self.resizing = true
+		-- height is set dynamically by the text and image size
+		self:SetWidth(200)
+		self:SetText()
+		self:SetImage(nil)
+		self:SetImageSize(16, 16)
+		self:SetColor()
+		self:SetFontObject()
+
+		-- reset the flag
+		self.resizing = nil
+		-- run the update explicitly
+		UpdateImageAnchor(self)
+	end,
+
+	-- ["OnRelease"] = nil,
+
+	["OnWidthSet"] = function(self, width)
+		UpdateImageAnchor(self)
+	end,
+
+	["SetText"] = function(self, text)
+		self.label:SetText(text)
+		UpdateImageAnchor(self)
+	end,
+
+	["SetColor"] = function(self, r, g, b)
+		if not (r and g and b) then
+			r, g, b = 1, 1, 1
+		end
+		self.label:SetVertexColor(r, g, b)
+	end,
+
+	["SetImage"] = function(self, path, ...)
+		local image = self.image
+		image:SetTexture(path)
+
+		if image:GetTexture() then
+			self.imageshown = true
+			local n = select("#", ...)
+			if n == 4 or n == 8 then
+				image:SetTexCoord(...)
+			else
+				image:SetTexCoord(0, 1, 0, 1)
+			end
+		else
+			self.imageshown = nil
+		end
+		UpdateImageAnchor(self)
+	end,
+
+	["SetFont"] = function(self, font, height, flags)
+		self.label:SetFont(font, height, flags)
+	end,
+
+	["SetFontObject"] = function(self, font)
+		self:SetFont((font or GameFontHighlightSmall):GetFont())
+	end,
+
+	["SetImageSize"] = function(self, width, height)
+		self.image:SetWidth(width)
+		self.image:SetHeight(height)
+		UpdateImageAnchor(self)
+	end,
+}
+
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+local function Constructor()
+	local frame = CreateFrame("Frame", nil, UIParent)
+	frame:Hide()
+
+	local label = frame:CreateFontString(nil, "BACKGROUND", "GameFontHighlightSmall")
+	label:SetJustifyH("LEFT")
+	label:SetJustifyV("TOP")
+
+	local image = frame:CreateTexture(nil, "BACKGROUND")
+
+	-- create widget
+	local widget = {
+		label = label,
+		image = image,
+		frame = frame,
+		type  = Type
+	}
+	for method, func in pairs(methods) do
+		widget[method] = func
+	end
+
+	return AceGUI:RegisterAsWidget(widget)
+end
+
+AceGUI:RegisterWidgetType(Type, Constructor, Version)
diff --git a/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-MultiLineEditBox.lua b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-MultiLineEditBox.lua
new file mode 100644
index 0000000..a27a2fc
--- /dev/null
+++ b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-MultiLineEditBox.lua
@@ -0,0 +1,368 @@
+local Type, Version = "MultiLineEditBox", 27
+local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
+if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
+
+-- Lua APIs
+local pairs = pairs
+
+-- WoW APIs
+local GetCursorInfo, GetSpellInfo, ClearCursor = GetCursorInfo, GetSpellInfo, ClearCursor
+local CreateFrame, UIParent = CreateFrame, UIParent
+local _G = _G
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: ACCEPT, ChatFontNormal
+
+local wowMoP
+do
+	local _, _, _, interface = GetBuildInfo()
+	wowMoP = (interface >= 50000)
+end
+
+--[[-----------------------------------------------------------------------------
+Support functions
+-------------------------------------------------------------------------------]]
+
+if not AceGUIMultiLineEditBoxInsertLink then
+	-- upgradeable hook
+	hooksecurefunc("ChatEdit_InsertLink", function(...) return _G.AceGUIMultiLineEditBoxInsertLink(...) end)
+end
+
+function _G.AceGUIMultiLineEditBoxInsertLink(text)
+	for i = 1, AceGUI:GetWidgetCount(Type) do
+		local editbox = _G[("MultiLineEditBox%uEdit"):format(i)]
+		if editbox and editbox:IsVisible() and editbox:HasFocus() then
+			editbox:Insert(text)
+			return true
+		end
+	end
+end
+
+
+local function Layout(self)
+	self:SetHeight(self.numlines * 14 + (self.disablebutton and 19 or 41) + self.labelHeight)
+
+	if self.labelHeight == 0 then
+		self.scrollBar:SetPoint("TOP", self.frame, "TOP", 0, -23)
+	else
+		self.scrollBar:SetPoint("TOP", self.label, "BOTTOM", 0, -19)
+	end
+
+	if self.disablebutton then
+		self.scrollBar:SetPoint("BOTTOM", self.frame, "BOTTOM", 0, 21)
+		self.scrollBG:SetPoint("BOTTOMLEFT", 0, 4)
+	else
+		self.scrollBar:SetPoint("BOTTOM", self.button, "TOP", 0, 18)
+		self.scrollBG:SetPoint("BOTTOMLEFT", self.button, "TOPLEFT")
+	end
+end
+
+--[[-----------------------------------------------------------------------------
+Scripts
+-------------------------------------------------------------------------------]]
+local function OnClick(self)                                                     -- Button
+	self = self.obj
+	self.editBox:ClearFocus()
+	if not self:Fire("OnEnterPressed", self.editBox:GetText()) then
+		self.button:Disable()
+	end
+end
+
+local function OnCursorChanged(self, _, y, _, cursorHeight)                      -- EditBox
+	self, y = self.obj.scrollFrame, -y
+	local offset = self:GetVerticalScroll()
+	if y < offset then
+		self:SetVerticalScroll(y)
+	else
+		y = y + cursorHeight - self:GetHeight()
+		if y > offset then
+			self:SetVerticalScroll(y)
+		end
+	end
+end
+
+local function OnEditFocusLost(self)                                             -- EditBox
+	self:HighlightText(0, 0)
+	self.obj:Fire("OnEditFocusLost")
+end
+
+local function OnEnter(self)                                                     -- EditBox / ScrollFrame
+	self = self.obj
+	if not self.entered then
+		self.entered = true
+		self:Fire("OnEnter")
+	end
+end
+
+local function OnLeave(self)                                                     -- EditBox / ScrollFrame
+	self = self.obj
+	if self.entered then
+		self.entered = nil
+		self:Fire("OnLeave")
+	end
+end
+
+local function OnMouseUp(self)                                                   -- ScrollFrame
+	self = self.obj.editBox
+	self:SetFocus()
+	self:SetCursorPosition(self:GetNumLetters())
+end
+
+local function OnReceiveDrag(self)                                               -- EditBox / ScrollFrame
+	local type, id, info = GetCursorInfo()
+	if type == "spell" then
+		info = GetSpellInfo(id, info)
+	elseif type ~= "item" then
+		return
+	end
+	ClearCursor()
+	self = self.obj
+	local editBox = self.editBox
+	if not editBox:HasFocus() then
+		editBox:SetFocus()
+		editBox:SetCursorPosition(editBox:GetNumLetters())
+	end
+	editBox:Insert(info)
+	self.button:Enable()
+end
+
+local function OnSizeChanged(self, width, height)                                -- ScrollFrame
+	self.obj.editBox:SetWidth(width)
+end
+
+local function OnTextChanged(self, userInput)                                    -- EditBox
+	if userInput then
+		self = self.obj
+		self:Fire("OnTextChanged", self.editBox:GetText())
+		self.button:Enable()
+	end
+end
+
+local function OnTextSet(self)                                                   -- EditBox
+	self:HighlightText(0, 0)
+	self:SetCursorPosition(self:GetNumLetters())
+	self:SetCursorPosition(0)
+	self.obj.button:Disable()
+end
+
+local function OnVerticalScroll(self, offset)                                    -- ScrollFrame
+	local editBox = self.obj.editBox
+	editBox:SetHitRectInsets(0, 0, offset, editBox:GetHeight() - offset - self:GetHeight())
+end
+
+local function OnShowFocus(frame)
+	frame.obj.editBox:SetFocus()
+	frame:SetScript("OnShow", nil)
+end
+
+local function OnEditFocusGained(frame)
+	AceGUI:SetFocus(frame.obj)
+	frame.obj:Fire("OnEditFocusGained")
+end
+
+--[[-----------------------------------------------------------------------------
+Methods
+-------------------------------------------------------------------------------]]
+local methods = {
+	["OnAcquire"] = function(self)
+		self.editBox:SetText("")
+		self:SetDisabled(false)
+		self:SetWidth(200)
+		self:DisableButton(false)
+		self:SetNumLines()
+		self.entered = nil
+		self:SetMaxLetters(0)
+	end,
+
+	["OnRelease"] = function(self)
+		self:ClearFocus()
+	end,
+
+	["SetDisabled"] = function(self, disabled)
+		local editBox = self.editBox
+		if disabled then
+			editBox:ClearFocus()
+			editBox:EnableMouse(false)
+			editBox:SetTextColor(0.5, 0.5, 0.5)
+			self.label:SetTextColor(0.5, 0.5, 0.5)
+			self.scrollFrame:EnableMouse(false)
+			self.button:Disable()
+		else
+			editBox:EnableMouse(true)
+			editBox:SetTextColor(1, 1, 1)
+			self.label:SetTextColor(1, 0.82, 0)
+			self.scrollFrame:EnableMouse(true)
+		end
+	end,
+
+	["SetLabel"] = function(self, text)
+		if text and text ~= "" then
+			self.label:SetText(text)
+			if self.labelHeight ~= 10 then
+				self.labelHeight = 10
+				self.label:Show()
+			end
+		elseif self.labelHeight ~= 0 then
+			self.labelHeight = 0
+			self.label:Hide()
+		end
+		Layout(self)
+	end,
+
+	["SetNumLines"] = function(self, value)
+		if not value or value < 4 then
+			value = 4
+		end
+		self.numlines = value
+		Layout(self)
+	end,
+
+	["SetText"] = function(self, text)
+		self.editBox:SetText(text)
+	end,
+
+	["GetText"] = function(self)
+		return self.editBox:GetText()
+	end,
+
+	["SetMaxLetters"] = function (self, num)
+		self.editBox:SetMaxLetters(num or 0)
+	end,
+
+	["DisableButton"] = function(self, disabled)
+		self.disablebutton = disabled
+		if disabled then
+			self.button:Hide()
+		else
+			self.button:Show()
+		end
+		Layout(self)
+	end,
+
+	["ClearFocus"] = function(self)
+		self.editBox:ClearFocus()
+		self.frame:SetScript("OnShow", nil)
+	end,
+
+	["SetFocus"] = function(self)
+		self.editBox:SetFocus()
+		if not self.frame:IsShown() then
+			self.frame:SetScript("OnShow", OnShowFocus)
+		end
+	end,
+
+	["GetCursorPosition"] = function(self)
+		return self.editBox:GetCursorPosition()
+	end,
+
+	["SetCursorPosition"] = function(self, ...)
+		return self.editBox:SetCursorPosition(...)
+	end,
+
+
+}
+
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+local backdrop = {
+	bgFile = [[Interface\Tooltips\UI-Tooltip-Background]],
+	edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]], edgeSize = 16,
+	insets = { left = 4, right = 3, top = 4, bottom = 3 }
+}
+
+local function Constructor()
+	local frame = CreateFrame("Frame", nil, UIParent)
+	frame:Hide()
+
+	local widgetNum = AceGUI:GetNextWidgetNum(Type)
+
+	local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
+	label:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, -4)
+	label:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 0, -4)
+	label:SetJustifyH("LEFT")
+	label:SetText(ACCEPT)
+	label:SetHeight(10)
+
+	local button = CreateFrame("Button", ("%s%dButton"):format(Type, widgetNum), frame, wowMoP and "UIPanelButtonTemplate" or "UIPanelButtonTemplate2")
+	button:SetPoint("BOTTOMLEFT", 0, 4)
+	button:SetHeight(22)
+	button:SetWidth(label:GetStringWidth() + 24)
+	button:SetText(ACCEPT)
+	button:SetScript("OnClick", OnClick)
+	button:Disable()
+
+	local text = button:GetFontString()
+	text:ClearAllPoints()
+	text:SetPoint("TOPLEFT", button, "TOPLEFT", 5, -5)
+	text:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -5, 1)
+	text:SetJustifyV("MIDDLE")
+
+	local scrollBG = CreateFrame("Frame", nil, frame)
+	scrollBG:SetBackdrop(backdrop)
+	scrollBG:SetBackdropColor(0, 0, 0)
+	scrollBG:SetBackdropBorderColor(0.4, 0.4, 0.4)
+
+	local scrollFrame = CreateFrame("ScrollFrame", ("%s%dScrollFrame"):format(Type, widgetNum), frame, "UIPanelScrollFrameTemplate")
+
+	local scrollBar = _G[scrollFrame:GetName() .. "ScrollBar"]
+	scrollBar:ClearAllPoints()
+	scrollBar:SetPoint("TOP", label, "BOTTOM", 0, -19)
+	scrollBar:SetPoint("BOTTOM", button, "TOP", 0, 18)
+	scrollBar:SetPoint("RIGHT", frame, "RIGHT")
+
+	scrollBG:SetPoint("TOPRIGHT", scrollBar, "TOPLEFT", 0, 19)
+	scrollBG:SetPoint("BOTTOMLEFT", button, "TOPLEFT")
+
+	scrollFrame:SetPoint("TOPLEFT", scrollBG, "TOPLEFT", 5, -6)
+	scrollFrame:SetPoint("BOTTOMRIGHT", scrollBG, "BOTTOMRIGHT", -4, 4)
+	scrollFrame:SetScript("OnEnter", OnEnter)
+	scrollFrame:SetScript("OnLeave", OnLeave)
+	scrollFrame:SetScript("OnMouseUp", OnMouseUp)
+	scrollFrame:SetScript("OnReceiveDrag", OnReceiveDrag)
+	scrollFrame:SetScript("OnSizeChanged", OnSizeChanged)
+	scrollFrame:HookScript("OnVerticalScroll", OnVerticalScroll)
+
+	local editBox = CreateFrame("EditBox", ("%s%dEdit"):format(Type, widgetNum), scrollFrame)
+	editBox:SetAllPoints()
+	editBox:SetFontObject(ChatFontNormal)
+	editBox:SetMultiLine(true)
+	editBox:EnableMouse(true)
+	editBox:SetAutoFocus(false)
+	editBox:SetCountInvisibleLetters(false)
+	editBox:SetScript("OnCursorChanged", OnCursorChanged)
+	editBox:SetScript("OnEditFocusLost", OnEditFocusLost)
+	editBox:SetScript("OnEnter", OnEnter)
+	editBox:SetScript("OnEscapePressed", editBox.ClearFocus)
+	editBox:SetScript("OnLeave", OnLeave)
+	editBox:SetScript("OnMouseDown", OnReceiveDrag)
+	editBox:SetScript("OnReceiveDrag", OnReceiveDrag)
+	editBox:SetScript("OnTextChanged", OnTextChanged)
+	editBox:SetScript("OnTextSet", OnTextSet)
+	editBox:SetScript("OnEditFocusGained", OnEditFocusGained)
+
+
+	scrollFrame:SetScrollChild(editBox)
+
+	local widget = {
+		button      = button,
+		editBox     = editBox,
+		frame       = frame,
+		label       = label,
+		labelHeight = 10,
+		numlines    = 4,
+		scrollBar   = scrollBar,
+		scrollBG    = scrollBG,
+		scrollFrame = scrollFrame,
+		type        = Type
+	}
+	for method, func in pairs(methods) do
+		widget[method] = func
+	end
+	button.obj, editBox.obj, scrollFrame.obj = widget, widget, widget
+
+	return AceGUI:RegisterAsWidget(widget)
+end
+
+AceGUI:RegisterWidgetType(Type, Constructor, Version)
diff --git a/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-Slider.lua b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-Slider.lua
new file mode 100644
index 0000000..583f29d
--- /dev/null
+++ b/SVUI_!Core/libs/AceGUI-3.0/widgets/AceGUIWidget-Slider.lua
@@ -0,0 +1,285 @@
+--[[-----------------------------------------------------------------------------
+Slider Widget
+Graphical Slider, like, for Range values.
+-------------------------------------------------------------------------------]]
+local Type, Version = "Slider", 21
+local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
+if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
+
+-- Lua APIs
+local min, max, floor = math.min, math.max, math.floor
+local tonumber, pairs = tonumber, pairs
+
+-- WoW APIs
+local PlaySound = PlaySound
+local CreateFrame, UIParent = CreateFrame, UIParent
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: GameFontHighlightSmall
+
+--[[-----------------------------------------------------------------------------
+Support functions
+-------------------------------------------------------------------------------]]
+local function UpdateText(self)
+	local value = self.value or 0
+	if self.ispercent then
+		self.editbox:SetText(("%s%%"):format(floor(value * 1000 + 0.5) / 10))
+	else
+		self.editbox:SetText(floor(value * 100 + 0.5) / 100)
+	end
+end
+
+local function UpdateLabels(self)
+	local min, max = (self.min or 0), (self.max or 100)
+	if self.ispercent then
+		self.lowtext:SetFormattedText("%s%%", (min * 100))
+		self.hightext:SetFormattedText("%s%%", (max * 100))
+	else
+		self.lowtext:SetText(min)
+		self.hightext:SetText(max)
+	end
+end
+
+--[[-----------------------------------------------------------------------------
+Scripts
+-------------------------------------------------------------------------------]]
+local function Control_OnEnter(frame)
+	frame.obj:Fire("OnEnter")
+end
+
+local function Control_OnLeave(frame)
+	frame.obj:Fire("OnLeave")
+end
+
+local function Frame_OnMouseDown(frame)
+	frame.obj.slider:EnableMouseWheel(true)
+	AceGUI:ClearFocus()
+end
+
+local function Slider_OnValueChanged(frame)
+	local self = frame.obj
+	if not frame.setup then
+		local newvalue = frame:GetValue()
+		if self.step and self.step > 0 then
+			local min_value = self.min or 0
+			newvalue = floor((newvalue - min_value) / self.step + 0.5) * self.step + min_value
+		end
+		if newvalue ~= self.value and not self.disabled then
+			self.value = newvalue
+			self:Fire("OnValueChanged", newvalue)
+		end
+		if self.value then
+			UpdateText(self)
+		end
+	end
+end
+
+local function Slider_OnMouseUp(frame)
+	local self = frame.obj
+	self:Fire("OnMouseUp", self.value)
+end
+
+local function Slider_OnMouseWheel(frame, v)
+	local self = frame.obj
+	if not self.disabled then
+		local value = self.value
+		if v > 0 then
+			value = min(value + (self.step or 1), self.max)
+		else
+			value = max(value - (self.step or 1), self.min)
+		end
+		self.slider:SetValue(value)
+	end
+end
+
+local function EditBox_OnEscapePressed(frame)
+	frame:ClearFocus()
+end
+
+local function EditBox_OnEnterPressed(frame)
+	local self = frame.obj
+	local value = frame:GetText()
+	if self.ispercent then
+		value = value:gsub('%%', '')
+		value = tonumber(value) / 100
+	else
+		value = tonumber(value)
+	end
+
+	if value then
+		PlaySound("igMainMenuOptionCheckBoxOn")
+		self.slider:SetValue(value)
+		self:Fire("OnMouseUp", value)
+	end
+end
+
+local function EditBox_OnEnter(frame)
+	frame:SetBackdropBorderColor(0.5, 0.5, 0.5, 1)
+end
+
+local function EditBox_OnLeave(frame)
+	frame:SetBackdropBorderColor(0.3, 0.3, 0.3, 0.8)
+end
+
+--[[-----------------------------------------------------------------------------
+Methods
+-------------------------------------------------------------------------------]]
+local methods = {
+	["OnAcquire"] = function(self)
+		self:SetWidth(200)
+		self:SetHeight(44)
+		self:SetDisabled(false)
+		self:SetIsPercent(nil)
+		self:SetSliderValues(0,100,1)
+		self:SetValue(0)
+		self.slider:EnableMouseWheel(false)
+	end,
+
+	-- ["OnRelease"] = nil,
+
+	["SetDisabled"] = function(self, disabled)
+		self.disabled = disabled
+		if disabled then
+			self.slider:EnableMouse(false)
+			self.label:SetTextColor(.5, .5, .5)
+			self.hightext:SetTextColor(.5, .5, .5)
+			self.lowtext:SetTextColor(.5, .5, .5)
+			--self.valuetext:SetTextColor(.5, .5, .5)
+			self.editbox:SetTextColor(.5, .5, .5)
+			self.editbox:EnableMouse(false)
+			self.editbox:ClearFocus()
+		else
+			self.slider:EnableMouse(true)
+			self.label:SetTextColor(1, .82, 0)
+			self.hightext:SetTextColor(1, 1, 1)
+			self.lowtext:SetTextColor(1, 1, 1)
+			--self.valuetext:SetTextColor(1, 1, 1)
+			self.editbox:SetTextColor(1, 1, 1)
+			self.editbox:EnableMouse(true)
+		end
+	end,
+
+	["SetValue"] = function(self, value)
+		self.slider.setup = true
+		self.slider:SetValue(value)
+		self.value = value
+		UpdateText(self)
+		self.slider.setup = nil
+	end,
+
+	["GetValue"] = function(self)
+		return self.value
+	end,
+
+	["SetLabel"] = function(self, text)
+		self.label:SetText(text)
+	end,
+
+	["SetSliderValues"] = function(self, min, max, step)
+		local frame = self.slider
+		frame.setup = true
+		self.min = min
+		self.max = max
+		self.step = step
+		frame:SetMinMaxValues(min or 0,max or 100)
+		UpdateLabels(self)
+		frame:SetValueStep(step or 1)
+		if self.value then
+			frame:SetValue(self.value)
+		end
+		frame.setup = nil
+	end,
+
+	["SetIsPercent"] = function(self, value)
+		self.ispercent = value
+		UpdateLabels(self)
+		UpdateText(self)
+	end
+}
+
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+local SliderBackdrop  = {
+	bgFile = "Interface\\Buttons\\UI-SliderBar-Background",
+	edgeFile = "Interface\\Buttons\\UI-SliderBar-Border",
+	tile = true, tileSize = 8, edgeSize = 8,
+	insets = { left = 3, right = 3, top = 6, bottom = 6 }
+}
+
+local ManualBackdrop = {
+	bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
+	edgeFile = "Interface\\ChatFrame\\ChatFrameBackground",
+	tile = true, edgeSize = 1, tileSize = 5,
+}
+
+local function Constructor()
+	local frame = CreateFrame("Frame", nil, UIParent)
+
+	frame:EnableMouse(true)
+	frame:SetScript("OnMouseDown", Frame_OnMouseDown)
+
+	local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
+	label:SetPoint("TOPLEFT")
+	label:SetPoint("TOPRIGHT")
+	label:SetJustifyH("CENTER")
+	label:SetHeight(15)
+
+	local slider = CreateFrame("Slider", nil, frame)
+	slider:SetOrientation("HORIZONTAL")
+	slider:SetHeight(15)
+	slider:SetHitRectInsets(0, 0, -10, 0)
+	slider:SetBackdrop(SliderBackdrop)
+	slider:SetThumbTexture("Interface\\Buttons\\UI-SliderBar-Button-Horizontal")
+	slider:SetPoint("TOP", label, "BOTTOM")
+	slider:SetPoint("LEFT", 3, 0)
+	slider:SetPoint("RIGHT", -3, 0)
+	slider:SetValue(0)
+	slider:SetScript("OnValueChanged",Slider_OnValueChanged)
+	slider:SetScript("OnEnter", Control_OnEnter)
+	slider:SetScript("OnLeave", Control_OnLeave)
+	slider:SetScript("OnMouseUp", Slider_OnMouseUp)
+	slider:SetScript("OnMouseWheel", Slider_OnMouseWheel)
+
+	local lowtext = slider:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
+	lowtext:SetPoint("TOPLEFT", slider, "BOTTOMLEFT", 2, 3)
+
+	local hightext = slider:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
+	hightext:SetPoint("TOPRIGHT", slider, "BOTTOMRIGHT", -2, 3)
+
+	local editbox = CreateFrame("EditBox", nil, frame)
+	editbox:SetAutoFocus(false)
+	editbox:SetFontObject(GameFontHighlightSmall)
+	editbox:SetPoint("TOP", slider, "BOTTOM")
+	editbox:SetHeight(14)
+	editbox:SetWidth(70)
+	editbox:SetJustifyH("CENTER")
+	editbox:EnableMouse(true)
+	editbox:SetBackdrop(ManualBackdrop)
+	editbox:SetBackdropColor(0, 0, 0, 0.5)
+	editbox:SetBackdropBorderColor(0.3, 0.3, 0.30, 0.80)
+	editbox:SetScript("OnEnter", EditBox_OnEnter)
+	editbox:SetScript("OnLeave", EditBox_OnLeave)
+	editbox:SetScript("OnEnterPressed", EditBox_OnEnterPressed)
+	editbox:SetScript("OnEscapePressed", EditBox_OnEscapePressed)
+
+	local widget = {
+		label       = label,
+		slider      = slider,
+		lowtext     = lowtext,
+		hightext    = hightext,
+		editbox     = editbox,
+		alignoffset = 25,
+		frame       = frame,
+		type        = Type
+	}
+	for method, func in pairs(methods) do
+		widget[method] = func
+	end
+	slider.obj, editbox.obj = widget, widget
+
+	return AceGUI:RegisterAsWidget(widget)
+end
+
+AceGUI:RegisterWidgetType(Type,Constructor,Version)
diff --git a/SVUI_!Core/libs/AceVillain-1.0/AceVillain-1.0.lua b/SVUI_!Core/libs/AceVillain-1.0/AceVillain-1.0.lua
new file mode 100644
index 0000000..9c2b394
--- /dev/null
+++ b/SVUI_!Core/libs/AceVillain-1.0/AceVillain-1.0.lua
@@ -0,0 +1,291 @@
+--- Ace3 modification library.
+-- @class file
+-- @name AceVillain
+-- @author Steven Jackson (2014)
+-- @release 1.0.0
+
+local _G            = getfenv(0)
+local next        	= _G.next;
+local ipairs        = _G.ipairs;
+local table      	  = _G.table;
+local LibStub 		  = _G.LibStub;
+
+local MAJOR, MINOR = "AceVillain-1.0", 1
+local AceVillain, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
+
+if not AceVillain then
+  return	-- already loaded and no upgrade necessary
+end
+
+local UIParent 		= _G.UIParent;
+local CreateFrame 	= _G.CreateFrame;
+
+LoadAddOn("LibSharedMedia-3.0")
+local AceGUI = LibStub("AceGUI-3.0")
+local Media = LibStub("LibSharedMedia-3.0")
+
+_G.AceVillainWidgets = {
+	['font'] = Media:HashTable("font"),
+	['sound'] = Media:HashTable("sound"),
+	['statusbar'] = Media:HashTable("statusbar"),
+	['border'] = Media:HashTable("border"),
+	['background'] = Media:HashTable("background"),
+}
+
+do
+	local function disable(frame)
+		frame.label:SetTextColor(.5,.5,.5)
+		frame.text:SetTextColor(.5,.5,.5)
+		frame.dropButton:Disable()
+		if frame.displayButtonFont then
+			frame.displayButtonFont:SetTextColor(.5,.5,.5)
+			frame.displayButton:Disable()
+		end
+	end
+
+	local function enable(frame)
+		frame.label:SetTextColor(1,.82,0)
+		frame.text:SetTextColor(1,1,1)
+		frame.dropButton:Enable()
+		if frame.displayButtonFont then
+			frame.displayButtonFont:SetTextColor(1,1,1)
+			frame.displayButton:Enable()
+		end
+	end
+
+	local displayButtonBackdrop = {
+		edgeFile = [[Interface\AddOns\SVUI_!Core\assets\borders\DEFAULT]],
+		tile = true, tileSize = 16, edgeSize = 1,
+		insets = { left = 1, right = 1, top = 1, bottom = 1 },
+	}
+
+	-- create or retrieve BaseFrame
+	function AceVillain:GetBaseFrame()
+		local frame = CreateFrame("Frame", nil, UIParent)
+		frame:SetHeight(44)
+		frame:SetWidth(320)
+		frame:SetPoint("CENTER", UIParent, "CENTER")
+
+		local label = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
+			label:SetWordWrap(false)
+			label:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
+			label:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,0)
+			label:SetJustifyH("LEFT")
+			label:SetHeight(18)
+			label:SetText("")
+		frame.label = label
+
+		local DLeft = frame:CreateTexture(nil, "ARTWORK")
+			DLeft:SetWidth(25)
+			DLeft:SetHeight(64)
+			DLeft:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", -17, -21)
+			DLeft:SetTexture([[Interface\Glues\CharacterCreate\CharacterCreate-LabelFrame]])
+			DLeft:SetTexCoord(0, 0.1953125, 0, 1)
+		frame.DLeft = DLeft
+
+		local DRight = frame:CreateTexture(nil, "ARTWORK")
+			DRight:SetWidth(25)
+			DRight:SetHeight(64)
+			DRight:SetPoint("TOP", DLeft, "TOP")
+			DRight:SetPoint("RIGHT", frame, "RIGHT", 17, 0)
+			DRight:SetTexture([[Interface\Glues\CharacterCreate\CharacterCreate-LabelFrame]])
+			DRight:SetTexCoord(0.8046875, 1, 0, 1)
+		frame.DRight = DRight
+
+		local DMiddle = frame:CreateTexture(nil, "ARTWORK")
+			DMiddle:SetHeight(64)
+			DMiddle:SetPoint("TOP", DLeft, "TOP")
+			DMiddle:SetPoint("LEFT", DLeft, "RIGHT")
+			DMiddle:SetPoint("RIGHT", DRight, "LEFT")
+			DMiddle:SetTexture([[Interface\Glues\CharacterCreate\CharacterCreate-LabelFrame]])
+			DMiddle:SetTexCoord(0.1953125, 0.8046875, 0, 1)
+		frame.DMiddle = DMiddle
+
+		local text = frame:CreateFontString(nil,"OVERLAY","GameFontHighlightSmall")
+			text:SetWordWrap(false)
+			text:SetPoint("RIGHT",DRight,"RIGHT",-43,1)
+			text:SetPoint("LEFT",DLeft,"LEFT",26,1)
+			text:SetJustifyH("RIGHT")
+			text:SetHeight(18)
+			text:SetText("")
+		frame.text = text
+
+		local dropButton = CreateFrame("Button", nil, frame)
+			dropButton:SetWidth(24)
+			dropButton:SetHeight(24)
+			dropButton:SetPoint("TOPRIGHT", DRight, "TOPRIGHT", -16, -18)
+			dropButton:SetNormalTexture([[Interface\ChatFrame\UI-ChatIcon-ScrollDown-Up]])
+			dropButton:SetPushedTexture([[Interface\ChatFrame\UI-ChatIcon-ScrollDown-Down]])
+			dropButton:SetDisabledTexture([[Interface\ChatFrame\UI-ChatIcon-ScrollDown-Disabled]])
+			dropButton:SetHighlightTexture([[Interface\Buttons\UI-Common-MouseHilight]], "ADD")
+		frame.dropButton = dropButton
+
+		frame.Disable = disable
+		frame.Enable = enable
+		return frame
+	end
+
+	function AceVillain:GetBaseFrameWithWindow()
+		local frame = self:GetBaseFrame()
+
+		local displayButton = CreateFrame("Button", nil, frame)
+			displayButton:SetHeight(42)
+			displayButton:SetWidth(42)
+			displayButton:SetPoint("TOPLEFT", frame, "TOPLEFT", 1, -2)
+			displayButton:SetBackdrop(displayButtonBackdrop)
+			displayButton:SetBackdropBorderColor(.5, .5, .5)
+		frame.displayButton = displayButton
+
+		frame.label:SetPoint("TOPLEFT",displayButton,"TOPRIGHT",1,2)
+
+		frame.DLeft:SetPoint("BOTTOMLEFT", displayButton, "BOTTOMRIGHT", -17, -20)
+
+		return frame
+	end
+
+end
+
+do
+
+	local sliderBackdrop = {
+		["bgFile"] = [[Interface\AddOns\SVUI_!Core\assets\backgrounds\TRANSPARENT]],
+		["edgeFile"] = [[Interface\AddOns\SVUI_!Core\assets\borders\DEFAULT]],
+		["tile"] = false,
+		["edgeSize"] = 1,
+		["tileSize"] = 0,
+		["insets"] = {
+			["left"] = 0,
+			["right"] = 0,
+			["top"] = 0,
+			["bottom"] = 0,
+		},
+	}
+	local frameBackdrop = {
+		["bgFile"] = [[Interface\AddOns\SVUI_!Core\assets\backgrounds\DARK]],
+		["edgeFile"] = [[Interface\AddOns\SVUI_!Core\assets\borders\DEFAULT]],
+		["tile"] = false,
+		["edgeSize"] = 1,
+		["tileSize"] = 0,
+		["insets"] = {
+			["left"] = 0,
+			["right"] = 0,
+			["top"] = 0,
+			["bottom"] = 0,
+		},
+	}
+
+	local function OnMouseWheel(self, dir)
+		self.slider:SetValue(self.slider:GetValue()+(15*dir*-1))
+	end
+
+	local function AddFrame(self, frame)
+		frame:SetParent(self.contentframe)
+		frame:SetFrameStrata(self:GetFrameStrata())
+		frame:SetFrameLevel(self:GetFrameLevel() + 100)
+
+		if next(self.contentRepo) then
+			frame:SetPoint("TOPLEFT", self.contentRepo[#self.contentRepo], "BOTTOMLEFT", 0, 0)
+			frame:SetPoint("RIGHT", self.contentframe, "RIGHT", 0, 0)
+			self.contentframe:SetHeight(self.contentframe:GetHeight() + frame:GetHeight())
+			self.contentRepo[#self.contentRepo+1] = frame
+		else
+			self.contentframe:SetHeight(frame:GetHeight())
+			frame:SetPoint("TOPLEFT", self.contentframe, "TOPLEFT", 0, 0)
+			frame:SetPoint("RIGHT", self.contentframe, "RIGHT", 0, 0)
+			self.contentRepo[1] = frame
+		end
+
+		if self.contentframe:GetHeight() > UIParent:GetHeight()*2/5 - 20 then
+			self.scrollframe:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", -14, 12)
+			self:SetHeight(UIParent:GetHeight()*2/5)
+			self.slider:Show()
+			self:SetScript("OnMouseWheel", OnMouseWheel)
+			self.scrollframe:UpdateScrollChildRect()
+			self.slider:SetMinMaxValues(0, self.contentframe:GetHeight()-self.scrollframe:GetHeight())
+		else
+			self.scrollframe:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", -2, 12)
+			self:SetHeight(self.contentframe:GetHeight()+25)
+			self.slider:Hide()
+			self:SetScript("OnMouseWheel", nil)
+			self.scrollframe:UpdateScrollChildRect()
+			self.slider:SetMinMaxValues(0, 0)
+		end
+		self.contentframe:SetWidth(self.scrollframe:GetWidth())
+	end
+
+	local function ClearFrames(self)
+		for i, frame in ipairs(self.contentRepo) do
+			frame:ReturnSelf()
+			self.contentRepo[i] = nil
+		end
+	end
+
+	local function slider_OnValueChanged(self, value)
+		self.frame.scrollframe:SetVerticalScroll(value)
+	end
+
+	local DropDownCache = {}
+	function AceVillain:GetDropDownFrame()
+		local frame
+		if next(DropDownCache) then
+			frame = table.remove(DropDownCache)
+		else
+			frame = CreateFrame("Frame", nil, UIParent)
+				frame:SetClampedToScreen(true)
+				frame:SetWidth(320)
+				frame:SetBackdrop(frameBackdrop)
+				frame:SetFrameStrata("TOOLTIP")
+				frame:EnableMouseWheel(true)
+
+			local contentframe = CreateFrame("Frame", nil, frame)
+				contentframe:SetWidth(316)
+				contentframe:SetHeight(0)
+			frame.contentframe = contentframe
+
+			local scrollframe = CreateFrame("ScrollFrame", nil, frame)
+				scrollframe:SetWidth(316)
+				scrollframe:SetPoint("TOPLEFT", frame, "TOPLEFT", 2, -13)
+				scrollframe:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -2, 12)
+				scrollframe:SetScrollChild(contentframe)
+			frame.scrollframe = scrollframe
+
+			contentframe:SetPoint("TOPLEFT", scrollframe)
+			contentframe:SetPoint("TOPRIGHT", scrollframe)
+
+			local bgTex = frame:CreateTexture(nil, "ARTWORK")
+				bgTex:SetAllPoints(scrollframe)
+			frame.bgTex = bgTex
+
+			frame.AddFrame = AddFrame
+			frame.ClearFrames = ClearFrames
+			frame.contentRepo = {} -- store all our frames in here so we can get rid of them later
+
+			local slider = CreateFrame("Slider", nil, scrollframe)
+				slider:SetOrientation("VERTICAL")
+				slider:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -2, -13)
+				slider:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -2, 12)
+				slider:SetBackdrop(sliderBackdrop)
+				slider:SetThumbTexture([[Interface\AddOns\SVUI_!Core\assets\buttons\SCROLLBAR-KNOB]])
+				slider:SetMinMaxValues(0, 1)
+				--slider:SetValueStep(1)
+				slider:SetWidth(12)
+				slider.frame = frame
+				slider:SetScript("OnValueChanged", slider_OnValueChanged)
+			frame.slider = slider
+		end
+		frame:SetHeight(UIParent:GetHeight()*2/5)
+		frame.slider:SetValue(0)
+		frame:Show()
+		return frame
+	end
+
+	function AceVillain:ReturnDropDownFrame(frame)
+		ClearFrames(frame)
+		frame:ClearAllPoints()
+		frame:Hide()
+		frame:SetBackdrop(frameBackdrop)
+		frame.bgTex:SetTexture("")
+		table.insert(DropDownCache, frame)
+		return nil
+	end
+end
diff --git a/SVUI_!Core/libs/AceVillain-1.0/AceVillain-1.0.toc b/SVUI_!Core/libs/AceVillain-1.0/AceVillain-1.0.toc
new file mode 100644
index 0000000..9a66a71
--- /dev/null
+++ b/SVUI_!Core/libs/AceVillain-1.0/AceVillain-1.0.toc
@@ -0,0 +1,11 @@
+## Interface: 70000
+## LoadOnDemand: 1
+
+## Title: Lib: AceVillain-1.0
+## Notes: Provides shared widgets for use by the AceGUI lib.
+## Author: Failcoder
+## Version: 1.0-1
+## X-Category: Library
+## X-Revision: 1
+
+AceVillain-1.0\AceVillain-1.0.lua
diff --git a/SVUI_!Core/libs/AceVillain-1.0/AceVillain-1.0.xml b/SVUI_!Core/libs/AceVillain-1.0/AceVillain-1.0.xml
new file mode 100644
index 0000000..a0f1a8c
--- /dev/null
+++ b/SVUI_!Core/libs/AceVillain-1.0/AceVillain-1.0.xml
@@ -0,0 +1,25 @@
+<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="AceVillain-1.0.lua"/>
+	<!-- Container -->
+	<Script file="widgets\AceGUIContainer-DropDownGroup.lua"/>
+	<Script file="widgets\AceGUIContainer-Frame.lua"/>
+	<Script file="widgets\AceGUIContainer-InlineGroup.lua"/>
+	<Script file="widgets\AceGUIContainer-TabGroup.lua"/>
+	<Script file="widgets\AceGUIContainer-TreeGroup.lua"/>
+	<!-- Widgets -->
+	<Script file="widgets\AceGUIWidget-Button.lua"/>
+	<Script file="widgets\AceGUIWidget-CheckBox.lua"/>
+	<Script file="widgets\AceGUIWidget-DropDown.lua"/>
+	<Script file="widgets\AceGUIWidget-EditBox.lua"/>
+	<Script file="widgets\AceGUIWidget-Heading.lua"/>
+	<Script file="widgets\AceGUIWidget-Keybinding.lua"/>
+	<Script file="widgets\AceGUIWidget-MultiLineEditBox.lua"/>
+	<Script file="widgets\AceGUIWidget-Slider.lua"/>
+	<!-- Shared Widgets -->
+	<Script file="widgets\shared\FontWidget.lua" />
+	<Script file="widgets\shared\SoundWidget.lua" />
+	<Script file="widgets\shared\StatusbarWidget.lua" />
+	<Script file="widgets\shared\BorderWidget.lua" />
+	<Script file="widgets\shared\BackgroundWidget.lua" />
+</Ui>
diff --git a/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIContainer-DropDownGroup.lua b/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIContainer-DropDownGroup.lua
new file mode 100644
index 0000000..665d97f
--- /dev/null
+++ b/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIContainer-DropDownGroup.lua
@@ -0,0 +1,157 @@
+--[[-----------------------------------------------------------------------------
+DropdownGroup Container
+Container controlled by a dropdown on the top.
+-------------------------------------------------------------------------------]]
+local Type, Version = "DropdownGroup", 999999
+local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
+if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
+
+-- Lua APIs
+local assert, pairs, type = assert, pairs, type
+
+-- WoW APIs
+local CreateFrame = CreateFrame
+
+--[[-----------------------------------------------------------------------------
+Scripts
+-------------------------------------------------------------------------------]]
+local function SelectedGroup(self, event, value)
+	local group = self.parentgroup
+	local status = group.status or group.localstatus
+	status.selected = value
+	self.parentgroup:Fire("OnGroupSelected", value)
+end
+
+--[[-----------------------------------------------------------------------------
+Methods
+-------------------------------------------------------------------------------]]
+local methods = {
+	["OnAcquire"] = function(self)
+		self.dropdown:SetText("")
+		self:SetDropdownWidth(200)
+		self:SetTitle("")
+	end,
+
+	["OnRelease"] = function(self)
+		self.dropdown.list = nil
+		self.status = nil
+		for k in pairs(self.localstatus) do
+			self.localstatus[k] = nil
+		end
+	end,
+
+	["SetTitle"] = function(self, title)
+		self.titletext:SetText(title)
+		self.dropdown.frame:ClearAllPoints()
+		if title and title ~= "" then
+			self.dropdown.frame:SetPoint("TOPRIGHT", -2, 0)
+		else
+			self.dropdown.frame:SetPoint("TOPLEFT", -1, 0)
+		end
+	end,
+
+	["SetGroupList"] = function(self,list,order)
+		self.dropdown:SetList(list,order)
+	end,
+
+	["SetStatusTable"] = function(self, status)
+		assert(type(status) == "table")
+		self.status = status
+	end,
+
+	["SetGroup"] = function(self,group)
+		self.dropdown:SetValue(group)
+		local status = self.status or self.localstatus
+		status.selected = group
+		self:Fire("OnGroupSelected", group)
+	end,
+
+	["OnWidthSet"] = function(self, width)
+		local content = self.content
+		local contentwidth = width - 26
+		if contentwidth < 0 then
+			contentwidth = 0
+		end
+		content:SetWidth(contentwidth)
+		content.width = contentwidth
+	end,
+
+	["OnHeightSet"] = function(self, height)
+		local content = self.content
+		local contentheight = height - 63
+		if contentheight < 0 then
+			contentheight = 0
+		end
+		content:SetHeight(contentheight)
+		content.height = contentheight
+	end,
+
+	["LayoutFinished"] = function(self, width, height)
+		self:SetHeight((height or 0) + 63)
+	end,
+
+	["SetDropdownWidth"] = function(self, width)
+		self.dropdown:SetWidth(width)
+	end
+}
+
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+local PaneBackdrop  = {
+	bgFile = "Interface\\AddOns\\SVUI_!Core\\assets\\backgrounds\\TRANSPARENT",
+	edgeFile = "Interface\\AddOns\\SVUI_!Core\\assets\\borders\\DEFAULT",
+	tile = false, edgeSize = 1,
+	insets = { left = 0, right = 0, top = 0, bottom = 0 }
+}
+
+local function Constructor()
+	local frame = CreateFrame("Frame")
+	frame:SetHeight(100)
+	frame:SetWidth(100)
+	frame:SetFrameStrata("FULLSCREEN_DIALOG")
+
+	local titletext = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
+	titletext:SetPoint("TOPLEFT", 4, -5)
+	titletext:SetPoint("TOPRIGHT", -4, -5)
+	titletext:SetJustifyH("LEFT")
+	titletext:SetHeight(18)
+
+	local dropdown = AceGUI:Create("Dropdown")
+	dropdown.frame:SetParent(frame)
+	dropdown.frame:SetFrameLevel(dropdown.frame:GetFrameLevel() + 2)
+	dropdown:SetCallback("OnValueChanged", SelectedGroup)
+	dropdown.frame:SetPoint("TOPLEFT", -1, 0)
+	dropdown.frame:Show()
+	dropdown:SetLabel("")
+
+	local border = CreateFrame("Frame", nil, frame)
+	border:SetPoint("TOPLEFT", 0, -26)
+	border:SetPoint("BOTTOMRIGHT", 0, 3)
+	border:SetBackdrop(PaneBackdrop)
+	border:SetBackdropColor(0.1,0.1,0.1,0.5)
+	border:SetBackdropBorderColor(0.4,0.4,0.4)
+
+	--Container Support
+	local content = CreateFrame("Frame", nil, border)
+	content:SetPoint("TOPLEFT", 10, -10)
+	content:SetPoint("BOTTOMRIGHT", -10, 10)
+
+	local widget = {
+		frame       = frame,
+		localstatus = {},
+		titletext   = titletext,
+		dropdown    = dropdown,
+		border      = border,
+		content     = content,
+		type        = Type
+	}
+	for method, func in pairs(methods) do
+		widget[method] = func
+	end
+	dropdown.parentgroup = widget
+
+	return AceGUI:RegisterAsContainer(widget)
+end
+
+AceGUI:RegisterWidgetType(Type, Constructor, Version)
diff --git a/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIContainer-Frame.lua b/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIContainer-Frame.lua
new file mode 100644
index 0000000..650dddc
--- /dev/null
+++ b/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIContainer-Frame.lua
@@ -0,0 +1,303 @@
+--[[-----------------------------------------------------------------------------
+Frame Container
+-------------------------------------------------------------------------------]]
+local Type, Version = "Frame", 999999
+local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
+if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
+
+-- Lua APIs
+local pairs, assert, type = pairs, assert, type
+local wipe = table.wipe
+
+-- WoW APIs
+local PlaySound = PlaySound
+local CreateFrame, UIParent = CreateFrame, UIParent
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: CLOSE
+
+--[[-----------------------------------------------------------------------------
+Scripts
+-------------------------------------------------------------------------------]]
+local function Button_OnClick(frame)
+	PlaySound("gsTitleOptionExit")
+	frame.obj:Hide()
+end
+
+local function Frame_OnClose(frame)
+	frame.obj:Fire("OnClose")
+end
+
+local function Frame_OnMouseDown(frame)
+	AceGUI:ClearFocus()
+end
+
+local function Title_OnMouseDown(frame)
+	frame:GetParent():StartMoving()
+	AceGUI:ClearFocus()
+end
+
+local function LayoutSizer_OnMouseUp(mover)
+	local frame = mover:GetParent()
+	frame:StopMovingOrSizing()
+	local self = frame.obj
+	local status = self.status or self.localstatus
+	status.width = frame:GetWidth()
+	status.height = frame:GetHeight()
+	status.top = frame:GetTop()
+	status.left = frame:GetLeft()
+end
+
+local function SizerSE_OnMouseDown(frame)
+	frame:GetParent():StartSizing("BOTTOMRIGHT")
+	AceGUI:ClearFocus()
+end
+
+local function SizerS_OnMouseDown(frame)
+	frame:GetParent():StartSizing("BOTTOM")
+	AceGUI:ClearFocus()
+end
+
+local function SizerE_OnMouseDown(frame)
+	frame:GetParent():StartSizing("RIGHT")
+	AceGUI:ClearFocus()
+end
+
+local function StatusBar_OnEnter(frame)
+	frame.obj:Fire("OnEnterStatusBar")
+end
+
+local function StatusBar_OnLeave(frame)
+	frame.obj:Fire("OnLeaveStatusBar")
+end
+
+--[[-----------------------------------------------------------------------------
+Methods
+-------------------------------------------------------------------------------]]
+local methods = {
+	["OnAcquire"] = function(self)
+		self.frame:SetParent(UIParent)
+		self.frame:SetFrameStrata("FULLSCREEN_DIALOG")
+		self:SetTitle()
+		self:SetStatusText()
+		self:ApplyStatus()
+		self:Show()
+        self:EnableResize(true)
+	end,
+
+	["OnRelease"] = function(self)
+		self.status = nil
+		wipe(self.localstatus)
+	end,
+
+	["OnWidthSet"] = function(self, width)
+		local content = self.content
+		local contentwidth = width - 34
+		if contentwidth < 0 then
+			contentwidth = 0
+		end
+		content:SetWidth(contentwidth)
+		content.width = contentwidth
+	end,
+
+	["OnHeightSet"] = function(self, height)
+		local content = self.content
+		local contentheight = height - 57
+		if contentheight < 0 then
+			contentheight = 0
+		end
+		content:SetHeight(contentheight)
+		content.height = contentheight
+	end,
+
+	["SetTitle"] = function(self, title)
+		self.titletext:SetText(title)
+		self.titlebg:SetWidth((self.titletext:GetWidth() or 0) + 10)
+	end,
+
+	["SetStatusText"] = function(self, text)
+		self.statustext:SetText(text)
+	end,
+
+	["Hide"] = function(self)
+		self.frame:Hide()
+	end,
+
+	["Show"] = function(self)
+		self.frame:Show()
+	end,
+
+	["EnableResize"] = function(self, state)
+		local func = state and "Show" or "Hide"
+		self.sizer_se[func](self.sizer_se)
+		self.sizer_s[func](self.sizer_s)
+		self.sizer_e[func](self.sizer_e)
+	end,
+
+	-- called to set an external table to store status in
+	["SetStatusTable"] = function(self, status)
+		assert(type(status) == "table")
+		self.status = status
+		self:ApplyStatus()
+	end,
+
+	["ApplyStatus"] = function(self)
+		local status = self.status or self.localstatus
+		local frame = self.frame
+		self:SetWidth(status.width or 700)
+		self:SetHeight(status.height or 500)
+		frame:ClearAllPoints()
+		if status.top and status.left then
+			frame:SetPoint("TOP", UIParent, "BOTTOM", 0, status.top)
+			frame:SetPoint("LEFT", UIParent, "LEFT", status.left, 0)
+		else
+			frame:SetPoint("CENTER")
+		end
+	end
+}
+
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+local function SetHeadingStyle(frame)
+	local backdrop = CreateFrame("Frame", nil, frame)
+	backdrop:SetPoint("TOP", frame, "TOP", 0, 12)
+	backdrop:SetWidth(100)
+	backdrop:SetHeight(24)
+
+	local bg = backdrop:CreateTexture(nil, "BORDER")
+	bg:SetAllPoints(backdrop)
+	bg:SetColorTexture(0, 0, 0, 0.5)
+
+	local left = backdrop:CreateTexture(nil, "OVERLAY")
+	left:SetColorTexture(0, 0, 0, 1)
+	left:SetPoint("TOPLEFT", 1, -1)
+	left:SetPoint("BOTTOMLEFT", -1, -1)
+	left:SetWidth(2)
+
+	local right = backdrop:CreateTexture(nil, "OVERLAY")
+	right:SetColorTexture(0, 0, 0, 1)
+	right:SetPoint("TOPRIGHT", -1, -1)
+	right:SetPoint("BOTTOMRIGHT", -1, -1)
+	right:SetWidth(2)
+
+	local bottom = backdrop:CreateTexture(nil, "OVERLAY")
+	bottom:SetColorTexture(0, 0, 0, 1)
+	bottom:SetPoint("BOTTOMLEFT", 1, -1)
+	bottom:SetPoint("BOTTOMRIGHT", -1, -1)
+	bottom:SetHeight(2)
+
+	local top = backdrop:CreateTexture(nil, "OVERLAY")
+	top:SetColorTexture(0, 0, 0, 1)
+	top:SetPoint("TOPLEFT", 1, -1)
+	top:SetPoint("TOPRIGHT", -1, 1)
+	top:SetHeight(2)
+
+	return backdrop
+end
+
+local function Constructor()
+	local frame = CreateFrame("Frame", nil, UIParent)
+	frame:Hide()
+
+	frame:EnableMouse(true)
+	frame:SetMovable(true)
+	frame:SetResizable(true)
+	frame:SetFrameStrata("FULLSCREEN_DIALOG")
+	frame:SetMinResize(400, 200)
+	frame:SetToplevel(true)
+	frame:SetScript("OnHide", Frame_OnClose)
+	frame:SetScript("OnMouseDown", Frame_OnMouseDown)
+
+	if(frame.SetStyle) then
+		frame:SetStyle("Frame", "Window2")
+	end
+
+	local closebutton = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
+	closebutton:SetScript("OnClick", Button_OnClick)
+	closebutton:SetPoint("BOTTOMRIGHT", -27, 17)
+	closebutton:SetHeight(20)
+	closebutton:SetWidth(100)
+	closebutton:SetText(CLOSE)
+
+	if(closebutton.SetStyle) then
+		closebutton:SetStyle("Button", 0, 0, "red")
+	end
+
+	local statusbg = CreateFrame("Button", nil, frame)
+	statusbg:SetPoint("BOTTOMLEFT", 15, 15)
+	statusbg:SetPoint("BOTTOMRIGHT", -132, 15)
+	statusbg:SetHeight(24)
+	statusbg:SetScript("OnEnter", StatusBar_OnEnter)
+	statusbg:SetScript("OnLeave", StatusBar_OnLeave)
+
+	local statustext = statusbg:CreateFontString(nil, "OVERLAY", "GameFontNormal")
+	statustext:SetPoint("TOPLEFT", 7, -2)
+	statustext:SetPoint("BOTTOMRIGHT", -7, 2)
+	statustext:SetHeight(20)
+	statustext:SetJustifyH("LEFT")
+	statustext:SetText("")
+
+	local titlebg = SetHeadingStyle(frame)
+
+	local title = CreateFrame("Frame", nil, frame)
+	title:EnableMouse(true)
+	title:SetFrameLevel(titlebg:GetFrameLevel() + 20)
+	title:SetScript("OnMouseDown", Title_OnMouseDown)
+	title:SetScript("OnMouseUp", LayoutSizer_OnMouseUp)
+	title:SetAllPoints(titlebg)
+
+	local titletext = title:CreateFontString(nil, "OVERLAY", "GameFontNormal")
+	titletext:SetPoint("TOP", titlebg, "TOP", 0, -8)
+
+	local sizer_se = CreateFrame("Frame", nil, frame)
+	sizer_se:SetPoint("BOTTOMRIGHT")
+	sizer_se:SetWidth(25)
+	sizer_se:SetHeight(25)
+	sizer_se:EnableMouse()
+	sizer_se:SetScript("OnMouseDown",SizerSE_OnMouseDown)
+	sizer_se:SetScript("OnMouseUp", LayoutSizer_OnMouseUp)
+
+	local sizer_s = CreateFrame("Frame", nil, frame)
+	sizer_s:SetPoint("BOTTOMRIGHT", -25, 0)
+	sizer_s:SetPoint("BOTTOMLEFT")
+	sizer_s:SetHeight(25)
+	sizer_s:EnableMouse(true)
+	sizer_s:SetScript("OnMouseDown", SizerS_OnMouseDown)
+	sizer_s:SetScript("OnMouseUp", LayoutSizer_OnMouseUp)
+
+	local sizer_e = CreateFrame("Frame", nil, frame)
+	sizer_e:SetPoint("BOTTOMRIGHT", 0, 25)
+	sizer_e:SetPoint("TOPRIGHT")
+	sizer_e:SetWidth(25)
+	sizer_e:EnableMouse(true)
+	sizer_e:SetScript("OnMouseDown", SizerE_OnMouseDown)
+	sizer_e:SetScript("OnMouseUp", LayoutSizer_OnMouseUp)
+
+	--Container Support
+	local content = CreateFrame("Frame", nil, frame)
+	content:SetPoint("TOPLEFT", 17, -27)
+	content:SetPoint("BOTTOMRIGHT", -17, 40)
+
+	local widget = {
+		localstatus = {},
+		titletext   = titletext,
+		statustext  = statustext,
+		titlebg     = titlebg,
+		sizer_se    = sizer_se,
+		sizer_s     = sizer_s,
+		sizer_e     = sizer_e,
+		content     = content,
+		frame       = frame,
+		type        = Type
+	}
+	for method, func in pairs(methods) do
+		widget[method] = func
+	end
+	closebutton.obj, statusbg.obj = widget, widget
+
+	return AceGUI:RegisterAsContainer(widget)
+end
+
+AceGUI:RegisterWidgetType(Type, Constructor, Version)
diff --git a/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIContainer-InlineGroup.lua b/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIContainer-InlineGroup.lua
new file mode 100644
index 0000000..ccab3d6
--- /dev/null
+++ b/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIContainer-InlineGroup.lua
@@ -0,0 +1,103 @@
+--[[-----------------------------------------------------------------------------
+InlineGroup Container
+Simple container widget that creates a visible "box" with an optional title.
+-------------------------------------------------------------------------------]]
+local Type, Version = "InlineGroup", 999999
+local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
+if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
+
+-- Lua APIs
+local pairs = pairs
+
+-- WoW APIs
+local CreateFrame, UIParent = CreateFrame, UIParent
+
+--[[-----------------------------------------------------------------------------
+Methods
+-------------------------------------------------------------------------------]]
+local methods = {
+	["OnAcquire"] = function(self)
+		self:SetWidth(300)
+		self:SetHeight(100)
+		self:SetTitle("")
+	end,
+
+	-- ["OnRelease"] = nil,
+
+	["SetTitle"] = function(self,title)
+		self.titletext:SetText(title)
+	end,
+
+
+	["LayoutFinished"] = function(self, width, height)
+		if self.noAutoHeight then return end
+		self:SetHeight((height or 0) + 40)
+	end,
+
+	["OnWidthSet"] = function(self, width)
+		local content = self.content
+		local contentwidth = width - 20
+		if contentwidth < 0 then
+			contentwidth = 0
+		end
+		content:SetWidth(contentwidth)
+		content.width = contentwidth
+	end,
+
+	["OnHeightSet"] = function(self, height)
+		local content = self.content
+		local contentheight = height - 20
+		if contentheight < 0 then
+			contentheight = 0
+		end
+		content:SetHeight(contentheight)
+		content.height = contentheight
+	end
+}
+
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+local PaneBackdrop  = {
+	bgFile = "Interface\\AddOns\\SVUI_!Core\\assets\\backgrounds\\TRANSPARENT",
+	edgeFile = "Interface\\AddOns\\SVUI_!Core\\assets\\borders\\DEFAULT",
+	tile = false, edgeSize = 1,
+	insets = { left = 0, right = 0, top = 0, bottom = 0 }
+}
+
+local function Constructor()
+	local frame = CreateFrame("Frame", nil, UIParent)
+	frame:SetFrameStrata("FULLSCREEN_DIALOG")
+
+	local titletext = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
+	titletext:SetPoint("TOPLEFT", 14, 0)
+	titletext:SetPoint("TOPRIGHT", -14, 0)
+	titletext:SetJustifyH("LEFT")
+	titletext:SetHeight(18)
+
+	local border = CreateFrame("Frame", nil, frame)
+	border:SetPoint("TOPLEFT", 0, -17)
+	border:SetPoint("BOTTOMRIGHT", -1, 3)
+	border:SetBackdrop(PaneBackdrop)
+	border:SetBackdropColor(0.1, 0.1, 0.1, 0.5)
+	border:SetBackdropBorderColor(0.4, 0.4, 0.4)
+
+	--Container Support
+	local content = CreateFrame("Frame", nil, border)
+	content:SetPoint("TOPLEFT", 10, -10)
+	content:SetPoint("BOTTOMRIGHT", -10, 10)
+
+	local widget = {
+		frame     = frame,
+		content   = content,
+		titletext = titletext,
+		type      = Type
+	}
+	for method, func in pairs(methods) do
+		widget[method] = func
+	end
+
+	return AceGUI:RegisterAsContainer(widget)
+end
+
+AceGUI:RegisterWidgetType(Type, Constructor, Version)
diff --git a/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIContainer-TabGroup.lua b/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIContainer-TabGroup.lua
new file mode 100644
index 0000000..4d5c76b
--- /dev/null
+++ b/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIContainer-TabGroup.lua
@@ -0,0 +1,353 @@
+--[[-----------------------------------------------------------------------------
+TabGroup Container
+Container that uses tabs on top to switch between groups.
+-------------------------------------------------------------------------------]]
+local Type, Version = "TabGroup", 999999
+local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
+if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
+
+-- Lua APIs
+local pairs, ipairs, assert, type, wipe = pairs, ipairs, assert, type, wipe
+
+-- WoW APIs
+local PlaySound = PlaySound
+local CreateFrame, UIParent = CreateFrame, UIParent
+local _G = _G
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: PanelTemplates_TabResize, PanelTemplates_SetDisabledTabState, PanelTemplates_SelectTab, PanelTemplates_DeselectTab
+
+-- local upvalue storage used by BuildTabs
+local widths = {}
+local rowwidths = {}
+local rowends = {}
+
+--[[-----------------------------------------------------------------------------
+Support functions
+-------------------------------------------------------------------------------]]
+local function UpdateTabLook(frame)
+	if frame.disabled then
+		PanelTemplates_SetDisabledTabState(frame)
+	elseif frame.selected then
+		PanelTemplates_SelectTab(frame)
+	else
+		PanelTemplates_DeselectTab(frame)
+	end
+end
+
+local function Tab_SetText(frame, text)
+	frame:_SetText(text)
+	local width = frame.obj.frame.width or frame.obj.frame:GetWidth() or 0
+	PanelTemplates_TabResize(frame, 0, nil, nil, width, frame:GetFontString():GetStringWidth())
+end
+
+local function Tab_SetSelected(frame, selected)
+	frame.selected = selected
+	UpdateTabLook(frame)
+end
+
+local function Tab_SetDisabled(frame, disabled)
+	frame.disabled = disabled
+	UpdateTabLook(frame)
+end
+
+local function BuildTabsOnUpdate(frame)
+	local self = frame.obj
+	self:BuildTabs()
+	frame:SetScript("OnUpdate", nil)
+end
+
+--[[-----------------------------------------------------------------------------
+Scripts
+-------------------------------------------------------------------------------]]
+local function Tab_OnClick(frame)
+	if not (frame.selected or frame.disabled) then
+		PlaySound("igCharacterInfoTab")
+		frame.obj:SelectTab(frame.value)
+	end
+end
+
+local function Tab_OnEnter(frame)
+	local self = frame.obj
+	self:Fire("OnTabEnter", self.tabs[frame.id].value, frame)
+end
+
+local function Tab_OnLeave(frame)
+	local self = frame.obj
+	self:Fire("OnTabLeave", self.tabs[frame.id].value, frame)
+end
+
+local function Tab_OnShow(frame)
+	_G[frame:GetName().."HighlightTexture"]:SetWidth(frame:GetTextWidth() + 30)
+end
+
+--[[-----------------------------------------------------------------------------
+Methods
+-------------------------------------------------------------------------------]]
+local methods = {
+	["OnAcquire"] = function(self)
+		self:SetTitle()
+	end,
+
+	["OnRelease"] = function(self)
+		self.status = nil
+		for k in pairs(self.localstatus) do
+			self.localstatus[k] = nil
+		end
+		self.tablist = nil
+		for _, tab in pairs(self.tabs) do
+			tab:Hide()
+		end
+	end,
+
+	["CreateTab"] = function(self, id)
+		local tabname = ("AceGUITabGroup%dTab%d"):format(self.num, id)
+		local tab = CreateFrame("Button", tabname, self.border, "OptionsFrameTabButtonTemplate")
+		tab.obj = self
+		tab.id = id
+		if(tab.RemoveTextures) then
+			tab:RemoveTextures()
+		end
+
+		tab.text = _G[tabname .. "Text"]
+		tab.text:ClearAllPoints()
+		tab.text:SetPoint("LEFT", 14, -3)
+		tab.text:SetPoint("RIGHT", -12, -3)
+
+		tab:SetScript("OnClick", Tab_OnClick)
+		tab:SetScript("OnEnter", Tab_OnEnter)
+		tab:SetScript("OnLeave", Tab_OnLeave)
+		tab:SetScript("OnShow", Tab_OnShow)
+
+		tab._SetText = tab.SetText
+		tab.SetText = Tab_SetText
+		tab.SetSelected = Tab_SetSelected
+		tab.SetDisabled = Tab_SetDisabled
+
+		return tab
+	end,
+
+	["SetTitle"] = function(self, text)
+		self.titletext:SetText(text or "")
+		if text and text ~= "" then
+			self.alignoffset = 25
+		else
+			self.alignoffset = 18
+		end
+		self:BuildTabs()
+	end,
+
+	["SetStatusTable"] = function(self, status)
+		assert(type(status) == "table")
+		self.status = status
+	end,
+
+	["SelectTab"] = function(self, value)
+		local status = self.status or self.localstatus
+		local found
+		for i, v in ipairs(self.tabs) do
+			if v.value == value then
+				v:SetSelected(true)
+				found = true
+			else
+				v:SetSelected(false)
+			end
+		end
+		status.selected = value
+		if found then
+			self:Fire("OnGroupSelected",value)
+		end
+	end,
+
+	["SetTabs"] = function(self, tabs)
+		self.tablist = tabs
+		self:BuildTabs()
+	end,
+
+
+	["BuildTabs"] = function(self)
+		local hastitle = (self.titletext:GetText() and self.titletext:GetText() ~= "")
+		local status = self.status or self.localstatus
+		local tablist = self.tablist
+		local tabs = self.tabs
+
+		if not tablist then return end
+
+		local width = self.frame.width or self.frame:GetWidth() or 0
+
+		wipe(widths)
+		wipe(rowwidths)
+		wipe(rowends)
+
+		--Place Text into tabs and get thier initial width
+		for i, v in ipairs(tablist) do
+			local tab = tabs[i]
+			if not tab then
+				tab = self:CreateTab(i)
+				tabs[i] = tab
+			end
+
+			tab:Show()
+			tab:SetText(v.text)
+			tab:SetDisabled(v.disabled)
+			tab.value = v.value
+
+			widths[i] = tab:GetWidth() - 6 --tabs are anchored 10 pixels from the right side of the previous one to reduce spacing, but add a fixed 4px padding for the text
+		end
+
+		for i = (#tablist)+1, #tabs, 1 do
+			tabs[i]:Hide()
+		end
+
+		--First pass, find the minimum number of rows needed to hold all tabs and the initial tab layout
+		local numtabs = #tablist
+		local numrows = 1
+		local usedwidth = 0
+
+		for i = 1, #tablist do
+			--If this is not the first tab of a row and there isn't room for it
+			if usedwidth ~= 0 and (width - usedwidth - widths[i]) < 0 then
+				rowwidths[numrows] = usedwidth + 10 --first tab in each row takes up an extra 10px
+				rowends[numrows] = i - 1
+				numrows = numrows + 1
+				usedwidth = 0
+			end
+			usedwidth = usedwidth + widths[i]
+		end
+		rowwidths[numrows] = usedwidth + 10 --first tab in each row takes up an extra 10px
+		rowends[numrows] = #tablist
+
+		--Fix for single tabs being left on the last row, move a tab from the row above if applicable
+		if numrows > 1 then
+			--if the last row has only one tab
+			if rowends[numrows-1] == numtabs-1 then
+				--if there are more than 2 tabs in the 2nd last row
+				if (numrows == 2 and rowends[numrows-1] > 2) or (rowends[numrows] - rowends[numrows-1] > 2) then
+					--move 1 tab from the second last row to the last, if there is enough space
+					if (rowwidths[numrows] + widths[numtabs-1]) <= width then
+						rowends[numrows-1] = rowends[numrows-1] - 1
+						rowwidths[numrows] = rowwidths[numrows] + widths[numtabs-1]
+						rowwidths[numrows-1] = rowwidths[numrows-1] - widths[numtabs-1]
+					end
+				end
+			end
+		end
+
+		--anchor the rows as defined and resize tabs to fill thier row
+		local starttab = 1
+		for row, endtab in ipairs(rowends) do
+			local first = true
+			for tabno = starttab, endtab do
+				local tab = tabs[tabno]
+				tab:ClearAllPoints()
+				if first then
+					tab:SetPoint("TOPLEFT", self.frame, "TOPLEFT", 0, -(hastitle and 14 or 7)-(row-1)*20 )
+					first = false
+				else
+					tab:SetPoint("LEFT", tabs[tabno-1], "RIGHT", -10, 0)
+				end
+			end
+
+			-- equal padding for each tab to fill the available width,
+			-- if the used space is above 75% already
+			-- the 18 pixel is the typical width of a scrollbar, so we can have a tab group inside a scrolling frame,
+			-- and not have the tabs jump around funny when switching between tabs that need scrolling and those that don't
+			local padding = 0
+			if not (numrows == 1 and rowwidths[1] < width*0.75 - 18) then
+				padding = (width - rowwidths[row]) / (endtab - starttab+1)
+			end
+
+			for i = starttab, endtab do
+				PanelTemplates_TabResize(tabs[i], padding + 4, nil, nil, width, tabs[i]:GetFontString():GetStringWidth())
+			end
+			starttab = endtab + 1
+		end
+
+		self.borderoffset = (hastitle and 17 or 10)+((numrows)*20)
+		self.border:SetPoint("TOPLEFT", 1, -self.borderoffset)
+	end,
+
+	["OnWidthSet"] = function(self, width)
+		local content = self.content
+		local contentwidth = width - 60
+		if contentwidth < 0 then
+			contentwidth = 0
+		end
+		content:SetWidth(contentwidth)
+		content.width = contentwidth
+		self:BuildTabs(self)
+		self.frame:SetScript("OnUpdate", BuildTabsOnUpdate)
+	end,
+
+	["OnHeightSet"] = function(self, height)
+		local content = self.content
+		local contentheight = height - (self.borderoffset + 23)
+		if contentheight < 0 then
+			contentheight = 0
+		end
+		content:SetHeight(contentheight)
+		content.height = contentheight
+	end,
+
+	["LayoutFinished"] = function(self, width, height)
+		if self.noAutoHeight then return end
+		self:SetHeight((height or 0) + (self.borderoffset + 23))
+	end
+}
+
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+local PaneBackdrop  = {
+	bgFile = "Interface\\AddOns\\SVUI_!Core\\assets\\backgrounds\\TRANSPARENT",
+	edgeFile = "Interface\\AddOns\\SVUI_!Core\\assets\\borders\\DEFAULT",
+	tile = false, edgeSize = 1,
+	insets = { left = 0, right = 0, top = 0, bottom = 0 }
+}
+
+local function Constructor()
+	local num = AceGUI:GetNextWidgetNum(Type)
+	local frame = CreateFrame("Frame",nil,UIParent)
+	frame:SetHeight(100)
+	frame:SetWidth(100)
+	frame:SetFrameStrata("FULLSCREEN_DIALOG")
+
+	local titletext = frame:CreateFontString(nil,"OVERLAY","GameFontNormal")
+	titletext:SetPoint("TOPLEFT", 14, 0)
+	titletext:SetPoint("TOPRIGHT", -14, 0)
+	titletext:SetJustifyH("LEFT")
+	titletext:SetHeight(18)
+	titletext:SetText("")
+
+	local border = CreateFrame("Frame", nil, frame)
+	border:SetPoint("TOPLEFT", 1, -27)
+	border:SetPoint("BOTTOMRIGHT", -1, 3)
+	border:SetBackdrop(PaneBackdrop)
+	border:SetBackdropColor(0.1, 0.1, 0.1, 0.5)
+	border:SetBackdropBorderColor(0.4, 0.4, 0.4)
+
+	local content = CreateFrame("Frame", nil, border)
+	content:SetPoint("TOPLEFT", 10, -7)
+	content:SetPoint("BOTTOMRIGHT", -10, 7)
+
+	local widget = {
+		num          = num,
+		frame        = frame,
+		localstatus  = {},
+		alignoffset  = 18,
+		titletext    = titletext,
+		border       = border,
+		borderoffset = 27,
+		tabs         = {},
+		content      = content,
+		type         = Type
+	}
+	for method, func in pairs(methods) do
+		widget[method] = func
+	end
+
+	return AceGUI:RegisterAsContainer(widget)
+end
+
+AceGUI:RegisterWidgetType(Type, Constructor, Version)
diff --git a/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIContainer-TreeGroup.lua b/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIContainer-TreeGroup.lua
new file mode 100644
index 0000000..4690437
--- /dev/null
+++ b/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIContainer-TreeGroup.lua
@@ -0,0 +1,707 @@
+--[[-----------------------------------------------------------------------------
+TreeGroup Container
+Container that uses a tree control to switch between groups.
+-------------------------------------------------------------------------------]]
+local Type, Version = "TreeGroup", 999999
+local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
+if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
+
+-- Lua APIs
+local next, pairs, ipairs, assert, type = next, pairs, ipairs, assert, type
+local math_min, math_max, floor = math.min, math.max, floor
+local select, tremove, unpack, tconcat = select, table.remove, unpack, table.concat
+
+-- WoW APIs
+local CreateFrame, UIParent = CreateFrame, UIParent
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: GameTooltip, FONT_COLOR_CODE_CLOSE
+
+-- Recycling functions
+local new, del
+do
+	local pool = setmetatable({},{__mode='k'})
+	function new()
+		local t = next(pool)
+		if t then
+			pool[t] = nil
+			return t
+		else
+			return {}
+		end
+	end
+	function del(t)
+		for k in pairs(t) do
+			t[k] = nil
+		end
+		pool[t] = true
+	end
+end
+
+local DEFAULT_TREE_WIDTH = 175
+local DEFAULT_TREE_SIZABLE = true
+
+--[[-----------------------------------------------------------------------------
+Support functions
+-------------------------------------------------------------------------------]]
+local function GetButtonUniqueValue(line)
+	local parent = line.parent
+	if parent and parent.value then
+		return GetButtonUniqueValue(parent).."\001"..line.value
+	else
+		return line.value
+	end
+end
+
+local function UpdateButton(button, treeline, selected, canExpand, isExpanded)
+	local self = button.obj
+	local toggle = button.toggle
+	local frame = self.frame
+	local text = treeline.text or ""
+	local icon = treeline.icon
+	local iconCoords = treeline.iconCoords
+	local level = treeline.level
+	local value = treeline.value
+	local uniquevalue = treeline.uniquevalue
+	local disabled = treeline.disabled
+
+	button.treeline = treeline
+	button.value = value
+	button.uniquevalue = uniquevalue
+	if selected then
+		button:LockHighlight()
+		button.selected = true
+	else
+		button:UnlockHighlight()
+		button.selected = false
+	end
+	local normalTexture = button:GetNormalTexture()
+	local line = button.line
+	button.level = level
+	if ( level == 1 ) then
+		button:SetNormalFontObject("GameFontNormal")
+		button:SetHighlightFontObject("GameFontHighlight")
+		button.text:SetPoint("LEFT", (icon and 16 or 0) + 8, 2)
+	else
+		button:SetNormalFontObject("GameFontHighlightSmall")
+		button:SetHighlightFontObject("GameFontHighlightSmall")
+		button.text:SetPoint("LEFT", (icon and 16 or 0) + 8 * level, 2)
+	end
+
+	if disabled then
+		button:EnableMouse(false)
+		button.text:SetText("|cff808080"..text..FONT_COLOR_CODE_CLOSE)
+	else
+		button.text:SetText(text)
+		button:EnableMouse(true)
+	end
+
+	if icon then
+		button.icon:SetTexture(icon)
+		button.icon:SetPoint("LEFT", 8 * level, (level == 1) and 0 or 1)
+	else
+		button.icon:SetTexture("")
+	end
+
+	if iconCoords then
+		button.icon:SetTexCoord(unpack(iconCoords))
+	else
+		button.icon:SetTexCoord(0, 1, 0, 1)
+	end
+
+	if canExpand then
+		if not isExpanded then
+			toggle:SetNormalTexture("Interface\\Buttons\\UI-PlusButton-UP")
+			toggle:SetPushedTexture("Interface\\Buttons\\UI-PlusButton-DOWN")
+		else
+			toggle:SetNormalTexture("Interface\\Buttons\\UI-MinusButton-UP")
+			toggle:SetPushedTexture("Interface\\Buttons\\UI-MinusButton-DOWN")
+		end
+		toggle:Show()
+	else
+		toggle:Hide()
+	end
+end
+
+local function ShouldDisplayLevel(tree)
+	local result = false
+	for k, v in ipairs(tree) do
+		if v.children == nil and v.visible ~= false then
+			result = true
+		elseif v.children then
+			result = result or ShouldDisplayLevel(v.children)
+		end
+		if result then return result end
+	end
+	return false
+end
+
+local function addLine(self, v, tree, level, parent)
+	local line = new()
+	line.value = v.value
+	line.text = v.text
+	line.icon = v.icon
+	line.iconCoords = v.iconCoords
+	line.disabled = v.disabled
+	line.tree = tree
+	line.level = level
+	line.parent = parent
+	line.visible = v.visible
+	line.uniquevalue = GetButtonUniqueValue(line)
+	if v.children then
+		line.hasChildren = true
+	else
+		line.hasChildren = nil
+	end
+	self.lines[#self.lines+1] = line
+	return line
+end
+
+--fire an update after one frame to catch the treeframes height
+local function FirstFrameUpdate(frame)
+	local self = frame.obj
+	frame:SetScript("OnUpdate", nil)
+	self:RefreshTree()
+end
+
+local function BuildUniqueValue(...)
+	local n = select('#', ...)
+	if n == 1 then
+		return ...
+	else
+		return (...).."\001"..BuildUniqueValue(select(2,...))
+	end
+end
+
+--[[-----------------------------------------------------------------------------
+Scripts
+-------------------------------------------------------------------------------]]
+local function Expand_OnClick(frame)
+	local button = frame.button
+	local self = button.obj
+	local status = (self.status or self.localstatus).groups
+	status[button.uniquevalue] = not status[button.uniquevalue]
+	self:RefreshTree()
+end
+
+local function Button_OnClick(frame)
+	local self = frame.obj
+	self:Fire("OnClick", frame.uniquevalue, frame.selected)
+	if not frame.selected then
+		self:SetSelected(frame.uniquevalue)
+		frame.selected = true
+		frame:LockHighlight()
+		self:RefreshTree()
+	end
+	AceGUI:ClearFocus()
+end
+
+local function Button_OnDoubleClick(button)
+	local self = button.obj
+	local status = self.status or self.localstatus
+	local status = (self.status or self.localstatus).groups
+	status[button.uniquevalue] = not status[button.uniquevalue]
+	self:RefreshTree()
+end
+
+local function Button_OnEnter(frame)
+	local self = frame.obj
+	self:Fire("OnButtonEnter", frame.uniquevalue, frame)
+
+	if self.enabletooltips then
+		GameTooltip:SetOwner(frame, "ANCHOR_NONE")
+		GameTooltip:SetPoint("LEFT",frame,"RIGHT")
+		GameTooltip:SetText(frame.text:GetText() or "", 1, .82, 0, 1)
+
+		GameTooltip:Show()
+	end
+end
+
+local function Button_OnLeave(frame)
+	local self = frame.obj
+	self:Fire("OnButtonLeave", frame.uniquevalue, frame)
+
+	if self.enabletooltips then
+		GameTooltip:Hide()
+	end
+end
+
+local function OnScrollValueChanged(frame, value)
+	if frame.obj.noupdate then return end
+	local self = frame.obj
+	local status = self.status or self.localstatus
+	status.scrollvalue = floor(value + 0.5)
+	self:RefreshTree()
+	AceGUI:ClearFocus()
+end
+
+local function Tree_OnSizeChanged(frame)
+	frame.obj:RefreshTree()
+end
+
+local function Tree_OnMouseWheel(frame, delta)
+	local self = frame.obj
+	if self.showscroll then
+		local scrollbar = self.scrollbar
+		local min, max = scrollbar:GetMinMaxValues()
+		local value = scrollbar:GetValue()
+		local newvalue = math_min(max,math_max(min,value - delta))
+		if value ~= newvalue then
+			scrollbar:SetValue(newvalue)
+		end
+	end
+end
+
+local function Dragger_OnLeave(frame)
+	frame:SetBackdropColor(1, 1, 1, 0)
+end
+
+local function Dragger_OnEnter(frame)
+	frame:SetBackdropColor(1, 1, 1, 0.8)
+end
+
+local function Dragger_OnMouseDown(frame)
+	local treeframe = frame:GetParent()
+	treeframe:StartSizing("RIGHT")
+end
+
+local function Dragger_OnMouseUp(frame)
+	local treeframe = frame:GetParent()
+	local self = treeframe.obj
+	local frame = treeframe:GetParent()
+	treeframe:StopMovingOrSizing()
+	--treeframe:SetScript("OnUpdate", nil)
+	treeframe:SetUserPlaced(false)
+	--Without this :GetHeight will get stuck on the current height, causing the tree contents to not resize
+	treeframe:SetHeight(0)
+	treeframe:SetPoint("TOPLEFT", frame, "TOPLEFT",0,0)
+	treeframe:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT",0,0)
+
+	local status = self.status or self.localstatus
+	status.treewidth = treeframe:GetWidth()
+
+	treeframe.obj:Fire("OnTreeResize",treeframe:GetWidth())
+	-- recalculate the content width
+	treeframe.obj:OnWidthSet(status.fullwidth)
+	-- update the layout of the content
+	treeframe.obj:DoLayout()
+end
+
+--[[-----------------------------------------------------------------------------
+Methods
+-------------------------------------------------------------------------------]]
+local methods = {
+	["OnAcquire"] = function(self)
+		self:SetTreeWidth(DEFAULT_TREE_WIDTH, DEFAULT_TREE_SIZABLE)
+		self:EnableButtonTooltips(true)
+	end,
+
+	["OnRelease"] = function(self)
+		self.status = nil
+		for k, v in pairs(self.localstatus) do
+			if k == "groups" then
+				for k2 in pairs(v) do
+					v[k2] = nil
+				end
+			else
+				self.localstatus[k] = nil
+			end
+		end
+		self.localstatus.scrollvalue = 0
+		self.localstatus.treewidth = DEFAULT_TREE_WIDTH
+		self.localstatus.treesizable = DEFAULT_TREE_SIZABLE
+	end,
+
+	["EnableButtonTooltips"] = function(self, enable)
+		self.enabletooltips = enable
+	end,
+
+	["CreateButton"] = function(self)
+		local num = AceGUI:GetNextWidgetNum("TreeGroupButton")
+		local button = CreateFrame("Button", ("AceGUI30TreeButton%d"):format(num), self.treeframe, "OptionsListButtonTemplate")
+		button.obj = self
+
+		local icon = button:CreateTexture(nil, "OVERLAY")
+		icon:SetWidth(14)
+		icon:SetHeight(14)
+		button.icon = icon
+
+		button:SetScript("OnClick",Button_OnClick)
+		button:SetScript("OnDoubleClick", Button_OnDoubleClick)
+		button:SetScript("OnEnter",Button_OnEnter)
+		button:SetScript("OnLeave",Button_OnLeave)
+
+		button.toggle.button = button
+		button.toggle:SetScript("OnClick",Expand_OnClick)
+
+		return button
+	end,
+
+	["SetStatusTable"] = function(self, status)
+		assert(type(status) == "table")
+		self.status = status
+		if not status.groups then
+			status.groups = {}
+		end
+		if not status.scrollvalue then
+			status.scrollvalue = 0
+		end
+		if not status.treewidth then
+			status.treewidth = DEFAULT_TREE_WIDTH
+		end
+		if status.treesizable == nil then
+			status.treesizable = DEFAULT_TREE_SIZABLE
+		end
+		self:SetTreeWidth(status.treewidth,status.treesizable)
+		self:RefreshTree()
+	end,
+
+	--sets the tree to be displayed
+	["SetTree"] = function(self, tree, filter)
+		self.filter = filter
+		if tree then
+			assert(type(tree) == "table")
+		end
+		self.tree = tree
+		self:RefreshTree()
+	end,
+
+	["BuildLevel"] = function(self, tree, level, parent)
+		local groups = (self.status or self.localstatus).groups
+		local hasChildren = self.hasChildren
+
+		for i, v in ipairs(tree) do
+			if v.children then
+				if not self.filter or ShouldDisplayLevel(v.children) then
+					local line = addLine(self, v, tree, level, parent)
+					if groups[line.uniquevalue] then
+						self:BuildLevel(v.children, level+1, line)
+					end
+				end
+			elseif v.visible ~= false or not self.filter then
+				addLine(self, v, tree, level, parent)
+			end
+		end
+	end,
+
+	["RefreshTree"] = function(self,scrollToSelection)
+		local buttons = self.buttons
+		local lines = self.lines
+
+		for i, v in ipairs(buttons) do
+			v:Hide()
+		end
+		while lines[1] do
+			local t = tremove(lines)
+			for k in pairs(t) do
+				t[k] = nil
+			end
+			del(t)
+		end
+
+		if not self.tree then return end
+		--Build the list of visible entries from the tree and status tables
+		local status = self.status or self.localstatus
+		local groupstatus = status.groups
+		local tree = self.tree
+
+		local treeframe = self.treeframe
+
+		status.scrollToSelection = status.scrollToSelection or scrollToSelection	-- needs to be cached in case the control hasn't been drawn yet (code bails out below)
+
+		self:BuildLevel(tree, 1)
+
+		local numlines = #lines
+
+		local maxlines = (floor(((self.treeframe:GetHeight()or 0) - 20 ) / 18))
+		if maxlines <= 0 then return end
+
+		local first, last
+
+		scrollToSelection = status.scrollToSelection
+		status.scrollToSelection = nil
+
+		if numlines <= maxlines then
+			--the whole tree fits in the frame
+			status.scrollvalue = 0
+			self:ShowScroll(false)
+			first, last = 1, numlines
+		else
+			self:ShowScroll(true)
+			--scrolling will be needed
+			self.noupdate = true
+			self.scrollbar:SetMinMaxValues(0, numlines - maxlines)
+			--check if we are scrolled down too far
+			if numlines - status.scrollvalue < maxlines then
+				status.scrollvalue = numlines - maxlines
+			end
+			self.noupdate = nil
+			first, last = status.scrollvalue+1, status.scrollvalue + maxlines
+			--show selection?
+			if scrollToSelection and status.selected then
+				local show
+				for i,line in ipairs(lines) do	-- find the line number
+					if line.uniquevalue==status.selected then
+						show=i
+					end
+				end
+				if not show then
+					-- selection was deleted or something?
+				elseif show>=first and show<=last then
+					-- all good
+				else
+					-- scrolling needed!
+					if show<first then
+						status.scrollvalue = show-1
+					else
+						status.scrollvalue = show-maxlines
+					end
+					first, last = status.scrollvalue+1, status.scrollvalue + maxlines
+				end
+			end
+			if self.scrollbar:GetValue() ~= status.scrollvalue then
+				self.scrollbar:SetValue(status.scrollvalue)
+			end
+		end
+
+		local buttonnum = 1
+		for i = first, last do
+			local line = lines[i]
+			local button = buttons[buttonnum]
+			if not button then
+				button = self:CreateButton()
+
+				buttons[buttonnum] = button
+				button:SetParent(treeframe)
+				button:SetFrameLevel(treeframe:GetFrameLevel()+1)
+				button:ClearAllPoints()
+				if buttonnum == 1 then
+					if self.showscroll then
+						button:SetPoint("TOPRIGHT", -22, -10)
+						button:SetPoint("TOPLEFT", 0, -10)
+					else
+						button:SetPoint("TOPRIGHT", 0, -10)
+						button:SetPoint("TOPLEFT", 0, -10)
+					end
+				else
+					button:SetPoint("TOPRIGHT", buttons[buttonnum-1], "BOTTOMRIGHT",0,0)
+					button:SetPoint("TOPLEFT", buttons[buttonnum-1], "BOTTOMLEFT",0,0)
+				end
+			end
+
+			UpdateButton(button, line, status.selected == line.uniquevalue, line.hasChildren, groupstatus[line.uniquevalue] )
+			button:Show()
+			buttonnum = buttonnum + 1
+		end
+
+	end,
+
+	["SetSelected"] = function(self, value)
+		local status = self.status or self.localstatus
+		if status.selected ~= value then
+			status.selected = value
+			self:Fire("OnGroupSelected", value)
+		end
+	end,
+
+	["Select"] = function(self, uniquevalue, ...)
+		self.filter = false
+		local status = self.status or self.localstatus
+		local groups = status.groups
+		local path = {...}
+		for i = 1, #path do
+			groups[tconcat(path, "\001", 1, i)] = true
+		end
+		status.selected = uniquevalue
+		self:RefreshTree(true)
+		self:Fire("OnGroupSelected", uniquevalue)
+	end,
+
+	["SelectByPath"] = function(self, ...)
+		self:Select(BuildUniqueValue(...), ...)
+	end,
+
+	["SelectByValue"] = function(self, uniquevalue)
+		self:Select(uniquevalue, ("\001"):split(uniquevalue))
+	end,
+
+	["ShowScroll"] = function(self, show)
+		self.showscroll = show
+		if show then
+			self.scrollbar:Show()
+			if self.buttons[1] then
+				self.buttons[1]:SetPoint("TOPRIGHT", self.treeframe,"TOPRIGHT",-22,-10)
+			end
+		else
+			self.scrollbar:Hide()
+			if self.buttons[1] then
+				self.buttons[1]:SetPoint("TOPRIGHT", self.treeframe,"TOPRIGHT",0,-10)
+			end
+		end
+	end,
+
+	["OnWidthSet"] = function(self, width)
+		local content = self.content
+		local treeframe = self.treeframe
+		local status = self.status or self.localstatus
+		status.fullwidth = width
+
+		local contentwidth = width - status.treewidth - 20
+		if contentwidth < 0 then
+			contentwidth = 0
+		end
+		content:SetWidth(contentwidth)
+		content.width = contentwidth
+
+		local maxtreewidth = math_min(400, width - 50)
+
+		if maxtreewidth > 100 and status.treewidth > maxtreewidth then
+			self:SetTreeWidth(maxtreewidth, status.treesizable)
+		end
+		treeframe:SetMaxResize(maxtreewidth, 1600)
+	end,
+
+	["OnHeightSet"] = function(self, height)
+		local content = self.content
+		local contentheight = height - 20
+		if contentheight < 0 then
+			contentheight = 0
+		end
+		content:SetHeight(contentheight)
+		content.height = contentheight
+	end,
+
+	["SetTreeWidth"] = function(self, treewidth, resizable)
+		if not resizable then
+			if type(treewidth) == 'number' then
+				resizable = false
+			elseif type(treewidth) == 'boolean' then
+				resizable = treewidth
+				treewidth = DEFAULT_TREE_WIDTH
+			else
+				resizable = false
+				treewidth = DEFAULT_TREE_WIDTH
+			end
+		end
+		self.treeframe:SetWidth(treewidth)
+		self.dragger:EnableMouse(resizable)
+
+		local status = self.status or self.localstatus
+		status.treewidth = treewidth
+		status.treesizable = resizable
+
+		-- recalculate the content width
+		if status.fullwidth then
+			self:OnWidthSet(status.fullwidth)
+		end
+	end,
+
+	["GetTreeWidth"] = function(self)
+		local status = self.status or self.localstatus
+		return status.treewidth or DEFAULT_TREE_WIDTH
+	end,
+
+	["LayoutFinished"] = function(self, width, height)
+		if self.noAutoHeight then return end
+		self:SetHeight((height or 0) + 20)
+	end
+}
+
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+local PaneBackdrop  = {
+	bgFile = "Interface\\AddOns\\SVUI_!Core\\assets\\backgrounds\\TRANSPARENT",
+	edgeFile = "Interface\\AddOns\\SVUI_!Core\\assets\\borders\\DEFAULT",
+	tile = false, edgeSize = 1,
+	insets = { left = 0, right = 0, top = 0, bottom = 0 }
+}
+
+local DraggerBackdrop  = {
+	bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
+	edgeFile = nil,
+	tile = true, tileSize = 16, edgeSize = 0,
+	insets = { left = 3, right = 3, top = 7, bottom = 7 }
+}
+
+local function Constructor()
+	local num = AceGUI:GetNextWidgetNum(Type)
+	local frame = CreateFrame("Frame", nil, UIParent)
+
+	local treeframe = CreateFrame("Frame", nil, frame)
+	treeframe:SetPoint("TOPLEFT")
+	treeframe:SetPoint("BOTTOMLEFT")
+	treeframe:SetWidth(DEFAULT_TREE_WIDTH)
+	treeframe:EnableMouseWheel(true)
+	treeframe:SetBackdrop(PaneBackdrop)
+	treeframe:SetBackdropColor(0.1, 0.1, 0.1, 0.5)
+	treeframe:SetBackdropBorderColor(0.4, 0.4, 0.4)
+	treeframe:SetResizable(true)
+	treeframe:SetMinResize(100, 1)
+	treeframe:SetMaxResize(400, 1600)
+	treeframe:SetScript("OnUpdate", FirstFrameUpdate)
+	treeframe:SetScript("OnSizeChanged", Tree_OnSizeChanged)
+	treeframe:SetScript("OnMouseWheel", Tree_OnMouseWheel)
+
+	local dragger = CreateFrame("Frame", nil, treeframe)
+	dragger:SetWidth(8)
+	dragger:SetPoint("TOP", treeframe, "TOPRIGHT")
+	dragger:SetPoint("BOTTOM", treeframe, "BOTTOMRIGHT")
+	dragger:SetBackdrop(DraggerBackdrop)
+	dragger:SetBackdropColor(1, 1, 1, 0)
+	dragger:SetScript("OnEnter", Dragger_OnEnter)
+	dragger:SetScript("OnLeave", Dragger_OnLeave)
+	dragger:SetScript("OnMouseDown", Dragger_OnMouseDown)
+	dragger:SetScript("OnMouseUp", Dragger_OnMouseUp)
+
+	local scrollbar = CreateFrame("Slider", ("AceConfigDialogTreeGroup%dScrollBar"):format(num), treeframe, "UIPanelScrollBarTemplate")
+	scrollbar:SetScript("OnValueChanged", nil)
+	scrollbar:SetPoint("TOPRIGHT", -10, -26)
+	scrollbar:SetPoint("BOTTOMRIGHT", -10, 26)
+	scrollbar:SetMinMaxValues(0,0)
+	scrollbar:SetValueStep(1)
+	scrollbar:SetValue(0)
+	scrollbar:SetWidth(16)
+	scrollbar:SetScript("OnValueChanged", OnScrollValueChanged)
+
+	local scrollbg = scrollbar:CreateTexture(nil, "BACKGROUND")
+	scrollbg:SetAllPoints(scrollbar)
+	scrollbg:SetColorTexture(0,0,0,0.4)
+
+	local border = CreateFrame("Frame",nil,frame)
+	border:SetPoint("TOPLEFT", treeframe, "TOPRIGHT")
+	border:SetPoint("BOTTOMRIGHT")
+	border:SetBackdrop(PaneBackdrop)
+	border:SetBackdropColor(0.1, 0.1, 0.1, 0.5)
+	border:SetBackdropBorderColor(0.4, 0.4, 0.4)
+
+	--Container Support
+	local content = CreateFrame("Frame", nil, border)
+	content:SetPoint("TOPLEFT", 10, -10)
+	content:SetPoint("BOTTOMRIGHT", -10, 10)
+
+	local widget = {
+		frame        = frame,
+		lines        = {},
+		levels       = {},
+		buttons      = {},
+		hasChildren  = {},
+		localstatus  = { groups = {}, scrollvalue = 0 },
+		filter       = false,
+		treeframe    = treeframe,
+		dragger      = dragger,
+		scrollbar    = scrollbar,
+		border       = border,
+		content      = content,
+		type         = Type
+	}
+	for method, func in pairs(methods) do
+		widget[method] = func
+	end
+	treeframe.obj, dragger.obj, scrollbar.obj = widget, widget, widget
+
+	return AceGUI:RegisterAsContainer(widget)
+end
+
+AceGUI:RegisterWidgetType(Type, Constructor, Version)
diff --git a/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIWidget-Button.lua b/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIWidget-Button.lua
new file mode 100644
index 0000000..2d4161f
--- /dev/null
+++ b/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIWidget-Button.lua
@@ -0,0 +1,113 @@
+--[[-----------------------------------------------------------------------------
+Button Widget
+Graphical Button.
+-------------------------------------------------------------------------------]]
+local Type, Version = "Button", 999999
+local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
+if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
+
+-- Lua APIs
+local pairs = pairs
+
+-- WoW APIs
+local _G = _G
+local PlaySound, CreateFrame, UIParent = PlaySound, CreateFrame, UIParent
+
+local wowMoP
+do
+	local _, _, _, interface = GetBuildInfo()
+	wowMoP = (interface >= 50000)
+end
+
+--[[-----------------------------------------------------------------------------
+Scripts
+-------------------------------------------------------------------------------]]
+local function Button_OnClick(frame, ...)
+	AceGUI:ClearFocus()
+	PlaySound("igMainMenuOption")
+	frame.obj:Fire("OnClick", ...)
+end
+
+local function Control_OnEnter(frame)
+	frame.obj:Fire("OnEnter")
+end
+
+local function Control_OnLeave(frame)
+	frame.obj:Fire("OnLeave")
+end
+
+--[[-----------------------------------------------------------------------------
+Methods
+-------------------------------------------------------------------------------]]
+local methods = {
+	["OnAcquire"] = function(self)
+		-- restore default values
+		self:SetHeight(24)
+		self:SetWidth(320)
+		self:SetDisabled(false)
+		self:SetAutoWidth(false)
+		self:SetText()
+	end,
+
+	-- ["OnRelease"] = nil,
+
+	["SetText"] = function(self, text)
+		self.text:SetText(text)
+		if self.autoWidth then
+			self:SetWidth(self.text:GetStringWidth() + 30)
+		end
+	end,
+
+	["SetAutoWidth"] = function(self, autoWidth)
+		self.autoWidth = autoWidth
+		if self.autoWidth then
+			self:SetWidth(self.text:GetStringWidth() + 30)
+		end
+	end,
+
+	["SetDisabled"] = function(self, disabled)
+		self.disabled = disabled
+		if disabled then
+			self.frame:Disable()
+		else
+			self.frame:Enable()
+		end
+	end
+}
+
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+local function Constructor()
+	local name = "AceGUI30Button" .. AceGUI:GetNextWidgetNum(Type)
+	local frame = CreateFrame("Button", name, UIParent, wowMoP and "UIPanelButtonTemplate" or "UIPanelButtonTemplate2")
+	frame:Hide()
+
+	frame:EnableMouse(true)
+	frame:SetScript("OnClick", Button_OnClick)
+	frame:SetScript("OnEnter", Control_OnEnter)
+	frame:SetScript("OnLeave", Control_OnLeave)
+
+	local text = frame:GetFontString()
+	text:ClearAllPoints()
+	text:SetPoint("TOPLEFT", 15, -1)
+	text:SetPoint("BOTTOMRIGHT", -15, 1)
+	text:SetJustifyV("MIDDLE")
+
+	local widget = {
+		text  = text,
+		frame = frame,
+		type  = Type
+	}
+	for method, func in pairs(methods) do
+		widget[method] = func
+	end
+
+	if(frame.SetStyle) then
+		frame:SetStyle("Button")
+	end
+
+	return AceGUI:RegisterAsWidget(widget)
+end
+
+AceGUI:RegisterWidgetType(Type, Constructor, Version)
diff --git a/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIWidget-CheckBox.lua b/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIWidget-CheckBox.lua
new file mode 100644
index 0000000..fd989d3
--- /dev/null
+++ b/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIWidget-CheckBox.lua
@@ -0,0 +1,300 @@
+--[[-----------------------------------------------------------------------------
+Checkbox Widget
+-------------------------------------------------------------------------------]]
+local Type, Version = "CheckBox", 999999
+local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
+if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
+
+-- Lua APIs
+local select, pairs = select, pairs
+
+-- WoW APIs
+local PlaySound = PlaySound
+local CreateFrame, UIParent = CreateFrame, UIParent
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: SetDesaturation, GameFontHighlight
+
+--[[-----------------------------------------------------------------------------
+Support functions
+-------------------------------------------------------------------------------]]
+local function AlignImage(self)
+	local img = self.image:GetTexture()
+	self.text:ClearAllPoints()
+	if not img then
+		self.text:SetPoint("LEFT", self.checkbg, "RIGHT")
+		self.text:SetPoint("RIGHT")
+	else
+		self.text:SetPoint("LEFT", self.image,"RIGHT", 1, 0)
+		self.text:SetPoint("RIGHT")
+	end
+end
+
+--[[-----------------------------------------------------------------------------
+Scripts
+-------------------------------------------------------------------------------]]
+local function Control_OnEnter(frame)
+	frame.obj:Fire("OnEnter")
+end
+
+local function Control_OnLeave(frame)
+	frame.obj:Fire("OnLeave")
+end
+
+local function CheckBox_OnMouseDown(frame)
+	local self = frame.obj
+	if not self.disabled then
+		if self.image:GetTexture() then
+			self.text:SetPoint("LEFT", self.image,"RIGHT", 2, -1)
+		else
+			self.text:SetPoint("LEFT", self.checkbg, "RIGHT", 1, -1)
+		end
+	end
+	AceGUI:ClearFocus()
+end
+
+local function CheckBox_OnMouseUp(frame)
+	local self = frame.obj
+	if not self.disabled then
+		self:ToggleChecked()
+
+		if self.checked then
+			PlaySound("igMainMenuOptionCheckBoxOn")
+		else -- for both nil and false (tristate)
+			PlaySound("igMainMenuOptionCheckBoxOff")
+		end
+
+		self:Fire("OnValueChanged", self.checked)
+		AlignImage(self)
+	end
+end
+
+--[[-----------------------------------------------------------------------------
+Methods
+-------------------------------------------------------------------------------]]
+local methods = {
+	["OnAcquire"] = function(self)
+		self:SetType()
+		self:SetValue(false)
+		self:SetTriState(nil)
+		-- height is calculated from the width and required space for the description
+		self:SetWidth(320)
+		self:SetImage()
+		self:SetDisabled(nil)
+		self:SetDescription(nil)
+	end,
+
+	-- ["OnRelease"] = nil,
+
+	["OnWidthSet"] = function(self, width)
+		if self.desc then
+			self.desc:SetWidth(width - 30)
+			if self.desc:GetText() and self.desc:GetText() ~= "" then
+				self:SetHeight(28 + self.desc:GetHeight())
+			end
+		end
+	end,
+
+	["SetDisabled"] = function(self, disabled)
+		self.disabled = disabled
+		if disabled then
+			self.frame:Disable()
+			self.text:SetTextColor(0.5, 0.5, 0.5)
+			SetDesaturation(self.check, true)
+			if self.desc then
+				self.desc:SetTextColor(0.5, 0.5, 0.5)
+			end
+		else
+			self.frame:Enable()
+			self.text:SetTextColor(1, 1, 1)
+			if self.tristate and self.checked == nil then
+				SetDesaturation(self.check, true)
+			else
+				SetDesaturation(self.check, false)
+			end
+			if self.desc then
+				self.desc:SetTextColor(1, 1, 1)
+			end
+		end
+	end,
+
+	["SetValue"] = function(self,value)
+		local check = self.check
+		self.checked = value
+		if value then
+			SetDesaturation(self.check, false)
+			self.check:Show()
+		else
+			--Nil is the unknown tristate value
+			if self.tristate and value == nil then
+				SetDesaturation(self.check, true)
+				self.check:Show()
+			else
+				SetDesaturation(self.check, false)
+				self.check:Hide()
+			end
+		end
+		self:SetDisabled(self.disabled)
+	end,
+
+	["GetValue"] = function(self)
+		return self.checked
+	end,
+
+	["SetTriState"] = function(self, enabled)
+		self.tristate = enabled
+		self:SetValue(self:GetValue())
+	end,
+
+	["SetType"] = function(self, type)
+		local checkbg = self.checkbg
+		local check = self.check
+		local highlight = self.highlight
+
+		local size
+		if type == "radio" then
+			size = 16
+			checkbg:SetTexture([[Interface\AddOns\SVUI_!Core\assets\buttons\RADIO]])
+			checkbg:SetTexCoord(0, 0.25, 0, 1)
+			check:SetTexture([[Interface\AddOns\SVUI_!Core\assets\buttons\RADIO]])
+			check:SetTexCoord(0.25, 0.5, 0, 1)
+			check:SetBlendMode("ADD")
+			highlight:SetTexture([[Interface\AddOns\SVUI_!Core\assets\buttons\RADIO]])
+			highlight:SetTexCoord(0.5, 0.75, 0, 1)
+		else
+			size = 18
+			checkbg:SetTexture([[Interface\AddOns\SVUI_!Core\assets\buttons\CHECK-BG]])
+			checkbg:SetTexCoord(0, 1, 0, 1)
+			check:SetTexture([[Interface\AddOns\SVUI_!Core\assets\buttons\CHECK]])
+			check:SetTexCoord(0, 1, 0, 1)
+			check:SetBlendMode("BLEND")
+			highlight:SetTexture([[Interface\AddOns\SVUI_!Core\assets\buttons\CHECK]])
+			highlight:SetTexCoord(0, 1, 0, 1)
+		end
+		checkbg:SetHeight(size)
+		checkbg:SetWidth(size)
+	end,
+
+	["SetPlusMinus"] = function(self, enabled)
+		self.plusminus = enabled
+		self:SetType()
+	end,
+
+	["ToggleChecked"] = function(self)
+		local value = self:GetValue()
+		if self.tristate then
+			--cycle in true, nil, false order
+			if value then
+				self:SetValue(nil)
+			elseif value == nil then
+				self:SetValue(false)
+			else
+				self:SetValue(true)
+			end
+		else
+			self:SetValue(not self:GetValue())
+		end
+	end,
+
+	["SetLabel"] = function(self, label)
+		self.text:SetText(label)
+	end,
+
+	["SetDescription"] = function(self, desc)
+		if desc then
+			if not self.desc then
+				local desc = self.frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
+				desc:ClearAllPoints()
+				desc:SetPoint("TOPLEFT", self.checkbg, "TOPRIGHT", 5, -21)
+				desc:SetWidth(self.frame.width - 30)
+				desc:SetJustifyH("LEFT")
+				desc:SetJustifyV("TOP")
+				self.desc = desc
+			end
+			self.desc:Show()
+			--self.text:SetFontObject(GameFontNormal)
+			self.desc:SetText(desc)
+			self:SetHeight(28 + self.desc:GetHeight())
+		else
+			if self.desc then
+				self.desc:SetText("")
+				self.desc:Hide()
+			end
+			--self.text:SetFontObject(GameFontHighlight)
+			self:SetHeight(24)
+		end
+	end,
+
+	["SetImage"] = function(self, path, ...)
+		local image = self.image
+		image:SetTexture(path)
+
+		if image:GetTexture() then
+			local n = select("#", ...)
+			if n == 4 or n == 8 then
+				image:SetTexCoord(...)
+			else
+				image:SetTexCoord(0, 1, 0, 1)
+			end
+		end
+		AlignImage(self)
+	end
+}
+
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+local function Constructor()
+	local frame = CreateFrame("Button", nil, UIParent)
+	frame:Hide()
+
+	frame:EnableMouse(true)
+	frame:SetScript("OnEnter", Control_OnEnter)
+	frame:SetScript("OnLeave", Control_OnLeave)
+	frame:SetScript("OnMouseDown", CheckBox_OnMouseDown)
+	frame:SetScript("OnMouseUp", CheckBox_OnMouseUp)
+
+	local checkbg = frame:CreateTexture(nil, "ARTWORK")
+	checkbg:SetWidth(18)
+	checkbg:SetHeight(18)
+	checkbg:SetPoint("TOPLEFT")
+	checkbg:SetTexture([[Interface\AddOns\SVUI_!Core\assets\buttons\CHECK-BG]])
+
+	local check = frame:CreateTexture(nil, "OVERLAY")
+	check:SetAllPoints(checkbg)
+	check:SetTexture([[Interface\AddOns\SVUI_!Core\assets\buttons\CHECK]])
+
+	local text = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
+	text:SetJustifyH("LEFT")
+	text:SetHeight(18)
+	text:SetPoint("LEFT", checkbg, "RIGHT")
+	text:SetPoint("RIGHT")
+
+	local highlight = frame:CreateTexture(nil, "HIGHLIGHT")
+	highlight:SetTexture([[Interface\AddOns\SVUI_!Core\assets\buttons\CHECK]])
+	highlight:SetBlendMode("ADD")
+	highlight:SetAllPoints(checkbg)
+
+	local image = frame:CreateTexture(nil, "OVERLAY")
+	image:SetHeight(16)
+	image:SetWidth(16)
+	image:SetPoint("LEFT", checkbg, "RIGHT", 1, 0)
+
+	local widget = {
+		checkbg   = checkbg,
+		check     = check,
+		text      = text,
+		highlight = highlight,
+		image     = image,
+		frame     = frame,
+		type      = Type
+	}
+	for method, func in pairs(methods) do
+		widget[method] = func
+	end
+
+	return AceGUI:RegisterAsWidget(widget)
+end
+
+AceGUI:RegisterWidgetType(Type, Constructor, Version)
diff --git a/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIWidget-DropDown.lua b/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIWidget-DropDown.lua
new file mode 100644
index 0000000..c2320bb
--- /dev/null
+++ b/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIWidget-DropDown.lua
@@ -0,0 +1,754 @@
+--[[ $Id: AceGUIWidget-DropDown.lua 1101 2013-10-25 12:46:47Z nevcairiel $ ]]--
+local AceGUI = LibStub("AceGUI-3.0")
+
+-- Lua APIs
+local min, max, floor = math.min, math.max, math.floor
+local select, pairs, ipairs, type = select, pairs, ipairs, type
+local tsort = table.sort
+
+-- WoW APIs
+local PlaySound = PlaySound
+local UIParent, CreateFrame = UIParent, CreateFrame
+local _G = _G
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: CLOSE
+
+local function fixlevels(parent,...)
+	local i = 1
+	local child = select(i, ...)
+	while child do
+		child:SetFrameLevel(parent:GetFrameLevel()+1)
+		fixlevels(child, child:GetChildren())
+		i = i + 1
+		child = select(i, ...)
+	end
+end
+
+local function fixstrata(strata, parent, ...)
+	local i = 1
+	local child = select(i, ...)
+	parent:SetFrameStrata(strata)
+	while child do
+		fixstrata(strata, child, child:GetChildren())
+		i = i + 1
+		child = select(i, ...)
+	end
+end
+
+do
+	local widgetType = "Dropdown-Pullout"
+	local widgetVersion = 999999
+
+	--[[ Static data ]]--
+	local backdrop  = {
+		bgFile = "Interface\\AddOns\\SVUI_!Core\\assets\\backgrounds\\TRANSPARENT",
+		edgeFile = "Interface\\AddOns\\SVUI_!Core\\assets\\borders\\DEFAULT",
+		tile = false, edgeSize = 1,
+		insets = { left = 0, right = 0, top = 0, bottom = 0 }
+	}
+
+	local defaultWidth = 200
+	local defaultMaxHeight = 600
+
+	--[[ UI Event Handlers ]]--
+
+	-- HACK: This should be no part of the pullout, but there
+	--       is no other 'clean' way to response to any item-OnEnter
+	--       Used to close Submenus when an other item is entered
+	local function OnEnter(item)
+		local self = item.pullout
+		for k, v in ipairs(self.items) do
+			if v.CloseMenu and v ~= item then
+				v:CloseMenu()
+			end
+		end
+	end
+
+	-- See the note in Constructor() for each scroll related function
+	local function OnMouseWheel(this, value)
+		this.obj:MoveScroll(value)
+	end
+
+	local function OnScrollValueChanged(this, value)
+		this.obj:SetScroll(value)
+	end
+
+	local function OnSizeChanged(this)
+		this.obj:FixScroll()
+	end
+
+	--[[ Exported methods ]]--
+
+	-- exported
+	local function SetScroll(self, value)
+		local status = self.scrollStatus
+		local frame, child = self.scrollFrame, self.itemFrame
+		local height, viewheight = frame:GetHeight(), child:GetHeight()
+
+		local offset
+		if height > viewheight then
+			offset = 0
+		else
+			offset = floor((viewheight - height) / 1000 * value)
+		end
+		child:ClearAllPoints()
+		child:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, offset)
+		child:SetPoint("TOPRIGHT", frame, "TOPRIGHT", self.slider:IsShown() and -12 or 0, offset)
+		status.offset = offset
+		status.scrollvalue = value
+	end
+
+	-- exported
+	local function MoveScroll(self, value)
+		local status = self.scrollStatus
+		local frame, child = self.scrollFrame, self.itemFrame
+		local height, viewheight = frame:GetHeight(), child:GetHeight()
+
+		if height > viewheight then
+			self.slider:Hide()
+		else
+			self.slider:Show()
+			local diff = height - viewheight
+			local delta = 1
+			if value < 0 then
+				delta = -1
+			end
+			self.slider:SetValue(min(max(status.scrollvalue + delta*(1000/(diff/45)),0), 1000))
+		end
+	end
+
+	-- exported
+	local function FixScroll(self)
+		local status = self.scrollStatus
+		local frame, child = self.scrollFrame, self.itemFrame
+		local height, viewheight = frame:GetHeight(), child:GetHeight()
+		local offset = status.offset or 0
+
+		if viewheight < height then
+			self.slider:Hide()
+			child:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 0, offset)
+			self.slider:SetValue(0)
+		else
+			self.slider:Show()
+			local value = (offset / (viewheight - height) * 1000)
+			if value > 1000 then value = 1000 end
+			self.slider:SetValue(value)
+			self:SetScroll(value)
+			if value < 1000 then
+				child:ClearAllPoints()
+				child:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, offset)
+				child:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -12, offset)
+				status.offset = offset
+			end
+		end
+	end
+
+	-- exported, AceGUI callback
+	local function OnAcquire(self)
+		self.frame:SetParent(UIParent)
+		--self.itemFrame:SetToplevel(true)
+	end
+
+	-- exported, AceGUI callback
+	local function OnRelease(self)
+		self:Clear()
+		self.frame:ClearAllPoints()
+		self.frame:Hide()
+	end
+
+	-- exported
+	local function AddItem(self, item)
+		self.items[#self.items + 1] = item
+
+		local h = #self.items * 16
+		self.itemFrame:SetHeight(h)
+		self.frame:SetHeight(min(h + 34, self.maxHeight)) -- +34: 20 for scrollFrame placement (10 offset) and +14 for item placement
+
+		item.frame:SetPoint("LEFT", self.itemFrame, "LEFT")
+		item.frame:SetPoint("RIGHT", self.itemFrame, "RIGHT")
+
+		item:SetPullout(self)
+		item:SetOnEnter(OnEnter)
+	end
+
+	-- exported
+	local function Open(self, point, relFrame, relPoint, x, y)
+		local items = self.items
+		local frame = self.frame
+		local itemFrame = self.itemFrame
+
+		frame:SetPoint(point, relFrame, relPoint, x, y)
+
+
+		local height = 8
+		for i, item in pairs(items) do
+			if i == 1 then
+				item:SetPoint("TOP", itemFrame, "TOP", 0, -2)
+			else
+				item:SetPoint("TOP", items[i-1].frame, "BOTTOM", 0, 1)
+			end
+
+			item:Show()
+
+			height = height + 16
+		end
+		itemFrame:SetHeight(height)
+		fixstrata("TOOLTIP", frame, frame:GetChildren())
+		frame:Show()
+		self:Fire("OnOpen")
+	end
+
+	-- exported
+	local function Close(self)
+		self.frame:Hide()
+		self:Fire("OnClose")
+	end
+
+	-- exported
+	local function Clear(self)
+		local items = self.items
+		for i, item in pairs(items) do
+			AceGUI:Release(item)
+			items[i] = nil
+		end
+	end
+
+	-- exported
+	local function IterateItems(self)
+		return ipairs(self.items)
+	end
+
+	-- exported
+	local function SetHideOnLeave(self, val)
+		self.hideOnLeave = val
+	end
+
+	-- exported
+	local function SetMaxHeight(self, height)
+		self.maxHeight = height or defaultMaxHeight
+		if self.frame:GetHeight() > height then
+			self.frame:SetHeight(height)
+		elseif (self.itemFrame:GetHeight() + 34) < height then
+			self.frame:SetHeight(self.itemFrame:GetHeight() + 34) -- see :AddItem
+		end
+	end
+
+	-- exported
+	local function GetRightBorderWidth(self)
+		return 6 + (self.slider:IsShown() and 12 or 0)
+	end
+
+	-- exported
+	local function GetLeftBorderWidth(self)
+		return 6
+	end
+
+	--[[ Constructor ]]--
+
+	local function Constructor()
+		local count = AceGUI:GetNextWidgetNum(widgetType)
+		local frame = CreateFrame("Frame", "AceGUI30Pullout"..count, UIParent)
+		local self = {}
+		self.count = count
+		self.type = widgetType
+		self.frame = frame
+		frame.obj = self
+
+		self.OnAcquire = OnAcquire
+		self.OnRelease = OnRelease
+
+		self.AddItem = AddItem
+		self.Open    = Open
+		self.Close   = Close
+		self.Clear   = Clear
+		self.IterateItems = IterateItems
+		self.SetHideOnLeave = SetHideOnLeave
+
+		self.SetScroll  = SetScroll
+		self.MoveScroll = MoveScroll
+		self.FixScroll  = FixScroll
+
+		self.SetMaxHeight = SetMaxHeight
+		self.GetRightBorderWidth = GetRightBorderWidth
+		self.GetLeftBorderWidth = GetLeftBorderWidth
+
+		self.items = {}
+
+		self.scrollStatus = {
+			scrollvalue = 0,
+		}
+
+		self.maxHeight = defaultMaxHeight
+
+		frame:SetBackdrop(backdrop)
+		frame:SetBackdropColor(0, 0, 0)
+		frame:SetFrameStrata("FULLSCREEN_DIALOG")
+		frame:SetClampedToScreen(true)
+		frame:SetWidth(defaultWidth)
+		frame:SetHeight(self.maxHeight)
+		--frame:SetToplevel(true)
+
+		-- NOTE: The whole scroll frame code is copied from the AceGUI-3.0 widget ScrollFrame
+		local scrollFrame = CreateFrame("ScrollFrame", nil, frame)
+		local itemFrame = CreateFrame("Frame", nil, scrollFrame)
+
+		self.scrollFrame = scrollFrame
+		self.itemFrame = itemFrame
+
+		scrollFrame.obj = self
+		itemFrame.obj = self
+
+		local slider = CreateFrame("Slider", "AceGUI30PulloutScrollbar"..count, scrollFrame)
+		slider:SetOrientation("VERTICAL")
+		slider:SetHitRectInsets(0, 0, -10, 0)
+		slider:SetBackdrop(backdrop)
+		slider:SetWidth(8)
+		slider:SetThumbTexture("Interface\\AddOns\\SVUI_!Core\\assets\\buttons\\SCROLLBAR-KNOB")
+		slider:SetFrameStrata("FULLSCREEN_DIALOG")
+		self.slider = slider
+		slider.obj = self
+
+		scrollFrame:SetScrollChild(itemFrame)
+		scrollFrame:SetPoint("TOPLEFT", frame, "TOPLEFT", 6, -12)
+		scrollFrame:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -6, 12)
+		scrollFrame:EnableMouseWheel(true)
+		scrollFrame:SetScript("OnMouseWheel", OnMouseWheel)
+		scrollFrame:SetScript("OnSizeChanged", OnSizeChanged)
+		scrollFrame:SetToplevel(true)
+		scrollFrame:SetFrameStrata("FULLSCREEN_DIALOG")
+
+		itemFrame:SetPoint("TOPLEFT", scrollFrame, "TOPLEFT", 0, 0)
+		itemFrame:SetPoint("TOPRIGHT", scrollFrame, "TOPRIGHT", -12, 0)
+		itemFrame:SetHeight(400)
+		itemFrame:SetToplevel(true)
+		itemFrame:SetFrameStrata("FULLSCREEN_DIALOG")
+
+		slider:SetPoint("TOPLEFT", scrollFrame, "TOPRIGHT", -16, 0)
+		slider:SetPoint("BOTTOMLEFT", scrollFrame, "BOTTOMRIGHT", -16, 0)
+		slider:SetScript("OnValueChanged", OnScrollValueChanged)
+		slider:SetMinMaxValues(0, 1000)
+		slider:SetValueStep(1)
+		slider:SetValue(0)
+
+		scrollFrame:Show()
+		itemFrame:Show()
+		slider:Hide()
+
+		self:FixScroll()
+
+		AceGUI:RegisterAsWidget(self)
+		return self
+	end
+
+	AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion)
+end
+
+do
+	local widgetType = "Dropdown"
+	local widgetVersion = 999999
+
+	--[[ Static data ]]--
+
+	--[[ UI event handler ]]--
+
+	local function Control_OnEnter(this)
+		this.obj.button:LockHighlight()
+		this.obj:Fire("OnEnter")
+	end
+
+	local function Control_OnLeave(this)
+		this.obj.button:UnlockHighlight()
+		this.obj:Fire("OnLeave")
+	end
+
+	local function Dropdown_OnHide(this)
+		local self = this.obj
+		if self.open then
+			self.pullout:Close()
+		end
+	end
+
+	local function Dropdown_TogglePullout(this)
+		local self = this.obj
+		PlaySound("igMainMenuOptionCheckBoxOn") -- missleading name, but the Blizzard code uses this sound
+		if self.open then
+			self.open = nil
+			self.pullout:Close()
+			AceGUI:ClearFocus()
+		else
+			self.open = true
+			self.pullout:SetWidth(self.pulloutWidth or self.frame:GetWidth())
+			self.pullout:Open("TOPLEFT", self.frame, "BOTTOMLEFT", 0, self.label:IsShown() and -2 or 0)
+			AceGUI:SetFocus(self)
+		end
+	end
+
+	local function OnPulloutOpen(this)
+		local self = this.userdata.obj
+		local value = self.value
+
+		if not self.multiselect then
+			for i, item in this:IterateItems() do
+				item:SetValue(item.userdata.value == value)
+			end
+		end
+
+		self.open = true
+		self:Fire("OnOpened")
+	end
+
+	local function OnPulloutClose(this)
+		local self = this.userdata.obj
+		self.open = nil
+		self:Fire("OnClosed")
+	end
+
+	local function ShowMultiText(self)
+		local text
+		for i, widget in self.pullout:IterateItems() do
+			if widget.type == "Dropdown-Item-Toggle" then
+				if widget:GetValue() then
+					if text then
+						text = text..", "..widget:GetText()
+					else
+						text = widget:GetText()
+					end
+				end
+			end
+		end
+		self:SetText(text)
+	end
+
+	local function OnItemValueChanged(this, event, checked)
+		local self = this.userdata.obj
+
+		if self.multiselect then
+			self:Fire("OnValueChanged", this.userdata.value, checked)
+			ShowMultiText(self)
+		else
+			if checked then
+				self:SetValue(this.userdata.value)
+				self:Fire("OnValueChanged", this.userdata.value)
+			else
+				this:SetValue(true)
+			end
+			if self.open then
+				self.pullout:Close()
+			end
+		end
+	end
+
+	--[[ Exported methods ]]--
+
+	-- exported, AceGUI callback
+	local function OnAcquire(self)
+		local pullout = AceGUI:Create("Dropdown-Pullout")
+		self.pullout = pullout
+		pullout.userdata.obj = self
+		pullout:SetCallback("OnClose", OnPulloutClose)
+		pullout:SetCallback("OnOpen", OnPulloutOpen)
+		self.pullout.frame:SetFrameLevel(self.frame:GetFrameLevel() + 1)
+		fixlevels(self.pullout.frame, self.pullout.frame:GetChildren())
+
+		self:SetHeight(44)
+		self:SetWidth(320)
+		self:SetLabel()
+		self:SetPulloutWidth(nil)
+	end
+
+	-- exported, AceGUI callback
+	local function OnRelease(self)
+		if self.open then
+			self.pullout:Close()
+		end
+		AceGUI:Release(self.pullout)
+		self.pullout = nil
+
+		self:SetText("")
+		self:SetDisabled(false)
+		self:SetMultiselect(false)
+
+		self.value = nil
+		self.list = nil
+		self.open = nil
+		self.hasClose = nil
+
+		self.frame:ClearAllPoints()
+		self.frame:Hide()
+	end
+
+	-- exported
+	local function SetDisabled(self, disabled)
+		self.disabled = disabled
+		if disabled then
+			self.text:SetTextColor(0.5,0.5,0.5)
+			self.button:Disable()
+			self.label:SetTextColor(0.5,0.5,0.5)
+		else
+			self.button:Enable()
+			self.label:SetTextColor(1,.82,0)
+			self.text:SetTextColor(1,1,1)
+		end
+	end
+
+	-- exported
+	local function ClearFocus(self)
+		if self.open then
+			self.pullout:Close()
+		end
+	end
+
+	-- exported
+	local function SetText(self, text)
+		self.text:SetText(text or "")
+	end
+
+	-- exported
+	local function SetLabel(self, text)
+		if text and text ~= "" then
+			self.label:SetText(text)
+			self.label:Show()
+			self.dropdown:SetPoint("TOPLEFT",self.frame,"TOPLEFT",-15,-14)
+			self:SetHeight(40)
+			self.alignoffset = 26
+		else
+			self.label:SetText("")
+			self.label:Hide()
+			self.dropdown:SetPoint("TOPLEFT",self.frame,"TOPLEFT",-15,0)
+			self:SetHeight(26)
+			self.alignoffset = 12
+		end
+	end
+
+	-- exported
+	local function SetValue(self, value)
+		if self.list then
+			self:SetText(self.list[value] or "")
+		end
+		self.value = value
+	end
+
+	-- exported
+	local function GetValue(self)
+		return self.value
+	end
+
+	-- exported
+	local function SetItemValue(self, item, value)
+		if not self.multiselect then return end
+		for i, widget in self.pullout:IterateItems() do
+			if widget.userdata.value == item then
+				if widget.SetValue then
+					widget:SetValue(value)
+				end
+			end
+		end
+		ShowMultiText(self)
+	end
+
+	-- exported
+	local function SetItemDisabled(self, item, disabled)
+		for i, widget in self.pullout:IterateItems() do
+			if widget.userdata.value == item then
+				widget:SetDisabled(disabled)
+			end
+		end
+	end
+
+	local function AddListItem(self, value, text, itemType)
+		if not itemType then itemType = "Dropdown-Item-Toggle" end
+		local exists = AceGUI:GetWidgetVersion(itemType)
+		if not exists then error(("The given item type, %q, does not exist within AceGUI-3.0"):format(tostring(itemType)), 2) end
+
+		local item = AceGUI:Create(itemType)
+		item:SetText(text)
+		item.userdata.obj = self
+		item.userdata.value = value
+		item:SetCallback("OnValueChanged", OnItemValueChanged)
+		self.pullout:AddItem(item)
+	end
+
+	local function AddCloseButton(self)
+		if not self.hasClose then
+			local close = AceGUI:Create("Dropdown-Item-Execute")
+			close:SetText(CLOSE)
+			self.pullout:AddItem(close)
+			self.hasClose = true
+		end
+	end
+
+	-- exported
+	local sortlist = {}
+	local function SetList(self, list, order, itemType)
+		self.list = list
+		self.pullout:Clear()
+		self.hasClose = nil
+		if not list then return end
+
+		if type(order) ~= "table" then
+			for v in pairs(list) do
+				sortlist[#sortlist + 1] = v
+			end
+			tsort(sortlist)
+
+			for i, key in ipairs(sortlist) do
+				AddListItem(self, key, list[key], itemType)
+				sortlist[i] = nil
+			end
+		else
+			for i, key in ipairs(order) do
+				AddListItem(self, key, list[key], itemType)
+			end
+		end
+		if self.multiselect then
+			ShowMultiText(self)
+			AddCloseButton(self)
+		end
+	end
+
+	-- exported
+	local function AddItem(self, value, text, itemType)
+		if self.list then
+			self.list[value] = text
+			AddListItem(self, value, text, itemType)
+		end
+	end
+
+	-- exported
+	local function SetMultiselect(self, multi)
+		self.multiselect = multi
+		if multi then
+			ShowMultiText(self)
+			AddCloseButton(self)
+		end
+	end
+
+	-- exported
+	local function GetMultiselect(self)
+		return self.multiselect
+	end
+
+	local function SetPulloutWidth(self, width)
+		self.pulloutWidth = width
+	end
+
+	local function SetDropDownStyle(self, xTopleft, yTopleft, xBottomright, yBottomright)
+		self:RemoveTextures()
+		self:SetStyle("Frame", "Transparent")
+		self.Panel:SetPoint("TOPLEFT", self, "TOPLEFT", xTopleft, yTopleft)
+		self.Panel:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", xBottomright, yBottomright)
+	end
+
+	local WidgetButton_OnClick = function(self)
+		local obj = self.obj;
+		if(obj and obj.pullout and obj.pullout.frame and SVUI and SVUI.API) then
+			SVUI.API:Set("Frame", obj.pullout.frame, "Default", true)
+		end
+	end
+
+	--[[ Constructor ]]--
+
+	local function Constructor()
+		local count = AceGUI:GetNextWidgetNum(widgetType)
+		local frame = CreateFrame("Frame", nil, UIParent)
+		local dropdown = CreateFrame("Frame", "AceGUI30DropDown"..count, frame, "UIDropDownMenuTemplate")
+
+		local self = {}
+		self.type = widgetType
+		self.frame = frame
+		self.dropdown = dropdown
+		self.count = count
+		frame.obj = self
+		dropdown.obj = self
+
+		self.OnRelease   = OnRelease
+		self.OnAcquire   = OnAcquire
+
+		self.ClearFocus  = ClearFocus
+
+		self.SetText     = SetText
+		self.SetValue    = SetValue
+		self.GetValue    = GetValue
+		self.SetList     = SetList
+		self.SetLabel    = SetLabel
+		self.SetDisabled = SetDisabled
+		self.AddItem     = AddItem
+		self.SetMultiselect = SetMultiselect
+		self.GetMultiselect = GetMultiselect
+		self.SetItemValue = SetItemValue
+		self.SetItemDisabled = SetItemDisabled
+		self.SetPulloutWidth = SetPulloutWidth
+
+		self.alignoffset = 26
+
+		frame:SetScript("OnHide",Dropdown_OnHide)
+
+		dropdown:ClearAllPoints()
+		dropdown:SetPoint("TOPLEFT",frame,"TOPLEFT",-15,0)
+		dropdown:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",17,0)
+		dropdown:SetScript("OnHide", nil)
+
+		if(dropdown.SetStyle) then
+			SetDropDownStyle(dropdown, 20, -2, -20, 2)
+		end
+
+		local left = _G[dropdown:GetName() .. "Left"]
+		local middle = _G[dropdown:GetName() .. "Middle"]
+		local right = _G[dropdown:GetName() .. "Right"]
+
+		middle:ClearAllPoints()
+		right:ClearAllPoints()
+
+		middle:SetPoint("LEFT", left, "RIGHT", 0, 0)
+		middle:SetPoint("RIGHT", right, "LEFT", 0, 0)
+		right:SetPoint("TOPRIGHT", dropdown, "TOPRIGHT", 0, 17)
+
+		local button = _G[dropdown:GetName() .. "Button"]
+		self.button = button
+		button.obj = self
+		button:SetScript("OnEnter",Control_OnEnter)
+		button:SetScript("OnLeave",Control_OnLeave)
+		button:SetScript("OnClick",Dropdown_TogglePullout)
+		button:ClearAllPoints()
+		button:SetPoint("RIGHT", dropdown, "RIGHT", -20, 0)
+		if(SVUI and SVUI.API) then
+			SVUI.API:Set("PageButton", button, true)
+		end
+
+		local button_cover = CreateFrame("BUTTON",nil,self.frame)
+		button_cover.obj = self
+		button_cover:SetPoint("TOPLEFT",self.frame,"BOTTOMLEFT",0,25)
+		button_cover:SetPoint("BOTTOMRIGHT",self.frame,"BOTTOMRIGHT")
+		button_cover:SetScript("OnEnter",Control_OnEnter)
+		button_cover:SetScript("OnLeave",Control_OnLeave)
+		button_cover:SetScript("OnClick",Dropdown_TogglePullout)
+
+		local text = _G[dropdown:GetName() .. "Text"]
+		self.text = text
+		text.obj = self
+		text:ClearAllPoints()
+		text:SetPoint("RIGHT", right, "RIGHT" ,-43, 2)
+		text:SetPoint("LEFT", left, "LEFT", 25, 2)
+
+		if(dropdown.Panel) then
+			button:HookScript("OnClick", WidgetButton_OnClick)
+			button:SetParent(dropdown.Panel)
+			text:SetParent(dropdown.Panel)
+		end
+
+		local label = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
+		label:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
+		label:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,0)
+		label:SetJustifyH("LEFT")
+		label:SetHeight(18)
+		label:Hide()
+		self.label = label
+
+		AceGUI:RegisterAsWidget(self)
+		return self
+	end
+
+	AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion)
+end
diff --git a/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIWidget-EditBox.lua b/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIWidget-EditBox.lua
new file mode 100644
index 0000000..1f50cf7
--- /dev/null
+++ b/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIWidget-EditBox.lua
@@ -0,0 +1,269 @@
+--[[-----------------------------------------------------------------------------
+EditBox Widget
+-------------------------------------------------------------------------------]]
+local Type, Version = "EditBox", 999999
+local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
+if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
+
+-- Lua APIs
+local tostring, pairs = tostring, pairs
+
+-- WoW APIs
+local PlaySound = PlaySound
+local GetCursorInfo, ClearCursor, GetSpellInfo = GetCursorInfo, ClearCursor, GetSpellInfo
+local CreateFrame, UIParent = CreateFrame, UIParent
+local _G = _G
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: AceGUIEditBoxInsertLink, ChatFontNormal, OKAY
+
+--[[-----------------------------------------------------------------------------
+Support functions
+-------------------------------------------------------------------------------]]
+if not AceGUIEditBoxInsertLink then
+	-- upgradeable hook
+	hooksecurefunc("ChatEdit_InsertLink", function(...) return _G.AceGUIEditBoxInsertLink(...) end)
+end
+
+function _G.AceGUIEditBoxInsertLink(text)
+	for i = 1, AceGUI:GetWidgetCount(Type) do
+		local editbox = _G["AceGUI-3.0EditBox"..i]
+		if editbox and editbox:IsVisible() and editbox:HasFocus() then
+			editbox:Insert(text)
+			return true
+		end
+	end
+end
+
+local function ShowButton(self)
+	if not self.disablebutton then
+		self.button:Show()
+		self.editbox:SetTextInsets(0, 20, 3, 3)
+	end
+end
+
+local function HideButton(self)
+	self.button:Hide()
+	self.editbox:SetTextInsets(0, 0, 3, 3)
+end
+
+--[[-----------------------------------------------------------------------------
+Scripts
+-------------------------------------------------------------------------------]]
+local function Control_OnEnter(frame)
+	frame.obj:Fire("OnEnter")
+end
+
+local function Control_OnLeave(frame)
+	frame.obj:Fire("OnLeave")
+end
+
+local function Frame_OnShowFocus(frame)
+	frame.obj.editbox:SetFocus()
+	frame:SetScript("OnShow", nil)
+end
+
+local function EditBox_OnEscapePressed(frame)
+	AceGUI:ClearFocus()
+end
+
+local function EditBox_OnEnterPressed(frame)
+	local self = frame.obj
+	local value = frame:GetText()
+	local cancel = self:Fire("OnEnterPressed", value)
+	if not cancel then
+		PlaySound("igMainMenuOptionCheckBoxOn")
+		HideButton(self)
+	end
+end
+
+local function EditBox_OnReceiveDrag(frame)
+	local self = frame.obj
+	local type, id, info = GetCursorInfo()
+	if type == "item" then
+		self:SetText(info)
+		self:Fire("OnEnterPressed", info)
+		ClearCursor()
+	elseif type == "spell" then
+		local name = GetSpellInfo(id, info)
+		self:SetText(name)
+		self:Fire("OnEnterPressed", name)
+		ClearCursor()
+	elseif type == "macro" then
+		local name = GetMacroInfo(id)
+		self:SetText(name)
+		self:Fire("OnEnterPressed", name)
+		ClearCursor()
+	end
+	HideButton(self)
+	AceGUI:ClearFocus()
+end
+
+local function EditBox_OnTextChanged(frame)
+	local self = frame.obj
+	local value = frame:GetText()
+	if tostring(value) ~= tostring(self.lasttext) then
+		self:Fire("OnTextChanged", value)
+		self.lasttext = value
+		ShowButton(self)
+	end
+end
+
+local function EditBox_OnFocusGained(frame)
+	AceGUI:SetFocus(frame.obj)
+end
+
+local function Button_OnClick(frame)
+	local editbox = frame.obj.editbox
+	editbox:ClearFocus()
+	EditBox_OnEnterPressed(editbox)
+end
+
+--[[-----------------------------------------------------------------------------
+Methods
+-------------------------------------------------------------------------------]]
+local methods = {
+	["OnAcquire"] = function(self)
+		-- height is controlled by SetLabel
+		self:SetWidth(320)
+		self:SetDisabled(false)
+		self:SetLabel()
+		self:SetText()
+		self:DisableButton(false)
+		self:SetMaxLetters(0)
+	end,
+
+	["OnRelease"] = function(self)
+		self:ClearFocus()
+	end,
+
+	["SetDisabled"] = function(self, disabled)
+		self.disabled = disabled
+		if disabled then
+			self.editbox:EnableMouse(false)
+			self.editbox:ClearFocus()
+			self.editbox:SetTextColor(0.5,0.5,0.5)
+			self.label:SetTextColor(0.5,0.5,0.5)
+		else
+			self.editbox:EnableMouse(true)
+			self.editbox:SetTextColor(1,1,1)
+			self.label:SetTextColor(1,.82,0)
+		end
+	end,
+
+	["SetText"] = function(self, text)
+		self.lasttext = text or ""
+		self.editbox:SetText(text or "")
+		self.editbox:SetCursorPosition(0)
+		HideButton(self)
+	end,
+
+	["GetText"] = function(self, text)
+		return self.editbox:GetText()
+	end,
+
+	["SetLabel"] = function(self, text)
+		if text and text ~= "" then
+			self.label:SetText(text)
+			self.label:Show()
+			self.editbox:SetPoint("TOPLEFT",self.frame,"TOPLEFT",7,-18)
+			self:SetHeight(44)
+			self.alignoffset = 30
+		else
+			self.label:SetText("")
+			self.label:Hide()
+			self.editbox:SetPoint("TOPLEFT",self.frame,"TOPLEFT",7,0)
+			self:SetHeight(26)
+			self.alignoffset = 12
+		end
+	end,
+
+	["DisableButton"] = function(self, disabled)
+		self.disablebutton = disabled
+		if disabled then
+			HideButton(self)
+		end
+	end,
+
+	["SetMaxLetters"] = function (self, num)
+		self.editbox:SetMaxLetters(num or 0)
+	end,
+
+	["ClearFocus"] = function(self)
+		self.editbox:ClearFocus()
+		self.frame:SetScript("OnShow", nil)
+	end,
+
+	["SetFocus"] = function(self)
+		self.editbox:SetFocus()
+		if not self.frame:IsShown() then
+			self.frame:SetScript("OnShow", Frame_OnShowFocus)
+		end
+	end
+}
+
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+local function Constructor()
+	local num  = AceGUI:GetNextWidgetNum(Type)
+	local frame = CreateFrame("Frame", nil, UIParent)
+	frame:Hide()
+
+	local editbox = CreateFrame("EditBox", "AceGUI-3.0EditBox"..num, frame, "InputBoxTemplate")
+	editbox:SetAutoFocus(false)
+	editbox:SetFontObject(ChatFontNormal)
+	editbox:SetScript("OnEnter", Control_OnEnter)
+	editbox:SetScript("OnLeave", Control_OnLeave)
+	editbox:SetScript("OnEscapePressed", EditBox_OnEscapePressed)
+	editbox:SetScript("OnEnterPressed", EditBox_OnEnterPressed)
+	editbox:SetScript("OnTextChanged", EditBox_OnTextChanged)
+	editbox:SetScript("OnReceiveDrag", EditBox_OnReceiveDrag)
+	editbox:SetScript("OnMouseDown", EditBox_OnReceiveDrag)
+	editbox:SetScript("OnEditFocusGained", EditBox_OnFocusGained)
+	editbox:SetTextInsets(0, 0, 3, 3)
+	editbox:SetMaxLetters(256)
+	editbox:SetPoint("BOTTOMLEFT", 6, 0)
+	editbox:SetPoint("BOTTOMRIGHT")
+	editbox:SetHeight(19)
+
+	local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
+	label:SetPoint("TOPLEFT", 0, -2)
+	label:SetPoint("TOPRIGHT", 0, -2)
+	label:SetJustifyH("LEFT")
+	label:SetHeight(18)
+
+	if(editbox.SetStyle) then
+		editbox:SetStyle("Editbox")
+	end
+
+	local button = CreateFrame("Button", nil, editbox, "UIPanelButtonTemplate")
+	button:SetWidth(40)
+	button:SetHeight(20)
+	button:SetPoint("RIGHT", -2, 0)
+	button:SetText(OKAY)
+	button:SetScript("OnClick", Button_OnClick)
+	button:Hide()
+
+	if(button.SetStyle) then
+		button:SetStyle("Button")
+	end
+
+	local widget = {
+		alignoffset = 30,
+		editbox     = editbox,
+		label       = label,
+		button      = button,
+		frame       = frame,
+		type        = Type
+	}
+	for method, func in pairs(methods) do
+		widget[method] = func
+	end
+	editbox.obj, button.obj = widget, widget
+
+	return AceGUI:RegisterAsWidget(widget)
+end
+
+AceGUI:RegisterWidgetType(Type, Constructor, Version)
diff --git a/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIWidget-Heading.lua b/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIWidget-Heading.lua
new file mode 100644
index 0000000..94ac001
--- /dev/null
+++ b/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIWidget-Heading.lua
@@ -0,0 +1,60 @@
+--[[-----------------------------------------------------------------------------
+Heading Widget
+-------------------------------------------------------------------------------]]
+local Type, Version = "Heading", 999999
+local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
+if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
+
+-- Lua APIs
+local pairs = pairs
+
+-- WoW APIs
+local CreateFrame, UIParent = CreateFrame, UIParent
+
+--[[-----------------------------------------------------------------------------
+Methods
+-------------------------------------------------------------------------------]]
+local methods = {
+	["OnAcquire"] = function(self)
+		self:SetText()
+		self:SetFullWidth()
+		self:SetHeight(18)
+	end,
+
+	-- ["OnRelease"] = nil,
+
+	["SetText"] = function(self, text)
+		self.label:SetText(text or "")
+	end
+}
+
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+local function Constructor()
+	local frame = CreateFrame("Frame", nil, UIParent)
+	frame:Hide()
+
+	local label = frame:CreateFontString(nil, "BACKGROUND", "GameFontNormal")
+	label:SetPoint("TOP")
+	label:SetPoint("BOTTOM")
+	label:SetJustifyH("CENTER")
+
+	local labelbg = frame:CreateTexture(nil, "BACKGROUND")
+	labelbg:SetTexture("Interface\\AddOns\\SVUI_!Core\\assets\\textures\\DIALOGBOX-HEADER")
+	labelbg:SetPoint("TOPLEFT", label, "TOPLEFT", 0, 0)
+	labelbg:SetPoint("BOTTOMRIGHT", label, "BOTTOMRIGHT", 0, -32)
+
+	local widget = {
+		label = label,
+		frame = frame,
+		type  = Type
+	}
+	for method, func in pairs(methods) do
+		widget[method] = func
+	end
+
+	return AceGUI:RegisterAsWidget(widget)
+end
+
+AceGUI:RegisterWidgetType(Type, Constructor, Version)
diff --git a/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIWidget-Keybinding.lua b/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIWidget-Keybinding.lua
new file mode 100644
index 0000000..af7c301
--- /dev/null
+++ b/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIWidget-Keybinding.lua
@@ -0,0 +1,238 @@
+--[[-----------------------------------------------------------------------------
+Keybinding Widget
+Set Keybindings in the Config UI.
+-------------------------------------------------------------------------------]]
+local Type, Version = "Keybinding", 999999
+local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
+if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
+
+-- Lua APIs
+local pairs = pairs
+
+-- WoW APIs
+local IsShiftKeyDown, IsControlKeyDown, IsAltKeyDown = IsShiftKeyDown, IsControlKeyDown, IsAltKeyDown
+local CreateFrame, UIParent = CreateFrame, UIParent
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: NOT_BOUND
+
+local wowMoP
+do
+	local _, _, _, interface = GetBuildInfo()
+	wowMoP = (interface >= 50000)
+end
+
+--[[-----------------------------------------------------------------------------
+Scripts
+-------------------------------------------------------------------------------]]
+
+local function Control_OnEnter(frame)
+	frame.obj:Fire("OnEnter")
+end
+
+local function Control_OnLeave(frame)
+	frame.obj:Fire("OnLeave")
+end
+
+local function Keybinding_OnClick(frame, button)
+	if button == "LeftButton" or button == "RightButton" then
+		local self = frame.obj
+		if self.waitingForKey then
+			frame:EnableKeyboard(false)
+			self.msgframe:Hide()
+			frame:UnlockHighlight()
+			self.waitingForKey = nil
+		else
+			frame:EnableKeyboard(true)
+			self.msgframe:Show()
+			frame:LockHighlight()
+			self.waitingForKey = true
+		end
+	end
+	AceGUI:ClearFocus()
+end
+
+local ignoreKeys = {
+	["BUTTON1"] = true, ["BUTTON2"] = true,
+	["UNKNOWN"] = true,
+	["LSHIFT"] = true, ["LCTRL"] = true, ["LALT"] = true,
+	["RSHIFT"] = true, ["RCTRL"] = true, ["RALT"] = true,
+}
+local function Keybinding_OnKeyDown(frame, key)
+	local self = frame.obj
+	if self.waitingForKey then
+		local keyPressed = key
+		if keyPressed == "ESCAPE" then
+			keyPressed = ""
+		else
+			if ignoreKeys[keyPressed] then return end
+			if IsShiftKeyDown() then
+				keyPressed = "SHIFT-"..keyPressed
+			end
+			if IsControlKeyDown() then
+				keyPressed = "CTRL-"..keyPressed
+			end
+			if IsAltKeyDown() then
+				keyPressed = "ALT-"..keyPressed
+			end
+		end
+
+		frame:EnableKeyboard(false)
+		self.msgframe:Hide()
+		frame:UnlockHighlight()
+		self.waitingForKey = nil
+
+		if not self.disabled then
+			self:SetKey(keyPressed)
+			self:Fire("OnKeyChanged", keyPressed)
+		end
+	end
+end
+
+local function Keybinding_OnMouseDown(frame, button)
+	if button == "LeftButton" or button == "RightButton" then
+		return
+	elseif button == "MiddleButton" then
+		button = "BUTTON3"
+	elseif button == "Button4" then
+		button = "BUTTON4"
+	elseif button == "Button5" then
+		button = "BUTTON5"
+	end
+	Keybinding_OnKeyDown(frame, button)
+end
+
+--[[-----------------------------------------------------------------------------
+Methods
+-------------------------------------------------------------------------------]]
+local methods = {
+	["OnAcquire"] = function(self)
+		self:SetWidth(320)
+		self:SetLabel("")
+		self:SetKey("")
+		self.waitingForKey = nil
+		self.msgframe:Hide()
+		self:SetDisabled(false)
+		self.button:EnableKeyboard(false)
+	end,
+
+	-- ["OnRelease"] = nil,
+
+	["SetDisabled"] = function(self, disabled)
+		self.disabled = disabled
+		if disabled then
+			self.button:Disable()
+			self.label:SetTextColor(0.5,0.5,0.5)
+		else
+			self.button:Enable()
+			self.label:SetTextColor(1,1,1)
+		end
+	end,
+
+	["SetKey"] = function(self, key)
+		if (key or "") == "" then
+			self.button:SetText(NOT_BOUND)
+			self.button:SetNormalFontObject("GameFontNormal")
+		else
+			self.button:SetText(key)
+			self.button:SetNormalFontObject("GameFontHighlight")
+		end
+	end,
+
+	["GetKey"] = function(self)
+		local key = self.button:GetText()
+		if key == NOT_BOUND then
+			key = nil
+		end
+		return key
+	end,
+
+	["SetLabel"] = function(self, label)
+		self.label:SetText(label or "")
+		if (label or "") == "" then
+			self.alignoffset = nil
+			self:SetHeight(24)
+		else
+			self.alignoffset = 30
+			self:SetHeight(44)
+		end
+	end,
+}
+
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+local backdrop  = {
+	bgFile = "Interface\\AddOns\\SVUI_!Core\\assets\\backgrounds\\TRANSPARENT",
+	edgeFile = "Interface\\AddOns\\SVUI_!Core\\assets\\borders\\DEFAULT",
+	tile = true, tileSize = 16, edgeSize = 8,
+	insets = { left = 2, right = 2, top = 2, bottom = 2 }
+}
+
+local function keybindingMsgFixWidth(frame)
+	frame:SetWidth(frame.msg:GetWidth() + 10)
+	frame:SetScript("OnUpdate", nil)
+end
+
+local function Constructor()
+	local name = "AceGUI30KeybindingButton" .. AceGUI:GetNextWidgetNum(Type)
+
+	local frame = CreateFrame("Frame", nil, UIParent)
+	local button = CreateFrame("Button", name, frame, wowMoP and "UIPanelButtonTemplate" or "UIPanelButtonTemplate2")
+
+	button:EnableMouse(true)
+	button:RegisterForClicks("AnyDown")
+	button:SetScript("OnEnter", Control_OnEnter)
+	button:SetScript("OnLeave", Control_OnLeave)
+	button:SetScript("OnClick", Keybinding_OnClick)
+	button:SetScript("OnKeyDown", Keybinding_OnKeyDown)
+	button:SetScript("OnMouseDown", Keybinding_OnMouseDown)
+	button:SetPoint("BOTTOMLEFT")
+	button:SetPoint("BOTTOMRIGHT")
+	button:SetHeight(24)
+	button:EnableKeyboard(false)
+
+	local text = button:GetFontString()
+	text:SetPoint("LEFT", 7, 0)
+	text:SetPoint("RIGHT", -7, 0)
+
+	local label = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
+	label:SetPoint("TOPLEFT")
+	label:SetPoint("TOPRIGHT")
+	label:SetJustifyH("CENTER")
+	label:SetHeight(18)
+
+	local msgframe = CreateFrame("Frame", nil, UIParent)
+	msgframe:SetHeight(30)
+	msgframe:SetBackdrop(backdrop)
+	msgframe:SetBackdropColor(0,0,0)
+	msgframe:SetFrameStrata("FULLSCREEN_DIALOG")
+	msgframe:SetFrameLevel(1000)
+	msgframe:SetToplevel(true)
+
+	local msg = msgframe:CreateFontString(nil, "OVERLAY", "GameFontNormal")
+	msg:SetText("Press a key to bind, ESC to clear the binding or click the button again to cancel.")
+	msgframe.msg = msg
+	msg:SetPoint("TOPLEFT", 5, -5)
+	msgframe:SetScript("OnUpdate", keybindingMsgFixWidth)
+	msgframe:SetPoint("BOTTOM", button, "TOP")
+	msgframe:Hide()
+
+	local widget = {
+		button      = button,
+		label       = label,
+		msgframe    = msgframe,
+		frame       = frame,
+		alignoffset = 30,
+		type        = Type
+	}
+	for method, func in pairs(methods) do
+		widget[method] = func
+	end
+	button.obj = widget
+
+	return AceGUI:RegisterAsWidget(widget)
+end
+
+AceGUI:RegisterWidgetType(Type, Constructor, Version)
diff --git a/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIWidget-MultiLineEditBox.lua b/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIWidget-MultiLineEditBox.lua
new file mode 100644
index 0000000..15dae36
--- /dev/null
+++ b/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIWidget-MultiLineEditBox.lua
@@ -0,0 +1,377 @@
+local Type, Version = "MultiLineEditBox", 999999
+local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
+if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
+
+-- Lua APIs
+local pairs = pairs
+
+-- WoW APIs
+local GetCursorInfo, GetSpellInfo, ClearCursor = GetCursorInfo, GetSpellInfo, ClearCursor
+local CreateFrame, UIParent = CreateFrame, UIParent
+local _G = _G
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: ACCEPT, ChatFontNormal
+
+local wowMoP
+do
+	local _, _, _, interface = GetBuildInfo()
+	wowMoP = (interface >= 50000)
+end
+
+--[[-----------------------------------------------------------------------------
+Support functions
+-------------------------------------------------------------------------------]]
+
+if not AceGUIMultiLineEditBoxInsertLink then
+	-- upgradeable hook
+	hooksecurefunc("ChatEdit_InsertLink", function(...) return _G.AceGUIMultiLineEditBoxInsertLink(...) end)
+end
+
+function _G.AceGUIMultiLineEditBoxInsertLink(text)
+	for i = 1, AceGUI:GetWidgetCount(Type) do
+		local editbox = _G[("MultiLineEditBox%uEdit"):format(i)]
+		if editbox and editbox:IsVisible() and editbox:HasFocus() then
+			editbox:Insert(text)
+			return true
+		end
+	end
+end
+
+
+local function Layout(self)
+	self:SetHeight(self.numlines * 14 + (self.disablebutton and 19 or 41) + self.labelHeight)
+
+	if self.labelHeight == 0 then
+		self.scrollBar:SetPoint("TOP", self.frame, "TOP", 0, -23)
+	else
+		self.scrollBar:SetPoint("TOP", self.label, "BOTTOM", 0, -19)
+	end
+
+	if self.disablebutton then
+		self.scrollBar:SetPoint("BOTTOM", self.frame, "BOTTOM", 0, 21)
+		self.scrollBG:SetPoint("BOTTOMLEFT", 0, 4)
+	else
+		self.scrollBar:SetPoint("BOTTOM", self.button, "TOP", 0, 18)
+		self.scrollBG:SetPoint("BOTTOMLEFT", self.button, "TOPLEFT")
+	end
+end
+
+--[[-----------------------------------------------------------------------------
+Scripts
+-------------------------------------------------------------------------------]]
+local function OnClick(self)                                                     -- Button
+	self = self.obj
+	self.editBox:ClearFocus()
+	if not self:Fire("OnEnterPressed", self.editBox:GetText()) then
+		self.button:Disable()
+	end
+end
+
+local function OnCursorChanged(self, _, y, _, cursorHeight)                      -- EditBox
+	self, y = self.obj.scrollFrame, -y
+	local offset = self:GetVerticalScroll()
+	if y < offset then
+		self:SetVerticalScroll(y)
+	else
+		y = y + cursorHeight - self:GetHeight()
+		if y > offset then
+			self:SetVerticalScroll(y)
+		end
+	end
+end
+
+local function OnEditFocusLost(self)                                             -- EditBox
+	self:HighlightText(0, 0)
+	self.obj:Fire("OnEditFocusLost")
+end
+
+local function OnEnter(self)                                                     -- EditBox / ScrollFrame
+	self = self.obj
+	if not self.entered then
+		self.entered = true
+		self:Fire("OnEnter")
+	end
+end
+
+local function OnLeave(self)                                                     -- EditBox / ScrollFrame
+	self = self.obj
+	if self.entered then
+		self.entered = nil
+		self:Fire("OnLeave")
+	end
+end
+
+local function OnMouseUp(self)                                                   -- ScrollFrame
+	self = self.obj.editBox
+	self:SetFocus()
+	self:SetCursorPosition(self:GetNumLetters())
+end
+
+local function OnReceiveDrag(self)                                               -- EditBox / ScrollFrame
+	local type, id, info = GetCursorInfo()
+	if type == "spell" then
+		info = GetSpellInfo(id, info)
+	elseif type ~= "item" then
+		return
+	end
+	ClearCursor()
+	self = self.obj
+	local editBox = self.editBox
+	if not editBox:HasFocus() then
+		editBox:SetFocus()
+		editBox:SetCursorPosition(editBox:GetNumLetters())
+	end
+	editBox:Insert(info)
+	self.button:Enable()
+end
+
+local function OnSizeChanged(self, width, height)                                -- ScrollFrame
+	self.obj.editBox:SetWidth(width)
+end
+
+local function OnTextChanged(self, userInput)                                    -- EditBox
+	if userInput then
+		self = self.obj
+		self:Fire("OnTextChanged", self.editBox:GetText())
+		self.button:Enable()
+	end
+end
+
+local function OnTextSet(self)                                                   -- EditBox
+	self:HighlightText(0, 0)
+	self:SetCursorPosition(self:GetNumLetters())
+	self:SetCursorPosition(0)
+	self.obj.button:Disable()
+end
+
+local function OnVerticalScroll(self, offset)                                    -- ScrollFrame
+	local editBox = self.obj.editBox
+	editBox:SetHitRectInsets(0, 0, offset, editBox:GetHeight() - offset - self:GetHeight())
+end
+
+local function OnShowFocus(frame)
+	frame.obj.editBox:SetFocus()
+	frame:SetScript("OnShow", nil)
+end
+
+local function OnEditFocusGained(frame)
+	AceGUI:SetFocus(frame.obj)
+	frame.obj:Fire("OnEditFocusGained")
+end
+
+--[[-----------------------------------------------------------------------------
+Methods
+-------------------------------------------------------------------------------]]
+local methods = {
+	["OnAcquire"] = function(self)
+		self.editBox:SetText("")
+		self:SetDisabled(false)
+		self:SetWidth(320)
+		self:DisableButton(false)
+		self:SetNumLines()
+		self.entered = nil
+		self:SetMaxLetters(0)
+	end,
+
+	["OnRelease"] = function(self)
+		self:ClearFocus()
+	end,
+
+	["SetDisabled"] = function(self, disabled)
+		local editBox = self.editBox
+		if disabled then
+			editBox:ClearFocus()
+			editBox:EnableMouse(false)
+			editBox:SetTextColor(0.5, 0.5, 0.5)
+			self.label:SetTextColor(0.5, 0.5, 0.5)
+			self.scrollFrame:EnableMouse(false)
+			self.button:Disable()
+		else
+			editBox:EnableMouse(true)
+			editBox:SetTextColor(1, 1, 1)
+			self.label:SetTextColor(1, 0.82, 0)
+			self.scrollFrame:EnableMouse(true)
+		end
+	end,
+
+	["SetLabel"] = function(self, text)
+		if text and text ~= "" then
+			self.label:SetText(text)
+			if self.labelHeight ~= 10 then
+				self.labelHeight = 10
+				self.label:Show()
+			end
+		elseif self.labelHeight ~= 0 then
+			self.labelHeight = 0
+			self.label:Hide()
+		end
+		Layout(self)
+	end,
+
+	["SetNumLines"] = function(self, value)
+		if not value or value < 4 then
+			value = 4
+		end
+		self.numlines = value
+		Layout(self)
+	end,
+
+	["SetText"] = function(self, text)
+		self.editBox:SetText(text)
+	end,
+
+	["GetText"] = function(self)
+		return self.editBox:GetText()
+	end,
+
+	["SetMaxLetters"] = function (self, num)
+		self.editBox:SetMaxLetters(num or 0)
+	end,
+
+	["DisableButton"] = function(self, disabled)
+		self.disablebutton = disabled
+		if disabled then
+			self.button:Hide()
+		else
+			self.button:Show()
+		end
+		Layout(self)
+	end,
+
+	["ClearFocus"] = function(self)
+		self.editBox:ClearFocus()
+		self.frame:SetScript("OnShow", nil)
+	end,
+
+	["SetFocus"] = function(self)
+		self.editBox:SetFocus()
+		if not self.frame:IsShown() then
+			self.frame:SetScript("OnShow", OnShowFocus)
+		end
+	end,
+
+	["GetCursorPosition"] = function(self)
+		return self.editBox:GetCursorPosition()
+	end,
+
+	["SetCursorPosition"] = function(self, ...)
+		return self.editBox:SetCursorPosition(...)
+	end,
+
+
+}
+
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+local backdrop  = {
+	bgFile = "Interface\\AddOns\\SVUI_!Core\\assets\\backgrounds\\TRANSPARENT",
+	edgeFile = "Interface\\AddOns\\SVUI_!Core\\assets\\borders\\DEFAULT",
+	tile = true, tileSize = 16, edgeSize = 8,
+	insets = { left = 2, right = 2, top = 2, bottom = 2 }
+}
+
+local function Constructor()
+	local frame = CreateFrame("Frame", nil, UIParent)
+	frame:Hide()
+
+	local widgetNum = AceGUI:GetNextWidgetNum(Type)
+
+	local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
+	label:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, -4)
+	label:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 0, -4)
+	label:SetJustifyH("LEFT")
+	label:SetText(ACCEPT)
+	label:SetHeight(10)
+
+	local button = CreateFrame("Button", ("%s%dButton"):format(Type, widgetNum), frame, wowMoP and "UIPanelButtonTemplate" or "UIPanelButtonTemplate2")
+	button:SetPoint("BOTTOMLEFT", 0, 4)
+	button:SetHeight(22)
+	button:SetWidth(label:GetStringWidth() + 24)
+	button:SetText(ACCEPT)
+	button:SetScript("OnClick", OnClick)
+	button:Disable()
+
+	if(button.SetStyle) then
+		button:SetStyle("Button")
+	end
+
+	local text = button:GetFontString()
+	text:ClearAllPoints()
+	text:SetPoint("TOPLEFT", button, "TOPLEFT", 5, -5)
+	text:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -5, 1)
+	text:SetJustifyV("MIDDLE")
+
+	local scrollBG = CreateFrame("Frame", nil, frame)
+	scrollBG:SetBackdrop(backdrop)
+	scrollBG:SetBackdropColor(0, 0, 0)
+	scrollBG:SetBackdropBorderColor(0.4, 0.4, 0.4)
+
+	local scrollFrame = CreateFrame("ScrollFrame", ("%s%dScrollFrame"):format(Type, widgetNum), frame, "UIPanelScrollFrameTemplate")
+
+	local scrollBar = _G[scrollFrame:GetName() .. "ScrollBar"]
+	scrollBar:ClearAllPoints()
+	scrollBar:SetPoint("TOP", label, "BOTTOM", 0, -19)
+	scrollBar:SetPoint("BOTTOM", button, "TOP", 0, 18)
+	scrollBar:SetPoint("RIGHT", frame, "RIGHT")
+
+	scrollBG:SetPoint("TOPRIGHT", scrollBar, "TOPLEFT", 0, 19)
+	scrollBG:SetPoint("BOTTOMLEFT", button, "TOPLEFT")
+
+	scrollFrame:SetPoint("TOPLEFT", scrollBG, "TOPLEFT", 5, -6)
+	scrollFrame:SetPoint("BOTTOMRIGHT", scrollBG, "BOTTOMRIGHT", -4, 4)
+	scrollFrame:SetScript("OnEnter", OnEnter)
+	scrollFrame:SetScript("OnLeave", OnLeave)
+	scrollFrame:SetScript("OnMouseUp", OnMouseUp)
+	scrollFrame:SetScript("OnReceiveDrag", OnReceiveDrag)
+	scrollFrame:SetScript("OnSizeChanged", OnSizeChanged)
+	scrollFrame:HookScript("OnVerticalScroll", OnVerticalScroll)
+
+	local editBox = CreateFrame("EditBox", ("%s%dEdit"):format(Type, widgetNum), scrollFrame)
+	editBox:SetAllPoints()
+	editBox:SetFontObject(ChatFontNormal)
+	editBox:SetMultiLine(true)
+	editBox:EnableMouse(true)
+	editBox:SetAutoFocus(false)
+	editBox:SetCountInvisibleLetters(false)
+	editBox:SetScript("OnCursorChanged", OnCursorChanged)
+	editBox:SetScript("OnEditFocusLost", OnEditFocusLost)
+	editBox:SetScript("OnEnter", OnEnter)
+	editBox:SetScript("OnEscapePressed", editBox.ClearFocus)
+	editBox:SetScript("OnLeave", OnLeave)
+	editBox:SetScript("OnMouseDown", OnReceiveDrag)
+	editBox:SetScript("OnReceiveDrag", OnReceiveDrag)
+	editBox:SetScript("OnTextChanged", OnTextChanged)
+	editBox:SetScript("OnTextSet", OnTextSet)
+	editBox:SetScript("OnEditFocusGained", OnEditFocusGained)
+
+	if(editBox.SetStyle) then
+		editBox:SetStyle("Editbox")
+	end
+
+
+	scrollFrame:SetScrollChild(editBox)
+
+	local widget = {
+		button      = button,
+		editBox     = editBox,
+		frame       = frame,
+		label       = label,
+		labelHeight = 10,
+		numlines    = 4,
+		scrollBar   = scrollBar,
+		scrollBG    = scrollBG,
+		scrollFrame = scrollFrame,
+		type        = Type
+	}
+	for method, func in pairs(methods) do
+		widget[method] = func
+	end
+	button.obj, editBox.obj, scrollFrame.obj = widget, widget, widget
+
+	return AceGUI:RegisterAsWidget(widget)
+end
+
+AceGUI:RegisterWidgetType(Type, Constructor, Version)
diff --git a/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIWidget-Slider.lua b/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIWidget-Slider.lua
new file mode 100644
index 0000000..555bfc3
--- /dev/null
+++ b/SVUI_!Core/libs/AceVillain-1.0/widgets/AceGUIWidget-Slider.lua
@@ -0,0 +1,283 @@
+--[[-----------------------------------------------------------------------------
+Slider Widget
+Graphical Slider, like, for Range values.
+-------------------------------------------------------------------------------]]
+local Type, Version = "Slider", 999999
+local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
+if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
+
+-- Lua APIs
+local min, max, floor = math.min, math.max, math.floor
+local tonumber, pairs = tonumber, pairs
+
+-- WoW APIs
+local PlaySound = PlaySound
+local CreateFrame, UIParent = CreateFrame, UIParent
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: GameFontHighlightSmall
+
+--[[-----------------------------------------------------------------------------
+Support functions
+-------------------------------------------------------------------------------]]
+local function UpdateText(self)
+	local value = self.value or 0
+	if self.ispercent then
+		self.editbox:SetText(("%s%%"):format(floor(value * 1000 + 0.5) / 10))
+	else
+		self.editbox:SetText(floor(value * 100 + 0.5) / 100)
+	end
+end
+
+local function UpdateLabels(self)
+	local min, max = (self.min or 0), (self.max or 100)
+	if self.ispercent then
+		self.lowtext:SetFormattedText("%s%%", (min * 100))
+		self.hightext:SetFormattedText("%s%%", (max * 100))
+	else
+		self.lowtext:SetText(min)
+		self.hightext:SetText(max)
+	end
+end
+
+--[[-----------------------------------------------------------------------------
+Scripts
+-------------------------------------------------------------------------------]]
+local function Control_OnEnter(frame)
+	frame.obj:Fire("OnEnter")
+end
+
+local function Control_OnLeave(frame)
+	frame.obj:Fire("OnLeave")
+end
+
+local function Frame_OnMouseDown(frame)
+	frame.obj.slider:EnableMouseWheel(true)
+	AceGUI:ClearFocus()
+end
+
+local function Slider_OnValueChanged(frame)
+	local self = frame.obj
+	if not frame.setup then
+		local newvalue = frame:GetValue()
+		if self.step and self.step > 0 then
+			local min_value = self.min or 0
+			newvalue = floor((newvalue - min_value) / self.step + 0.5) * self.step + min_value
+		end
+		if newvalue ~= self.value and not self.disabled then
+			self.value = newvalue
+			self:Fire("OnValueChanged", newvalue)
+		end
+		if self.value then
+			UpdateText(self)
+		end
+	end
+end
+
+local function Slider_OnMouseUp(frame)
+	local self = frame.obj
+	self:Fire("OnMouseUp", self.value)
+end
+
+local function Slider_OnMouseWheel(frame, v)
+	local self = frame.obj
+	if not self.disabled then
+		local value = self.value
+		if v > 0 then
+			value = min(value + (self.step or 1), self.max)
+		else
+			value = max(value - (self.step or 1), self.min)
+		end
+		self.slider:SetValue(value)
+	end
+end
+
+local function EditBox_OnEscapePressed(frame)
+	frame:ClearFocus()
+end
+
+local function EditBox_OnEnterPressed(frame)
+	local self = frame.obj
+	local value = frame:GetText()
+	if self.ispercent then
+		value = value:gsub('%%', '')
+		value = tonumber(value) / 100
+	else
+		value = tonumber(value)
+	end
+
+	if value then
+		PlaySound("igMainMenuOptionCheckBoxOn")
+		self.slider:SetValue(value)
+		self:Fire("OnMouseUp", value)
+	end
+end
+
+local function EditBox_OnEnter(frame)
+	frame:SetBackdropBorderColor(0.2, 0.2, 0.2)
+end
+
+local function EditBox_OnLeave(frame)
+	frame:SetBackdropBorderColor(0, 0, 0)
+end
+
+--[[-----------------------------------------------------------------------------
+Methods
+-------------------------------------------------------------------------------]]
+local methods = {
+	["OnAcquire"] = function(self)
+		self:SetWidth(320)
+		self:SetHeight(44)
+		self:SetDisabled(false)
+		self:SetIsPercent(nil)
+		self:SetSliderValues(0,100,1)
+		self:SetValue(0)
+		self.slider:EnableMouseWheel(false)
+	end,
+
+	-- ["OnRelease"] = nil,
+
+	["SetDisabled"] = function(self, disabled)
+		self.disabled = disabled
+		if disabled then
+			self.slider:EnableMouse(false)
+			self.label:SetTextColor(.5, .5, .5)
+			self.hightext:SetTextColor(.5, .5, .5)
+			self.lowtext:SetTextColor(.5, .5, .5)
+			--self.valuetext:SetTextColor(.5, .5, .5)
+			self.editbox:SetTextColor(.5, .5, .5)
+			self.editbox:EnableMouse(false)
+			self.editbox:ClearFocus()
+		else
+			self.slider:EnableMouse(true)
+			self.label:SetTextColor(1, .82, 0)
+			self.hightext:SetTextColor(1, 1, 1)
+			self.lowtext:SetTextColor(1, 1, 1)
+			--self.valuetext:SetTextColor(1, 1, 1)
+			self.editbox:SetTextColor(1, 1, 1)
+			self.editbox:EnableMouse(true)
+		end
+	end,
+
+	["SetValue"] = function(self, value)
+		self.slider.setup = true
+		self.slider:SetValue(value)
+		self.value = value
+		UpdateText(self)
+		self.slider.setup = nil
+	end,
+
+	["GetValue"] = function(self)
+		return self.value
+	end,
+
+	["SetLabel"] = function(self, text)
+		self.label:SetText(text)
+	end,
+
+	["SetSliderValues"] = function(self, min, max, step)
+		local frame = self.slider
+		frame.setup = true
+		self.min = min
+		self.max = max
+		self.step = step
+		frame:SetMinMaxValues(min or 0,max or 100)
+		UpdateLabels(self)
+		frame:SetValueStep(step or 1)
+		if self.value then
+			frame:SetValue(self.value)
+		end
+		frame.setup = nil
+	end,
+
+	["SetIsPercent"] = function(self, value)
+		self.ispercent = value
+		UpdateLabels(self)
+		UpdateText(self)
+	end
+}
+
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+local SliderBackdrop  = {
+	bgFile = [[Interface\AddOns\SVUI_!Core\assets\backgrounds\TRANSPARENT]],
+	edgeFile = [[Interface\AddOns\SVUI_!Core\assets\borders\DEFAULT]],
+	tile = false, edgeSize = 1,
+	insets = { left = 0, right = 0, top = 0, bottom = 0 }
+}
+
+local function Constructor()
+	local frame = CreateFrame("Frame", nil, UIParent)
+
+	frame:EnableMouse(true)
+	frame:SetScript("OnMouseDown", Frame_OnMouseDown)
+
+	local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
+	label:SetPoint("TOPLEFT")
+	label:SetPoint("TOPRIGHT")
+	label:SetJustifyH("CENTER")
+	label:SetHeight(15)
+
+	local slider = CreateFrame("Slider", nil, frame)
+	slider:SetOrientation("HORIZONTAL")
+	slider:SetHeight(15)
+	slider:SetHitRectInsets(0, 0, -10, 0)
+	slider:SetBackdrop(SliderBackdrop)
+	slider:SetThumbTexture([[Interface\AddOns\SVUI_!Core\assets\buttons\SCROLLBAR-KNOB]])
+	slider:SetPoint("TOP", label, "BOTTOM")
+	slider:SetPoint("LEFT", 3, 0)
+	slider:SetPoint("RIGHT", -3, 0)
+	slider:SetValue(0)
+	slider:SetScript("OnValueChanged",Slider_OnValueChanged)
+	slider:SetScript("OnEnter", Control_OnEnter)
+	slider:SetScript("OnLeave", Control_OnLeave)
+	slider:SetScript("OnMouseUp", Slider_OnMouseUp)
+	slider:SetScript("OnMouseWheel", Slider_OnMouseWheel)
+
+	local lowtext = slider:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
+	lowtext:SetPoint("TOPLEFT", slider, "BOTTOMLEFT", 2, 0)
+
+	local hightext = slider:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
+	hightext:SetPoint("TOPRIGHT", slider, "BOTTOMRIGHT", -2, 0)
+
+	local editbox = CreateFrame("EditBox", nil, frame)
+	editbox:SetAutoFocus(false)
+	editbox:SetFontObject(GameFontHighlightSmall)
+	editbox:SetPoint("TOP", slider, "BOTTOM")
+	editbox:SetHeight(14)
+	editbox:SetWidth(70)
+	editbox:SetJustifyH("CENTER")
+	editbox:EnableMouse(true)
+	editbox:SetBackdrop(SliderBackdrop)
+	editbox:SetBackdropColor(0, 0, 0, 0.5)
+	editbox:SetBackdropBorderColor(0.3, 0.3, 0.30, 0.80)
+	editbox:SetScript("OnEnter", EditBox_OnEnter)
+	editbox:SetScript("OnLeave", EditBox_OnLeave)
+	editbox:SetScript("OnEnterPressed", EditBox_OnEnterPressed)
+	editbox:SetScript("OnEscapePressed", EditBox_OnEscapePressed)
+
+	if(editbox.SetStyle) then
+		editbox:SetStyle("Editbox")
+	end
+
+	local widget = {
+		label       = label,
+		slider      = slider,
+		lowtext     = lowtext,
+		hightext    = hightext,
+		editbox     = editbox,
+		alignoffset = 25,
+		frame       = frame,
+		type        = Type
+	}
+	for method, func in pairs(methods) do
+		widget[method] = func
+	end
+	slider.obj, editbox.obj = widget, widget
+
+	return AceGUI:RegisterAsWidget(widget)
+end
+
+AceGUI:RegisterWidgetType(Type,Constructor,Version)
diff --git a/SVUI_!Core/libs/AceVillain-1.0/widgets/shared/BackgroundWidget.lua b/SVUI_!Core/libs/AceVillain-1.0/widgets/shared/BackgroundWidget.lua
new file mode 100644
index 0000000..929950b
--- /dev/null
+++ b/SVUI_!Core/libs/AceVillain-1.0/widgets/shared/BackgroundWidget.lua
@@ -0,0 +1,251 @@
+-- Widget is based on the AceGUIWidget-DropDown.lua supplied with AceGUI-3.0
+-- Widget created by Yssaril
+
+local AceGUI = LibStub("AceGUI-3.0")
+local Media = LibStub("LibSharedMedia-3.0")
+
+local AceVillain = LibStub("AceVillain-1.0")
+
+do
+	local widgetType = "LSM30_Background"
+	local widgetVersion = 999999
+
+	local contentFrameCache = {}
+	local function ReturnSelf(self)
+		self:ClearAllPoints()
+		self:Hide()
+		self.check:Hide()
+		table.insert(contentFrameCache, self)
+	end
+
+	local function ContentOnClick(this, button)
+		local self = this.obj
+		self:Fire("OnValueChanged", this.text:GetText())
+		if self.dropdown then
+			self.dropdown = AceVillain:ReturnDropDownFrame(self.dropdown)
+		end
+	end
+
+	local function ContentOnEnter(this, button)
+		local self = this.obj
+		local text = this.text:GetText()
+		local background = self.list[text] ~= text and self.list[text] or Media:Fetch('background',text)
+		self.dropdown.bgTex:SetTexture(background)
+	end
+
+	local function GetContentLine()
+		local frame
+		if next(contentFrameCache) then
+			frame = table.remove(contentFrameCache)
+		else
+			frame = CreateFrame("Button", nil, UIParent)
+				--frame:SetWidth(320)
+				frame:SetHeight(18)
+				frame:SetHighlightTexture([[Interface\AddOns\SVUI_!Core\assets\textures\TITLE-HIGHLIGHT]], "ADD")
+				frame:SetScript("OnClick", ContentOnClick)
+				frame:SetScript("OnEnter", ContentOnEnter)
+
+			local check = frame:CreateTexture("OVERLAY")
+				check:SetWidth(16)
+				check:SetHeight(16)
+				check:SetPoint("LEFT",frame,"LEFT",1,-1)
+				check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
+				check:Hide()
+			frame.check = check
+
+			local text = frame:CreateFontString(nil,"OVERLAY","GameFontWhite")
+				local font, size = text:GetFont()
+				text:SetFont(font,size,"OUTLINE")
+				text:SetWordWrap(false)
+				text:SetPoint("LEFT", check, "RIGHT", 1, 0)
+				text:SetPoint("RIGHT", frame, "RIGHT", -2, 0)
+				text:SetJustifyH("LEFT")
+				text:SetText("Test Test Test Test Test Test Test")
+			frame.text = text
+
+			frame.ReturnSelf = ReturnSelf
+		end
+		frame:Show()
+		return frame
+	end
+
+	local function OnAcquire(self)
+		self:SetHeight(44)
+		self:SetWidth(320)
+	end
+
+	local function OnRelease(self)
+		self:SetText("")
+		self:SetLabel("")
+		self:SetDisabled(false)
+
+		self.value = nil
+		self.list = nil
+		self.open = nil
+		self.hasClose = nil
+
+		self.frame:ClearAllPoints()
+		self.frame:Hide()
+	end
+
+	local function SetValue(self, value) -- Set the value to an item in the List.
+		if self.list then
+			self:SetText(value or "")
+		end
+		self.value = value
+	end
+
+	local function GetValue(self)
+		return self.value
+	end
+
+	local function SetList(self, list) -- Set the list of values for the dropdown (key => value pairs)
+		self.list = list or Media:HashTable("background")
+	end
+
+
+	local function SetText(self, text) -- Set the text displayed in the box.
+		self.frame.text:SetText(text or "")
+		local background = self.list[text] ~= text and self.list[text] or Media:Fetch('background',text)
+
+		self.frame.displayButton:SetBackdrop({bgFile = background,
+			edgeFile = [[Interface\AddOns\SVUI_!Core\assets\borders\DEFAULT]],
+			edgeSize = 1,
+			insets = { left = 1, right = 1, top = 1, bottom = 1 }})
+	end
+
+	local function SetLabel(self, text) -- Set the text for the label.
+		self.frame.label:SetText(text or "")
+	end
+
+	local function AddItem(self, key, value) -- Add an item to the list.
+		self.list = self.list or {}
+		self.list[key] = value
+	end
+	local SetItemValue = AddItem -- Set the value of a item in the list. <<same as adding a new item>>
+
+	local function SetMultiselect(self, flag) end -- Toggle multi-selecting. <<Dummy function to stay inline with the dropdown API>>
+	local function GetMultiselect() return false end-- Query the multi-select flag. <<Dummy function to stay inline with the dropdown API>>
+	local function SetItemDisabled(self, key) end-- Disable one item in the list. <<Dummy function to stay inline with the dropdown API>>
+
+	local function SetDisabled(self, disabled) -- Disable the widget.
+		self.disabled = disabled
+		if disabled then
+			self.frame:Disable()
+			self.frame.displayButton:SetBackdropColor(.2,.2,.2,1)
+		else
+			self.frame:Enable()
+			self.frame.displayButton:SetBackdropColor(1,1,1,1)
+		end
+	end
+
+	local function textSort(a,b)
+		return string.upper(a) < string.upper(b)
+	end
+
+	local sortedlist = {}
+	local function ToggleDrop(this)
+		local self = this.obj
+		if self.dropdown then
+			self.dropdown = AceVillain:ReturnDropDownFrame(self.dropdown)
+			AceGUI:ClearFocus()
+		else
+			AceGUI:SetFocus(self)
+			self.dropdown = AceVillain:GetDropDownFrame()
+			local width = self.frame:GetWidth()
+			self.dropdown:SetPoint("TOPLEFT", self.frame, "BOTTOMLEFT")
+			self.dropdown:SetPoint("TOPRIGHT", self.frame, "BOTTOMRIGHT", width < 160 and (160 - width) or 0, 0)
+			for k, v in pairs(self.list) do
+				sortedlist[#sortedlist+1] = k
+			end
+			table.sort(sortedlist, textSort)
+			for i, k in ipairs(sortedlist) do
+				local f = GetContentLine()
+				f.text:SetText(k)
+				f.text:SetWordWrap(false)
+				if k == self.value then
+					f.check:Show()
+				end
+				f.obj = self
+				f.dropdown = self.dropdown
+				self.dropdown:AddFrame(f)
+			end
+			wipe(sortedlist)
+		end
+	end
+
+	local function ClearFocus(self)
+		if self.dropdown then
+			self.dropdown = AceVillain:ReturnDropDownFrame(self.dropdown)
+		end
+	end
+
+	local function OnHide(this)
+		local self = this.obj
+		if self.dropdown then
+			self.dropdown = AceVillain:ReturnDropDownFrame(self.dropdown)
+		end
+	end
+
+	local function Drop_OnEnter(this)
+		this.obj:Fire("OnEnter")
+	end
+
+	local function Drop_OnLeave(this)
+		this.obj:Fire("OnLeave")
+	end
+
+	local function SetDropDownStyle(self, xTopleft, yTopleft, xBottomright, yBottomright)
+		self:RemoveTextures()
+		self:SetStyle("Frame", "Transparent")
+		self.Panel:SetPoint("TOPLEFT", self, "TOPLEFT", xTopleft, yTopleft)
+		self.Panel:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", xBottomright, yBottomright)
+	end
+
+	local function Constructor()
+		local frame = AceVillain:GetBaseFrameWithWindow()
+		local self = {}
+
+		self.type = widgetType
+		self.frame = frame
+		frame.obj = self
+		frame.dropButton.obj = self
+		frame.dropButton:SetScript("OnEnter", Drop_OnEnter)
+		frame.dropButton:SetScript("OnLeave", Drop_OnLeave)
+		frame.dropButton:SetScript("OnClick",ToggleDrop)
+		frame:SetScript("OnHide", OnHide)
+		if(frame.SetStyle) then
+			SetDropDownStyle(frame, 2, -20, -2, 0)
+			frame.dropButton:ClearAllPoints()
+			frame.dropButton:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -2, 0)
+			if(SVUI and SVUI.API) then
+				SVUI.API:Set("PageButton", frame.dropButton, true)
+			end
+			frame.dropButton:SetParent(frame.Panel)
+		end
+
+		self.alignoffset = 31
+
+		self.OnRelease = OnRelease
+		self.OnAcquire = OnAcquire
+		self.ClearFocus = ClearFocus
+		self.SetText = SetText
+		self.SetValue = SetValue
+		self.GetValue = GetValue
+		self.SetList = SetList
+		self.SetLabel = SetLabel
+		self.SetDisabled = SetDisabled
+		self.AddItem = AddItem
+		self.SetMultiselect = SetMultiselect
+		self.GetMultiselect = GetMultiselect
+		self.SetItemValue = SetItemValue
+		self.SetItemDisabled = SetItemDisabled
+		self.ToggleDrop = ToggleDrop
+
+		AceGUI:RegisterAsWidget(self)
+		return self
+	end
+
+	AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion)
+
+end
diff --git a/SVUI_!Core/libs/AceVillain-1.0/widgets/shared/BorderWidget.lua b/SVUI_!Core/libs/AceVillain-1.0/widgets/shared/BorderWidget.lua
new file mode 100644
index 0000000..49c6a2b
--- /dev/null
+++ b/SVUI_!Core/libs/AceVillain-1.0/widgets/shared/BorderWidget.lua
@@ -0,0 +1,247 @@
+-- Widget is based on the AceGUIWidget-DropDown.lua supplied with AceGUI-3.0
+-- Widget created by Yssaril
+
+local AceGUI = LibStub("AceGUI-3.0")
+local Media = LibStub("LibSharedMedia-3.0")
+
+local AceVillain = LibStub("AceVillain-1.0")
+
+do
+	local widgetType = "LSM30_Border"
+	local widgetVersion = 999999
+
+	local contentFrameCache = {}
+	local function ReturnSelf(self)
+		self:ClearAllPoints()
+		self:Hide()
+		self.check:Hide()
+		table.insert(contentFrameCache, self)
+	end
+
+	local function ContentOnClick(this, button)
+		local self = this.obj
+		self:Fire("OnValueChanged", this.text:GetText())
+		if self.dropdown then
+			self.dropdown = AceVillain:ReturnDropDownFrame(self.dropdown)
+		end
+	end
+
+	local function ContentOnEnter(this, button)
+		local self = this.obj
+		local text = this.text:GetText()
+		local border = self.list[text] ~= text and self.list[text] or Media:Fetch('border',text)
+		this.dropdown:SetBackdrop({edgeFile = border,
+			bgFile=[[Interface\DialogFrame\UI-DialogBox-Background-Dark]],
+			tile = true, tileSize = 16, edgeSize = 16,
+			insets = { left = 4, right = 4, top = 4, bottom = 4 }})
+	end
+
+	local function GetContentLine()
+		local frame
+		if next(contentFrameCache) then
+			frame = table.remove(contentFrameCache)
+		else
+			frame = CreateFrame("Button", nil, UIParent)
+				--frame:SetWidth(320)
+				frame:SetHeight(18)
+				frame:SetHighlightTexture([[Interface\AddOns\SVUI_!Core\assets\textures\TITLE-HIGHLIGHT]], "ADD")
+				frame:SetScript("OnClick", ContentOnClick)
+				frame:SetScript("OnEnter", ContentOnEnter)
+			local check = frame:CreateTexture("OVERLAY")
+				check:SetWidth(16)
+				check:SetHeight(16)
+				check:SetPoint("LEFT",frame,"LEFT",1,-1)
+				check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
+				check:Hide()
+			frame.check = check
+			local text = frame:CreateFontString(nil,"OVERLAY","GameFontWhite")
+				text:SetWordWrap(false)
+				text:SetPoint("LEFT", check, "RIGHT", 1, 0)
+				text:SetPoint("RIGHT", frame, "RIGHT", -2, 0)
+				text:SetJustifyH("LEFT")
+				text:SetText("Test Test Test Test Test Test Test")
+			frame.text = text
+			frame.ReturnSelf = ReturnSelf
+		end
+		frame:Show()
+		return frame
+	end
+
+	local function OnAcquire(self)
+		self:SetHeight(44)
+		self:SetWidth(320)
+	end
+
+	local function OnRelease(self)
+		self:SetText("")
+		self:SetLabel("")
+		self:SetDisabled(false)
+
+		self.value = nil
+		self.list = nil
+		self.open = nil
+		self.hasClose = nil
+
+		self.frame:ClearAllPoints()
+		self.frame:Hide()
+	end
+
+	local function SetValue(self, value) -- Set the value to an item in the List.
+		if self.list then
+			self:SetText(value or "")
+		end
+		self.value = value
+	end
+
+	local function GetValue(self)
+		return self.value
+	end
+
+	local function SetList(self, list) -- Set the list of values for the dropdown (key => value pairs)
+		self.list = list or Media:HashTable("border")
+	end
+
+
+	local function SetText(self, text) -- Set the text displayed in the box.
+		self.frame.text:SetText(text or "")
+		local border = self.list[text] ~= text and self.list[text] or Media:Fetch('border',text)
+
+		self.frame.displayButton:SetBackdrop({edgeFile = border,
+			bgFile=[[Interface\DialogFrame\UI-DialogBox-Background-Dark]],
+			tile = true, tileSize = 16, edgeSize = 16,
+			insets = { left = 4, right = 4, top = 4, bottom = 4 }})
+	end
+
+	local function SetLabel(self, text) -- Set the text for the label.
+		self.frame.label:SetText(text or "")
+	end
+
+	local function AddItem(self, key, value) -- Add an item to the list.
+		self.list = self.list or {}
+		self.list[key] = value
+	end
+	local SetItemValue = AddItem -- Set the value of a item in the list. <<same as adding a new item>>
+
+	local function SetMultiselect(self, flag) end -- Toggle multi-selecting. <<Dummy function to stay inline with the dropdown API>>
+	local function GetMultiselect() return false end-- Query the multi-select flag. <<Dummy function to stay inline with the dropdown API>>
+	local function SetItemDisabled(self, key) end-- Disable one item in the list. <<Dummy function to stay inline with the dropdown API>>
+
+	local function SetDisabled(self, disabled) -- Disable the widget.
+		self.disabled = disabled
+		if disabled then
+			self.frame:Disable()
+		else
+			self.frame:Enable()
+		end
+	end
+
+	local function textSort(a,b)
+		return string.upper(a) < string.upper(b)
+	end
+
+	local sortedlist = {}
+	local function ToggleDrop(this)
+		local self = this.obj
+		if self.dropdown then
+			self.dropdown = AceVillain:ReturnDropDownFrame(self.dropdown)
+			AceGUI:ClearFocus()
+		else
+			AceGUI:SetFocus(self)
+			self.dropdown = AceVillain:GetDropDownFrame()
+			local width = self.frame:GetWidth()
+			self.dropdown:SetPoint("TOPLEFT", self.frame, "BOTTOMLEFT")
+			self.dropdown:SetPoint("TOPRIGHT", self.frame, "BOTTOMRIGHT", width < 160 and (160 - width) or 0, 0)
+			for k, v in pairs(self.list) do
+				sortedlist[#sortedlist+1] = k
+			end
+			table.sort(sortedlist, textSort)
+			for i, k in ipairs(sortedlist) do
+				local f = GetContentLine()
+				f.text:SetText(k)
+				--print(k)
+				if k == self.value then
+					f.check:Show()
+				end
+				f.obj = self
+				f.dropdown = self.dropdown
+				self.dropdown:AddFrame(f)
+			end
+			wipe(sortedlist)
+		end
+	end
+
+	local function ClearFocus(self)
+		if self.dropdown then
+			self.dropdown = AceVillain:ReturnDropDownFrame(self.dropdown)
+		end
+	end
+
+	local function OnHide(this)
+		local self = this.obj
+		if self.dropdown then
+			self.dropdown = AceVillain:ReturnDropDownFrame(self.dropdown)
+		end
+	end
+
+	local function Drop_OnEnter(this)
+		this.obj:Fire("OnEnter")
+	end
+
+	local function Drop_OnLeave(this)
+		this.obj:Fire("OnLeave")
+	end
+
+	local function SetDropDownStyle(self, xTopleft, yTopleft, xBottomright, yBottomright)
+		self:RemoveTextures()
+		self:SetStyle("Frame", "Transparent")
+		self.Panel:SetPoint("TOPLEFT", self, "TOPLEFT", xTopleft, yTopleft)
+		self.Panel:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", xBottomright, yBottomright)
+	end
+
+	local function Constructor()
+		local frame = AceVillain:GetBaseFrameWithWindow()
+		local self = {}
+
+		self.type = widgetType
+		self.frame = frame
+		frame.obj = self
+		frame.dropButton.obj = self
+		frame.dropButton:SetScript("OnEnter", Drop_OnEnter)
+		frame.dropButton:SetScript("OnLeave", Drop_OnLeave)
+		frame.dropButton:SetScript("OnClick",ToggleDrop)
+		frame:SetScript("OnHide", OnHide)
+		if(frame.SetStyle) then
+			SetDropDownStyle(frame, 2, -20, -2, 0)
+			frame.dropButton:ClearAllPoints()
+			frame.dropButton:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -2, 0)
+			if(SVUI and SVUI.API) then
+				SVUI.API:Set("PageButton", frame.dropButton, true)
+			end
+			frame.dropButton:SetParent(frame.Panel)
+		end
+
+		self.alignoffset = 31
+
+		self.OnRelease = OnRelease
+		self.OnAcquire = OnAcquire
+		self.ClearFocus = ClearFocus
+		self.SetText = SetText
+		self.SetValue = SetValue
+		self.GetValue = GetValue
+		self.SetList = SetList
+		self.SetLabel = SetLabel
+		self.SetDisabled = SetDisabled
+		self.AddItem = AddItem
+		self.SetMultiselect = SetMultiselect
+		self.GetMultiselect = GetMultiselect
+		self.SetItemValue = SetItemValue
+		self.SetItemDisabled = SetItemDisabled
+		self.ToggleDrop = ToggleDrop
+
+		AceGUI:RegisterAsWidget(self)
+		return self
+	end
+
+	AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion)
+
+end
diff --git a/SVUI_!Core/libs/AceVillain-1.0/widgets/shared/FontWidget.lua b/SVUI_!Core/libs/AceVillain-1.0/widgets/shared/FontWidget.lua
new file mode 100644
index 0000000..e5d34f8
--- /dev/null
+++ b/SVUI_!Core/libs/AceVillain-1.0/widgets/shared/FontWidget.lua
@@ -0,0 +1,233 @@
+-- Widget is based on the AceGUIWidget-DropDown.lua supplied with AceGUI-3.0
+-- Widget created by Yssaril
+
+local AceGUI = LibStub("AceGUI-3.0")
+local Media = LibStub("LibSharedMedia-3.0")
+
+local AceVillain = LibStub("AceVillain-1.0")
+
+do
+	local widgetType = "LSM30_Font"
+	local widgetVersion = 999999
+
+	local contentFrameCache = {}
+	local function ReturnSelf(self)
+		self:ClearAllPoints()
+		self:Hide()
+		self.check:Hide()
+		table.insert(contentFrameCache, self)
+	end
+
+	local function ContentOnClick(this, button)
+		local self = this.obj
+		self:Fire("OnValueChanged", this.text:GetText())
+		if self.dropdown then
+			self.dropdown = AceVillain:ReturnDropDownFrame(self.dropdown)
+		end
+	end
+
+	local function GetContentLine()
+		local frame
+		if next(contentFrameCache) then
+			frame = table.remove(contentFrameCache)
+		else
+			frame = CreateFrame("Button", nil, UIParent)
+				--frame:SetWidth(320)
+				frame:SetHeight(18)
+				frame:SetHighlightTexture([[Interface\AddOns\SVUI_!Core\assets\textures\TITLE-HIGHLIGHT]], "ADD")
+				frame:SetScript("OnClick", ContentOnClick)
+			local check = frame:CreateTexture("OVERLAY")
+				check:SetWidth(16)
+				check:SetHeight(16)
+				check:SetPoint("LEFT",frame,"LEFT",1,-1)
+				check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
+				check:Hide()
+			frame.check = check
+			local text = frame:CreateFontString(nil,"OVERLAY","GameFontWhite")
+				text:SetWordWrap(false)
+				text:SetPoint("LEFT", check, "RIGHT", 1, 0)
+				text:SetPoint("RIGHT", frame, "RIGHT", -2, 0)
+				text:SetJustifyH("LEFT")
+				text:SetText("Test Test Test Test Test Test Test")
+			frame.text = text
+			frame.ReturnSelf = ReturnSelf
+		end
+		frame:Show()
+		return frame
+	end
+
+	local function OnAcquire(self)
+		self:SetHeight(44)
+		self:SetWidth(320)
+	end
+
+	local function OnRelease(self)
+		self:SetText("")
+		self:SetLabel("")
+		self:SetDisabled(false)
+
+		self.value = nil
+		self.list = nil
+		self.open = nil
+		self.hasClose = nil
+
+		self.frame:ClearAllPoints()
+		self.frame:Hide()
+	end
+
+	local function SetValue(self, value) -- Set the value to an item in the List.
+		if self.list then
+			self:SetText(value or "")
+		end
+		self.value = value
+	end
+
+	local function GetValue(self)
+		return self.value
+	end
+
+	local function SetList(self, list) -- Set the list of values for the dropdown (key => value pairs)
+		self.list = list or Media:HashTable("font")
+	end
+
+	local function SetText(self, text) -- Set the text displayed in the box.
+		self.frame.text:SetText(text or "")
+		local font = self.list[text] ~= text and self.list[text] or Media:Fetch('font',text)
+		local _, size, outline= self.frame.text:GetFont()
+		self.frame.text:SetFont(font,size,outline)
+	end
+
+	local function SetLabel(self, text) -- Set the text for the label.
+		self.frame.label:SetText(text or "")
+	end
+
+	local function AddItem(self, key, value) -- Add an item to the list.
+		self.list = self.list or {}
+		self.list[key] = value
+	end
+	local SetItemValue = AddItem -- Set the value of a item in the list. <<same as adding a new item>>
+
+	local function SetMultiselect(self, flag) end -- Toggle multi-selecting. <<Dummy function to stay inline with the dropdown API>>
+	local function GetMultiselect() return false end-- Query the multi-select flag. <<Dummy function to stay inline with the dropdown API>>
+	local function SetItemDisabled(self, key) end-- Disable one item in the list. <<Dummy function to stay inline with the dropdown API>>
+
+	local function SetDisabled(self, disabled) -- Disable the widget.
+		self.disabled = disabled
+		if disabled then
+			self.frame:Disable()
+		else
+			self.frame:Enable()
+		end
+	end
+
+	local function textSort(a,b)
+		return string.upper(a) < string.upper(b)
+	end
+
+	local sortedlist = {}
+	local function ToggleDrop(this)
+		local self = this.obj
+		if self.dropdown then
+			self.dropdown = AceVillain:ReturnDropDownFrame(self.dropdown)
+			AceGUI:ClearFocus()
+		else
+			AceGUI:SetFocus(self)
+			self.dropdown = AceVillain:GetDropDownFrame()
+			local width = self.frame:GetWidth()
+			self.dropdown:SetPoint("TOPLEFT", self.frame, "BOTTOMLEFT")
+			self.dropdown:SetPoint("TOPRIGHT", self.frame, "BOTTOMRIGHT", width < 160 and (160 - width) or 0, 0)
+			for k, v in pairs(self.list) do
+				sortedlist[#sortedlist+1] = k
+			end
+			table.sort(sortedlist, textSort)
+			for i, k in ipairs(sortedlist) do
+				local f = GetContentLine()
+				local _, size, outline= f.text:GetFont()
+				local font = self.list[k] ~= k and self.list[k] or Media:Fetch('font',k)
+				f.text:SetFont(font,size,outline)
+				f.text:SetText(k)
+				if k == self.value then
+					f.check:Show()
+				end
+				f.obj = self
+				self.dropdown:AddFrame(f)
+			end
+			wipe(sortedlist)
+		end
+	end
+
+	local function ClearFocus(self)
+		if self.dropdown then
+			self.dropdown = AceVillain:ReturnDropDownFrame(self.dropdown)
+		end
+	end
+
+	local function OnHide(this)
+		local self = this.obj
+		if self.dropdown then
+			self.dropdown = AceVillain:ReturnDropDownFrame(self.dropdown)
+		end
+	end
+
+	local function Drop_OnEnter(this)
+		this.obj:Fire("OnEnter")
+	end
+
+	local function Drop_OnLeave(this)
+		this.obj:Fire("OnLeave")
+	end
+
+	local function SetDropDownStyle(self, xTopleft, yTopleft, xBottomright, yBottomright)
+		self:RemoveTextures()
+		self:SetStyle("Frame", "Transparent")
+		self.Panel:SetPoint("TOPLEFT", self, "TOPLEFT", xTopleft, yTopleft)
+		self.Panel:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", xBottomright, yBottomright)
+	end
+
+	local function Constructor()
+		local frame = AceVillain:GetBaseFrame()
+		local self = {}
+
+		self.type = widgetType
+		self.frame = frame
+		frame.obj = self
+		frame.dropButton.obj = self
+		frame.dropButton:SetScript("OnEnter", Drop_OnEnter)
+		frame.dropButton:SetScript("OnLeave", Drop_OnLeave)
+		frame.dropButton:SetScript("OnClick",ToggleDrop)
+		frame:SetScript("OnHide", OnHide)
+		if(frame.SetStyle) then
+			SetDropDownStyle(frame, 2, -20, -2, 0)
+			frame.dropButton:ClearAllPoints()
+			frame.dropButton:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -2, 0)
+			if(SVUI and SVUI.API) then
+				SVUI.API:Set("PageButton", frame.dropButton, true)
+			end
+			frame.dropButton:SetParent(frame.Panel)
+		end
+
+		self.alignoffset = 31
+
+		self.OnRelease = OnRelease
+		self.OnAcquire = OnAcquire
+		self.ClearFocus = ClearFocus
+		self.SetText = SetText
+		self.SetValue = SetValue
+		self.GetValue = GetValue
+		self.SetList = SetList
+		self.SetLabel = SetLabel
+		self.SetDisabled = SetDisabled
+		self.AddItem = AddItem
+		self.SetMultiselect = SetMultiselect
+		self.GetMultiselect = GetMultiselect
+		self.SetItemValue = SetItemValue
+		self.SetItemDisabled = SetItemDisabled
+		self.ToggleDrop = ToggleDrop
+
+		AceGUI:RegisterAsWidget(self)
+		return self
+	end
+
+	AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion)
+
+end
diff --git a/SVUI_!Core/libs/AceVillain-1.0/widgets/shared/SoundWidget.lua b/SVUI_!Core/libs/AceVillain-1.0/widgets/shared/SoundWidget.lua
new file mode 100644
index 0000000..c5736e5
--- /dev/null
+++ b/SVUI_!Core/libs/AceVillain-1.0/widgets/shared/SoundWidget.lua
@@ -0,0 +1,280 @@
+-- Widget is based on the AceGUIWidget-DropDown.lua supplied with AceGUI-3.0
+-- Widget created by Yssaril
+
+local AceGUI = LibStub("AceGUI-3.0")
+local Media = LibStub("LibSharedMedia-3.0")
+
+local AceVillain = LibStub("AceVillain-1.0")
+
+do
+	local widgetType = "LSM30_Sound"
+	local widgetVersion = 999999
+
+	local contentFrameCache = {}
+	local function ReturnSelf(self)
+		self:ClearAllPoints()
+		self:Hide()
+		self.check:Hide()
+		table.insert(contentFrameCache, self)
+	end
+
+	local function ContentOnClick(this, button)
+		local self = this.obj
+		self:Fire("OnValueChanged", this.text:GetText())
+		if self.dropdown then
+			self.dropdown = AceVillain:ReturnDropDownFrame(self.dropdown)
+		end
+	end
+
+	local function ContentSpeakerOnClick(this, button)
+		local self = this.frame.obj
+		local sound = this.frame.text:GetText()
+		PlaySoundFile(self.list[sound] ~= sound and self.list[sound] or Media:Fetch('sound',sound), "Master")
+	end
+
+	local function GetContentLine()
+		local frame
+		if next(contentFrameCache) then
+			frame = table.remove(contentFrameCache)
+		else
+			frame = CreateFrame("Button", nil, UIParent)
+				--frame:SetWidth(320)
+				frame:SetHeight(18)
+				frame:SetHighlightTexture([[Interface\AddOns\SVUI_!Core\assets\textures\TITLE-HIGHLIGHT]], "ADD")
+				frame:SetScript("OnClick", ContentOnClick)
+			local check = frame:CreateTexture("OVERLAY")
+				check:SetWidth(16)
+				check:SetHeight(16)
+				check:SetPoint("LEFT",frame,"LEFT",1,-1)
+				check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
+				check:Hide()
+			frame.check = check
+
+			local soundbutton = CreateFrame("Button", nil, frame)
+				soundbutton:SetWidth(16)
+				soundbutton:SetHeight(16)
+				soundbutton:SetPoint("RIGHT",frame,"RIGHT",-1,0)
+				soundbutton.frame = frame
+				soundbutton:SetScript("OnClick", ContentSpeakerOnClick)
+			frame.soundbutton = soundbutton
+
+			local speaker = soundbutton:CreateTexture(nil, "BACKGROUND")
+				speaker:SetTexture("Interface\\Common\\VoiceChat-Speaker")
+				speaker:SetAllPoints(soundbutton)
+			frame.speaker = speaker
+			local speakeron = soundbutton:CreateTexture(nil, "HIGHLIGHT")
+				speakeron:SetTexture("Interface\\Common\\VoiceChat-On")
+				speakeron:SetAllPoints(soundbutton)
+			frame.speakeron = speakeron
+
+			local text = frame:CreateFontString(nil,"OVERLAY","GameFontWhite")
+				text:SetWordWrap(false)
+				text:SetPoint("LEFT", check, "RIGHT", 1, 0)
+				text:SetPoint("RIGHT", soundbutton, "LEFT", -2, 0)
+				text:SetJustifyH("LEFT")
+				text:SetText("Test Test Test Test Test Test Test")
+			frame.text = text
+			frame.ReturnSelf = ReturnSelf
+		end
+		frame:Show()
+		return frame
+	end
+
+	local function OnAcquire(self)
+		self:SetHeight(44)
+		self:SetWidth(320)
+	end
+
+	local function OnRelease(self)
+		self:SetText("")
+		self:SetLabel("")
+		self:SetDisabled(false)
+
+		self.value = nil
+		self.list = nil
+		self.open = nil
+		self.hasClose = nil
+
+		self.frame:ClearAllPoints()
+		self.frame:Hide()
+	end
+
+	local function SetValue(self, value) -- Set the value to an item in the List.
+		if self.list then
+			self:SetText(value or "")
+		end
+		self.value = value
+	end
+
+	local function GetValue(self)
+		return self.value
+	end
+
+	local function SetList(self, list) -- Set the list of values for the dropdown (key => value pairs)
+		self.list = list or Media:HashTable("sound")
+	end
+
+	local function SetText(self, text) -- Set the text displayed in the box.
+		self.frame.text:SetText(text or "")
+	end
+
+	local function SetLabel(self, text) -- Set the text for the label.
+		self.frame.label:SetText(text or "")
+	end
+
+	local function AddItem(self, key, value) -- Add an item to the list.
+		self.list = self.list or {}
+		self.list[key] = value
+	end
+	local SetItemValue = AddItem -- Set the value of a item in the list. <<same as adding a new item>>
+
+	local function SetMultiselect(self, flag) end -- Toggle multi-selecting. <<Dummy function to stay inline with the dropdown API>>
+	local function GetMultiselect() return false end-- Query the multi-select flag. <<Dummy function to stay inline with the dropdown API>>
+	local function SetItemDisabled(self, key) end-- Disable one item in the list. <<Dummy function to stay inline with the dropdown API>>
+
+	local function SetDisabled(self, disabled) -- Disable the widget.
+		self.disabled = disabled
+		if disabled then
+			self.frame:Disable()
+			self.speaker:SetDesaturated(true)
+			self.speakeron:SetDesaturated(true)
+		else
+			self.frame:Enable()
+			self.speaker:SetDesaturated(false)
+			self.speakeron:SetDesaturated(false)
+		end
+	end
+
+	local function textSort(a,b)
+		return string.upper(a) < string.upper(b)
+	end
+
+	local sortedlist = {}
+	local function ToggleDrop(this)
+		local self = this.obj
+		if self.dropdown then
+			self.dropdown = AceVillain:ReturnDropDownFrame(self.dropdown)
+			AceGUI:ClearFocus()
+		else
+			AceGUI:SetFocus(self)
+			self.dropdown = AceVillain:GetDropDownFrame()
+			local width = self.frame:GetWidth()
+			self.dropdown:SetPoint("TOPLEFT", self.frame, "BOTTOMLEFT")
+			self.dropdown:SetPoint("TOPRIGHT", self.frame, "BOTTOMRIGHT", width < 160 and (160 - width) or 0, 0)
+			for k, v in pairs(self.list) do
+				sortedlist[#sortedlist+1] = k
+			end
+			table.sort(sortedlist, textSort)
+			for i, k in ipairs(sortedlist) do
+				local f = GetContentLine()
+				f.text:SetText(k)
+				if k == self.value then
+					f.check:Show()
+				end
+				f.obj = self
+				self.dropdown:AddFrame(f)
+			end
+			wipe(sortedlist)
+		end
+	end
+
+	local function ClearFocus(self)
+		if self.dropdown then
+			self.dropdown = AceVillain:ReturnDropDownFrame(self.dropdown)
+		end
+	end
+
+	local function OnHide(this)
+		local self = this.obj
+		if self.dropdown then
+			self.dropdown = AceVillain:ReturnDropDownFrame(self.dropdown)
+		end
+	end
+
+	local function Drop_OnEnter(this)
+		this.obj:Fire("OnEnter")
+	end
+
+	local function Drop_OnLeave(this)
+		this.obj:Fire("OnLeave")
+	end
+
+	local function WidgetPlaySound(this)
+		local self = this.obj
+		local sound = self.frame.text:GetText()
+		PlaySoundFile(self.list[sound] ~= sound and self.list[sound] or Media:Fetch('sound',sound), "Master")
+	end
+
+	local function SetDropDownStyle(self, xTopleft, yTopleft, xBottomright, yBottomright)
+		self:RemoveTextures()
+		self:SetStyle("Frame", "Transparent")
+		self.Panel:SetPoint("TOPLEFT", self, "TOPLEFT", xTopleft, yTopleft)
+		self.Panel:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", xBottomright, yBottomright)
+	end
+
+	local function Constructor()
+		local frame = AceVillain:GetBaseFrame()
+		local self = {}
+
+		self.type = widgetType
+		self.frame = frame
+		frame.obj = self
+		frame.dropButton.obj = self
+		frame.dropButton:SetScript("OnEnter", Drop_OnEnter)
+		frame.dropButton:SetScript("OnLeave", Drop_OnLeave)
+		frame.dropButton:SetScript("OnClick",ToggleDrop)
+		frame:SetScript("OnHide", OnHide)
+		if(frame.SetStyle) then
+			SetDropDownStyle(frame, 2, -20, -2, 0)
+			frame.dropButton:ClearAllPoints()
+			frame.dropButton:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -2, 0)
+			if(SVUI and SVUI.API) then
+				SVUI.API:Set("PageButton", frame.dropButton, true)
+			end
+			frame.dropButton:SetParent(frame.Panel)
+		end
+
+		local soundbutton = CreateFrame("Button", nil, frame)
+			soundbutton:SetWidth(16)
+			soundbutton:SetHeight(16)
+			soundbutton:SetPoint("LEFT",frame.DLeft,"LEFT",26,1)
+			soundbutton:SetScript("OnClick", WidgetPlaySound)
+			soundbutton.obj = self
+		self.soundbutton = soundbutton
+		frame.text:SetPoint("LEFT",soundbutton,"RIGHT",2,0)
+
+
+		local speaker = soundbutton:CreateTexture(nil, "BACKGROUND")
+			speaker:SetTexture("Interface\\Common\\VoiceChat-Speaker")
+			speaker:SetAllPoints(soundbutton)
+		self.speaker = speaker
+		local speakeron = soundbutton:CreateTexture(nil, "HIGHLIGHT")
+			speakeron:SetTexture("Interface\\Common\\VoiceChat-On")
+			speakeron:SetAllPoints(soundbutton)
+		self.speakeron = speakeron
+
+		self.alignoffset = 31
+
+		self.OnRelease = OnRelease
+		self.OnAcquire = OnAcquire
+		self.ClearFocus = ClearFocus
+		self.SetText = SetText
+		self.SetValue = SetValue
+		self.GetValue = GetValue
+		self.SetList = SetList
+		self.SetLabel = SetLabel
+		self.SetDisabled = SetDisabled
+		self.AddItem = AddItem
+		self.SetMultiselect = SetMultiselect
+		self.GetMultiselect = GetMultiselect
+		self.SetItemValue = SetItemValue
+		self.SetItemDisabled = SetItemDisabled
+		self.ToggleDrop = ToggleDrop
+
+		AceGUI:RegisterAsWidget(self)
+		return self
+	end
+
+	AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion)
+
+end
diff --git a/SVUI_!Core/libs/AceVillain-1.0/widgets/shared/StatusbarWidget.lua b/SVUI_!Core/libs/AceVillain-1.0/widgets/shared/StatusbarWidget.lua
new file mode 100644
index 0000000..f6cef64
--- /dev/null
+++ b/SVUI_!Core/libs/AceVillain-1.0/widgets/shared/StatusbarWidget.lua
@@ -0,0 +1,249 @@
+-- Widget is based on the AceGUIWidget-DropDown.lua supplied with AceGUI-3.0
+-- Widget created by Yssaril
+
+local AceGUI = LibStub("AceGUI-3.0")
+local Media = LibStub("LibSharedMedia-3.0")
+
+local AceVillain = LibStub("AceVillain-1.0")
+
+do
+	local widgetType = "LSM30_Statusbar"
+	local widgetVersion = 999999
+
+	local contentFrameCache = {}
+	local function ReturnSelf(self)
+		self:ClearAllPoints()
+		self:Hide()
+		self.check:Hide()
+		table.insert(contentFrameCache, self)
+	end
+
+	local function ContentOnClick(this, button)
+		local self = this.obj
+		self:Fire("OnValueChanged", this.text:GetText())
+		if self.dropdown then
+			self.dropdown = AceVillain:ReturnDropDownFrame(self.dropdown)
+		end
+	end
+
+	local function GetContentLine()
+		local frame
+		if next(contentFrameCache) then
+			frame = table.remove(contentFrameCache)
+		else
+			frame = CreateFrame("Button", nil, UIParent)
+				--frame:SetWidth(320)
+				frame:SetHeight(18)
+				frame:SetHighlightTexture([[Interface\AddOns\SVUI_!Core\assets\textures\TITLE-HIGHLIGHT]], "ADD")
+				frame:SetScript("OnClick", ContentOnClick)
+			local check = frame:CreateTexture("OVERLAY")
+				check:SetWidth(16)
+				check:SetHeight(16)
+				check:SetPoint("LEFT",frame,"LEFT",1,-1)
+				check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
+				check:Hide()
+			frame.check = check
+			local bar = frame:CreateTexture("ARTWORK")
+				bar:SetHeight(16)
+				bar:SetPoint("LEFT",check,"RIGHT",1,0)
+				bar:SetPoint("RIGHT",frame,"RIGHT",-1,0)
+			frame.bar = bar
+			local text = frame:CreateFontString(nil,"OVERLAY","GameFontWhite")
+
+				local font, size = text:GetFont()
+				text:SetFont(font,size,"OUTLINE")
+				text:SetWordWrap(false)
+				text:SetPoint("LEFT", check, "RIGHT", 3, 0)
+				text:SetPoint("RIGHT", frame, "RIGHT", -2, 0)
+				text:SetJustifyH("LEFT")
+				text:SetText("Test Test Test Test Test Test Test")
+			frame.text = text
+			frame.ReturnSelf = ReturnSelf
+		end
+		frame:Show()
+		return frame
+	end
+
+	local function OnAcquire(self)
+		self:SetHeight(44)
+		self:SetWidth(320)
+	end
+
+	local function OnRelease(self)
+		self:SetText("")
+		self:SetLabel("")
+		self:SetDisabled(false)
+
+		self.value = nil
+		self.list = nil
+		self.open = nil
+		self.hasClose = nil
+
+		self.frame:ClearAllPoints()
+		self.frame:Hide()
+	end
+
+	local function SetValue(self, value) -- Set the value to an item in the List.
+		if self.list then
+			self:SetText(value or "")
+		end
+		self.value = value
+	end
+
+	local function GetValue(self)
+		return self.value
+	end
+
+	local function SetList(self, list) -- Set the list of values for the dropdown (key => value pairs)
+		self.list = list or Media:HashTable("statusbar")
+	end
+
+
+	local function SetText(self, text) -- Set the text displayed in the box.
+		self.frame.text:SetText(text or "")
+		local statusbar = self.list[text] ~= text and self.list[text] or Media:Fetch('statusbar',text)
+		self.bar:SetTexture(statusbar)
+	end
+
+	local function SetLabel(self, text) -- Set the text for the label.
+		self.frame.label:SetText(text or "")
+	end
+
+	local function AddItem(self, key, value) -- Add an item to the list.
+		self.list = self.list or {}
+		self.list[key] = value
+	end
+	local SetItemValue = AddItem -- Set the value of a item in the list. <<same as adding a new item>>
+
+	local function SetMultiselect(self, flag) end -- Toggle multi-selecting. <<Dummy function to stay inline with the dropdown API>>
+	local function GetMultiselect() return false end-- Query the multi-select flag. <<Dummy function to stay inline with the dropdown API>>
+	local function SetItemDisabled(self, key) end-- Disable one item in the list. <<Dummy function to stay inline with the dropdown API>>
+
+	local function SetDisabled(self, disabled) -- Disable the widget.
+		self.disabled = disabled
+		if disabled then
+			self.frame:Disable()
+		else
+			self.frame:Enable()
+		end
+	end
+
+	local function textSort(a,b)
+		return string.upper(a) < string.upper(b)
+	end
+
+	local sortedlist = {}
+	local function ToggleDrop(this)
+		local self = this.obj
+		if self.dropdown then
+			self.dropdown = AceVillain:ReturnDropDownFrame(self.dropdown)
+			AceGUI:ClearFocus()
+		else
+			AceGUI:SetFocus(self)
+			self.dropdown = AceVillain:GetDropDownFrame()
+			local width = self.frame:GetWidth()
+			self.dropdown:SetPoint("TOPLEFT", self.frame, "BOTTOMLEFT")
+			self.dropdown:SetPoint("TOPRIGHT", self.frame, "BOTTOMRIGHT", width < 160 and (160 - width) or 0, 0)
+			for k, v in pairs(self.list) do
+				sortedlist[#sortedlist+1] = k
+			end
+			table.sort(sortedlist, textSort)
+			for i, k in ipairs(sortedlist) do
+				local f = GetContentLine()
+				f.text:SetText(k)
+				--print(k)
+				if k == self.value then
+					f.check:Show()
+				end
+
+				local statusbar = self.list[k] ~= k and self.list[k] or Media:Fetch('statusbar',k)
+				f.bar:SetTexture(statusbar)
+				f.obj = self
+				f.dropdown = self.dropdown
+				self.dropdown:AddFrame(f)
+			end
+			wipe(sortedlist)
+		end
+	end
+
+	local function ClearFocus(self)
+		if self.dropdown then
+			self.dropdown = AceVillain:ReturnDropDownFrame(self.dropdown)
+		end
+	end
+
+	local function OnHide(this)
+		local self = this.obj
+		if self.dropdown then
+			self.dropdown = AceVillain:ReturnDropDownFrame(self.dropdown)
+		end
+	end
+
+	local function Drop_OnEnter(this)
+		this.obj:Fire("OnEnter")
+	end
+
+	local function Drop_OnLeave(this)
+		this.obj:Fire("OnLeave")
+	end
+
+	local function SetDropDownStyle(self, xTopleft, yTopleft, xBottomright, yBottomright)
+		self:RemoveTextures()
+		self:SetStyle("Frame", "Transparent")
+		self.Panel:SetPoint("TOPLEFT", self, "TOPLEFT", xTopleft, yTopleft)
+		self.Panel:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", xBottomright, yBottomright)
+	end
+
+	local function Constructor()
+		local frame = AceVillain:GetBaseFrame()
+		local self = {}
+
+		self.type = widgetType
+		self.frame = frame
+		frame.obj = self
+		frame.dropButton.obj = self
+		frame.dropButton:SetScript("OnEnter", Drop_OnEnter)
+		frame.dropButton:SetScript("OnLeave", Drop_OnLeave)
+		frame.dropButton:SetScript("OnClick",ToggleDrop)
+		frame:SetScript("OnHide", OnHide)
+		if(frame.SetStyle) then
+			SetDropDownStyle(frame, 2, -20, -2, 0)
+			frame.dropButton:ClearAllPoints()
+			frame.dropButton:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -2, 0)
+			if(SVUI and SVUI.API) then
+				SVUI.API:Set("PageButton", frame.dropButton, true)
+			end
+			frame.dropButton:SetParent(frame.Panel)
+		end
+
+		local bar = frame:CreateTexture(nil, "OVERLAY")
+			bar:SetPoint("TOPLEFT", frame,"TOPLEFT",6,-25)
+			bar:SetPoint("BOTTOMRIGHT", frame,"BOTTOMRIGHT", -21, 5)
+			bar:SetAlpha(0.5)
+		self.bar = bar
+
+		self.alignoffset = 31
+
+		self.OnRelease = OnRelease
+		self.OnAcquire = OnAcquire
+		self.ClearFocus = ClearFocus
+		self.SetText = SetText
+		self.SetValue = SetValue
+		self.GetValue = GetValue
+		self.SetList = SetList
+		self.SetLabel = SetLabel
+		self.SetDisabled = SetDisabled
+		self.AddItem = AddItem
+		self.SetMultiselect = SetMultiselect
+		self.GetMultiselect = GetMultiselect
+		self.SetItemValue = SetItemValue
+		self.SetItemDisabled = SetItemDisabled
+		self.ToggleDrop = ToggleDrop
+
+		AceGUI:RegisterAsWidget(self)
+		return self
+	end
+
+	AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion)
+
+end
diff --git a/SVUI_!Core/libs/CallbackHandler-1.0/CallbackHandler-1.0.lua b/SVUI_!Core/libs/CallbackHandler-1.0/CallbackHandler-1.0.lua
new file mode 100644
index 0000000..b489e9b
--- /dev/null
+++ b/SVUI_!Core/libs/CallbackHandler-1.0/CallbackHandler-1.0.lua
@@ -0,0 +1,237 @@
+--[[ $Id: CallbackHandler-1.0.lua 18 2014-10-16 02:52:20Z mikk $ ]]
+local MAJOR, MINOR = "CallbackHandler-1.0", 6
+local CallbackHandler = LibStub:NewLibrary(MAJOR, MINOR)
+
+if not CallbackHandler then return end -- No upgrade needed
+
+local meta = {__index = function(tbl, key) tbl[key] = {} return tbl[key] end}
+
+-- Lua APIs
+local tconcat = table.concat
+local assert, error, loadstring = assert, error, loadstring
+local setmetatable, rawset, rawget = setmetatable, rawset, rawget
+local next, select, pairs, type, tostring = next, select, pairs, type, tostring
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: geterrorhandler
+
+local xpcall = xpcall
+
+local function errorhandler(err)
+	return geterrorhandler()(err)
+end
+
+local function CreateDispatcher(argCount)
+	local code = [[
+	local next, xpcall, eh = ...
+
+	local method, ARGS
+	local function call() method(ARGS) end
+
+	local function dispatch(handlers, ...)
+		local index
+		index, method = next(handlers)
+		if not method then return end
+		local OLD_ARGS = ARGS
+		ARGS = ...
+		repeat
+			xpcall(call, eh)
+			index, method = next(handlers, index)
+		until not method
+		ARGS = OLD_ARGS
+	end
+
+	return dispatch
+	]]
+
+	local ARGS, OLD_ARGS = {}, {}
+	for i = 1, argCount do ARGS[i], OLD_ARGS[i] = "arg"..i, "old_arg"..i end
+	code = code:gsub("OLD_ARGS", tconcat(OLD_ARGS, ", ")):gsub("ARGS", tconcat(ARGS, ", "))
+	return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(next, xpcall, errorhandler)
+end
+
+local Dispatchers = setmetatable({}, {__index=function(self, argCount)
+	local dispatcher = CreateDispatcher(argCount)
+	rawset(self, argCount, dispatcher)
+	return dispatcher
+end})
+
+--------------------------------------------------------------------------
+-- CallbackHandler:New
+--
+--   target            - target object to embed public APIs in
+--   RegisterName      - name of the callback registration API, default "RegisterCallback"
+--   UnregisterName    - name of the callback unregistration API, default "UnregisterCallback"
+--   UnregisterAllName - name of the API to unregister all callbacks, default "UnregisterAllCallbacks". false == don't publish this API.
+
+function CallbackHandler:New(target, RegisterName, UnregisterName, UnregisterAllName)
+
+	RegisterName = RegisterName or "RegisterCallback"
+	UnregisterName = UnregisterName or "UnregisterCallback"
+	if UnregisterAllName==nil then	-- false is used to indicate "don't want this method"
+		UnregisterAllName = "UnregisterAllCallbacks"
+	end
+
+	-- we declare all objects and exported APIs inside this closure to quickly gain access
+	-- to e.g. function names, the "target" parameter, etc
+
+
+	-- Create the registry object
+	local events = setmetatable({}, meta)
+	local registry = { recurse=0, events=events }
+
+	-- registry:Fire() - fires the given event/message into the registry
+	function registry:Fire(eventname, ...)
+		if not rawget(events, eventname) or not next(events[eventname]) then return end
+		local oldrecurse = registry.recurse
+		registry.recurse = oldrecurse + 1
+
+		Dispatchers[select('#', ...) + 1](events[eventname], eventname, ...)
+
+		registry.recurse = oldrecurse
+
+		if registry.insertQueue and oldrecurse==0 then
+			-- Something in one of our callbacks wanted to register more callbacks; they got queued
+			for eventname,callbacks in pairs(registry.insertQueue) do
+				local first = not rawget(events, eventname) or not next(events[eventname])	-- test for empty before. not test for one member after. that one member may have been overwritten.
+				for self,func in pairs(callbacks) do
+					events[eventname][self] = func
+					-- fire OnUsed callback?
+					if first and registry.OnUsed then
+						registry.OnUsed(registry, target, eventname)
+						first = nil
+					end
+				end
+			end
+			registry.insertQueue = nil
+		end
+	end
+
+	-- Registration of a callback, handles:
+	--   self["method"], leads to self["method"](self, ...)
+	--   self with function ref, leads to functionref(...)
+	--   "addonId" (instead of self) with function ref, leads to functionref(...)
+	-- all with an optional arg, which, if present, gets passed as first argument (after self if present)
+	target[RegisterName] = function(self, eventname, method, ... --[[actually just a single arg]])
+		if type(eventname) ~= "string" then
+			error("Usage: "..RegisterName.."(eventname, method[, arg]): 'eventname' - string expected.", 2)
+		end
+
+		method = method or eventname
+
+		local first = not rawget(events, eventname) or not next(events[eventname])	-- test for empty before. not test for one member after. that one member may have been overwritten.
+
+		if type(method) ~= "string" and type(method) ~= "function" then
+			error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - string or function expected.", 2)
+		end
+
+		local regfunc
+
+		if type(method) == "string" then
+			-- self["method"] calling style
+			if type(self) ~= "table" then
+				error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): self was not a table?", 2)
+			elseif self==target then
+				error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): do not use Library:"..RegisterName.."(), use your own 'self'", 2)
+			elseif type(self[method]) ~= "function" then
+				error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - method '"..tostring(method).."' not found on self.", 2)
+			end
+
+			if select("#",...)>=1 then	-- this is not the same as testing for arg==nil!
+				local arg=select(1,...)
+				regfunc = function(...) self[method](self,arg,...) end
+			else
+				regfunc = function(...) self[method](self,...) end
+			end
+		else
+			-- function ref with self=object or self="addonId" or self=thread
+			if type(self)~="table" and type(self)~="string" and type(self)~="thread" then
+				error("Usage: "..RegisterName.."(self or \"addonId\", eventname, method): 'self or addonId': table or string or thread expected.", 2)
+			end
+
+			if select("#",...)>=1 then	-- this is not the same as testing for arg==nil!
+				local arg=select(1,...)
+				regfunc = function(...) method(arg,...) end
+			else
+				regfunc = method
+			end
+		end
+
+
+		if events[eventname][self] or registry.recurse<1 then
+		-- if registry.recurse<1 then
+			-- we're overwriting an existing entry, or not currently recursing. just set it.
+			events[eventname][self] = regfunc
+			-- fire OnUsed callback?
+			if registry.OnUsed and first then
+				registry.OnUsed(registry, target, eventname)
+			end
+		else
+			-- we're currently processing a callback in this registry, so delay the registration of this new entry!
+			-- yes, we're a bit wasteful on garbage, but this is a fringe case, so we're picking low implementation overhead over garbage efficiency
+			registry.insertQueue = registry.insertQueue or setmetatable({},meta)
+			registry.insertQueue[eventname][self] = regfunc
+		end
+	end
+
+	-- Unregister a callback
+	target[UnregisterName] = function(self, eventname)
+		if not self or self==target then
+			error("Usage: "..UnregisterName.."(eventname): bad 'self'", 2)
+		end
+		if type(eventname) ~= "string" then
+			error("Usage: "..UnregisterName.."(eventname): 'eventname' - string expected.", 2)
+		end
+		if rawget(events, eventname) and events[eventname][self] then
+			events[eventname][self] = nil
+			-- Fire OnUnused callback?
+			if registry.OnUnused and not next(events[eventname]) then
+				registry.OnUnused(registry, target, eventname)
+			end
+		end
+		if registry.insertQueue and rawget(registry.insertQueue, eventname) and registry.insertQueue[eventname][self] then
+			registry.insertQueue[eventname][self] = nil
+		end
+	end
+
+	-- OPTIONAL: Unregister all callbacks for given selfs/addonIds
+	if UnregisterAllName then
+		target[UnregisterAllName] = function(...)
+			if select("#",...)<1 then
+				error("Usage: "..UnregisterAllName.."([whatFor]): missing 'self' or \"addonId\" to unregister events for.", 2)
+			end
+			if select("#",...)==1 and ...==target then
+				error("Usage: "..UnregisterAllName.."([whatFor]): supply a meaningful 'self' or \"addonId\"", 2)
+			end
+
+
+			for i=1,select("#",...) do
+				local self = select(i,...)
+				if registry.insertQueue then
+					for eventname, callbacks in pairs(registry.insertQueue) do
+						if callbacks[self] then
+							callbacks[self] = nil
+						end
+					end
+				end
+				for eventname, callbacks in pairs(events) do
+					if callbacks[self] then
+						callbacks[self] = nil
+						-- Fire OnUnused callback?
+						if registry.OnUnused and not next(callbacks) then
+							registry.OnUnused(registry, target, eventname)
+						end
+					end
+				end
+			end
+		end
+	end
+
+	return registry
+end
+
+
+-- CallbackHandler purposefully does NOT do explicit embedding. Nor does it
+-- try to upgrade old implicit embeds since the system is selfcontained and
+-- relies on closures to work.
diff --git a/SVUI_!Core/libs/CallbackHandler-1.0/CallbackHandler-1.0.toc b/SVUI_!Core/libs/CallbackHandler-1.0/CallbackHandler-1.0.toc
new file mode 100644
index 0000000..9c19679
--- /dev/null
+++ b/SVUI_!Core/libs/CallbackHandler-1.0/CallbackHandler-1.0.toc
@@ -0,0 +1,10 @@
+## Interface: 60000
+## LoadOnDemand: 1
+## Title: Lib: CallbackHandler-1.0
+## Notes: Callback handling Library, normally embedded inside other libraries
+## Author: Ace3 Development Team
+## X-Website: http://www.wowace.com/projects/callbackhandler/
+## X-Category: Library
+## X-License: BSD-2.0
+
+CallbackHandler-1.0.lua
diff --git a/SVUI_!Core/libs/LibSharedMedia-3.0/LibSharedMedia-3.0.lua b/SVUI_!Core/libs/LibSharedMedia-3.0/LibSharedMedia-3.0.lua
new file mode 100644
index 0000000..f98cecd
--- /dev/null
+++ b/SVUI_!Core/libs/LibSharedMedia-3.0/LibSharedMedia-3.0.lua
@@ -0,0 +1,292 @@
+--[[
+Name: LibSharedMedia-3.0
+Revision: $Revision: 91 $
+Author: Elkano (elkano@gmx.de)
+Inspired By: SurfaceLib by Haste/Otravi (troeks@gmail.com)
+Website: http://www.wowace.com/projects/libsharedmedia-3-0/
+Description: Shared handling of media data (fonts, sounds, textures, ...) between addons.
+Dependencies: LibStub, CallbackHandler-1.0
+License: LGPL v2.1
+]]
+
+local MAJOR, MINOR = "LibSharedMedia-3.0", 6010002 -- 6.1.0 v2 / increase manually on changes
+local lib = LibStub:NewLibrary(MAJOR, MINOR)
+
+if not lib then return end
+
+local _G = getfenv(0)
+
+local pairs		= _G.pairs
+local type		= _G.type
+
+local band			= _G.bit.band
+
+local table_insert	= _G.table.insert
+local table_sort	= _G.table.sort
+
+local locale = GetLocale()
+local locale_is_western
+local LOCALE_MASK = 0
+lib.LOCALE_BIT_koKR		= 1
+lib.LOCALE_BIT_ruRU		= 2
+lib.LOCALE_BIT_zhCN		= 4
+lib.LOCALE_BIT_zhTW		= 8
+lib.LOCALE_BIT_western	= 128
+
+local CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0")
+
+lib.callbacks		= lib.callbacks			or CallbackHandler:New(lib)
+
+lib.DefaultMedia	= lib.DefaultMedia		or {}
+lib.MediaList		= lib.MediaList			or {}
+lib.MediaTable		= lib.MediaTable		or {}
+lib.MediaType		= lib.MediaType			or {}
+lib.OverrideMedia	= lib.OverrideMedia		or {}
+
+local defaultMedia = lib.DefaultMedia
+local mediaList = lib.MediaList
+local mediaTable = lib.MediaTable
+local overrideMedia = lib.OverrideMedia
+
+
+-- create mediatype constants
+lib.MediaType.BACKGROUND	= "background"			-- background textures
+lib.MediaType.BORDER		= "border"				-- border textures
+lib.MediaType.FONT			= "font"				-- fonts
+lib.MediaType.STATUSBAR		= "statusbar"			-- statusbar textures
+lib.MediaType.SOUND			= "sound"				-- sound files
+
+-- populate lib with default Blizzard data
+-- BACKGROUND
+if not lib.MediaTable.background then lib.MediaTable.background = {} end
+lib.MediaTable.background["None"]									= [[]]
+lib.MediaTable.background["Blizzard Collections Background"]		= [[Interface\Collections\CollectionsBackgroundTile]]
+lib.MediaTable.background["Blizzard Dialog Background"]				= [[Interface\DialogFrame\UI-DialogBox-Background]]
+lib.MediaTable.background["Blizzard Dialog Background Dark"]		= [[Interface\DialogFrame\UI-DialogBox-Background-Dark]]
+lib.MediaTable.background["Blizzard Dialog Background Gold"]		= [[Interface\DialogFrame\UI-DialogBox-Gold-Background]]
+lib.MediaTable.background["Blizzard Garrison Background"]			= [[Interface\Garrison\GarrisonUIBackground]]
+lib.MediaTable.background["Blizzard Garrison Background 2"]			= [[Interface\Garrison\GarrisonUIBackground2]]
+lib.MediaTable.background["Blizzard Garrison Background 3"]			= [[Interface\Garrison\GarrisonMissionUIInfoBoxBackgroundTile]]
+lib.MediaTable.background["Blizzard Low Health"]					= [[Interface\FullScreenTextures\LowHealth]]
+lib.MediaTable.background["Blizzard Marble"]						= [[Interface\FrameGeneral\UI-Background-Marble]]
+lib.MediaTable.background["Blizzard Out of Control"]				= [[Interface\FullScreenTextures\OutOfControl]]
+lib.MediaTable.background["Blizzard Parchment"]						= [[Interface\AchievementFrame\UI-Achievement-Parchment-Horizontal]]
+lib.MediaTable.background["Blizzard Parchment 2"]					= [[Interface\AchievementFrame\UI-GuildAchievement-Parchment-Horizontal]]
+lib.MediaTable.background["Blizzard Rock"]							= [[Interface\FrameGeneral\UI-Background-Rock]]
+lib.MediaTable.background["Blizzard Tabard Background"]				= [[Interface\TabardFrame\TabardFrameBackground]]
+lib.MediaTable.background["Blizzard Tooltip"]						= [[Interface\Tooltips\UI-Tooltip-Background]]
+lib.MediaTable.background["Solid"]									= [[Interface\Buttons\WHITE8X8]]
+lib.DefaultMedia.background = "None"
+
+-- BORDER
+if not lib.MediaTable.border then lib.MediaTable.border = {} end
+lib.MediaTable.border["None"]								= [[]]
+lib.MediaTable.border["Blizzard Achievement Wood"]			= [[Interface\AchievementFrame\UI-Achievement-WoodBorder]]
+lib.MediaTable.border["Blizzard Chat Bubble"]				= [[Interface\Tooltips\ChatBubble-Backdrop]]
+lib.MediaTable.border["Blizzard Dialog"]					= [[Interface\DialogFrame\UI-DialogBox-Border]]
+lib.MediaTable.border["Blizzard Dialog Gold"]				= [[Interface\DialogFrame\UI-DialogBox-Gold-Border]]
+lib.MediaTable.border["Blizzard Party"]						= [[Interface\CHARACTERFRAME\UI-Party-Border]]
+lib.MediaTable.border["Blizzard Tooltip"]					= [[Interface\Tooltips\UI-Tooltip-Border]]
+lib.DefaultMedia.border = "None"
+
+-- FONT
+if not lib.MediaTable.font then lib.MediaTable.font = {} end
+local SML_MT_font = lib.MediaTable.font
+--[[
+All font files are currently in all clients, the following table depicts which font supports which charset as of 5.0.4
+Fonts were checked using langcover.pl from DejaVu fonts (http://sourceforge.net/projects/dejavu/) and FontForge (http://fontforge.org/)
+latin means check for: de, en, es, fr, it, pt
+
+file				name							latin	koKR	ruRU	zhCN	zhTW
+2002.ttf			2002							X		X		X		-		-
+2002B.ttf			2002 Bold						X		X		X		-		-
+ARHei.ttf			AR CrystalzcuheiGBK Demibold	X		-		X		X		X
+ARIALN.TTF			Arial Narrow					X		-		X		-		-
+ARKai_C.ttf			AR ZhongkaiGBK Medium (Combat)	X		-		X		X		X
+ARKai_T.ttf			AR ZhongkaiGBK Medium			X		-		X		X		X
+bHEI00M.ttf			AR Heiti2 Medium B5				-		-		-		-		X
+bHEI01B.ttf			AR Heiti2 Bold B5				-		-		-		-		X
+bKAI00M.ttf			AR Kaiti Medium B5				-		-		-		-		X
+bLEI00D.ttf			AR Leisu Demi B5				-		-		-		-		X
+FRIZQT__.TTF		Friz Quadrata TT				X		-		-		-		-
+FRIZQT___CYR.TTF	FrizQuadrataCTT					x		-		X		-		-
+K_Damage.TTF		YDIWingsM						-		X		X		-		-
+K_Pagetext.TTF		MoK								X		X		X		-		-
+MORPHEUS.TTF		Morpheus						X		-		-		-		-
+MORPHEUS_CYR.TTF	Morpheus						X		-		X		-		-
+NIM_____.ttf		Nimrod MT						X		-		X		-		-
+SKURRI.TTF			Skurri							X		-		-		-		-
+SKURRI_CYR.TTF		Skurri							X		-		X		-		-
+
+WARNING: Although FRIZQT___CYR is available on western clients, it doesn't support special European characters e.g. é, ï, ö
+Due to this, we cannot use it as a replacement for FRIZQT__.TTF
+]]
+
+if locale == "koKR" then
+	LOCALE_MASK = lib.LOCALE_BIT_koKR
+--
+	SML_MT_font["굵은 글꼴"]		= [[Fonts\2002B.TTF]]
+	SML_MT_font["기본 글꼴"]		= [[Fonts\2002.TTF]]
+	SML_MT_font["데미지 글꼴"]		= [[Fonts\K_Damage.TTF]]
+	SML_MT_font["퀘스트 글꼴"]		= [[Fonts\K_Pagetext.TTF]]
+--
+	lib.DefaultMedia["font"] = "기본 글꼴" -- someone from koKR please adjust if needed
+--
+elseif locale == "zhCN" then
+	LOCALE_MASK = lib.LOCALE_BIT_zhCN
+--
+	SML_MT_font["伤害数字"]		= [[Fonts\ARKai_C.ttf]]
+	SML_MT_font["默认"]			= [[Fonts\ARKai_T.ttf]]
+	SML_MT_font["聊天"]			= [[Fonts\ARHei.ttf]]
+--
+	lib.DefaultMedia["font"] = "默认" -- someone from zhCN please adjust if needed
+--
+elseif locale == "zhTW" then
+	LOCALE_MASK = lib.LOCALE_BIT_zhTW
+--
+	SML_MT_font["提示訊息"]		= [[Fonts\bHEI00M.ttf]]
+	SML_MT_font["聊天"]			= [[Fonts\bHEI01B.ttf]]
+	SML_MT_font["傷害數字"]		= [[Fonts\bKAI00M.ttf]]
+	SML_MT_font["預設"]			= [[Fonts\bLEI00D.ttf]]
+--
+	lib.DefaultMedia["font"] = "預設" -- someone from zhTW please adjust if needed
+
+elseif locale == "ruRU" then
+	LOCALE_MASK = lib.LOCALE_BIT_ruRU
+--
+	SML_MT_font["2002"]								= [[Fonts\2002.TTF]]
+	SML_MT_font["2002 Bold"]						= [[Fonts\2002B.TTF]]
+	SML_MT_font["AR CrystalzcuheiGBK Demibold"]		= [[Fonts\ARHei.TTF]]
+	SML_MT_font["AR ZhongkaiGBK Medium (Combat)"]	= [[Fonts\ARKai_C.TTF]]
+	SML_MT_font["AR ZhongkaiGBK Medium"]			= [[Fonts\ARKai_T.TTF]]
+	SML_MT_font["Arial Narrow"]						= [[Fonts\ARIALN.TTF]]
+	SML_MT_font["Friz Quadrata TT"]					= [[Fonts\FRIZQT___CYR.TTF]]
+	SML_MT_font["MoK"]								= [[Fonts\K_Pagetext.TTF]]
+	SML_MT_font["Morpheus"]							= [[Fonts\MORPHEUS_CYR.TTF]]
+	SML_MT_font["Nimrod MT"]						= [[Fonts\NIM_____.ttf]]
+	SML_MT_font["Skurri"]							= [[Fonts\SKURRI_CYR.TTF]]
+--
+	lib.DefaultMedia.font = "Friz Quadrata TT"
+--
+else
+	LOCALE_MASK = lib.LOCALE_BIT_western
+	locale_is_western = true
+--
+	SML_MT_font["2002"]								= [[Fonts\2002.TTF]]
+	SML_MT_font["2002 Bold"]						= [[Fonts\2002B.TTF]]
+	SML_MT_font["AR CrystalzcuheiGBK Demibold"]		= [[Fonts\ARHei.TTF]]
+	SML_MT_font["AR ZhongkaiGBK Medium (Combat)"]	= [[Fonts\ARKai_C.TTF]]
+	SML_MT_font["AR ZhongkaiGBK Medium"]			= [[Fonts\ARKai_T.TTF]]
+	SML_MT_font["Arial Narrow"]						= [[Fonts\ARIALN.TTF]]
+	SML_MT_font["Friz Quadrata TT"]					= [[Fonts\FRIZQT__.TTF]]
+	SML_MT_font["MoK"]								= [[Fonts\K_Pagetext.TTF]]
+	SML_MT_font["Morpheus"]							= [[Fonts\MORPHEUS_CYR.TTF]]
+	SML_MT_font["Nimrod MT"]						= [[Fonts\NIM_____.ttf]]
+	SML_MT_font["Skurri"]							= [[Fonts\SKURRI_CYR.TTF]]
+--
+	lib.DefaultMedia.font = "Friz Quadrata TT"
+--
+end
+
+-- STATUSBAR
+if not lib.MediaTable.statusbar then lib.MediaTable.statusbar = {} end
+lib.MediaTable.statusbar["Blizzard"]						= [[Interface\TargetingFrame\UI-StatusBar]]
+lib.MediaTable.statusbar["Blizzard Character Skills Bar"]	= [[Interface\PaperDollInfoFrame\UI-Character-Skills-Bar]]
+lib.MediaTable.statusbar["Blizzard Raid Bar"]				= [[Interface\RaidFrame\Raid-Bar-Hp-Fill]]
+lib.DefaultMedia.statusbar = "Blizzard"
+
+-- SOUND
+if not lib.MediaTable.sound then lib.MediaTable.sound = {} end
+lib.MediaTable.sound["None"]								= [[Interface\Quiet.ogg]]	-- Relies on the fact that PlaySound[File] doesn't error on non-existing input.
+lib.DefaultMedia.sound = "None"
+
+local function rebuildMediaList(mediatype)
+	local mtable = mediaTable[mediatype]
+	if not mtable then return end
+	if not mediaList[mediatype] then mediaList[mediatype] = {} end
+	local mlist = mediaList[mediatype]
+	-- list can only get larger, so simply overwrite it
+	local i = 0
+	for k in pairs(mtable) do
+		i = i + 1
+		mlist[i] = k
+	end
+	table_sort(mlist)
+end
+
+function lib:Register(mediatype, key, data, langmask)
+	if type(mediatype) ~= "string" then
+		error(MAJOR..":Register(mediatype, key, data, langmask) - mediatype must be string, got "..type(mediatype))
+	end
+	if type(key) ~= "string" then
+		error(MAJOR..":Register(mediatype, key, data, langmask) - key must be string, got "..type(key))
+	end
+	mediatype = mediatype:lower()
+	if mediatype == lib.MediaType.FONT and ((langmask and band(langmask, LOCALE_MASK) == 0) or not (langmask or locale_is_western)) then return false end
+	if mediatype == lib.MediaType.SOUND and type(data) == "string" then
+		local path = data:lower()
+		-- Only ogg and mp3 are valid sounds.
+		if not path:find(".ogg", nil, true) and not path:find(".mp3", nil, true) then
+			return false
+		end
+	end
+	if not mediaTable[mediatype] then mediaTable[mediatype] = {} end
+	local mtable = mediaTable[mediatype]
+	if mtable[key] then return false end
+
+	mtable[key] = data
+	rebuildMediaList(mediatype)
+	self.callbacks:Fire("LibSharedMedia_Registered", mediatype, key)
+	return true
+end
+
+function lib:Fetch(mediatype, key, noDefault)
+	local mtt = mediaTable[mediatype]
+	local overridekey = overrideMedia[mediatype]
+	local result = mtt and ((overridekey and mtt[overridekey] or mtt[key]) or (not noDefault and defaultMedia[mediatype] and mtt[defaultMedia[mediatype]])) or nil
+	return result ~= "" and result or nil
+end
+
+function lib:IsValid(mediatype, key)
+	return mediaTable[mediatype] and (not key or mediaTable[mediatype][key]) and true or false
+end
+
+function lib:HashTable(mediatype)
+	return mediaTable[mediatype]
+end
+
+function lib:List(mediatype)
+	if not mediaTable[mediatype] then
+		return nil
+	end
+	if not mediaList[mediatype] then
+		rebuildMediaList(mediatype)
+	end
+	return mediaList[mediatype]
+end
+
+function lib:GetGlobal(mediatype)
+	return overrideMedia[mediatype]
+end
+
+function lib:SetGlobal(mediatype, key)
+	if not mediaTable[mediatype] then
+		return false
+	end
+	overrideMedia[mediatype] = (key and mediaTable[mediatype][key]) and key or nil
+	self.callbacks:Fire("LibSharedMedia_SetGlobal", mediatype, overrideMedia[mediatype])
+	return true
+end
+
+function lib:GetDefault(mediatype)
+	return defaultMedia[mediatype]
+end
+
+function lib:SetDefault(mediatype, key)
+	if mediaTable[mediatype] and mediaTable[mediatype][key] and not defaultMedia[mediatype] then
+		defaultMedia[mediatype] = key
+		return true
+	else
+		return false
+	end
+end
diff --git a/SVUI_!Core/libs/LibSharedMedia-3.0/LibSharedMedia-3.0.toc b/SVUI_!Core/libs/LibSharedMedia-3.0/LibSharedMedia-3.0.toc
new file mode 100644
index 0000000..a1fe837
--- /dev/null
+++ b/SVUI_!Core/libs/LibSharedMedia-3.0/LibSharedMedia-3.0.toc
@@ -0,0 +1,18 @@
+## Interface: 70000
+## LoadOnDemand: 1
+## X-Curse-Packaged-Version: 6.1.0 - r92
+## X-Curse-Project-Name: LibSharedMedia-3.0
+## X-Curse-Project-ID: libsharedmedia-3-0
+## X-Curse-Repository-ID: wow/libsharedmedia-3-0/mainline
+
+## Title: Lib: SharedMedia-3.0
+## Notes: Shared handling of media data (fonts, sounds, textures, ...) between addons.
+## Author: Elkano
+## Version: 3.0-91
+## X-Website: http://www.wowace.com/projects/libsharedmedia-3-0/
+## X-Category: Library
+
+## X-Revision: 91
+## X-Date: 2015-02-27T01:36:14Z
+
+LibSharedMedia-3.0\LibSharedMedia-3.0.lua
diff --git a/SVUI_!Core/libs/_Librarian/Librarian.lua b/SVUI_!Core/libs/_Librarian/Librarian.lua
new file mode 100644
index 0000000..12303f2
--- /dev/null
+++ b/SVUI_!Core/libs/_Librarian/Librarian.lua
@@ -0,0 +1,173 @@
+--- Librarian lib management library.
+-- Librarian is a versioning manager for use with proprietary SVUI libraries.
+-- @file Librarian
+-- @author Steven Jackson (2014)
+-- @release 1.0.0
+
+--[[
+@usage
+Librarian is a library used to manage localization, packages, scripts, animations and data embedded
+into the SVUI core addon.
+
+It's main purpose is to keep all methods and logic needed to properly keep
+core add-ins functioning outside of the core object.
+
+It is also modifyiing LibStub to give me dominating control over which libraries are
+allowed to be created and loaded regardless of versioning or timing.
+
+The reasoning for this is due to the potential for other addon to get loaded earlier
+and embed newer versions of lib dependencies which can be devastating.
+--]]
+local _G            = getfenv(0)
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local ipairs        = _G.ipairs;
+local loadstring    = _G.loadstring;
+local setmetatable  = _G.setmetatable;
+local rawset        = _G.rawset;
+local rawget        = _G.rawget;
+local tostring      = _G.tostring;
+local tonumber      = _G.tonumber;
+local tostring      = _G.tostring;
+local xpcall        = _G.xpcall;
+local table         = _G.table;
+local tconcat       = table.concat;
+local tremove       = table.remove;
+local strmatch      = _G.strmatch;
+local table_sort    = table.sort;
+local bit           = _G.bit;
+local band          = bit.band;
+local math          = _G.math;
+local min,max,abs   = math.min,math.max,math.abs;
+
+local UIParent = _G.UIParent;
+local GetScreenWidth = _G.GetScreenWidth;
+local GetScreenHeight = _G.GetScreenHeight;
+local IsAltKeyDown = _G.IsAltKeyDown;
+
+local MAX_MINOR     = 999999999;
+local Librarian     = _G.Librarian;
+
+if not Librarian then
+    ---------------------------------------------------------------------
+    -- Global Librarian object.
+    -- @todo Does this need to be global?
+    ---------------------------------------------------------------------
+
+    Librarian = { libs = {} };
+
+    _G.Librarian = Librarian;
+
+    ---------------------------------------------------------------------
+    -- Adds a new lib to saved objects.
+    -- @return Lib class object
+    -- @param libName hashable name of the new library.
+    ---------------------------------------------------------------------
+
+    function Librarian:NewLibrary(libName)
+        assert(type(libName) == "string", "Missing Library Name")
+        self.libs[libName] = self.libs[libName] or {}
+        return self.libs[libName]
+    end
+
+    ---------------------------------------------------------------------
+    -- Retrieve a saved library object.
+    -- @return Lib class object
+    -- @param libName Saved name of the library.
+    -- @param silent do not allow errors to propegate.
+    ---------------------------------------------------------------------
+
+    function Librarian:Fetch(libName, silent)
+        if not self.libs[libName] and not silent then
+            error(("Cannot find a library instance of %q."):format(tostring(libName)), 2)
+        end
+        return self.libs[libName]
+    end
+
+    setmetatable(Librarian, { __call = Librarian.Fetch })
+end
+
+local LibStub = _G.LibStub;
+local dead = function() return end
+
+if not LibStub then
+    LibStub         = {libs = {}, minors = {}};
+    _G.LibStub      = LibStub;
+
+    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
+
+local LibStubNew = function(self, major, minor, replace)
+    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(replace) then
+        minor = MAX_MINOR
+    end
+    if(oldminor and oldminor >= minor) then return nil end
+    self.libs[major] = self.libs[major] or {}
+    self.minors[major] = minor
+    --print('Returning: '..major..' v.'..minor)
+    return self.libs[major], oldminor
+end
+
+local LibStubKill = function(self, major, silent)
+    if not self.libs[major] and not silent then
+        error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
+    end
+    for key,obj in pairs(self.libs) do
+        if(key:find(tostring(major))) then
+            self.libs[key] = nil
+        end
+    end
+end
+
+local LibStubLock = function(self, major, silent)
+    if(self.locked[major]) then return end
+    for key,obj in pairs(self.libs) do
+        if(key:find(tostring(major)) and (not self.recovery[key])) then
+            self.locked[major] = true
+            self.recovery[key] = {}
+            for k,v in pairs(obj) do
+                if(type(v) == 'function') then
+                    self.recovery[key][k] = v
+                    v = dead
+                end
+            end
+        end
+    end
+end
+
+local LibStubUnlock = function(self, major, silent)
+    if(not self.locked[major]) then return end
+    for key,obj in pairs(self.libs) do
+        if(key:find(tostring(major)) and (self.recovery[key])) then
+            for k,v in pairs(self.recovery[key]) do
+                obj[k] = v
+            end
+            self.locked[major] = nil
+            self.recovery[key] = nil
+        end
+    end
+end
+
+LibStub.minor       = MAX_MINOR;
+LibStub.recovery    = {};
+LibStub.locked      = {};
+LibStub.NewLibrary  = LibStubNew;
+LibStub.Kill        = LibStubKill;
+LibStub.Lock        = LibStubLock;
+LibStub.Unlock      = LibStubUnlock;
diff --git a/SVUI_!Core/libs/_SVUI_Lib/Animate.lua b/SVUI_!Core/libs/_SVUI_Lib/Animate.lua
new file mode 100644
index 0000000..41895d5
--- /dev/null
+++ b/SVUI_!Core/libs/_SVUI_Lib/Animate.lua
@@ -0,0 +1,507 @@
+--[[
+  /$$$$$$            /$$                           /$$
+ /$$__  $$          |__/                          | $$
+| $$  \ $$ /$$$$$$$  /$$ /$$$$$$/$$$$   /$$$$$$  /$$$$$$    /$$$$$$
+| $$$$$$$$| $$__  $$| $$| $$_  $$_  $$ |____  $$|_  $$_/   /$$__  $$
+| $$__  $$| $$  \ $$| $$| $$ \ $$ \ $$  /$$$$$$$  | $$    | $$$$$$$$
+| $$  | $$| $$  | $$| $$| $$ | $$ | $$ /$$__  $$  | $$ /$$| $$_____/
+| $$  | $$| $$  | $$| $$| $$ | $$ | $$|  $$$$$$$  |  $$$$/|  $$$$$$$
+|__/  |__/|__/  |__/|__/|__/ |__/ |__/ \_______/   \___/   \_______/
+--]]
+
+--[[ LOCALIZED GLOBALS ]]--
+--GLOBAL NAMESPACE
+local _G = getfenv(0);
+--LUA
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pcall         = _G.pcall;
+--BLIZZARD API
+local UIParent          = _G.UIParent;
+local UIFrameFadeOut    = _G.UIFrameFadeOut;
+local FlickerAlpha      = {0.2,0.15,0.1,0.15,0.2,0.15,0.1,0.15}
+--[[ LIB CONSTRUCT ]]--
+
+local lib = Librarian:NewLibrary("Animate")
+
+if not lib then return end -- No upgrade needed
+
+local MANAGED_ANIMATIONS = {
+    ["Orbit"] = true,
+    ["Sprite4"] = true,
+    ["Sprite8"] = true,
+    ["StopSprite"] = false,
+    ["Pulse"] = false,
+    ["Kapow"] = false,
+    ["Flash"] = false,
+    ["StopFlash"] = false,
+    ["Slide"] = false,
+    ["SlideIn"] = false,
+    ["SlideOut"] = false,
+    ["RandomSlide"] = false,
+};
+
+--[[ LOCAL FUNCTIONS ]]--
+
+local Anim_OnShow = function(self)
+    if self.anim:IsPlaying() then
+        self.anim:Finish()
+    end
+    self.anim:Play()
+end
+
+local Anim_OnHide = function(self)
+    self.anim:Finish()
+end
+
+local Anim_OnPlay = function(self)
+    local parent = self.parent
+    parent:SetAlpha(1)
+    if self.hideOnFinished and not parent:IsShown() then
+        parent:Show()
+    end
+end
+
+local Anim_OnStop = function(self)
+    local parent = self.parent
+    if self.fadeOnFinished then
+        parent:SetAlpha(0)
+    end
+    if self.hideOnFinished and parent:IsShown() then
+        parent:Hide()
+    end
+    if self.startscale then
+        parent:SetScale(1)
+        self.startscale = 1
+    end
+end
+
+local Anim_OnFinished = function(self)
+    local parent = self.parent
+    local looped = self:GetLooping()
+    self:Stop()
+    if(looped and looped == "REPEAT" and parent:IsShown()) then
+        self:Play()
+    end
+end
+
+local Sprite4_OnUpdate = function(self)
+    local order = self:GetOrder()
+    local parent = self.parent
+    local left, right;
+    if(self.isFadeFrame) then
+        parent:SetAlpha(0)
+        return
+    end
+    left = (order - 1) * 0.25;
+    right = left + 0.25;
+    parent:SetTexCoord(left,right,0,1)
+    if parent.overlay then
+        parent.overlay:SetTexCoord(left,right,0,1)
+        parent.overlay:SetVertexColor(1,1,1,FlickerAlpha[order])
+    end
+end
+
+local Sprite8_OnUpdate = function(self)
+    local order = self:GetOrder()
+    local parent = self.parent
+    local left, right;
+    if(self.isFadeFrame) then
+        parent:SetAlpha(0)
+        return
+    end
+    left = (order - 1) * 0.125;
+    right = left + 0.125;
+    parent:SetTexCoord(left,right,0,1)
+    if parent.overlay then
+        parent.overlay:SetTexCoord(left,right,0,1)
+        parent.overlay:SetVertexColor(1,1,1,FlickerAlpha[order])
+    end
+end
+
+local Pulse_OnPlay = function(self)
+    local parent = self.parent
+    parent:SetAlpha(1)
+    parent:SetScale(1)
+end
+
+local Pulse_OnUpdate1 = function(self)
+    local parent = self.parent
+    local step = self:GetProgress()
+    parent:SetScale(1 + (1.05 * step))
+end
+
+local Pulse_OnUpdate2 = function(self)
+    local parent = self.parent
+    local step = self:GetProgress()
+    parent:SetScale(1 + (1.05 * (1 - step)))
+end
+
+local Kapow_OnUpdate1 = function(self)
+    local parent = self.parent
+    local step = self:GetProgress()
+    if(not parent.startscale) then
+        parent.startscale = parent:GetScale()
+    end
+    local scale = parent.startscale
+    parent:SetAlpha(1)
+    parent:SetScale(scale + (1.05 * step))
+end
+
+local Kapow_OnUpdate2 = function(self)
+    local parent = self.parent
+    local step = self:GetProgress()
+    UIFrameFadeOut(parent, 0.3, 1, 0)
+end
+
+local Kapow_OnUpdate2Special = function(self)
+    local parent = self.parent
+    local step = self:GetProgress()
+    local scale = 1
+    if(parent.startscale) then
+        scale = scale * parent.startscale
+    end
+    parent:SetScale(scale + (1.05 * (scale - step)))
+end
+
+local Slide_OnUpdate = function(self)
+    local parent = self.parent
+    local step = self:GetProgress()
+    parent:SetScale(1 + (1.05 * step))
+end
+
+local Slide_OnPlay = function(self)
+    local parent = self.parent
+    parent:SetScale(0.01)
+    parent:SetAlpha(1)
+end
+
+local Slide_FadeStart = function(self)
+    local parent = self.parent
+    UIFrameFadeOut(parent, 0.3, 1, 0)
+end
+
+local Slide_FadeStop = function(self)
+    self.parent:SetAlpha(0)
+end
+
+--[[ HELPER FUNCTION ]]--
+
+local function SetNewAnimation(frame, animType)
+    local anim = frame:CreateAnimation(animType)
+    anim.parent = frame.parent
+    return anim
+end
+
+--[[ LIB METHODS ]]--
+
+local function AnimationTemplate(frame, animType, hideOnFinished, speed, special, scriptToParent, noShowHide)
+    if(not frame or not animType) then return end
+
+    frame.anim = frame:CreateAnimationGroup(animType)
+    frame.anim.parent = frame;
+    frame.anim.hideOnFinished = hideOnFinished
+
+    if(MANAGED_ANIMATIONS[animType]) then
+        if(animType ~= 'Pulse' and animType ~= 'Kapow') then
+            frame.anim:SetScript("OnPlay", Anim_OnPlay)
+        end
+        if(animType ~= 'Kapow' or (animType == 'Kapow' and (not special))) then
+            frame.anim:SetScript("OnFinished", Anim_OnFinished)
+            frame.anim:SetScript("OnStop", Anim_OnStop)
+        end
+    end
+
+    if(not noShowHide) then
+        if(scriptToParent) then
+            local frameParent = frame:GetParent();
+            if(frameParent.SetScript) then
+                frameParent.anim = frame.anim;
+                frameParent:SetScript("OnShow", Anim_OnShow)
+                frameParent:SetScript("OnHide", Anim_OnHide)
+            end
+        elseif(frame.SetScript) then
+            frame:SetScript("OnShow", Anim_OnShow)
+            frame:SetScript("OnHide", Anim_OnHide)
+        end
+    end
+
+    if(animType == 'Flash') then
+        frame.anim.fadeOnFinished = true
+        if not speed then speed = 0.33 end
+
+        frame.anim[1] = SetNewAnimation(frame.anim, "Alpha")
+        frame.anim[1]:SetFromAlpha(0)
+        frame.anim[1]:SetToAlpha(1)
+        frame.anim[1]:SetOrder(2)
+        frame.anim[1]:SetDuration(speed)
+
+        frame.anim[2] = SetNewAnimation(frame.anim, "Alpha")
+        frame.anim[2]:SetFromAlpha(1)
+        frame.anim[2]:SetToAlpha(0)
+        frame.anim[2]:SetOrder(1)
+        frame.anim[2]:SetDuration(speed)
+
+        if special then
+            frame.anim:SetLooping("REPEAT")
+        end
+    elseif(animType == 'Orbit') then
+        frame.anim[1] = SetNewAnimation(frame.anim, "Rotation")
+        if special then
+            frame.anim[1]:SetDegrees(-360)
+        else
+            frame.anim[1]:SetDegrees(360)
+        end
+        frame.anim[1]:SetDuration(speed)
+        frame.anim:SetLooping("REPEAT")
+        frame.anim:Play()
+    elseif(animType == 'Sprite4') then
+        frame.anim[1] = SetNewAnimation(frame.anim, "Translation")
+        frame.anim[1]:SetOrder(1)
+        frame.anim[1]:SetDuration(speed)
+        frame.anim[1]:SetScript("OnUpdate", Sprite4_OnUpdate)
+
+        frame.anim[2] = SetNewAnimation(frame.anim, "Translation")
+        frame.anim[2]:SetOrder(2)
+        frame.anim[2]:SetDuration(speed)
+        frame.anim[2]:SetScript("OnUpdate", Sprite4_OnUpdate)
+
+        frame.anim[3] = SetNewAnimation(frame.anim, "Translation")
+        frame.anim[3]:SetOrder(3)
+        frame.anim[3]:SetDuration(speed)
+        frame.anim[3]:SetScript("OnUpdate", Sprite4_OnUpdate)
+
+        frame.anim[4] = SetNewAnimation(frame.anim, "Translation")
+        frame.anim[4]:SetOrder(4)
+        frame.anim[4]:SetDuration(speed)
+        frame.anim[4]:SetScript("OnUpdate", Sprite4_OnUpdate)
+
+        if special then
+            frame.anim[5] = SetNewAnimation(frame.anim, "Translation")
+            frame.anim[5]:SetOrder(5)
+            frame.anim[5]:SetDuration(special)
+            frame.anim[5].isFadeFrame = true;
+            frame.anim[5]:SetScript("OnUpdate", Sprite4_OnUpdate)
+        end
+        if(not hideOnFinished) then
+            frame.anim:SetLooping("REPEAT")
+        end
+    elseif(animType == 'Sprite8') then
+        frame.anim[1] = SetNewAnimation(frame.anim, "Translation")
+        frame.anim[1]:SetOrder(1)
+        frame.anim[1]:SetDuration(speed)
+        frame.anim[1]:SetScript("OnUpdate", Sprite8_OnUpdate)
+
+        frame.anim[2] = SetNewAnimation(frame.anim, "Translation")
+        frame.anim[2]:SetOrder(2)
+        frame.anim[2]:SetDuration(speed)
+        frame.anim[2]:SetScript("OnUpdate", Sprite8_OnUpdate)
+
+        frame.anim[3] = SetNewAnimation(frame.anim, "Translation")
+        frame.anim[3]:SetOrder(3)
+        frame.anim[3]:SetDuration(speed)
+        frame.anim[3]:SetScript("OnUpdate", Sprite8_OnUpdate)
+
+        frame.anim[4] = SetNewAnimation(frame.anim, "Translation")
+        frame.anim[4]:SetOrder(4)
+        frame.anim[4]:SetDuration(speed)
+        frame.anim[4]:SetScript("OnUpdate", Sprite8_OnUpdate)
+
+        frame.anim[5] = SetNewAnimation(frame.anim, "Translation")
+        frame.anim[5]:SetOrder(5)
+        frame.anim[5]:SetDuration(speed)
+        frame.anim[5]:SetScript("OnUpdate", Sprite8_OnUpdate)
+
+        frame.anim[6] = SetNewAnimation(frame.anim, "Translation")
+        frame.anim[6]:SetOrder(6)
+        frame.anim[6]:SetDuration(speed)
+        frame.anim[6]:SetScript("OnUpdate", Sprite8_OnUpdate)
+
+        frame.anim[7] = SetNewAnimation(frame.anim, "Translation")
+        frame.anim[7]:SetOrder(7)
+        frame.anim[7]:SetDuration(speed)
+        frame.anim[7]:SetScript("OnUpdate", Sprite8_OnUpdate)
+
+        frame.anim[8] = SetNewAnimation(frame.anim, "Translation")
+        frame.anim[8]:SetOrder(8)
+        frame.anim[8]:SetDuration(speed)
+        frame.anim[8]:SetScript("OnUpdate", Sprite8_OnUpdate)
+
+        if(special) then
+            frame.anim[9] = SetNewAnimation(frame.anim, "Translation")
+            frame.anim[9]:SetOrder(9)
+            frame.anim[9]:SetDuration(special)
+            frame.anim[9].isFadeFrame = true;
+            frame.anim[9]:SetScript("OnUpdate", Sprite4_OnUpdate)
+        end
+
+        if(not hideOnFinished) then
+            frame.anim:SetLooping("REPEAT")
+        end
+    elseif(animType == 'Pulse') then
+        frame.anim:SetScript("OnPlay", Pulse_OnPlay)
+
+        frame.anim[1] = SetNewAnimation(frame.anim)
+        frame.anim[1]:SetDuration(0.2)
+        frame.anim[1]:SetOrder(1)
+        frame.anim[1]:SetScript("OnUpdate", Pulse_OnUpdate1)
+
+        frame.anim[2] = SetNewAnimation(frame.anim)
+        frame.anim[2]:SetDuration(0.6)
+        frame.anim[2]:SetOrder(2)
+        frame.anim[2]:SetScript("OnUpdate", Pulse_OnUpdate2)
+    elseif(animType == 'Kapow') then
+        --frame.anim:SetScript("OnPlay", Kapow_OnPlay)
+
+        frame.anim.startscale = frame:GetScale()
+
+        frame.anim[1] = SetNewAnimation(frame.anim, "Rotation")
+        frame.anim[1]:SetDuration(0.2)
+        frame.anim[1]:SetOrder(1)
+        frame.anim[1]:SetDegrees(360)
+        frame.anim[1]:SetScript("OnUpdate", Kapow_OnUpdate1)
+
+        frame.anim[2] = SetNewAnimation(frame.anim)
+        frame.anim[2]:SetDuration(0.3)
+        frame.anim[2]:SetOrder(2)
+
+        if(not special) then
+            frame.anim[2]:SetScript("OnUpdate", Kapow_OnUpdate2)
+        else
+            frame.anim[2]:SetScript("OnUpdate", Kapow_OnUpdate2Special)
+        end
+    end
+end
+
+--[[ ROTATE AND WOBBLE (kinda like twerking i guess...) ]]--
+
+function lib:Orbit(frame, speed, reversed, hideOnFinished)
+    if not frame then return end
+    if not speed then speed = 1 end
+    AnimationTemplate(frame, 'Orbit', hideOnFinished, speed, reversed)
+end
+
+function lib:Pulse(frame, hideOnFinished)
+    if not frame then return end
+    AnimationTemplate(frame, 'Pulse', hideOnFinished)
+end
+
+function lib:Kapow(frame, hideOnFinished, noShowHide, noHide)
+    if not frame then return end
+    AnimationTemplate(frame, 'Kapow', hideOnFinished, nil, noHide, nil, noShowHide)
+end
+
+--[[ ANIMATED SPRITES ]]--
+
+function lib:Sprite4(frame, speed, fadeTime, scriptToParent)
+    if not frame then return end
+    speed = speed or 0.08;
+    AnimationTemplate(frame, 'Sprite4', false, speed, fadeTime, scriptToParent)
+end
+
+function lib:Sprite8(frame, speed, fadeTime, scriptToParent, hideOnFinished)
+    if not frame then return end
+    speed = speed or 0.08;
+    AnimationTemplate(frame, 'Sprite8', hideOnFinished, speed, fadeTime, scriptToParent)
+end
+
+function lib:StopSprite(frame)
+    if not frame then return end
+    frame.anim:Finish()
+end
+
+--[[ FLASHING ]]--
+
+function lib:Flash(frame, speed, looped)
+    if not frame.anim then
+        AnimationTemplate(frame, 'Flash', false, speed, looped)
+    end
+    if not frame.anim:IsPlaying() then
+        frame.anim:Play()
+    end
+end
+
+function lib:StopFlash(frame)
+    if not frame.anim then return end
+    frame.anim:Finish()
+    frame.anim:Stop()
+end
+
+--[[ SLIDING ]]--
+
+function lib:Slide(frame, xDirection, yDirection, bounce, extendedTime)
+    if(not frame or (frame and frame.anim)) then return end
+
+    frame.anim = frame:CreateAnimationGroup("Slide")
+    frame.anim.hideOnFinished = true;
+    frame.anim.parent = frame;
+    frame.anim:SetScript("OnPlay", Anim_OnPlay)
+    frame.anim:SetScript("OnFinished", Anim_OnFinished)
+    frame.anim:SetScript("OnStop", Anim_OnStop)
+
+    frame.anim[1] = SetNewAnimation(frame.anim, "Translation")
+    frame.anim[1]:SetDuration(0)
+    frame.anim[1]:SetOrder(1)
+
+    frame.anim[2] = SetNewAnimation(frame.anim, "Translation")
+    frame.anim[2]:SetDuration(0.3)
+    frame.anim[2]:SetOrder(2)
+    frame.anim[2]:SetSmoothing("OUT")
+
+    if bounce then
+        frame.anim[3] = SetNewAnimation(frame.anim, "Translation")
+        frame.anim[3]:SetDuration(extendedTime or 0.5)
+        frame.anim[3]:SetOrder(3)
+
+        frame.anim[4] = SetNewAnimation(frame.anim, "Translation")
+        frame.anim[4]:SetDuration(0.3)
+        frame.anim[4]:SetOrder(4)
+        frame.anim[4]:SetSmoothing("IN")
+        frame.anim[4]:SetOffset(xDirection, yDirection)
+    end
+end
+
+function lib:RandomSlide(frame, raised)
+    if not frame then return end
+    if raised then
+        frame:SetFrameLevel(30)
+    else
+        frame:SetFrameLevel(20)
+    end
+    frame:SetPoint("CENTER", UIParent, "CENTER", 0, -150)
+
+    frame.anim = frame:CreateAnimationGroup("RandomSlide")
+    frame.anim.parent = frame;
+    frame.anim[1] = SetNewAnimation(frame.anim, "Translation")
+    frame.anim[1]:SetOrder(1)
+    frame.anim[1]:SetDuration(0.1)
+    frame.anim[1]:SetScript("OnUpdate", Slide_OnUpdate)
+    frame.anim[1]:SetScript("OnPlay", Slide_OnPlay)
+
+    frame.anim[2] = SetNewAnimation(frame.anim, "Translation")
+    frame.anim[2]:SetOrder(2)
+    frame.anim[2]:SetDuration(1)
+
+    frame.anim[3] = SetNewAnimation(frame.anim, "Translation")
+    frame.anim[3]:SetOrder(3)
+    frame.anim[3]:SetDuration(0.3)
+    frame.anim[3]:SetSmoothing("OUT")
+    frame.anim[3]:SetScript("OnPlay", Slide_FadeStart)
+    frame.anim[3]:SetScript("OnStop", Slide_FadeStop)
+
+    frame.anim:SetScript("OnFinished", Slide_FadeStop)
+end
+
+function lib:SlideIn(frame)
+    if not frame.anim then return end
+    frame:Show()
+    frame.anim:Play()
+end
+
+function lib:SlideOut(frame)
+    if not frame.anim then return end
+    frame.anim:Finish()
+    frame.anim:Stop()
+end
diff --git a/SVUI_!Core/libs/_SVUI_Lib/Events.lua b/SVUI_!Core/libs/_SVUI_Lib/Events.lua
new file mode 100644
index 0000000..8e68cf2
--- /dev/null
+++ b/SVUI_!Core/libs/_SVUI_Lib/Events.lua
@@ -0,0 +1,197 @@
+--[[
+ /$$$$$$$$                              /$$
+| $$_____/                             | $$
+| $$    /$$    /$$ /$$$$$$  /$$$$$$$  /$$$$$$   /$$$$$$$
+| $$$$$|  $$  /$$//$$__  $$| $$__  $$|_  $$_/  /$$_____/
+| $$__/ \  $$/$$/| $$$$$$$$| $$  \ $$  | $$   |  $$$$$$
+| $$     \  $$$/ | $$_____/| $$  | $$  | $$ /$$\____  $$
+| $$$$$$$$\  $/  |  $$$$$$$| $$  | $$  |  $$$$//$$$$$$$/
+|________/ \_/    \_______/|__/  |__/   \___/ |_______/
+--]]
+
+--[[ LOCALIZED GLOBALS ]]--
+--GLOBAL NAMESPACE
+local _G = getfenv(0);
+--LUA
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pcall         = _G.pcall;
+local print         = _G.print;
+local ipairs        = _G.ipairs;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local rawset        = _G.rawset;
+local rawget        = _G.rawget;
+local tostring      = _G.tostring;
+local tonumber      = _G.tonumber;
+local getmetatable  = _G.getmetatable;
+local setmetatable  = _G.setmetatable;
+--STRING
+local string        = _G.string;
+local upper         = string.upper;
+local format        = string.format;
+local find          = string.find;
+local match         = string.match;
+local gsub          = string.gsub;
+--MATH
+local math          = _G.math;
+local floor         = math.floor
+--TABLE
+local table         = _G.table;
+local tsort         = table.sort;
+local tconcat       = table.concat;
+local tremove       = _G.tremove;
+local twipe         = _G.wipe;
+
+--[[ LIB CONSTRUCT ]]--
+
+local lib = Librarian:NewLibrary("Events")
+
+if not lib then return end -- No upgrade needed
+
+--[[ ADDON DATA ]]--
+
+local CoreName, CoreObject  = ...
+
+--[[ LIB CALLBACK STORAGE ]]--
+
+lib.Triggers = {};
+lib.FireOnce = {};
+lib.LockCallback = {};
+lib.UnlockCallback = {};
+
+--[[ EVENT TRIGGERING ]]--
+
+function lib:Trigger(eventName, ...)
+    if(not eventName) then return end;
+    --print(eventName)
+    if(self.Triggers[eventName]) then
+        for i=1, #self.Triggers[eventName] do
+            local fn = self.Triggers[eventName][i];
+            if(fn and type(fn) == "function") then
+                local _, catch = pcall(fn, ...)
+                if(catch) then
+                    CoreObject:HandleError("Librarian:Events:Trigger(" .. eventName .. "):", "callback", catch)
+                end
+            end
+        end
+    elseif(self.FireOnce[eventName]) then
+        for i=1, #self.FireOnce[eventName] do
+            local fn = self.FireOnce[eventName][i];
+            if(fn and type(fn) == "function") then
+                local _, catch = pcall(fn, ...)
+                if(catch) then
+                    CoreObject:HandleError("Librarian:Events:Trigger(" .. eventName .. "):", "callback", catch)
+                end
+            end
+        end
+
+        self.FireOnce[eventName] = nil;
+    end
+end
+
+function lib:TriggerOnce(eventName, ...)
+    if(not eventName) then return end;
+    if(self.Triggers[eventName]) then
+        for i=1, #self.Triggers[eventName] do
+            local fn = self.Triggers[eventName][i];
+            if(fn and type(fn) == "function") then
+                local _, catch = pcall(fn, ...)
+                if(catch) then
+                    CoreObject:HandleError("Librarian:Events:TriggerOnce(" .. eventName .. "):", "callback", catch)
+                end
+            end
+        end
+
+        self.Triggers[eventName] = nil;
+
+    elseif(self.FireOnce[eventName]) then
+        for i=1, #self.FireOnce[eventName] do
+            local fn = self.FireOnce[eventName][i];
+            if(fn and type(fn) == "function") then
+                local _, catch = pcall(fn, ...)
+                if(catch) then
+                    CoreObject:HandleError("Librarian:Events:TriggerOnce(" .. eventName .. "):", "callback", catch)
+                end
+            end
+        end
+
+        self.FireOnce[eventName] = nil;
+    end
+end
+
+--[[ REGISTRATION ]]--
+
+function lib:On(event, callback, always)
+    if((not event) or (not callback)) then return end;
+    if(type(callback) == "function") then
+        if(always) then
+            if(not self.Triggers[event]) then
+                self.Triggers[event] = {}
+            end
+            self.Triggers[event][#self.Triggers[event] + 1] = callback
+        else
+            if(not self.FireOnce[event]) then
+                self.FireOnce[event] = {}
+            end
+            self.FireOnce[event][#self.FireOnce[event] + 1] = callback
+        end
+    end
+end
+
+function lib:OnLock(callback)
+    if(callback and type(callback) == "function") then
+        self.LockCallback[#self.LockCallback + 1] = callback
+    end
+end
+
+function lib:OnUnlock(callback)
+    if(callback and type(callback) == "function") then
+        self.UnlockCallback[#self.UnlockCallback + 1] = callback
+    end
+end
+
+--[[ COMMON EVENTS ]]--
+
+function lib:PLAYER_REGEN_DISABLED(...)
+  for i=1, #self.LockCallback do
+      local fn = self.LockCallback[i]
+      if(fn and type(fn) == "function") then
+          local _, catch = pcall(fn, ...)
+          if(catch) then
+              CoreObject:HandleError("Librarian:Events:OnLock(PLAYER_REGEN_DISABLED):", "callback", catch)
+          end
+      end
+  end
+end
+
+function lib:PLAYER_REGEN_ENABLED(...)
+  for i=1, #self.UnlockCallback do
+      local fn = self.UnlockCallback[i]
+      if(fn and type(fn) == "function") then
+          local _, catch = pcall(fn, ...)
+          if(catch) then
+              CoreObject:HandleError("Librarian:Events:OnLock(PLAYER_REGEN_ENABLED):", "callback", catch)
+          end
+      end
+  end
+end
+
+--[[ EVENT DISTRIBUTION ]]--
+
+local Library_OnEvent = function(self, event, ...)
+  local fn = self[event]
+  if(fn and type(fn) == "function") then
+      local _, catch = pcall(fn, self, ...)
+      if(catch) then
+          CoreObject:HandleError("Librarian:Events:OnEvent", event, catch)
+      end
+  end
+end
+
+lib.EventManager = CreateFrame("Frame", nil)
+lib.EventManager:RegisterEvent("PLAYER_REGEN_DISABLED")
+lib.EventManager:RegisterEvent("PLAYER_REGEN_ENABLED")
+lib.EventManager:SetScript("OnEvent", Library_OnEvent)
diff --git a/SVUI_!Core/libs/_SVUI_Lib/External.lua b/SVUI_!Core/libs/_SVUI_Lib/External.lua
new file mode 100644
index 0000000..440bcbd
--- /dev/null
+++ b/SVUI_!Core/libs/_SVUI_Lib/External.lua
@@ -0,0 +1,76 @@
+--[[
+Librarian is a library used to manage localization, packages, scripts, animations and data embedded
+into the SVUI core addon.
+
+It's main purpose is to keep all methods and logic needed to properly keep
+core add-ins functioning outside of the core object.
+
+It is also modifyiing LibStub to give me dominating control over which libraries are
+allowed to be created and loaded regardless of versioning or timing.
+
+The reasoning for this is due to the potential for other addon to get loaded earlier
+and embed newer versions of lib dependencies which can be devastating.
+--]]
+local _G              = getfenv(0)
+local select          = _G.select;
+local assert          = _G.assert;
+local type            = _G.type;
+local error           = _G.error;
+local pairs           = _G.pairs;
+local next            = _G.next;
+local ipairs          = _G.ipairs;
+local loadstring      = _G.loadstring;
+local setmetatable    = _G.setmetatable;
+local rawset          = _G.rawset;
+local rawget          = _G.rawget;
+local tostring        = _G.tostring;
+local tonumber        = _G.tonumber;
+local tostring        = _G.tostring;
+local xpcall          = _G.xpcall;
+local table           = _G.table;
+local tconcat         = table.concat;
+local tremove         = table.remove;
+local strmatch        = _G.strmatch;
+local table_sort      = table.sort;
+local bit             = _G.bit;
+local band            = bit.band;
+local math            = _G.math;
+local min,max,abs     = math.min,math.max,math.abs;
+local LibStub         = _G.LibStub;
+local UIParent        = _G.UIParent;
+local GetScreenWidth  = _G.GetScreenWidth;
+local GetScreenHeight = _G.GetScreenHeight;
+local IsAltKeyDown    = _G.IsAltKeyDown;
+--[[
+The following are private and compressed versions of dependancy libraries
+--]]
+local MAX_MINOR         = 999999999;
+local WINDOW_MAJOR = "LibWindow-1.1";
+local WINDOW = LibStub:NewLibrary(WINDOW_MAJOR, MAX_MINOR, true);
+if(WINDOW) then
+    WINDOW.utilFrame = WINDOW.utilFrame or CreateFrame("Frame")
+    WINDOW.delayedSavePosition = WINDOW.delayedSavePosition or {}
+    WINDOW.windowData = WINDOW.windowData or {}
+    WINDOW.embeds = WINDOW.embeds or {}
+    local mixins = {}
+    local function a(b,c)local names=WINDOW.windowData[b].names;if names then if names[c]then return names[c]end;if names.prefix then return names.prefix..c end end;return c end;
+    local function d(b,c,e)WINDOW.windowData[b].storage[a(b,c)]=e end;
+    local function f(b,c)return WINDOW.windowData[b].storage[a(b,c)]end;
+    WINDOW.utilFrame:SetScript("OnUpdate",function(g)g:Hide()for b,h in pairs(WINDOW.delayedSavePosition)do WINDOW.delayedSavePosition[b]=nil;WINDOW.SavePosition(b)end end)
+    local function i(b)WINDOW.delayedSavePosition[b]=true;WINDOW.utilFrame:Show()end;
+    mixins["RegisterConfig"]=true;
+    function WINDOW.RegisterConfig(b,storage,names)if not WINDOW.windowData[b]then WINDOW.windowData[b]={}end;WINDOW.windowData[b].names=names;WINDOW.windowData[b].storage=storage end;local j={GetWidth=function()return GetScreenWidth()*UIParent:GetScale()end,GetHeight=function()return GetScreenHeight()*UIParent:GetScale()end,GetScale=function()return 1 end}mixins["SavePosition"]=true;
+    function WINDOW.SavePosition(b)local k=b:GetParent()if not k then k=j elseif k~=UIParent then return end;local l=b:GetScale()local m,n=b:GetLeft()*l,b:GetTop()*l;local o,p=b:GetRight()*l,b:GetBottom()*l;local q,r=k:GetWidth(),k:GetHeight()local s,t,u;if m<q-o and m<abs((m+o)/2-q/2)then s=m;u="LEFT"elseif q-o<abs((m+o)/2-q/2)then s=o-q;u="RIGHT"else s=(m+o)/2-q/2;u=""end;if p<r-n and p<abs((p+n)/2-r/2)then t=p;u="BOTTOM"..u elseif r-n<abs((p+n)/2-r/2)then t=n-r;u="TOP"..u else t=(p+n)/2-r/2 end;if u==""then u="CENTER"end;d(b,"x",s)d(b,"y",t)d(b,"point",u)d(b,"scale",l)b:ClearAllPoints()b:SetPoint(u,b:GetParent(),u,s/l,t/l)end;mixins["RestorePosition"]=true;
+    function WINDOW.RestorePosition(b)local s=f(b,"x")local t=f(b,"y")local u=f(b,"point")local l=f(b,"scale")if l then (b.lw11origSetScale or b.SetScale)(b,l)else l=b:GetScale()end;if not s or not t then s=0;t=0;u="CENTER"end;s=s/l;t=t/l;b:ClearAllPoints()if not u and t==0 then u="CENTER"end;if not u then b:SetPoint("TOPLEFT",b:GetParent(),"BOTTOMLEFT",s,t)i(b)return end;b:SetPoint(u,b:GetParent(),u,s,t)end;mixins["SetScale"]=true;
+    function WINDOW.SetScale(b,v)d(b,"scale",v)(b.lw11origSetScale or b.SetScale)(b,v)WINDOW.RestorePosition(b)end;
+    function WINDOW.OnDragStart(b)WINDOW.windowData[b].isDragging=true;b:StartMoving()end;
+    function WINDOW.OnDragStop(b)b:StopMovingOrSizing()WINDOW.SavePosition(b)WINDOW.windowData[b].isDragging=false;if WINDOW.windowData[b].altEnable and not IsAltKeyDown()then b:EnableMouse(false)end end;local function w(...)return WINDOW.OnDragStart(...)end;
+    local function x(...)return WINDOW.OnDragStop(...)end;mixins["MakeDraggable"]=true;
+    function WINDOW.MakeDraggable(b)assert(WINDOW.windowData[b])b:SetMovable(true)b:SetScript("OnDragStart",w)b:SetScript("OnDragStop",x)b:RegisterForDrag("LeftButton")end;
+    function WINDOW.OnMouseWheel(b,y)local v=f(b,"scale")if y<0 then v=max(v*0.9,0.1)else v=min(v/0.9,3)end;WINDOW.SetScale(b,v)end;
+    local function z(...)return WINDOW.OnMouseWheel(...)end;
+    mixins["EnableMouseWheelScaling"]=true;
+    function WINDOW.EnableMouseWheelScaling(b)b:SetScript("OnMouseWheel",z)end;WINDOW.utilFrame:SetScript("OnEvent",function(g,A,B,C)if A=="MODIFIER_STATE_CHANGED"then if B=="LALT"or B=="RALT"then for b,h in pairs(WINDOW.altEnabledFrames)do if not WINDOW.windowData[b].isDragging then b:EnableMouse(C==1)end end end end end)mixins["EnableMouseOnAlt"]=true;
+    function WINDOW.EnableMouseOnAlt(b)assert(WINDOW.windowData[b])WINDOW.windowData[b].altEnable=true;b:EnableMouse(not not IsAltKeyDown())if not WINDOW.altEnabledFrames then WINDOW.altEnabledFrames={}WINDOW.utilFrame:RegisterEvent("MODIFIER_STATE_CHANGED")end;WINDOW.altEnabledFrames[b]=true end;
+    function WINDOW:Embed(D)if not D or not D[0]or not D.GetObjectType then error("Usage: WINDOW:Embed(frame)",1)end;D.lw11origSetScale=D.SetScale;for c,h in pairs(mixins)do D[c]=self[c]end;WINDOW.embeds[D]=true;return D end;for D,h in pairs(WINDOW.embeds)do WINDOW:Embed(D)end
+end
diff --git a/SVUI_!Core/libs/_SVUI_Lib/LUA.lua b/SVUI_!Core/libs/_SVUI_Lib/LUA.lua
new file mode 100644
index 0000000..3c2cb85
--- /dev/null
+++ b/SVUI_!Core/libs/_SVUI_Lib/LUA.lua
@@ -0,0 +1,606 @@
+--- LUA companion library.
+-- @class file
+-- @name LUA
+-- @author Steven Jackson (2014)
+-- @release 1.0.0
+local _G            = getfenv(0)
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local ipairs        = _G.ipairs;
+local loadstring    = _G.loadstring;
+local setmetatable  = _G.setmetatable;
+local getmetatable  = _G.getmetatable;
+local rawset        = _G.rawset;
+local rawget        = _G.rawget;
+local tostring      = _G.tostring;
+local tonumber      = _G.tonumber;
+local xpcall        = _G.xpcall;
+local pcall         = _G.pcall;
+local table         = _G.table;
+local tconcat       = table.concat;
+local tremove       = table.remove;
+local tinsert       = table.insert;
+local table_sort    = table.sort;
+local string        = _G.string;
+local match         = string.match;
+local gmatch 				= string.gmatch;
+local gsub          = string.gsub;
+local rep           = string.rep;
+local char 					= string.char;
+local strmatch      = _G.strmatch;
+local bit           = _G.bit;
+local band          = bit.band;
+local math          = _G.math;
+local floor         = math.floor;
+local huge          = math.huge;
+
+---------------------------------------------------------------------
+-- Math
+-- @section MATH UTILITIES
+---------------------------------------------------------------------
+
+---------------------------------------------------------------------
+-- Integer float utility for lua.
+-- @return floating point integer
+-- @param value The integer amount to be adjusted.
+-- @param decimal Number of decimal places allowed.
+---------------------------------------------------------------------
+
+function math.parsefloat(value, decimal)
+	value = value or 0
+	if(decimal and decimal > 0) then
+		local calc1 = 10 ^ decimal;
+		local calc2 = (value * calc1) + 0.5;
+		return floor(calc2) / calc1
+	end
+	return floor(value + 0.5)
+end
+
+---------------------------------------------------------------------
+-- Pickle
+-- @section SERIALIZE UTILITIES
+---------------------------------------------------------------------
+
+---------------------------------------------------------------------
+-- Global class used by pickle/unpickle functions.
+-- @todo Does this need to be global?
+---------------------------------------------------------------------
+
+Pickle = {
+  clone = function (t) local nt={}; for i, v in pairs(t) do nt[i]=v end return nt end
+}
+
+---------------------------------------------------------------------
+-- A table serialization utility for lua.
+-- @return serialized table data
+-- @param t A table to be serialized.
+-- @author Steve Dekorte, http://www.dekorte.com, Apr 2000
+---------------------------------------------------------------------
+
+function pickle(t)
+  return Pickle:clone():pickle_(t)
+end
+
+function Pickle:pickle_(root)
+  if type(root) ~= "table" then
+    error("can only pickle tables, not ".. type(root).."s")
+  end
+  self._tableToRef = {}
+  self._refToTable = {}
+  local savecount = 0
+  self:ref_(root)
+  local s = ""
+
+  while table.getn(self._refToTable) > savecount do
+    savecount = savecount + 1
+    local t = self._refToTable[savecount]
+    s = s.."{\n"
+    for i, v in pairs(t) do
+        s = string.format("%s[%s]=%s,\n", s, self:value_(i), self:value_(v))
+    end
+    s = s.."},\n"
+  end
+
+  return string.format("{%s}", s)
+end
+
+function Pickle:value_(v)
+  local vtype = type(v)
+  if     vtype == "string" then return string.format("%q", v)
+  elseif vtype == "number" then return v
+  elseif vtype == "boolean" then return tostring(v)
+  elseif vtype == "table" then return "{"..self:ref_(v).."}"
+  else --error("pickle a "..type(v).." is not supported")
+  end
+end
+
+function Pickle:ref_(t)
+  local ref = self._tableToRef[t]
+  if not ref then
+    if t == self then error("can't pickle the pickle class") end
+    table.insert(self._refToTable, t)
+    ref = table.getn(self._refToTable)
+    self._tableToRef[t] = ref
+  end
+  return ref
+end
+
+---------------------------------------------------------------------
+-- Un-serialization tool (pretty sure thats not a word).
+-- @return serialized table data
+-- @param s A serialized table to be reversed.
+-- @author Steve Dekorte, http://www.dekorte.com, Apr 2000
+---------------------------------------------------------------------
+
+function unpickle(s)
+  if type(s) ~= "string" then
+    error("can't unpickle a "..type(s)..", only strings")
+  end
+  local gentables = loadstring("return "..s)
+  local tables = gentables()
+
+  for tnum = 1, table.getn(tables) do
+    local t = tables[tnum]
+    local tcopy = {}; for i, v in pairs(t) do tcopy[i] = v end
+    for i, v in pairs(tcopy) do
+      local ni, nv
+      if type(i) == "table" then ni = tables[i[1]] else ni = i end
+      if type(v) == "table" then nv = tables[v[1]] else nv = v end
+      t[i] = nil
+      t[ni] = nv
+    end
+  end
+  return tables[1]
+end
+
+---------------------------------------------------------------------
+-- String
+-- @section STRING UTILITIES
+---------------------------------------------------------------------
+
+local char_table='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
+
+---------------------------------------------------------------------
+-- Base64 encoding tool.
+-- @return encoded string
+-- @param data string data to be encoded.
+---------------------------------------------------------------------
+
+function string.encode(data)
+    return ((data:gsub('.', function(x)
+        local r,b='',x:byte()
+        for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end
+        return r;
+    end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x)
+        if (#x < 6) then return '' end
+        local c=0
+        for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end
+        return char_table:sub(c+1,c+1)
+    end)..({ '', '==', '=' })[#data%3+1])
+end
+
+---------------------------------------------------------------------
+-- Base64 decoding tool.
+-- @return decoded string
+-- @param data encoded string to be decoded.
+---------------------------------------------------------------------
+
+function string.decode(data)
+    data = gsub(data, '[^'..char_table..'=]', '')
+    return (data:gsub('.', function(x)
+        if (x == '=') then return '' end
+        local r,f='',(char_table:find(x)-1)
+        for i=6,1,-1 do r=r..(f%2^i-f%2^(i-1)>0 and '1' or '0') end
+        return r;
+    end):gsub('%d%d%d?%d?%d?%d?%d?%d?', function(x)
+        if (#x ~= 8) then return '' end
+        local c=0
+        for i=1,8 do c=c+(x:sub(i,i)=='1' and 2^(8-i) or 0) end
+        return char(c)
+    end))
+end
+
+---------------------------------------------------------------------
+-- String to array utility.
+-- @return table data
+-- @param data string to be converted to table data.
+-- @param delim Character delimiter to separate the string by.
+---------------------------------------------------------------------
+
+function string.explode(data, delim)
+    local pattern = format("([^%s]+)", delim);
+    local res = {};
+		local count = 1;
+    for line in gmatch(data, pattern) do
+				res[count] = line;
+				count = count + 1;
+    end
+    return res
+end
+
+function string.loadtable(data)
+   local t = {}
+   local f = assert(loadstring(data))
+   setfenv(f, t)
+   f()
+   return t
+end
+
+-------------------------------------------------------------------
+--PRETTY PRINT FOR TABLES
+
+local prettify = {}
+prettify.KEY       = setmetatable({}, {__tostring = function() return 'prettify.KEY' end})
+prettify.METATABLE = setmetatable({}, {__tostring = function() return 'prettify.METATABLE' end})
+
+-- Apostrophizes the string if it has quotes, but not aphostrophes
+-- Otherwise, it returns a regular quoted string
+local function smartQuote(str)
+  if str:match('"') and not str:match("'") then
+	return "'" .. str .. "'"
+  end
+  return '"' .. str:gsub('"', '\\"') .. '"'
+end
+
+local controlCharsTranslation = {
+  ["\a"] = "\\a",  ["\b"] = "\\b", ["\f"] = "\\f",  ["\n"] = "\\n",
+  ["\r"] = "\\r",  ["\t"] = "\\t", ["\v"] = "\\v"
+}
+
+local function escape(str)
+  local result = str:gsub("\\", "\\\\"):gsub("(%c)", controlCharsTranslation)
+  return result
+end
+
+local function isIdentifier(str)
+  return type(str) == 'string' and str:match( "^[_%a][_%a%d]*$" )
+end
+
+local function isSequenceKey(k, length)
+  return type(k) == 'number'
+	 and 1 <= k
+	 and k <= length
+	 and floor(k) == k
+end
+
+local defaultTypeOrders = {
+  ['number']   = 1, ['boolean']  = 2, ['string'] = 3, ['table'] = 4,
+  ['function'] = 5, ['userdata'] = 6, ['thread'] = 7
+}
+
+local function sortKeys(a, b)
+  local ta, tb = type(a), type(b)
+
+  -- strings and numbers are sorted numerically/alphabetically
+  if ta == tb and (ta == 'string' or ta == 'number') then return a < b end
+
+  local dta, dtb = defaultTypeOrders[ta], defaultTypeOrders[tb]
+  -- Two default types are compared according to the defaultTypeOrders table
+  if dta and dtb then return defaultTypeOrders[ta] < defaultTypeOrders[tb]
+  elseif dta     then return true  -- default types before custom ones
+  elseif dtb     then return false -- custom types after default ones
+  end
+
+  -- custom types are sorted out alphabetically
+  return ta < tb
+end
+
+local function getNonSequentialKeys(t)
+  local keys, length = {}, #t
+  for k,_ in pairs(t) do
+	if not isSequenceKey(k, length) then table.insert(keys, k) end
+  end
+  table.sort(keys, sortKeys)
+  return keys
+end
+
+local function getToStringResultSafely(t, mt)
+  local __tostring = type(mt) == 'table' and rawget(mt, '__tostring')
+  local str, ok
+  if type(__tostring) == 'function' then
+	ok, str = pcall(__tostring, t)
+	str = ok and str or 'error: ' .. tostring(str)
+  end
+  if type(str) == 'string' and #str > 0 then return str end
+end
+
+local maxIdsMetaTable = {
+  __index = function(self, typeName)
+	rawset(self, typeName, 0)
+	return 0
+  end
+}
+
+local idsMetaTable = {
+  __index = function (self, typeName)
+	local col = setmetatable({}, {__mode = "kv"})
+	rawset(self, typeName, col)
+	return col
+  end
+}
+
+local function countTableAppearances(t, tableAppearances)
+  tableAppearances = tableAppearances or setmetatable({}, {__mode = "k"})
+
+  if type(t) == 'table' then
+	if not tableAppearances[t] then
+	  tableAppearances[t] = 1
+	  for k,v in pairs(t) do
+		countTableAppearances(k, tableAppearances)
+		countTableAppearances(v, tableAppearances)
+	  end
+	  countTableAppearances(getmetatable(t), tableAppearances)
+	else
+	  tableAppearances[t] = tableAppearances[t] + 1
+	end
+  end
+
+  return tableAppearances
+end
+
+local copySequence = function(s)
+  local copy, len = {}, #s
+  for i=1, len do copy[i] = s[i] end
+  return copy, len
+end
+
+local function makePath(path, ...)
+  local keys = {...}
+  local newPath, len = copySequence(path)
+  for i=1, #keys do
+	newPath[len + i] = keys[i]
+  end
+  return newPath
+end
+
+local function processRecursive(process, item, path)
+  if item == nil then return nil end
+
+  local processed = process(item, path)
+  if type(processed) == 'table' then
+	local processedCopy = {}
+	local processedKey
+
+	for k,v in pairs(processed) do
+	  processedKey = processRecursive(process, k, makePath(path, k, prettify.KEY))
+	  if processedKey ~= nil then
+		processedCopy[processedKey] = processRecursive(process, v, makePath(path, processedKey))
+	  end
+	end
+
+	local mt  = processRecursive(process, getmetatable(processed), makePath(path, prettify.METATABLE))
+	setmetatable(processedCopy, mt)
+	processed = processedCopy
+  end
+  return processed
+end
+
+
+-------------------------------------------------------------------
+
+local PrettifyTable = {}
+local PrettifyTable_mt = {__index = PrettifyTable}
+
+function PrettifyTable:puts(...)
+  local args   = {...}
+  local buffer = self.buffer
+  local len    = #buffer
+  for i=1, #args do
+	len = len + 1
+	buffer[len] = tostring(args[i])
+  end
+end
+
+function PrettifyTable:down(f)
+  self.level = self.level + 1
+  f()
+  self.level = self.level - 1
+end
+
+function PrettifyTable:tabify()
+  self:puts(self.newline, rep(self.indent, self.level))
+end
+
+function PrettifyTable:alreadyVisited(v)
+  return self.ids[type(v)][v] ~= nil
+end
+
+function PrettifyTable:getId(v)
+  local tv = type(v)
+  local id = self.ids[tv][v]
+  if not id then
+	id              = self.maxIds[tv] + 1
+	self.maxIds[tv] = id
+	self.ids[tv][v] = id
+  end
+  return id
+end
+
+function PrettifyTable:putKey(k)
+  if isIdentifier(k) then return self:puts(k) end
+  self:puts("[")
+  self:putValue(k)
+  self:puts("]")
+end
+
+function PrettifyTable:putTable(t)
+  if t == prettify.KEY or t == prettify.METATABLE then
+	self:puts(tostring(t))
+  elseif self:alreadyVisited(t) then
+	self:puts('<table ', self:getId(t), '>')
+  elseif self.level >= self.depth then
+	self:puts('{...}')
+  else
+	if self.tableAppearances[t] > 1 then self:puts('<', self:getId(t), '>') end
+
+	local nonSequentialKeys = getNonSequentialKeys(t)
+	local length            = #t
+	local mt                = getmetatable(t)
+	local toStringResult    = getToStringResultSafely(t, mt)
+
+	self:puts('{')
+	self:down(function()
+	  if toStringResult then
+		self:puts(' -- ', escape(toStringResult))
+		if length >= 1 then self:tabify() end
+	  end
+
+	  local count = 0
+	  for i=1, length do
+		if count > 0 then self:puts(',') end
+		self:puts(' ')
+		self:putValue(t[i])
+		count = count + 1
+	  end
+
+	  for _,k in ipairs(nonSequentialKeys) do
+		if count > 0 then self:puts(',') end
+		self:tabify()
+		self:putKey(k)
+		self:puts(' = ')
+		self:putValue(t[k])
+		count = count + 1
+	  end
+
+	  if mt then
+		if count > 0 then self:puts(',') end
+		self:tabify()
+		self:puts('<metatable> = ')
+		self:putValue(mt)
+	  end
+	end)
+
+	if #nonSequentialKeys > 0 or mt then -- result is multi-lined. Justify closing }
+	  self:tabify()
+	elseif length > 0 then -- array tables have one extra space before closing }
+	  self:puts(' ')
+	end
+
+	self:puts('}')
+  end
+end
+
+function PrettifyTable:putValue(v)
+  local tv = type(v)
+
+  if tv == 'string' then
+	self:puts(smartQuote(escape(v)))
+  elseif tv == 'number' or tv == 'boolean' or tv == 'nil' then
+	self:puts(tostring(v))
+  elseif tv == 'table' then
+	self:putTable(v)
+  else
+	self:puts('<',tv,' ',self:getId(v),'>')
+  end
+end
+
+
+function prettify.prettify(root, options)
+  options       = options or {}
+
+  local depth   = options.depth   or huge
+  local newline = options.newline or '\n'
+  local indent  = options.indent  or '  '
+  local process = options.process
+
+  if process then
+	root = processRecursive(process, root, {})
+  end
+
+  local prettify_table = setmetatable({
+	depth            = depth,
+	buffer           = {},
+	level            = 0,
+	ids              = setmetatable({}, idsMetaTable),
+	maxIds           = setmetatable({}, maxIdsMetaTable),
+	newline          = newline,
+	indent           = indent,
+	tableAppearances = countTableAppearances(root)
+  }, PrettifyTable_mt)
+
+  prettify_table:putValue(root)
+
+  return tconcat(prettify_table.buffer)
+end
+
+setmetatable(prettify, { __call = function(_, ...) return prettify.prettify(...) end })
+
+---------------------------------------------------------------------
+-- Table
+-- @section TABLE UTILITIES
+---------------------------------------------------------------------
+
+function table.val_to_str(v)
+  	if "string" == type(v) then
+		v = gsub(v, "\n", "\\n")
+		if match( gsub(v,"[^'\"]",""), '^"+$') then
+			return "'" .. v .. "'"
+		end
+	  	return '"' .. gsub(v,'"', '\\"') .. '"'
+	else
+		return "table" == type(v) and table.tostring(v) or
+		tostring(v)
+	end
+end
+
+function table.key_to_str(k)
+	if "string" == type(k) and match(k, "^[_%a][_%a%d]*$") then
+		return k
+	else
+		return "[" .. table.val_to_str(k) .. "]"
+	end
+end
+
+---------------------------------------------------------------------
+-- Dump table contents to string
+-- @return string value
+-- @param tbl A table to be stringified.
+-- @param pretty Flag to syntactically format the result.
+---------------------------------------------------------------------
+
+function table.tostring(tbl, pretty)
+	if(pretty) then
+		return prettify(tbl)
+	else
+		local result, done = {}, {}
+		for k, v in ipairs(tbl) do
+			tinsert(result, table.val_to_str(v))
+			done[k] = true
+		end
+		for k, v in pairs(tbl) do
+			if not done[k] then
+			  	tinsert(result, table.key_to_str(k) .. "=" .. table.val_to_str(v))
+		  	end
+		end
+		return "{" .. tconcat( result, "," ) .. "}"
+	end
+end
+
+---------------------------------------------------------------------
+-- Copy all table data from a source to another table
+-- @return copied data
+-- @param targetTable The recipient of the copied data.
+-- @param deepCopy Flag the use of DEEP copying.
+-- @param mergeTable The origin of the copied data.
+---------------------------------------------------------------------
+
+function table.copy(targetTable, deepCopy, mergeTable)
+	mergeTable = mergeTable or {};
+	if(targetTable == nil) then return nil end
+	if(mergeTable[targetTable]) then return mergeTable[targetTable] end
+	local replacementTable = {}
+	for key,value in pairs(targetTable)do
+		if deepCopy and type(value) == "table" then
+			replacementTable[key] = table.copy(value, deepCopy, mergeTable)
+		else
+			replacementTable[key] = value
+		end
+	end
+	setmetatable(replacementTable, table.copy(getmetatable(targetTable), deepCopy, mergeTable))
+	mergeTable[targetTable] = replacementTable;
+	return replacementTable
+end
diff --git a/SVUI_!Core/libs/_SVUI_Lib/Linguist.lua b/SVUI_!Core/libs/_SVUI_Lib/Linguist.lua
new file mode 100644
index 0000000..e31e104
--- /dev/null
+++ b/SVUI_!Core/libs/_SVUI_Lib/Linguist.lua
@@ -0,0 +1,73 @@
+--[[
+Linguist is a simple localization component. Seriously, thats it!
+--]]
+
+--[[ LOCALIZED GLOBALS ]]--
+--GLOBAL NAMESPACE
+local _G = getfenv(0);
+--LUA
+local select        = _G.select;
+local assert        = _G.assert;
+local rawset        = _G.rawset;
+local rawget        = _G.rawget;
+local getmetatable  = _G.getmetatable;
+local setmetatable  = _G.setmetatable;
+--BLIZZARD API
+local GetLocale             = _G.GetLocale;
+
+--[[ LIB CONSTRUCT ]]--
+
+local lib = Librarian:NewLibrary("Linguist")
+
+if not lib then return end -- No upgrade needed
+
+--[[ COMMON LOCAL VARS ]]--
+
+local activeLocale
+
+local failsafe = function() assert(false) end
+
+--LINGUIST META METHODS
+local metaread = {
+    __index = function(self, key)
+        rawset(self, key, key)
+        return key
+    end
+}
+
+local defaultwrite = setmetatable({}, {
+    __newindex = function(self, key, value)
+        if not rawget(activeLocale, key) then
+            rawset(activeLocale, key, value == true and key or value)
+        end
+    end,
+    __index = failsafe
+})
+
+local metawrite = setmetatable({}, {
+    __newindex = function(self, key, value)
+        rawset(activeLocale, key, value == true and key or value)
+    end,
+    __index = failsafe
+})
+
+--LINGUIST STORAGE
+lib.Localization = setmetatable({}, metaread);
+
+--LINGUIST PUBLIC METHOD
+function lib:Lang(locale, isDefault)
+    if(not locale) then
+        return self.Localization
+    else
+        local GAME_LOCALE = GetLocale()
+        if GAME_LOCALE == "enGB" then GAME_LOCALE = "enUS" end
+
+        activeLocale = self.Localization
+
+        if isDefault then
+            return defaultwrite
+        elseif(locale == GAME_LOCALE) then
+            return metawrite
+        end
+    end
+end
diff --git a/SVUI_!Core/libs/_SVUI_Lib/Parser.lua b/SVUI_!Core/libs/_SVUI_Lib/Parser.lua
new file mode 100644
index 0000000..70dfb58
--- /dev/null
+++ b/SVUI_!Core/libs/_SVUI_Lib/Parser.lua
@@ -0,0 +1,436 @@
+--[[
+ /$$$$$$$
+| $$__  $$
+| $$  \ $$/$$$$$$   /$$$$$$  /$$$$$$$  /$$$$$$   /$$$$$$
+| $$$$$$$/____  $$ /$$__  $$/$$_____/ /$$__  $$ /$$__  $$
+| $$____/ /$$$$$$$| $$  \__/  $$$$$$ | $$$$$$$$| $$  \__/
+| $$     /$$__  $$| $$      \____  $$| $$_____/| $$
+| $$    |  $$$$$$$| $$      /$$$$$$$/|  $$$$$$$| $$
+|__/     \_______/|__/     |_______/  \_______/|__/
+
+
+
+--]]
+
+--[[ LOCALIZED GLOBALS ]]--
+--GLOBAL NAMESPACE
+local _G = getfenv(0);
+--LUA
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pcall         = _G.pcall;
+local print         = _G.print;
+local ipairs        = _G.ipairs;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local rawset        = _G.rawset;
+local rawget        = _G.rawget;
+local tostring      = _G.tostring;
+local tonumber      = _G.tonumber;
+local getmetatable  = _G.getmetatable;
+local setmetatable  = _G.setmetatable;
+--STRING
+local string        = _G.string;
+local upper         = string.upper;
+local format        = string.format;
+local find          = string.find;
+local match         = string.match;
+local gsub          = string.gsub;
+--MATH
+local math          = _G.math;
+local random        = math.random;
+local floor         = math.floor
+--TABLE
+local table         = _G.table;
+local tsort         = table.sort;
+local tconcat       = table.concat;
+local tremove       = _G.tremove;
+local wipe          = _G.wipe;
+local bit_band      = bit.band;
+local bit_bor       = bit.bor;
+-- Bit flags.
+local AFFILIATION_MINE		= 0x00000001
+local AFFILIATION_PARTY		= 0x00000002
+local AFFILIATION_RAID		= 0x00000004
+local AFFILIATION_OUTSIDER	= 0x00000008
+local REACTION_FRIENDLY		= 0x00000010
+local REACTION_NEUTRAL		= 0x00000020
+local REACTION_HOSTILE		= 0x00000040
+local CONTROL_HUMAN			= 0x00000100
+local CONTROL_SERVER		= 0x00000200
+local UNITTYPE_PLAYER		= 0x00000400
+local UNITTYPE_NPC			= 0x00000800
+local UNITTYPE_PET			= 0x00001000
+local UNITTYPE_GUARDIAN		= 0x00002000
+local UNITTYPE_OBJECT		= 0x00004000
+local TARGET_TARGET			= 0x00010000
+local TARGET_FOCUS			= 0x00020000
+local OBJECT_NONE			= 0x80000000
+
+local GUID_NONE				= "0x0000000000000000"
+
+local MAX_BUFFS = 16
+local MAX_DEBUFFS = 40
+
+local AURA_TYPE_BUFF = "BUFF"
+local AURA_TYPE_DEBUFF = "DEBUFF"
+
+local UNIT_MAP_UPDATE_DELAY = 0.2
+local PET_UPDATE_DELAY = 1
+local REFLECT_HOLD_TIME = 3
+local CLASS_HOLD_TIME = 300
+
+local FLAGS_ME			= bit_bor(AFFILIATION_MINE, REACTION_FRIENDLY, CONTROL_HUMAN, UNITTYPE_PLAYER)
+local FLAGS_MINE		= bit_bor(AFFILIATION_MINE, REACTION_FRIENDLY, CONTROL_HUMAN)
+local FLAGS_MY_GUARDIAN	= bit_bor(AFFILIATION_MINE, REACTION_FRIENDLY, CONTROL_HUMAN, UNITTYPE_GUARDIAN)
+
+--[[ LIB CONSTRUCT ]]--
+
+local CoreName, CoreObject  = ...
+local lib = Librarian:NewLibrary("Parser")
+
+if not lib then return end -- No upgrade needed
+
+--[[ LIB STORAGE ]]--
+
+lib.EventCallback = {};
+
+--[[ EVENT HANDLING ]]--
+
+local LOG_EVENT, _R, _T = {},{},{};
+local COMBAT_LOG_EVENTS = {
+  SWING_DAMAGE            = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "damage";
+                                LOG_EVENT.amount, LOG_EVENT.overkill, LOG_EVENT.damage, LOG_EVENT.resisted, LOG_EVENT.blocked,
+                                LOG_EVENT.absorbed, LOG_EVENT.crit, LOG_EVENT.glancing, LOG_EVENT.crushing, LOG_EVENT.multi = ...;
+                            end,
+  RANGE_DAMAGE            = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "damage";
+                                LOG_EVENT.ranged = true;
+                                LOG_EVENT.spellID, LOG_EVENT.spellName, LOG_EVENT.school, LOG_EVENT.amount, LOG_EVENT.overkill,
+                                LOG_EVENT.damage, LOG_EVENT.resisted, LOG_EVENT.blocked, LOG_EVENT.absorbed, LOG_EVENT.crit,
+                                LOG_EVENT.glancing, LOG_EVENT.crushing, LOG_EVENT.offhand, LOG_EVENT.multi = ...;
+                            end,
+  DAMAGE_SPLIT            = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "damage";
+                                LOG_EVENT.spellID, LOG_EVENT.spellName, LOG_EVENT.school, LOG_EVENT.amount, LOG_EVENT.overkill,
+                                LOG_EVENT.damage, LOG_EVENT.resisted, LOG_EVENT.blocked, LOG_EVENT.absorbed, LOG_EVENT.crit,
+                                LOG_EVENT.glancing, LOG_EVENT.crushing, LOG_EVENT.offhand, LOG_EVENT.multi = ...;
+                            end,
+  SPELL_DAMAGE            = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "damage";
+                                LOG_EVENT.spellID, LOG_EVENT.spellName, LOG_EVENT.school, LOG_EVENT.amount, LOG_EVENT.overkill,
+                                LOG_EVENT.damage, LOG_EVENT.resisted, LOG_EVENT.blocked, LOG_EVENT.absorbed, LOG_EVENT.crit,
+                                LOG_EVENT.glancing, LOG_EVENT.crushing, LOG_EVENT.offhand, LOG_EVENT.multi = ...;
+                            end,
+  SPELL_PERIODIC_DAMAGE   = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "damage";
+                                LOG_EVENT.dot = true;
+                                LOG_EVENT.spellID, LOG_EVENT.spellName, LOG_EVENT.school, LOG_EVENT.amount, LOG_EVENT.overkill,
+                                LOG_EVENT.damage, LOG_EVENT.resisted, LOG_EVENT.blocked, LOG_EVENT.absorbed, LOG_EVENT.crit,
+                                LOG_EVENT.glancing, LOG_EVENT.crushing, LOG_EVENT.offhand, LOG_EVENT.multi = ...;
+                            end,
+  SPELL_BUILDING_DAMAGE   = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "damage";
+                                LOG_EVENT.spellID, LOG_EVENT.spellName, LOG_EVENT.school, LOG_EVENT.amount, LOG_EVENT.overkill,
+                                LOG_EVENT.damage, LOG_EVENT.resisted, LOG_EVENT.blocked, LOG_EVENT.absorbed, LOG_EVENT.crit,
+                                LOG_EVENT.glancing, LOG_EVENT.crushing = ...;
+                            end,
+  DAMAGE_SHIELD           = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "damage";
+                                LOG_EVENT.shield = true;
+                                LOG_EVENT.spellID, LOG_EVENT.spellName, LOG_EVENT.school, LOG_EVENT.amount, LOG_EVENT.overkill,
+                                LOG_EVENT.damage, LOG_EVENT.resisted, LOG_EVENT.blocked, LOG_EVENT.absorbed, LOG_EVENT.crit,
+                                LOG_EVENT.glancing, LOG_EVENT.crushing = ...;
+                            end,
+  SWING_MISSED            = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "miss";
+                                LOG_EVENT.miss, LOG_EVENT.offhand, LOG_EVENT.multi, LOG_EVENT.amount = ...;
+                            end,
+  RANGE_MISSED            = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "miss";
+                                LOG_EVENT.ranged = true;
+                                LOG_EVENT.spellID, LOG_EVENT.spellName, LOG_EVENT.school, LOG_EVENT.miss,
+                                LOG_EVENT.offhand, LOG_EVENT.multi, LOG_EVENT.amount = ...;
+                            end,
+  SPELL_MISSED            = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "miss";
+                                LOG_EVENT.spellID, LOG_EVENT.spellName, LOG_EVENT.school, LOG_EVENT.miss,
+                                LOG_EVENT.offhand, LOG_EVENT.multi, LOG_EVENT.amount = ...;
+                            end,
+  SPELL_PERIODIC_MISSED   = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "miss";
+                                LOG_EVENT.spellID, LOG_EVENT.spellName, LOG_EVENT.school, LOG_EVENT.miss,
+                                LOG_EVENT.offhand, LOG_EVENT.multi, LOG_EVENT.amount = ...;
+                            end,
+  DAMAGE_SHIELD_MISSED    = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "miss";
+                                LOG_EVENT.shield = true;
+                                LOG_EVENT.spellID, LOG_EVENT.spellName, LOG_EVENT.school, LOG_EVENT.miss,
+                                LOG_EVENT.offhand, LOG_EVENT.multi, LOG_EVENT.amount = ...;
+                            end,
+  SPELL_DISPEL_FAILED     = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "miss";
+                                LOG_EVENT.miss = "RESIST";
+                                LOG_EVENT.spellID, LOG_EVENT.spellName, LOG_EVENT.school, LOG_EVENT.spellID2,
+                                LOG_EVENT.spellName2, LOG_EVENT.school2 = ...;
+                            end,
+  SPELL_PERIODIC_ENERGIZE = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "power";
+                                LOG_EVENT.gain = true;
+                                LOG_EVENT.spellID, LOG_EVENT.spellName, LOG_EVENT.school, LOG_EVENT.amount, LOG_EVENT.powerType = ...;
+                            end,
+  SPELL_PERIODIC_DRAIN    = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "power";
+                                LOG_EVENT.drain = true;
+                                LOG_EVENT.spellID, LOG_EVENT.spellName, LOG_EVENT.school, LOG_EVENT.amount,
+                                LOG_EVENT.powerType, LOG_EVENT.amount2 = ...;
+                            end,
+  SPELL_PERIODIC_LEECH    = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "power";
+                                LOG_EVENT.leech = true;
+                                LOG_EVENT.spellID, LOG_EVENT.spellName, LOG_EVENT.school, LOG_EVENT.amount,
+                                LOG_EVENT.powerType, LOG_EVENT.amount2 = ...;
+                            end,
+  SPELL_ENERGIZE          = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "power";
+                                LOG_EVENT.gain = true;
+                                LOG_EVENT.spellID, LOG_EVENT.spellName, LOG_EVENT.school, LOG_EVENT.amount, LOG_EVENT.powerType = ...;
+                            end,
+  SPELL_DRAIN             = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "power";
+                                LOG_EVENT.drain = true;
+                                LOG_EVENT.spellID, LOG_EVENT.spellName, LOG_EVENT.school, LOG_EVENT.amount,
+                                LOG_EVENT.powerType, LOG_EVENT.amount2 = ...;
+                            end,
+  SPELL_LEECH             = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "power";
+                                LOG_EVENT.leech = true;
+                                LOG_EVENT.spellID, LOG_EVENT.spellName, LOG_EVENT.school, LOG_EVENT.amount,
+                                LOG_EVENT.powerType, LOG_EVENT.amount2 = ...;
+                            end,
+  SPELL_STOLEN            = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "dispel";
+                                LOG_EVENT.spellID, LOG_EVENT.spellName, LOG_EVENT.school, LOG_EVENT.spellID2,
+                                LOG_EVENT.spellName2, LOG_EVENT.school2, LOG_EVENT.aura = ...;
+                            end,
+  SPELL_DISPEL            = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "dispel";
+                                LOG_EVENT.spellID, LOG_EVENT.spellName, LOG_EVENT.school, LOG_EVENT.spellID2,
+                                LOG_EVENT.spellName2, LOG_EVENT.school2, LOG_EVENT.aura = ...;
+                            end,
+  SPELL_HEAL              = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "heal";
+                                LOG_EVENT.spellID, LOG_EVENT.spellName, LOG_EVENT.school, LOG_EVENT.amount,
+                                LOG_EVENT.overheal, LOG_EVENT.absorbed, LOG_EVENT.crit, LOG_EVENT.multi = ...;
+                            end,
+  SPELL_PERIODIC_HEAL     = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "heal";
+                                LOG_EVENT.hot = true;
+                                LOG_EVENT.spellID, LOG_EVENT.spellName, LOG_EVENT.school, LOG_EVENT.amount,
+                                LOG_EVENT.overheal, LOG_EVENT.absorbed, LOG_EVENT.crit, LOG_EVENT.multi = ...;
+                            end,
+  ENVIRONMENTAL_DAMAGE    = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "environmental";
+                                LOG_EVENT.hazard, LOG_EVENT.amount, LOG_EVENT.overkill, LOG_EVENT.damage,
+                                LOG_EVENT.resisted, LOG_EVENT.blocked, LOG_EVENT.absorbed, LOG_EVENT.crit,
+                                LOG_EVENT.glancing, LOG_EVENT.crushing = ...;
+                            end,
+  SPELL_INTERRUPT         = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "interrupt";
+                                LOG_EVENT.spellID, LOG_EVENT.spellName, LOG_EVENT.school, LOG_EVENT.spellID2,
+                                LOG_EVENT.spellName2, LOG_EVENT.school2 = ...;
+                            end,
+  SPELL_AURA_APPLIED      = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "aura";
+                                LOG_EVENT.spellID, LOG_EVENT.spellName, LOG_EVENT.school, LOG_EVENT.aura, LOG_EVENT.amount = ...;
+                            end,
+  SPELL_AURA_APPLIED_DOSE = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "aura";
+                                LOG_EVENT.dose = true;
+                                LOG_EVENT.spellID, LOG_EVENT.spellName, LOG_EVENT.school, LOG_EVENT.aura, LOG_EVENT.amount = ...;
+                            end,
+  SPELL_AURA_REMOVED      = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "aura";
+                                LOG_EVENT.faded = true;
+                                LOG_EVENT.spellID, LOG_EVENT.spellName, LOG_EVENT.school, LOG_EVENT.aura, LOG_EVENT.amount = ...;
+                            end,
+  SPELL_AURA_REMOVED_DOSE = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "aura";
+                                LOG_EVENT.faded = true;
+                                LOG_EVENT.dose = true;
+                                LOG_EVENT.spellID, LOG_EVENT.spellName, LOG_EVENT.school, LOG_EVENT.aura, LOG_EVENT.amount = ...;
+                            end,
+  ENCHANT_APPLIED         = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "enchant";
+                                LOG_EVENT.spellName, LOG_EVENT.itemID, LOG_EVENT.itemName = ...;
+                            end,
+  ENCHANT_REMOVED         = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "enchant";
+                                LOG_EVENT.faded = true;
+                                LOG_EVENT.spellName, LOG_EVENT.itemID, LOG_EVENT.itemName = ...;
+                            end,
+  SPELL_CAST_START        = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "cast";
+                                LOG_EVENT.spellID, LOG_EVENT.spellName, LOG_EVENT.school = ...;
+                            end,
+  PARTY_KILL              = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "kill";
+                            end,
+  SPELL_EXTRA_ATTACKS     = function (...)
+                                wipe(LOG_EVENT);
+                                LOG_EVENT.type = "extraattacks";
+                                LOG_EVENT.spellID, LOG_EVENT.spellName, LOG_EVENT.school, LOG_EVENT.amount = ...;
+                            end
+};
+local FULL_PARSE = {
+  SPELL_AURA_APPLIED = true,
+  SPELL_AURA_REMOVED = true,
+  SPELL_AURA_APPLIED_DOSE = true,
+  SPELL_AURA_REMOVED_DOSE = true,
+  SPELL_CAST_START = true,
+};
+local PROXY_UNITS = { player = true, pet = true };
+
+local function flagTest(a, b, c)
+  if(c) then
+    if(bit_band(a, b) > 0) then return true end
+  else
+    if(bit_band(a, b) == b) then return true end
+  end
+end
+--[[ LIB METHODS ]]--
+
+function lib:Register(event, obj, callback)
+    local key = obj.Schema
+    if(not self.EventCallback[event]) then
+        self.EventCallback[event] = {}
+    end
+    self.EventCallback[event][key] = callback;
+end;
+
+function lib:Unregister(event, obj)
+    local key = obj.Schema
+    if((not self.EventCallback[event]) or (not self.EventCallback[event][key])) then
+        return
+    end
+    self.EventCallback[event][key] = nil;
+end;
+
+function lib:BroadCast(event)
+  if(not self.EventCallback[event]) then return end;
+  for key,fn in pairs(self.EventCallback[event]) do
+    local obj = CoreObject[key];
+    local _, catch = pcall(fn, obj, LOG_EVENT)
+    if(catch) then
+        CoreObject:HandleError("Librarian:Parser", "BroadCast", catch)
+    end
+  end
+end;
+
+--[[ COMBAT LOG PARSING ]]--
+
+function lib:COMBAT_LOG_EVENT_UNFILTERED(timestamp, event, hideCaster, sourceGUID, sourceName, sourceFlags, sourceRaidFlags, destGUID, destName, destFlags, destRaidFlags, ...)
+  local fn = COMBAT_LOG_EVENTS[event]
+  if (not fn) then return end
+
+  if (sourceGUID == destGUID and _T[destGUID] and event == "SPELL_DAMAGE") then
+    local skillID = ...
+    if (skillID == _R[destGUID]) then
+      _T[destGUID] = nil;
+      _R[destGUID] = nil;
+      sourceGUID = playerGUID;
+      sourceName = playerName;
+      sourceFlags = FLAGS_ME;
+    end
+  end
+
+  local sourceUnit = unitMap[sourceGUID] or petMap[sourceGUID];
+  local destUnit = unitMap[destGUID] or petMap[destGUID];
+  if ((not sourceUnit) and flagTest(sourceFlags, FLAGS_MINE)) then
+    sourceUnit = flagTest(sourceFlags, FLAGS_MY_GUARDIAN) and "pet" or "player";
+  end
+  if ((not destUnit) and flagTest(destFlags, FLAGS_MINE)) then
+    destUnit = flagTest(destFlags, FLAGS_MY_GUARDIAN) and "pet" or "player";
+  end
+  if ((not FULL_PARSE[event]) and (not PROXY_UNITS[sourceUnit]) and (not PROXY_UNITS[destUnit])) then
+    return;
+  end
+
+  fn(...)
+
+  LOG_EVENT.hostile = flagTest(sourceFlags, COMBATLOG_OBJECT_REACTION_HOSTILE)
+  LOG_EVENT.sourceGUID = sourceGUID
+  LOG_EVENT.sourceName = sourceName
+  LOG_EVENT.sourceFlags = sourceFlags
+  LOG_EVENT.sourceUnit = sourceUnit
+  LOG_EVENT.destGUID = destGUID
+  LOG_EVENT.destName = destName
+  LOG_EVENT.destFlags = destFlags
+  LOG_EVENT.destUnit = destUnit
+
+  if (LOG_EVENT.type == "miss" and LOG_EVENT.miss == "REFLECT" and LOG_EVENT.destUnit == "player") then
+    for guid, reflectTime in pairs(_T) do
+      if (timestamp - reflectTime > REFLECT_HOLD_TIME) then
+        _T[guid] = nil
+        _R[guid] = nil
+      end
+    end
+
+    _T[sourceGUID] = timestamp
+    _R[sourceGUID] = LOG_EVENT.spellID
+  end
+
+  self:BroadCast()
+end
+
+--[[ COMMON EVENTS ]]--
+
+local Library_OnEvent = function(self, event, ...)
+  local fn = self[event]
+  if(fn and type(fn) == "function") then
+      local _, catch = pcall(fn, self, ...)
+      if(catch) then
+          CoreObject:HandleError("Librarian:Parser", event, catch)
+      end
+  end
+end
+
+lib.EventManager = CreateFrame("Frame", nil)
+lib.EventManager:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
+lib.EventManager:SetScript("OnEvent", Library_OnEvent)
diff --git a/SVUI_!Core/libs/_SVUI_Lib/Registry.lua b/SVUI_!Core/libs/_SVUI_Lib/Registry.lua
new file mode 100644
index 0000000..4302e82
--- /dev/null
+++ b/SVUI_!Core/libs/_SVUI_Lib/Registry.lua
@@ -0,0 +1,1561 @@
+--[[
+ /$$$$$$$                      /$$            /$$
+| $$__  $$                    |__/           | $$
+| $$  \ $$  /$$$$$$   /$$$$$$  /$$  /$$$$$$$/$$$$$$    /$$$$$$  /$$   /$$
+| $$$$$$$/ /$$__  $$ /$$__  $$| $$ /$$_____/_  $$_/   /$$__  $$| $$  | $$
+| $$__  $$| $$$$$$$$| $$  \ $$| $$|  $$$$$$  | $$    | $$  \__/| $$  | $$
+| $$  \ $$| $$_____/| $$  | $$| $$ \____  $$ | $$ /$$| $$      | $$  | $$
+| $$  | $$|  $$$$$$$|  $$$$$$$| $$ /$$$$$$$/ |  $$$$/| $$      |  $$$$$$$
+|__/  |__/ \_______/ \____  $$|__/|_______/   \___/  |__/       \____  $$
+                     /$$  \ $$                                  /$$  | $$
+                    |  $$$$$$/                                 |  $$$$$$/
+                     \______/                                   \______/
+
+Registry is a component used to manage packages and scripts embedded
+into the SVUI core addon.
+
+It's main purpose is to keep all methods and logic needed to properly keep
+core add-ins functioning outside of the core object.
+--]]
+
+--[[ LOCALIZED GLOBALS ]]--
+--GLOBAL NAMESPACE
+local _G = getfenv(0);
+--LUA
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pcall         = _G.pcall;
+local print         = _G.print;
+local ipairs        = _G.ipairs;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local rawset        = _G.rawset;
+local rawget        = _G.rawget;
+local tostring      = _G.tostring;
+local tonumber      = _G.tonumber;
+local getmetatable  = _G.getmetatable;
+local setmetatable  = _G.setmetatable;
+--STRING
+local string        = _G.string;
+local upper         = string.upper;
+local format        = string.format;
+local find          = string.find;
+local match         = string.match;
+local gsub          = string.gsub;
+--MATH
+local math          = _G.math;
+local floor         = math.floor
+--TABLE
+local table         = _G.table;
+local tremove       = _G.tremove;
+local wipe          = _G.wipe;
+
+local date          = _G.date;
+
+--[[ LIB CONSTRUCT ]]--
+
+local Librarian = _G.Librarian;
+local lib = Librarian:NewLibrary("Registry")
+
+if not lib then return end -- No upgrade needed
+
+--[[ ADDON DATA ]]--
+
+local CoreName, CoreObject  = ...
+local SchemaFromMeta        = "X-SVUISchema";
+local HeaderFromMeta        = "X-SVUIName";
+local ThemeFromMeta         = "X-SVUITheme";
+local CoreGlobalName        = GetAddOnMetadata(..., HeaderFromMeta);
+local AddonVersion          = GetAddOnMetadata(..., "Version");
+local InterfaceVersion      = select(4, GetBuildInfo());
+--print(InterfaceVersion)
+--[[ COMMON LOCAL VARS ]]--
+
+local GLOBAL_FILENAME       = CoreGlobalName.."_Global";
+local ERROR_FILENAME        = CoreGlobalName.."_Errors";
+local PRIVATE_FILENAME      = CoreGlobalName.."_Private";
+local MEDIA_FILENAME        = CoreGlobalName.."_Media";
+local SHARED_FILENAME       = CoreGlobalName.."_Shared";
+local GLOBAL_SV, PRIVATE_SV, FILTER_SV, MEDIA_SV, ERROR_SV, SHARED_SV;
+local MODULES, PLUGINS;
+local LoadOnDemand, ScriptQueue = {},{};
+local DirtyDataList, DirtyMediaList = {},{};
+local debugHeader = "|cffFF2F00%s|r [|cff992FFF%s|r]|cffFF2F00:|r";
+local debugPattern = '|cffFF2F00%s|r [|cff0affff%s|r]|cffFF2F00:|r @|cffFF0000(|r%s|cffFF0000)|r - %s';
+
+local playerClass           = select(2,UnitClass("player"));
+local playerRealm           = GetRealmName();
+local playerName            = UnitName("player");
+local DEFAULT_PROFILE_KEY   = ("%s - Default"):format(playerName);
+--local DEFAULT_PROFILE_KEY   = ("%s [%s] - Default"):format(playerName, playerRealm);
+local PROFILE_KEY           = DEFAULT_PROFILE_KEY;
+local DEFAULT_THEME_KEY     = "Default";
+local THEME_KEY             = DEFAULT_THEME_KEY;
+local DATESTAMP             = date("%m_%d_%y");
+local DEEP_CLEAN_REQUESTED  = false;
+
+local INFO_FORMAT = "|cffFFFF00%s|r\n        |cff33FF00Version: %s|r |cff0099FFby %s|r";
+
+if GetLocale() == "ruRU" then
+    INFO_FORMAT = "|cffFFFF00%s|r\n        |cff33FF00Версия: %s|r |cff0099FFот %s|r";
+end
+
+--[[ LIB EVENT LISTENER ]]--
+
+lib.EventManager = CreateFrame("Frame", nil)
+
+--[[ LIB VARS ]]--
+
+lib.CURRENT_SCHEMA = 'GENERAL';
+
+--[[ LIB CONSTRAINTS ]]--
+
+lib.CONSTRAINTS = {
+    ["IGNORED"] = {},
+    ["PROTECTED"] = {}
+}
+
+--[[ COMMON META METHODS ]]--
+
+local rootstring = function(self) return self.NameID end
+
+--DATABASE LOCAL HELPERS
+
+local function copydefaults(d, s)
+    if(type(s) ~= "table") then return end
+    if(type(d) ~= "table") then return end
+    for k, v in pairs(s) do
+        local saved = rawget(d, k)
+        if type(v) == "table" then
+            if not saved then rawset(d, k, {}) end
+            copydefaults(d[k], v)
+        else
+            rawset(d, k, v)
+        end
+    end
+end
+
+local function tablecopy(d, s, debug)
+    if(debug) then
+        print(debug)
+        assert(type(s) == "table", "tablecopy ERROR: source (" .. debug .. ") is not a table")
+        assert(type(d) == "table", "tablecopy ERROR: destination (" .. debug .. ") is not a table")
+    end
+    if(type(s) ~= "table") then return end
+    if(type(d) ~= "table") then return end
+    for k, v in pairs(s) do
+        local saved = rawget(d, k)
+        if type(v) == "table" then
+            if not saved then rawset(d, k, {}) end
+            if(debug) then debug = k end
+            tablecopy(d[k], v, debug)
+        elseif(saved == nil or (saved and type(saved) ~= type(v))) then
+            rawset(d, k, v)
+        end
+    end
+end
+
+local function sharedcopy(d, s)
+    if((type(d) == "table") and (type(s) == "table")) then
+      for k, v in pairs(s) do
+          local saved = rawget(d, k)
+          if(type(v) == "table") then
+              if(saved == nil) then
+                rawset(d, k, {})
+                sharedcopy(d[k], v)
+              elseif(type(saved) == "table") then
+                sharedcopy(d[k], v)
+              else
+                rawset(d, k, false)
+              end
+          else
+              rawset(d, k, v)
+          end
+      end
+    else
+      d = s
+    end
+end
+
+local function importdata(s, d)
+    if type(d) ~= "table" then d = {} end
+    if type(s) == "table" then
+        for k,v in pairs(s) do
+            if type(v) == "table" then
+                v = importdata(v, d[k])
+            end
+            d[k] = v
+        end
+    end
+    return d
+end
+
+local function clear_data(db)
+    if(type(db) ~= "table") then return end
+    for k,v in pairs(db) do
+        if(type(v) == "table") then
+            clear_data(db[k]);
+        else
+            db[k] = nil;
+        end
+    end
+end
+
+local function remove_undefined(src, db)
+    if(type(src) ~= "table") then return end
+    if(type(db) ~= "table") then return end
+    for k,v in pairs(db) do
+        if src[k] == nil then
+            db[k] = nil
+        elseif type(v) == "table" and type(src[k]) == "table" then
+            remove_undefined(src[k], v)
+        end
+    end
+end
+
+local function remove_defaults(db, src, nometa)
+    if(type(src) ~= "table") then
+        if(db == src) then db = nil end
+        return
+    end
+    if(not nometa) then
+        setmetatable(db, nil)
+    end
+    for k,v in pairs(src) do
+        if type(v) == "table" and type(db[k]) == "table" then
+            remove_defaults(db[k], v, nometa)
+            if next(db[k]) == nil then
+                db[k] = nil
+            end
+        else
+            if db[k] == v then
+                db[k] = nil
+            end
+        end
+    end
+end
+
+local function sanitize(db, src, double)
+    local ignored   = lib.CONSTRAINTS.IGNORED;
+    local protected = lib.CONSTRAINTS.PROTECTED;
+    if((type(src) == "table")) then
+        if(type(db) == "table") then
+            for k,v in pairs(db) do
+                if(not ignored[k]) then
+                    if((src[k] == nil) and (protected[k] == nil)) then
+                        db[k] = nil
+                    elseif(src[k] ~= nil) then
+                        remove_defaults(db[k], src[k])
+                        if(double and (protected[k] == nil)) then
+                            remove_undefined(src[k], db[k])
+                        end
+                    end
+                end
+            end
+        end
+    end
+end
+
+--DATABASE META METHODS
+local meta_transdata = {
+    __index = function(t, k)
+        if(not k or k == "") then return end
+        local sv = rawget(t, "data")
+        local dv = rawget(t, "defaults")
+        local src = dv and dv[k]
+
+        if(src ~= nil) then
+            if(type(src) == "table") then
+                if(sv[k] == nil or (sv[k] ~= nil and type(sv[k]) ~= "table")) then sv[k] = {} end
+                tablecopy(sv[k], src)
+            else
+                if(sv[k] == nil or (sv[k] ~= nil and type(sv[k]) ~= type(src))) then sv[k] = src end
+            end
+        end
+
+        rawset(t, k, sv[k])
+        return rawget(t, k)
+    end,
+}
+
+local meta_database = {
+    __index = function(t, k)
+        if(not k or k == "") then return end
+        local sv = rawget(t, "data")
+        if(sv[k] == nil) then sv[k] = {} end
+        rawset(t, k, sv[k])
+        return rawget(t, k)
+    end,
+}
+
+--REGISTRY LOCAL HELPERS
+
+local function CopySharedData(key)
+  if((not key) or (not SHARED_SV.profiles[key])) then return end
+  local export = SHARED_SV.profiles[key];
+  for schema,data in pairs(export) do
+    local obj = CoreObject[schema];
+    if(obj and obj.private) then
+      sharedcopy(obj.private, data);
+    end
+  end
+end
+
+local function SaveSharedData()
+  for schema,data in pairs(PRIVATE_SV.SAFEDATA.SHARED) do
+    local obj = CoreObject[schema];
+    if(data.enabled and obj and obj.private) then
+      SHARED_SV.profiles[PROFILE_KEY][schema] = {};
+      for k,v in pairs(obj.private) do
+        if(not data.ignored[k]) then
+          if(not SHARED_SV.profiles[PROFILE_KEY][schema][k]) then
+            SHARED_SV.profiles[PROFILE_KEY][schema][k] = {};
+          end
+          local saved = SHARED_SV.profiles[PROFILE_KEY][schema][k];
+          sharedcopy(saved, v);
+        end
+      end
+    end
+  end
+end
+
+local function LoadSharedData(schema,datastore)
+  if((not schema) or (not datastore)) then return end
+  local data = PRIVATE_SV.SAFEDATA.SHARED[schema];
+  if(data and data.enabled) then
+    local export = SHARED_SV.profiles[PROFILE_KEY][schema];
+    if(not export) then return end
+    for k,v in pairs(export) do
+      if(not data.ignored[k]) then
+        sharedcopy(datastore[k], v);
+      end
+    end
+  end
+end
+
+local function LoadingProxy(schema, obj, loadShared)
+    if(not obj) then print(schema .. ' not found') return end
+    lib.CURRENT_SCHEMA = schema;
+    if(not obj.initialized) then
+        if(obj.Load and type(obj.Load) == "function") then
+            local _, catch = pcall(obj.Load, obj)
+            if(catch) then
+                CoreObject:HandleError(schema, "Load", catch)
+            else
+                obj.initialized = true
+                -- if(loadShared and obj.private) then
+                --     LoadSharedData(schema, obj.private);
+                -- end
+            end
+        end
+    else
+        if(obj.ReLoad and type(obj.ReLoad) == "function") then
+            --print(schema .. ' Reloading')
+            local _, catch = pcall(obj.ReLoad, obj)
+            if(catch) then
+                CoreObject:HandleError(schema, "ReLoad", catch)
+            end
+        end
+    end
+    lib.CURRENT_SCHEMA = 'GENERAL';
+end
+
+local function OptionsProxy(schema, obj)
+    if(not obj) then return end
+    if(not obj.optionsLoaded) then
+        if(obj.LoadOptions and type(obj.LoadOptions) == "function") then
+            local _, catch = pcall(obj.LoadOptions, obj)
+            if(catch) then
+                CoreObject:HandleError(schema, "LoadOptions", catch)
+            else
+                obj.optionsLoaded = true
+            end
+        end
+    end
+end
+
+--OBJECT INTERNALS
+local makeSharable = function(self)
+  self.___canShare = true;
+end
+
+local isSharingEnabled = function(self)
+  local schema = self.Schema;
+  if(self.private and PRIVATE_SV.SAFEDATA.SHARED[schema]) then
+    return PRIVATE_SV.SAFEDATA.SHARED[schema].enabled;
+  end
+  return false;
+end
+
+local toggleSharedData = function(self, value)
+  local schema = self.Schema;
+  if(self.private) then
+    PRIVATE_SV.SAFEDATA.SHARED[schema].enabled = value;
+    if(value) then
+      SaveSharedData();
+    end
+  end
+end
+
+local ignoreSharedKeys = function(self, ...)
+  local schema = self.Schema;
+  if(self.private) then
+    for i=1,select("#",...) do
+      local key = select(i,...);
+      PRIVATE_SV.SAFEDATA.SHARED[schema].ignored[key] = true;
+    end
+  end
+end
+
+local clearPrivateDB = function(self)
+  --print(self.Schema)
+  if(self.private) then
+    clear_data(self.private);
+  end
+end
+
+local changeDBVar = function(self, value, key, sub1, sub2, sub3)
+  local db = CoreObject.db[self.Schema]
+  if((sub1 and sub2 and sub3) and (db[sub1] and db[sub1][sub2] and db[sub1][sub2][sub3])) then
+    db[sub1][sub2][sub3][key] = value
+  elseif((sub1 and sub2) and (db[sub1] and db[sub1][sub2])) then
+    db[sub1][sub2][key] = value
+  elseif(sub1 and db[sub1]) then
+    db[sub1][key] = value
+  else
+    db[key] = value
+  end
+
+  if(self.UpdateLocals) then
+    self:UpdateLocals()
+  end
+end
+
+local innerOnEvent = function(self, event, ...)
+  local obj = self.___owner
+  local fn = self[event]
+  if(fn and type(fn) == "function" and obj.initialized) then
+    local _, catch = pcall(fn, obj, event, ...)
+    if(catch) then
+      local schema = obj.Schema
+      CoreObject:HandleError(schema, event, catch)
+    end
+  end
+end
+
+local registerEvent = function(self, eventname, eventfunc)
+  if not self.___eventframe then
+    self.___eventframe = CreateFrame("Frame", nil)
+    self.___eventframe.___owner = self
+    self.___eventframe:SetScript("OnEvent", innerOnEvent)
+  end
+
+  if(not self.___eventframe[eventname]) then
+    local fn = eventfunc
+    if(type(eventfunc) == "string") then
+      fn = self[eventfunc]
+    elseif(not fn and self[eventname]) then
+      fn = self[eventname]
+    end
+    self.___eventframe[eventname] = fn
+  end
+
+  self.___eventframe:RegisterEvent(eventname)
+end
+
+local unregisterEvent = function(self, event, ...)
+  if(self.___eventframe) then
+    self.___eventframe:UnregisterEvent(event)
+  end
+end
+
+local innerOnUpdate = function(self, elapsed)
+  if self.elapsed and self.elapsed > (self.throttle) then
+    local obj = self.___owner
+    local callbacks = self.callbacks
+
+    for name, fn in pairs(callbacks) do
+      local _, catch = pcall(fn, obj)
+      if(catch and CoreObject.Debugging) then
+        local schema = obj.Schema
+        CoreObject:HandleError(schema, "OnUpdate", catch)
+      end
+    end
+
+    self.elapsed = 0
+  else
+    self.elapsed = (self.elapsed or 0) + elapsed
+  end
+end
+
+local registerUpdate = function(self, updatefunc, throttle)
+  if not self.___updateframe then
+    self.___updateframe = CreateFrame("Frame", nil);
+    self.___updateframe.___owner = self;
+    self.___updateframe.callbacks = {};
+    self.___updateframe.elapsed = 0;
+    self.___updateframe.throttle = throttle or 0.2;
+  end
+
+  if(updatefunc and type(updatefunc) == "string" and self[updatefunc]) then
+    self.___updateframe.callbacks[updatefunc] = self[updatefunc]
+  end
+
+  self.___updateframe:SetScript("OnUpdate", innerOnUpdate)
+end
+
+local unregisterUpdate = function(self, updatefunc)
+  if(updatefunc and type(updatefunc) == "string" and self.___updateframe.callbacks[updatefunc]) then
+    self.___updateframe.callbacks[updatefunc] = nil
+    if(#self.___updateframe.callbacks == 0) then
+      self.___updateframe:SetScript("OnUpdate", nil)
+    end
+  else
+    self.___updateframe:SetScript("OnUpdate", nil)
+  end
+end
+
+local function SetPluginString(addonName)
+    local author = GetAddOnMetadata(addonName, "Author") or "Unknown"
+    local name = GetAddOnMetadata(addonName, "Title") or addonName
+    local version = GetAddOnMetadata(addonName, "Version") or "???"
+    return INFO_FORMAT:format(name, version, author)
+end
+
+--REGISTRY PUBLIC METHODS
+
+function lib:RefreshModule(schema)
+    local obj = CoreObject[schema]
+    LoadingProxy(schema, obj)
+end
+
+function lib:RefreshPlugin(schema)
+    local obj = _G[schema]
+    LoadingProxy(schema, obj)
+end
+
+function lib:RefreshAll()
+    if(MODULES) then
+        for i=1, #MODULES do
+            local schema = MODULES[i];
+            local obj = CoreObject[schema];
+            if(obj) then
+                LoadingProxy(schema, obj)
+            end
+        end
+    end
+    if(PLUGINS) then
+        for i=1, #PLUGINS do
+            local schema = PLUGINS[i];
+            local obj = _G[schema];
+            if(obj) then
+                LoadingProxy(schema, obj)
+            end
+        end
+    end
+end
+
+function lib:LoadModuleOptions()
+    if(MODULES) then
+        for i=1,#MODULES do
+            local schema = MODULES[i]
+            local obj = CoreObject[schema]
+            if(obj and (not obj.optionsLoaded)) then
+                OptionsProxy(schema, obj)
+            end
+        end
+    end
+    if(PLUGINS) then
+        for i=1, #PLUGINS do
+            local schema = PLUGINS[i];
+            local obj = _G[schema];
+            if(obj and (not obj.optionsLoaded)) then
+                OptionsProxy(schema, obj)
+            end
+        end
+    end
+end
+
+function lib:LiveUpdate(forced)
+    if(forced or PRIVATE_SV.SAFEDATA.NEEDSLIVEUPDATE) then
+        if(CoreObject.ReLoad) then
+            CoreObject.Timers:ClearAllTimers()
+            if(forced) then CoreObject:ReLoad() end
+        end
+        self:RefreshAll()
+        if((not InCombatLockdown()) and (not C_PetBattles.IsInBattle())) then
+            PRIVATE_SV.SAFEDATA.NEEDSLIVEUPDATE = false
+        end
+    end
+end
+
+function lib:GetModuletable()
+    return MODULES
+end
+
+function lib:CleanUpData(deep)
+    local defaults = CoreObject.defaults
+    local media = CoreObject.mediadefaults
+    if(DEEP_CLEAN_REQUESTED) then
+        for key,data in pairs(GLOBAL_SV.profiles) do
+            sanitize(data, defaults, true)
+        end
+        for theme,realms in pairs(MEDIA_SV.profiles) do
+            if(CoreObject.AvailableThemes[theme]) then
+                for key,data in pairs(MEDIA_SV.profiles[theme]) do
+                    if(not GLOBAL_SV.profileKeys[key]) then
+                        MEDIA_SV.profiles[theme][key] = nil
+                    else
+                        sanitize(data, media)
+                    end
+                end
+            end
+        end
+    elseif(not deep) then
+        for key,data in pairs(GLOBAL_SV.profiles) do
+            local linked = DirtyDataList[key]
+            if(linked) then
+                sanitize(data, defaults, true)
+                sanitize(MEDIA_SV.profiles[linked][key], media)
+            end
+        end
+    else
+        DEEP_CLEAN_REQUESTED = true;
+    end
+end
+
+--[[ CONSTRUCTORS ]]--
+
+local function CheckForDeprecated(oldKey)
+  if(GLOBAL_SV.profiles[oldKey]) then
+    local export = GLOBAL_SV.profiles[oldKey];
+    local saved = GLOBAL_SV.profiles[PROFILE_KEY];
+    tablecopy(saved, export);
+    GLOBAL_SV.profiles[oldKey] = nil
+  end
+
+  if(MEDIA_SV.profiles[THEME_KEY][oldKey]) then
+    local export = MEDIA_SV.profiles[THEME_KEY][oldKey];
+    local saved = MEDIA_SV.profiles[THEME_KEY][PROFILE_KEY];
+    tablecopy(saved, export);
+    MEDIA_SV.profiles[THEME_KEY][oldKey] = nil
+  end
+end
+
+local function GenerateProfileKey(key)
+    local safeKey = key;
+    if(not safeKey) then
+        safeKey = PRIVATE_SV.SAFEDATA.CurrentProfile or ("%s - %s"):format(playerName, "Default");
+    end
+    key = key or "Default";
+    if(not GLOBAL_SV.profileRealms[safeKey]) then
+        GLOBAL_SV.profileRealms[safeKey] = playerRealm;
+    elseif(safeKey:find(playerName) and GLOBAL_SV.profileRealms[safeKey] ~= playerRealm) then
+        if(key:find(playerName)) then
+            safeKey = ("%s [%s] - %s"):format(playerName, playerRealm, "Default");
+        else
+            safeKey = ("%s [%s] - %s"):format(playerName, playerRealm, key);
+        end
+        GLOBAL_SV.profileRealms[safeKey] = playerRealm;
+    end
+    PRIVATE_SV.SAFEDATA.CurrentProfile = safeKey
+
+    return safeKey
+end
+
+local function UpdateProfileSources(newKey)
+    local SOURCE_KEY = newKey;
+    local PREVIOUS_PROFILE_KEY = PROFILE_KEY;
+    if(PRIVATE_SV.SAFEDATA.DUALSPEC) then
+        local specID = GetSpecialization();
+        if(specID) then
+            local _, talentKey, _, _, _, _ = GetSpecializationInfo(specID);
+            SOURCE_KEY = talentKey or "Default";
+        end
+        lib.EventManager:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED")
+    else
+        lib.EventManager:UnregisterEvent("ACTIVE_TALENT_GROUP_CHANGED")
+    end
+
+    PROFILE_KEY = GenerateProfileKey(SOURCE_KEY)
+
+    if(not GLOBAL_SV.profiles[PROFILE_KEY]) then GLOBAL_SV.profiles[PROFILE_KEY] = {} end
+    if(not GLOBAL_SV.profileKeys[PROFILE_KEY]) then
+        for k,v in pairs(GLOBAL_SV.profiles) do
+            GLOBAL_SV.profileKeys[k] = k
+        end
+    end
+    if(not SHARED_SV.profiles[PROFILE_KEY]) then
+      SHARED_SV.profiles[PROFILE_KEY] = {};
+    end
+    if(PRIVATE_SV.SAFEDATA.THEME) then
+        THEME_KEY = PRIVATE_SV.SAFEDATA.THEME;
+    else
+        THEME_KEY = DEFAULT_THEME_KEY;
+    end
+    if(not MEDIA_SV.profiles[THEME_KEY]) then MEDIA_SV.profiles[THEME_KEY] = {} end
+    if(not MEDIA_SV.profiles[THEME_KEY][PROFILE_KEY]) then MEDIA_SV.profiles[THEME_KEY][PROFILE_KEY] = {} end
+
+    DirtyDataList[PROFILE_KEY] = THEME_KEY;
+    SaveSharedData();
+
+    if(not newKey) then
+        if((CoreObject.initialized) and (PREVIOUS_PROFILE_KEY ~= PROFILE_KEY)) then
+            local db           = setmetatable({}, meta_transdata)
+            db.data            = GLOBAL_SV.profiles[PROFILE_KEY]
+            db.defaults        = CoreObject.defaults
+            if(CoreObject.db) then wipe(CoreObject.db) end
+            CoreObject.db      = db
+
+            local media        = setmetatable({}, meta_transdata)
+            media.data         = MEDIA_SV.profiles[THEME_KEY][PROFILE_KEY]
+            media.defaults     = CoreObject.mediadefaults
+            if(CoreObject.media) then wipe(CoreObject.media) end
+            CoreObject.media   = media
+
+            lib:LiveUpdate(true)
+        end
+    end
+end
+
+local function UpdateConstraints()
+    for k,v in pairs(PRIVATE_SV.SAFEDATA.SAVED) do
+        lib.CONSTRAINTS.PROTECTED[k] = true
+    end
+end
+
+local function UpdateCoreDatabases()
+    UpdateProfileSources()
+
+    local db           = setmetatable({}, meta_transdata)
+    db.data            = GLOBAL_SV.profiles[PROFILE_KEY]
+    db.defaults        = CoreObject.defaults
+    CoreObject.db      = db
+
+    local media        = setmetatable({}, meta_transdata)
+    media.data         = MEDIA_SV.profiles[THEME_KEY][PROFILE_KEY]
+    media.defaults     = CoreObject.mediadefaults
+    CoreObject.media   = media
+
+    local private      = setmetatable({}, meta_database)
+    private.data       = PRIVATE_SV
+    CoreObject.private = private
+
+    CoreObject.ERRORLOG = ERROR_SV.FOUND
+
+    UpdateConstraints()
+end
+
+local function CorePreInitialize()
+    --PROFILE SAVED VARIABLES
+    if not _G[PRIVATE_FILENAME] then _G[PRIVATE_FILENAME] = {} end
+    PRIVATE_SV = _G[PRIVATE_FILENAME]
+    --PROFILE SAFE VARIABLES
+    if(not PRIVATE_SV.SAFEDATA) then PRIVATE_SV.SAFEDATA = {} end
+    if(not PRIVATE_SV.SAFEDATA.SAVED) then PRIVATE_SV.SAFEDATA.SAVED = {} end
+    if(not PRIVATE_SV.SAFEDATA.SHARED) then PRIVATE_SV.SAFEDATA.SHARED = {} end
+    if(not PRIVATE_SV.SAFEDATA.THEME) then PRIVATE_SV.SAFEDATA.THEME = DEFAULT_THEME_KEY end
+    if(not PRIVATE_SV.SAFEDATA.DUALSPEC) then PRIVATE_SV.SAFEDATA.DUALSPEC = false end
+    if(not PRIVATE_SV.SAFEDATA.NEEDSLIVEUPDATE) then PRIVATE_SV.SAFEDATA.NEEDSLIVEUPDATE = false end
+    --GLOBAL SAVED VARIABLES
+    if(not _G[GLOBAL_FILENAME]) then _G[GLOBAL_FILENAME] = {} end
+    GLOBAL_SV = _G[GLOBAL_FILENAME]
+    --GLOBAL PROFILE DATA
+    if(not GLOBAL_SV.profiles) then GLOBAL_SV.profiles = {} end
+    if(not GLOBAL_SV.profiles[PROFILE_KEY]) then GLOBAL_SV.profiles[PROFILE_KEY] = {} end
+    if(not GLOBAL_SV.profileRealms) then GLOBAL_SV.profileRealms = {} end
+    if(not GLOBAL_SV.profileRealms[PROFILE_KEY]) then GLOBAL_SV.profileRealms[PROFILE_KEY] = playerRealm end
+    if(not GLOBAL_SV.SAFEDATA) then GLOBAL_SV.SAFEDATA = {} end
+    if(not GLOBAL_SV.SAFEDATA.MasterProfile) then GLOBAL_SV.SAFEDATA.MasterProfile = false; end
+    --GLOBAL KEY STORAGE (ALWAYS EMPTY ON LOGIN)
+    GLOBAL_SV.profileKeys = {}
+    --SAVED ERRORS
+    if not _G[ERROR_FILENAME] then _G[ERROR_FILENAME] = {} end
+    ERROR_SV = _G[ERROR_FILENAME]
+    --ONLY ALLOW TODAYS ERRORS
+    if(ERROR_SV.TODAY and ERROR_SV.TODAY ~= DATESTAMP) then
+        ERROR_SV.FOUND = {}
+    elseif(not ERROR_SV.FOUND) then
+        ERROR_SV.FOUND = {}
+    end
+    --UPDATE THE ERROR DATESTAMP
+    ERROR_SV.TODAY = DATESTAMP
+    --MEDIA SAVED VARIABLES
+    if not _G[MEDIA_FILENAME] then _G[MEDIA_FILENAME] = {} end
+    MEDIA_SV = _G[MEDIA_FILENAME]
+    --MEDIA PROFILE DATA
+    if(not MEDIA_SV.profiles) then MEDIA_SV.profiles = {} end
+    if(not MEDIA_SV.profiles[THEME_KEY]) then MEDIA_SV.profiles[THEME_KEY] = {} end
+    if(not MEDIA_SV.profiles[THEME_KEY][PROFILE_KEY]) then MEDIA_SV.profiles[THEME_KEY][PROFILE_KEY] = {} end
+    --SHARED PRIVATE DATA
+    if not _G[SHARED_FILENAME] then _G[SHARED_FILENAME] = {} end
+    SHARED_SV = _G[SHARED_FILENAME]
+    if(not SHARED_SV.profiles) then SHARED_SV.profiles = {} end
+    if(not SHARED_SV.profiles[PROFILE_KEY]) then SHARED_SV.profiles[PROFILE_KEY] = {} end
+    --CheckForDeprecated(OLD_PROFILE_KEY);
+
+    THEME_KEY = PRIVATE_SV.SAFEDATA.THEME;
+
+    for i = 1, GetNumAddOns() do
+        local addonName, _, _, _, _, reason = GetAddOnInfo(i)
+
+        if(IsAddOnLoadOnDemand(i)) then
+            local header = GetAddOnMetadata(i, HeaderFromMeta)
+            local schema = GetAddOnMetadata(i, SchemaFromMeta)
+            local theme  = GetAddOnMetadata(i, ThemeFromMeta)
+
+            if(header and schema) then
+                LoadOnDemand[schema] = addonName;
+                if(not PRIVATE_SV.SAFEDATA.SAVED[schema]) then
+                    PRIVATE_SV.SAFEDATA.SAVED[schema] = true
+                end
+                CoreObject.Options.args[schema] = {
+                    type = "group",
+                    name = header,
+                    childGroups = "tree",
+                    args = {
+                        enable = {
+                            order = 1,
+                            type = "execute",
+                            width = "full",
+                            name = function()
+                                local nameString = "Disable"
+                                if(not IsAddOnLoaded(addonName)) then
+                                    nameString = "Enable"
+                                end
+                                return nameString
+                            end,
+                            func = function()
+                                if(not IsAddOnLoaded(addonName)) then
+                                    local loaded, reason = LoadAddOn(addonName)
+                                    PRIVATE_SV.SAFEDATA.SAVED[schema] = true
+                                    EnableAddOn(addonName)
+                                    CoreObject:StaticPopup_Show("RL_CLIENT")
+                                else
+                                    PRIVATE_SV.SAFEDATA.SAVED[schema] = false
+                                    DisableAddOn(addonName)
+                                    CoreObject:StaticPopup_Show("RL_CLIENT")
+                                end
+                            end,
+                        }
+                    }
+                }
+
+                local enabled = PRIVATE_SV.SAFEDATA.SAVED[schema]
+
+                if(enabled) then
+                    EnableAddOn(addonName)
+                    if(not IsAddOnLoaded(addonName)) then
+                        local loaded, reason = LoadAddOn(addonName)
+                    end
+                else
+                    DisableAddOn(addonName)
+                end
+            elseif(theme) then
+                CoreObject.AvailableThemes[theme] = theme;
+                if(theme == THEME_KEY) then
+                    EnableAddOn(addonName)
+                    if(not IsAddOnLoaded(addonName)) then
+                        local loaded, reason = LoadAddOn(addonName)
+                    end
+                else
+                    DisableAddOn(addonName)
+                end
+            end
+        end
+    end
+
+    UpdateCoreDatabases()
+    CoreObject.___preinitialized = true
+end
+
+--LIBRARY EVENT HANDLING
+
+local Library_OnEvent = function(self, event, arg, ...)
+    if(event == "PLAYER_LOGOUT") then
+        SaveSharedData();
+        lib:CleanUpData()
+    elseif(event == "ADDON_LOADED") then
+        if(arg == CoreName) then
+            CorePreInitialize()
+            if(not CoreObject.___loaded and CoreObject.PreLoad) then
+                CoreObject.Timers:ClearAllTimers()
+                CoreObject:PreLoad()
+                CoreObject.___loaded = true
+                self:UnregisterEvent("ADDON_LOADED")
+            end
+        end
+    elseif(event == "PLAYER_LOGIN") then
+        if(not CoreObject.initialized and CoreObject.Initialize and IsLoggedIn()) then
+            if(CoreObject.LoadTheme) then
+                CoreObject:LoadTheme()
+            end
+            UpdateCoreDatabases()
+            CoreObject:Initialize()
+            CoreObject.initialized = true
+            self:UnregisterEvent("PLAYER_LOGIN")
+        end
+        PRIVATE_SV.SAFEDATA.NEEDSLIVEUPDATE = C_PetBattles.IsInBattle()
+    elseif(event == "ACTIVE_TALENT_GROUP_CHANGED") then
+        UpdateProfileSources()
+    end
+end
+
+-- CORE OBJECT CONSTRUCT
+
+local Core_NewPlugin = function(self, addonName, addonObject, gfile, pfile)
+    local version   = GetAddOnMetadata(addonName, "Version")
+    local header    = GetAddOnMetadata(addonName, HeaderFromMeta)
+    local schema    = GetAddOnMetadata(addonName, SchemaFromMeta)
+
+    if((not schema) or (schema and _G[schema])) then return end
+
+    if(not PLUGINS) then PLUGINS = {} end
+    PLUGINS[#PLUGINS+1] = schema
+
+    local lod       = IsAddOnLoadOnDemand(addonName)
+    local addonmeta = {}
+    local oldmeta   = getmetatable(addonObject)
+
+    if oldmeta then
+        for k, v in pairs(oldmeta) do addonmeta[k] = v end
+    end
+
+    addonmeta.__tostring = rootstring
+    setmetatable( addonObject, addonmeta )
+
+    local infoString = SetPluginString(addonName)
+
+    addonObject.Version             = version
+    addonObject.NameID              = addonName
+    addonObject.TitleID             = header
+    addonObject.Info                = infoString
+    addonObject.Schema              = schema
+    addonObject.LoD                 = lod
+    addonObject.initialized         = false
+    addonObject.CombatLocked        = false
+    addonObject.MakeSharable        = makeSharable
+    addonObject.IsSharingEnabled    = isSharingEnabled
+    addonObject.ToggleSharedData    = toggleSharedData
+    addonObject.IgnoreSharedKeys    = ignoreSharedKeys
+    addonObject.ClearPrivateData    = clearPrivateDB
+    addonObject.ChangeDBVar         = changeDBVar
+    addonObject.RegisterEvent       = registerEvent
+    addonObject.UnregisterEvent     = unregisterEvent
+    addonObject.RegisterUpdate      = registerUpdate
+    addonObject.UnregisterUpdate    = unregisterUpdate
+
+    addonObject.public              = addonObject.public or {}
+    addonObject.private             = addonObject.private or {}
+
+    addonObject.___svfiles          = {["PUBLIC"] = gfile, ["PRIVATE"] = pfile}
+    addonObject.___canShare         = false;
+
+    _G[schema] = addonObject
+
+    return addonObject
+end
+
+local Core_NewPackage = function(self, schema, header)
+    if(self[schema]) then return end
+
+    if(not MODULES) then MODULES = {} end
+    MODULES[#MODULES+1] = schema
+
+    local addonName = ("SVUI [%s]"):format(schema)
+
+    local obj = {
+        NameID              = addonName,
+        TitleID             = header,
+        Schema              = schema,
+        initialized         = false,
+        CombatLocked        = false,
+        MakeSharable        = makeSharable,
+        IsSharingEnabled    = isSharingEnabled,
+        ToggleSharedData    = toggleSharedData,
+        IgnoreSharedKeys    = ignoreSharedKeys,
+        ClearPrivateData    = clearPrivateDB,
+        ChangeDBVar         = changeDBVar,
+        RegisterEvent       = registerEvent,
+        UnregisterEvent     = unregisterEvent,
+        RegisterUpdate      = registerUpdate,
+        UnregisterUpdate    = unregisterUpdate
+    }
+
+    local addonmeta = {}
+    local oldmeta = getmetatable(obj)
+    if oldmeta then
+        for k, v in pairs(oldmeta) do addonmeta[k] = v end
+    end
+    addonmeta.__tostring = rootstring
+    setmetatable( obj, addonmeta )
+
+    self[schema] = obj
+
+    return self[schema]
+end
+
+local Core_NewScript = function(self, fn)
+    if(fn and type(fn) == "function") then
+        ScriptQueue[#ScriptQueue+1] = fn
+    end
+end
+
+local Core_NewModule = function(self, addonName, addonObject, gfile, pfile)
+    local version   = GetAddOnMetadata(addonName, "Version")
+    local header    = GetAddOnMetadata(addonName, HeaderFromMeta)
+    local schema    = GetAddOnMetadata(addonName, SchemaFromMeta)
+
+    if(self[schema]) then return end
+
+    if(not MODULES) then MODULES = {} end
+    MODULES[#MODULES+1] = schema
+
+    local lod       = IsAddOnLoadOnDemand(addonName)
+    local addonmeta = {}
+    local oldmeta   = getmetatable(addonObject)
+
+    if oldmeta then
+        for k, v in pairs(oldmeta) do addonmeta[k] = v end
+    end
+
+    addonmeta.__tostring = rootstring
+    setmetatable( addonObject, addonmeta )
+
+    local packageName = ("SVUI [%s]"):format(schema)
+
+    addonObject.Version             = version
+    addonObject.NameID              = packageName
+    addonObject.TitleID             = header
+    addonObject.Schema              = schema
+    addonObject.LoD                 = lod
+    addonObject.initialized         = false
+    addonObject.CombatLocked        = false
+    addonObject.MakeSharable        = makeSharable
+    addonObject.IsSharingEnabled    = isSharingEnabled
+    addonObject.ToggleSharedData    = toggleSharedData
+    addonObject.IgnoreSharedKeys    = ignoreSharedKeys
+    addonObject.ClearPrivateData    = clearPrivateDB
+    addonObject.ChangeDBVar         = changeDBVar
+    addonObject.RegisterEvent       = registerEvent
+    addonObject.UnregisterEvent     = unregisterEvent
+    addonObject.RegisterUpdate      = registerUpdate
+    addonObject.UnregisterUpdate    = unregisterUpdate
+
+    addonObject.public              = addonObject.public or {}
+    addonObject.private             = addonObject.private or {}
+
+    addonObject.___svfiles          = {["PUBLIC"] = gfile, ["PRIVATE"] = pfile}
+    addonObject.___canShare         = false;
+
+    self[schema] = addonObject
+
+    return self[schema]
+end
+
+local Core_ResetData = function(self, sub, sub2, sub3)
+    local data = self.db
+    local sv = rawget(data, "data")
+    local src = rawget(data, "defaults")
+    local targetData
+    if(sub3 and sub2 and sv and sv[sub] and sv[sub][sub2]) then
+        targetData = sv[sub][sub2][sub3]
+    elseif(sub2 and sv and sv[sub]) then
+        targetData = sv[sub][sub2]
+    elseif(sub and sv) then
+        targetData = sv[sub]
+    else
+        targetData = sv
+    end
+    if(targetData) then
+        if(type(targetData) == 'table') then
+            for k,v in pairs(targetData) do
+                targetData[k] = nil
+            end
+        else
+            targetData = nil
+        end
+    else
+        sv = {}
+    end
+    tablecopy(sv, src)
+end
+
+local Core_ResetFilter = function(self, key)
+    local data = self.db.Filters
+    local sv = rawget(data, "data")
+    local src = rawget(data, "defaults")
+    local targetData
+    if(key and sv[key]) then
+        targetData = sv[key]
+    else
+        targetData = sv
+    end
+    if(targetData) then
+        if(type(targetData) == 'table') then
+            for k,v in pairs(targetData) do
+                targetData[k] = nil
+            end
+        else
+            targetData = nil
+        end
+    else
+        sv = {}
+    end
+    tablecopy(sv, src)
+end
+
+local Core_HandleError = function(self, schema, action, catch)
+    schema = schema or "Lib:Registry"
+    action = action or "Unknown Function"
+    local timestamp = date("%m/%d/%y %H:%M:%S")
+    local err_message = (debugPattern):format(schema, action, timestamp, catch)
+    local count = #self.ERRORLOG + 1;
+    self.ERRORLOG[count] = err_message;
+    if(self.DebugMode == true) then
+        self.HasErrors = true;
+        --self:Debugger(err_message)
+    end
+end
+
+function lib:NewCore(gfile, efile, pfile, mfile, sfile)
+    --meta assurance
+    local mt = {};
+    local old = getmetatable(CoreObject);
+    if old then
+        for k, v in pairs(old) do mt[k] = v end
+    end
+    mt.__tostring = rootstring;
+    setmetatable(CoreObject, mt);
+
+    --database
+    GLOBAL_FILENAME     = gfile or GLOBAL_FILENAME
+    ERROR_FILENAME      = efile or ERROR_FILENAME
+    PRIVATE_FILENAME    = pfile or PRIVATE_FILENAME
+    MEDIA_FILENAME      = mfile or MEDIA_FILENAME
+    SHARED_FILENAME     = sfile or SHARED_FILENAME
+
+    --events
+    if(not self.EventManager.Initialized) then
+        self.EventManager:RegisterEvent("ADDON_LOADED")
+        self.EventManager:RegisterEvent("PLAYER_LOGIN")
+        self.EventManager:RegisterEvent("PLAYER_LOGOUT")
+        self.EventManager:SetScript("OnEvent", Library_OnEvent)
+        self.EventManager.Initialized = true
+    end
+
+    --internals
+    CoreObject.___errors            = {};
+
+    CoreObject.NameID               = CoreGlobalName;
+    CoreObject.Version              = AddonVersion;
+    CoreObject.GameVersion          = tonumber(InterfaceVersion);
+    CoreObject.DebugMode            = true;
+    CoreObject.HasErrors            = false;
+    CoreObject.Schema               = GetAddOnMetadata(CoreName, SchemaFromMeta);
+    CoreObject.TitleID              = GetAddOnMetadata(CoreName, HeaderFromMeta);
+
+    CoreObject.RegisterEvent        = registerEvent
+    CoreObject.UnregisterEvent      = unregisterEvent
+    CoreObject.RegisterUpdate       = registerUpdate
+    CoreObject.UnregisterUpdate     = unregisterUpdate
+
+    CoreObject.AvailableThemes      = {["Default"] = "Default"};
+
+    CoreObject.NewScript            = Core_NewScript
+    CoreObject.NewModule            = Core_NewModule
+    CoreObject.NewPackage           = Core_NewPackage
+    CoreObject.NewPlugin            = Core_NewPlugin
+    CoreObject.ResetData            = Core_ResetData
+    CoreObject.ResetFilter          = Core_ResetFilter
+    CoreObject.HandleError          = Core_HandleError
+
+    --[[ EMBEDDED LIBS ]]--
+
+    CoreObject.L                    = Librarian("Linguist"):Lang()
+    CoreObject.Events               = Librarian("Events")
+    CoreObject.Animate              = Librarian("Animate")
+    CoreObject.Timers               = Librarian("Timers")
+    CoreObject.Sounds               = Librarian("Sounds")
+    CoreObject.SpecialFX            = Librarian("SpecialFX")
+
+    -- if(playerName == 'Failcoder') then
+    --     CoreObject.DebugMode = true;
+    -- end
+
+    --set global
+    _G[CoreGlobalName] = CoreObject;
+
+    return _G[CoreGlobalName]
+end
+
+-- INITIALIZE AND LAUNCH
+
+local function InitExternalDB(variableFile)
+  local mt = {};
+  if(not variableFile) then return mt; end
+  if(not _G[variableFile]) then _G[variableFile] = {}; end
+  if(not _G[variableFile].SAFEDATA) then _G[variableFile].SAFEDATA = {}; end
+  local db = setmetatable(mt, meta_database);
+  db.data = _G[variableFile];
+  return db;
+end
+
+function lib:Launch()
+    local settings = CoreObject.db;
+    CoreObject.Timers:Initialize();
+    if MODULES then
+        for i=1,#MODULES do
+            local halt = false;
+            local schema = MODULES[i];
+            local obj = CoreObject[schema];
+            if(obj and (not obj.initialized)) then
+                if(settings[schema] and settings[schema].incompatible) then
+                    for addon,_ in pairs(settings[schema].incompatible) do
+                        if IsAddOnLoaded(addon) then halt = true end
+                    end
+                end
+                if(not halt) then
+                    if(not PRIVATE_SV.SAFEDATA.SHARED[schema]) then
+                        PRIVATE_SV.SAFEDATA.SHARED[schema] = {
+                          enabled = false,
+                          ignored = {}
+                        };
+                    end
+                    PRIVATE_SV.SAFEDATA.SHARED[schema].ignored.SAFEDATA = true;
+                    PRIVATE_SV.SAFEDATA.SHARED[schema].ignored.data = true;
+                    local files = obj.___svfiles;
+                    if(files) then
+                        if(not PRIVATE_SV.SAFEDATA.SAVED[schema]) then
+                            PRIVATE_SV.SAFEDATA.SAVED[schema] = true;
+                        end
+
+                        obj.private = InitExternalDB(files.PRIVATE);
+                        obj.public = InitExternalDB(files.PUBLIC);
+                    end
+                    LoadingProxy(schema, obj, true)
+                end
+            end
+        end
+    end
+    if PLUGINS then
+        for i=1,#PLUGINS do
+            local halt = false;
+            local schema = PLUGINS[i];
+            local obj = _G[schema];
+            if(obj and (not obj.initialized)) then
+                local files = obj.___svfiles;
+                if(files) then
+                    if(not PRIVATE_SV.SAFEDATA.SAVED[schema]) then
+                        PRIVATE_SV.SAFEDATA.SAVED[schema] = true;
+                    end
+                    if(not PRIVATE_SV.SAFEDATA.SHARED[schema]) then
+                        PRIVATE_SV.SAFEDATA.SHARED[schema] = {
+                          enabled = false,
+                          ignored = {}
+                        };
+                    end
+                    PRIVATE_SV.SAFEDATA.SHARED[schema].ignored.SAFEDATA = true;
+                    PRIVATE_SV.SAFEDATA.SHARED[schema].ignored.data = true;
+                    obj.private = InitExternalDB(files.PRIVATE);
+                    if(obj.private.incompatible) then
+                        for addon,_ in pairs(obj.private.incompatible) do
+                            if IsAddOnLoaded(addon) then halt = true end
+                        end
+                    end
+                    if(not halt) then
+                        obj.public = InitExternalDB(files.PUBLIC);
+                    end
+                end
+                if(not halt) then
+                    LoadingProxy(schema, obj, true)
+                end
+            end
+        end
+    end
+    UpdateConstraints()
+end
+
+function lib:LoadScripts()
+    if ScriptQueue then
+        for i=1, #ScriptQueue do
+            local fn = ScriptQueue[i]
+            if(fn and type(fn) == "function") then
+                fn()
+            end
+        end
+
+        ScriptQueue = nil
+    end
+end
+
+--DATABASE PUBLIC METHODS
+function lib:Remove(key)
+    if(GLOBAL_SV.profiles[key]) then GLOBAL_SV.profiles[key] = nil end
+    if(GLOBAL_SV.profileRealms[key]) then GLOBAL_SV.profileRealms[key] = nil end
+    wipe(GLOBAL_SV.profileKeys)
+    for k,v in pairs(GLOBAL_SV.profiles) do
+        GLOBAL_SV.profileKeys[k] = k
+    end
+end
+
+function lib:GetProfiles()
+    local list = GLOBAL_SV.profileKeys or {}
+    return list
+end
+
+function lib:CheckProfiles()
+    local hasProfile = false
+    local list = GLOBAL_SV.profileKeys or {}
+    for key,_ in pairs(list) do
+        hasProfile = true
+    end
+    return hasProfile
+end
+
+function lib:CurrentProfile()
+    return PRIVATE_SV.SAFEDATA.CurrentProfile
+end
+
+function lib:UnsetProfile()
+    PRIVATE_SV.SAFEDATA.CurrentProfile = nil;
+end
+
+function lib:CopyDatabase(key, linked)
+  if((not key) or (not GLOBAL_SV.profiles[key])) then return end
+  PRIVATE_SV.SAFEDATA["install_version"] = CoreObject.Version
+  if(not linked) then
+    wipe(GLOBAL_SV.profiles[PROFILE_KEY])
+    local export = GLOBAL_SV.profiles[key];
+    local saved = GLOBAL_SV.profiles[PROFILE_KEY];
+    tablecopy(saved, export);
+
+    if(MEDIA_SV.profiles[THEME_KEY][key]) then
+      wipe(MEDIA_SV.profiles[THEME_KEY][PROFILE_KEY])
+      export = MEDIA_SV.profiles[THEME_KEY][key];
+      saved = MEDIA_SV.profiles[THEME_KEY][PROFILE_KEY];
+      tablecopy(saved, export);
+    end
+
+    CopySharedData(key);
+
+    ReloadUI()
+  else
+    UpdateProfileSources(key)
+    ReloadUI()
+  end
+end
+
+function lib:CloneDatabase(key)
+    if(not key) then return end
+    PRIVATE_SV.SAFEDATA["install_version"] = CoreObject.Version
+    local export, saved
+    if(not GLOBAL_SV.profiles[key]) then GLOBAL_SV.profiles[key] = {} end;
+    export = GLOBAL_SV.profiles[PROFILE_KEY];
+    saved = GLOBAL_SV.profiles[key];
+    tablecopy(saved, export);
+
+    if(not MEDIA_SV.profiles[THEME_KEY][key]) then MEDIA_SV.profiles[THEME_KEY][key] = {} end;
+    export = MEDIA_SV.profiles[THEME_KEY][PROFILE_KEY];
+    saved = MEDIA_SV.profiles[THEME_KEY][key];
+    tablecopy(saved, export);
+
+    DirtyDataList[key] = THEME_KEY;
+    CopySharedData(key);
+    UpdateProfileSources(key);
+end
+
+function lib:ExportDatabase()
+    local t = {["PROFILE"] = {}, ["MEDIA"] = {[THEME_KEY] = {}}};
+    tablecopy(t["PROFILE"], GLOBAL_SV.profiles[PROFILE_KEY]);
+    tablecopy(t["MEDIA"][THEME_KEY], MEDIA_SV.profiles[THEME_KEY][PROFILE_KEY]);
+
+    sanitize(t["PROFILE"], CoreObject.defaults, true)
+    sanitize(t["MEDIA"][THEME_KEY], CoreObject.mediadefaults)
+
+    local export = pickle(t)
+
+    return export:encode()
+end
+
+function lib:ImportDatabase(encoded)
+    if(not encoded) then return end
+
+    local decoded = encoded:decode();
+    local newtable = unpickle(decoded);
+    local import, saved;
+
+    wipe(GLOBAL_SV.profiles[PROFILE_KEY])
+    import = newtable["PROFILE"];
+    saved = GLOBAL_SV.profiles[PROFILE_KEY];
+    tablecopy(saved, import);
+
+    if(newtable["MEDIA"][THEME_KEY]) then
+        wipe(MEDIA_SV.profiles[THEME_KEY][PROFILE_KEY])
+        import = newtable["MEDIA"][THEME_KEY];
+        saved = MEDIA_SV.profiles[THEME_KEY][PROFILE_KEY];
+        tablecopy(saved, import);
+    end
+
+    ReloadUI()
+end
+
+function lib:WipeDatabase()
+    for k,v in pairs(GLOBAL_SV.profiles[PROFILE_KEY]) do
+        GLOBAL_SV.profiles[PROFILE_KEY][k] = nil
+    end
+    for k,v in pairs(MEDIA_SV.profiles[THEME_KEY][PROFILE_KEY]) do
+        MEDIA_SV.profiles[THEME_KEY][PROFILE_KEY][k] = nil
+    end
+    for k,v in pairs(SHARED_SV.profiles[PROFILE_KEY]) do
+        SHARED_SV.profiles[PROFILE_KEY][k] = nil
+    end
+end
+
+function lib:WipeAllSharedData()
+    for k,v in pairs(SHARED_SV.profiles) do
+        SHARED_SV.profiles[k] = nil
+    end
+end
+
+function lib:GetSafeData(index)
+    if(index) then
+        return PRIVATE_SV.SAFEDATA[index]
+    else
+        return PRIVATE_SV.SAFEDATA
+    end
+end
+
+function lib:SaveSafeData(index, value)
+    PRIVATE_SV.SAFEDATA[index] = value
+end
+
+function lib:CheckData(schema, key)
+    local file = GLOBAL_SV.profiles[PROFILE_KEY][schema]
+    print("______" .. schema .. ".db[" .. key .. "]_____")
+    print(file[key])
+    print("______SAVED_____")
+end
+
+function lib:NewGlobal(index)
+    index = index or CoreObject.Schema
+    if(not GLOBAL_SV[index]) then
+        GLOBAL_SV[index] = {}
+    end
+    return GLOBAL_SV[index]
+end
+
+function lib:CheckDualProfile()
+    return PRIVATE_SV.SAFEDATA.DUALSPEC
+end
+
+function lib:ToggleDualProfile(enabled)
+    PRIVATE_SV.SAFEDATA.DUALSPEC = enabled
+    UpdateProfileSources()
+end
+
+function lib:CheckMasterProfile()
+    local mp = GLOBAL_SV.SAFEDATA.MasterProfile
+    if(mp and GLOBAL_SV.profiles[mp]) then
+      return mp
+    else
+      return false
+    end
+end
+
+function lib:SetMasterProfile(key)
+    if((not key) or (not GLOBAL_SV.profiles[key])) then
+      GLOBAL_SV.SAFEDATA.MasterProfile = false;
+    else
+      GLOBAL_SV.SAFEDATA.MasterProfile = key;
+    end
+end
+
+--[[ UNUSED
+
+local DB_QUEUE;
+
+local addNewSubClass = function(self, schema)
+    if(self[schema]) then return end
+
+    local obj = {
+        parent              = self,
+        Schema              = schema,
+        RegisterEvent       = registerEvent,
+        UnregisterEvent     = unregisterEvent,
+        RegisterUpdate      = registerUpdate,
+        UnregisterUpdate    = unregisterUpdate
+    }
+
+    local addonmeta = {}
+    local oldmeta = getmetatable(obj)
+    if oldmeta then
+        for k, v in pairs(oldmeta) do addonmeta[k] = v end
+    end
+    addonmeta.__tostring = rootstring
+    setmetatable( obj, addonmeta )
+
+    self[schema] = obj
+
+    return self[schema]
+end
+
+local function tablesplice(mergeTable, targetTable)
+    if type(targetTable) ~= "table" then targetTable = {} end
+
+    if type(mergeTable) == 'table' then
+        for key,val in pairs(mergeTable) do
+            if type(val) == "table" then
+                targetTable[key] = tablesplice(val, targetTable[key])
+            else
+                targetTable[key] = val
+            end
+        end
+    end
+    return targetTable
+end
+
+local function ScheduledDatabase(obj)
+    local schema  = obj.Schema;
+    if(DB_QUEUE and DB_QUEUE[schema]) then
+        for key, db_keys in pairs(DB_QUEUE[schema]) do
+
+            local db_file  = db_keys[1];
+            local db_dkey = db_keys[2];
+
+            if not _G[db_file] then _G[db_file] = {} end
+
+            if(db_dkey) then
+                if not obj[db_dkey] then obj[db_dkey] = {} end
+                local this    = setmetatable({}, meta_transdata);
+                this.data     = _G[db_file];
+                this.defaults = obj[db_dkey];
+                obj[key] = this;
+            else
+                local this    = setmetatable({}, meta_database);
+                this.data     = _G[db_file];
+                obj[key] = this;
+            end
+        end
+
+        DB_QUEUE[schema] = nil;
+    end
+end
+
+local function NewDatabase(obj, newKey, fileKey, defaultKey)
+    local schema = obj.Schema
+    if not DB_QUEUE then DB_QUEUE = {} end
+    if not DB_QUEUE[schema] then DB_QUEUE[schema] = {} end
+    DB_QUEUE[schema][newKey] = {fileKey, defaultKey}
+    if(defaultKey) then
+        if not obj[defaultKey] then obj[defaultKey] = {} end
+        return tablesplice(obj[defaultKey], {});
+    else
+        return {}
+    end
+end
+
+local protected = {"customClassColor", "extended", "shared", "color", "bordercolor"},
+]]--
diff --git a/SVUI_!Core/libs/_SVUI_Lib/Sounds.lua b/SVUI_!Core/libs/_SVUI_Lib/Sounds.lua
new file mode 100644
index 0000000..a2220d5
--- /dev/null
+++ b/SVUI_!Core/libs/_SVUI_Lib/Sounds.lua
@@ -0,0 +1,168 @@
+--[[
+  /$$$$$$                                      /$$
+ /$$__  $$                                    | $$
+| $$  \__/  /$$$$$$  /$$   /$$ /$$$$$$$   /$$$$$$$  /$$$$$$$
+|  $$$$$$  /$$__  $$| $$  | $$| $$__  $$ /$$__  $$ /$$_____/
+ \____  $$| $$  \ $$| $$  | $$| $$  \ $$| $$  | $$|  $$$$$$
+ /$$  \ $$| $$  | $$| $$  | $$| $$  | $$| $$  | $$ \____  $$
+|  $$$$$$/|  $$$$$$/|  $$$$$$/| $$  | $$|  $$$$$$$ /$$$$$$$/
+ \______/  \______/  \______/ |__/  |__/ \_______/|_______/
+--]]
+
+--[[ LOCALIZED GLOBALS ]]--
+--GLOBAL NAMESPACE
+local _G = getfenv(0);
+--LUA
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pcall         = _G.pcall;
+local print         = _G.print;
+local ipairs        = _G.ipairs;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local rawset        = _G.rawset;
+local rawget        = _G.rawget;
+local tostring      = _G.tostring;
+local tonumber      = _G.tonumber;
+local getmetatable  = _G.getmetatable;
+local setmetatable  = _G.setmetatable;
+--STRING
+local string        = _G.string;
+local upper         = string.upper;
+local format        = string.format;
+local find          = string.find;
+local match         = string.match;
+local gsub          = string.gsub;
+--MATH
+local math          = _G.math;
+local random        = math.random;
+local floor         = math.floor
+--TABLE
+local table         = _G.table;
+local tsort         = table.sort;
+local tconcat       = table.concat;
+local tremove       = _G.tremove;
+local twipe         = _G.wipe;
+
+local PlaySoundFile         = _G.PlaySoundFile;
+
+--[[ LIB CONSTRUCT ]]--
+
+local lib = Librarian:NewLibrary("Sounds")
+
+if not lib then return end -- No upgrade needed
+
+--[[ DUMMY FALLBACK ]]--
+
+local BLANK_FOLEY = function()
+    return;
+end;
+
+--[[ LIB MASTER LIST ]]--
+
+lib.Master = {};
+
+-- do
+--     local DEFAULT_SOUND_TYPES = { 'button', 'error', 'window', 'misc' };
+
+--     for i = 1, #DEFAULT_SOUND_TYPES do
+--         local key = DEFAULT_SOUND_TYPES[i];
+--         lib.Master[key] = {};
+--     end
+-- end
+
+--[[ LIB TYPE CONTROLLERS ]]--
+
+lib.Effects = {};
+lib.Blends = {};
+
+--[[ LIB METHODS ]]--
+
+function lib:Register(soundType, soundFile)
+    soundType = soundType:lower();
+    if(not self.Master[soundType]) then self.Master[soundType] = {} end;
+    local count = #self.Master + 1;
+    self.Master[soundType][count] = soundFile;
+end;
+
+--[[ BLENDED SOUND EFFECTS ]]--
+
+local BlendedSound_Effect = function(self)
+    local key, sound, list;
+    local bank = self.Bank;
+    local channels = self.Channels;
+    for i = 1, channels do
+        key = random(1, #bank[i]);
+        sound = bank[i][key];
+        PlaySoundFile(sound);
+    end
+end
+
+function lib:Blend(blendName, ...)
+    blendName = blendName:lower();
+    if(not self.Blends[blendName]) then
+        self.Blends[blendName] = {};
+        self.Blends[blendName].Bank = {};
+
+        local numChannels = select('#', ...)
+
+        for i = 1, numChannels do
+            local soundType = select(i, ...)
+            soundType = soundType:lower();
+            if not soundType then break end
+            if(not self.Master[soundType]) then
+                self.Master[soundType] = {};
+            end
+            self.Blends[blendName].Bank[i] = self.Master[soundType];
+        end
+
+        self.Blends[blendName].Channels = numChannels;
+        self.Blends[blendName].Foley = BlendedSound_Effect;
+
+        setmetatable(self.Blends[blendName], { __call = self.Blends[blendName].Foley })
+    end
+
+    if(self.Blends[blendName]) then
+        return self.Blends[blendName]
+    else
+        return BLANK_FOLEY
+    end
+end;
+
+--[[ STANDARD SOUND EFFECTS ]]--
+
+local StandardSound_Effect = function(self)
+    local key, sound, list;
+    local bank = self.Bank;
+    local channels = self.Channels;
+    for i = 1, channels do
+        list = bank[i];
+        key = random(1,#list);
+        sound = list[key];
+        PlaySoundFile(sound)
+    end
+end
+
+function lib:Effect(effectName)
+    effectName = effectName:lower();
+    if(not self.Effects[effectName]) then
+        self.Effects[effectName] = {};
+
+        if(not self.Master[effectName]) then
+            self.Master[effectName] = {};
+        end
+
+        self.Effects[effectName].Bank = self.Master[effectName];
+        self.Effects[effectName].Foley = StandardSound_Effect;
+
+        setmetatable(self.Effects[effectName], { __call = self.Effects[effectName].Foley })
+    end
+
+    if(self.Effects[effectName]) then
+        return self.Effects[effectName]
+    else
+        return BLANK_FOLEY
+    end
+end;
diff --git a/SVUI_!Core/libs/_SVUI_Lib/SpecialFX.lua b/SVUI_!Core/libs/_SVUI_Lib/SpecialFX.lua
new file mode 100644
index 0000000..77dd552
--- /dev/null
+++ b/SVUI_!Core/libs/_SVUI_Lib/SpecialFX.lua
@@ -0,0 +1,293 @@
+--[[
+  /$$$$$$                                /$$           /$$ /$$$$$$$$ /$$   /$$
+ /$$__  $$                              |__/          | $$| $$_____/| $$  / $$
+| $$  \__/  /$$$$$$   /$$$$$$   /$$$$$$$ /$$  /$$$$$$ | $$| $$      |  $$/ $$/
+|  $$$$$$  /$$__  $$ /$$__  $$ /$$_____/| $$ |____  $$| $$| $$$$$    \  $$$$/
+ \____  $$| $$  \ $$| $$$$$$$$| $$      | $$  /$$$$$$$| $$| $$__/     >$$  $$
+ /$$  \ $$| $$  | $$| $$_____/| $$      | $$ /$$__  $$| $$| $$       /$$/\  $$
+|  $$$$$$/| $$$$$$$/|  $$$$$$$|  $$$$$$$| $$|  $$$$$$$| $$| $$      | $$  \ $$
+ \______/ | $$____/  \_______/ \_______/|__/ \_______/|__/|__/      |__/  |__/
+          | $$
+          | $$
+          |__/
+--]]
+
+--[[ LOCALIZED GLOBALS ]]--
+--GLOBAL NAMESPACE
+local _G = getfenv(0);
+--LUA
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pcall         = _G.pcall;
+local print         = _G.print;
+local ipairs        = _G.ipairs;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local rawset        = _G.rawset;
+local rawget        = _G.rawget;
+local tostring      = _G.tostring;
+local tonumber      = _G.tonumber;
+local getmetatable  = _G.getmetatable;
+local setmetatable  = _G.setmetatable;
+--STRING
+local string        = _G.string;
+local upper         = string.upper;
+local format        = string.format;
+local find          = string.find;
+local match         = string.match;
+local gsub          = string.gsub;
+--MATH
+local math          = _G.math;
+local random        = math.random;
+local floor         = math.floor
+--TABLE
+local table         = _G.table;
+local tsort         = table.sort;
+local tconcat       = table.concat;
+local tremove       = _G.tremove;
+local twipe         = _G.wipe;
+
+local CreateFrame           = _G.CreateFrame;
+
+--[[ LIB CONSTRUCT ]]--
+
+local lib = Librarian:NewLibrary("SpecialFX")
+
+if not lib then return end
+
+--[[ LIB EFFECT TABLES ]]--
+
+local DEFAULT_MODEL = [[Spells\Missile_bomb.m2]];
+local DEFAULT_EFFECT = {DEFAULT_MODEL, 0, 0, 0, 0, 0.75, 0, 0};
+local EFFECTS_LIST = setmetatable({
+    ["default"]     = {[[Spells\Missile_bomb.m2]], -12, 12, 12, -12, 0.4, 0.125, 0.05},
+    ["holy"]        = {[[Spells\Solar_precast_hand.m2]], -12, 12, 12, -12, 0.23, 0, 0},
+    ["shadow"]      = {[[Spells\Shadow_precast_uber_hand.m2]], -12, 12, 12, -12, 0.23, -0.1, 0.1},
+    ["arcane"]      = {[[Spells\Cast_arcane_01.m2]], -12, 12, 12, -12, 0.25, 0, 0},
+    ["fire"]        = {[[Spells\Bloodlust_state_hand.m2]], -8, 4, 24, -24, 0.70, -0.22, 0.22},
+    ["frost"]       = {[[Spells\Ice_cast_low_hand.m2]], -12, 12, 12, -12, 0.25, -0.2, -0.35},
+    ["chi"]         = {[[Spells\Fel_fire_precast_high_hand.m2]], -12, 12, 12, -12, 0.3, -0.04, -0.1},
+    ["lightning"]   = {[[Spells\Fill_lightning_cast_01.m2]], -12, 12, 12, -12, 1.25, 0, 0},
+    ["water"]       = {[[Spells\Monk_drunkenhaze_impact.m2]], -12, 12, 12, -12, 0.9, 0, 0},
+    ["earth"]       = {[[Spells\Sand_precast_hand.m2]], -12, 12, 12, -12, 0.23, 0, 0},
+}, { __index = function(t, k)
+  return DEFAULT_EFFECT
+end });
+
+local DEFAULT_ROUTINE = {0, 2000};
+local MODEL_ROUTINES = setmetatable({
+    ["idle"]            = {0, 2000},
+    ["walk"]            = {4, 2000},
+    ["run"]             = {5, 2000},
+    ["attack1"]         = {26, 2000},
+    ["falling"]         = {40, 2000},
+    ["casting1"]        = {52, 2000},
+    ["static_roar"]     = {55, 2000},
+    ["chat"]            = {60, 2000},
+    ["yell"]            = {64, 2000},
+    ["shrug"]           = {65, 2000},
+    ["dance"]           = {69, 2000},
+    ["roar"]            = {74, 2000},
+    ["attack2"]         = {111, 2000},
+    ["sneak"]           = {119, 2000},
+    ["stealth"]         = {120, 2000},
+    ["casting2"]        = {125, 2000},
+    ["crafting"]        = {138, 2000},
+    ["kneel"]           = {141, 2000},
+    ["cannibalize"]     = {203, 2000},
+    ["cower"]           = {225, 2000},
+}, { __index = function(t, k)
+  return DEFAULT_ROUTINE
+end });
+
+--[[ CHARACTER MODEL METHODS ]]--
+
+local CharacterModel_OnUpdate = function(self, elapsed)
+    if(self.___frameIndex < self.___maxIndex) then
+        self.___frameIndex = (self.___frameIndex + (elapsed * 1000));
+    else
+        self.___frameIndex = 0;
+        self:SetAnimation(0);
+        self:SetScript("OnUpdate", nil);
+    end
+end
+
+local CharacterModel_UseAnimation = function(self, animationName)
+    animationName = animationName or self.___currentAnimation;
+    local effectTable = self.___routines[effectName];
+    self.___frameIndex = 0;
+    self.___maxIndex = effectTable[2];
+    self.___currentAnimation = animationName;
+    self:SetAnimation(effectTable[1]);
+    self:SetScript("OnUpdate", CharacterModel_OnUpdate);
+end
+
+--[[ EFFECT FRAME METHODS ]]--
+
+local EffectModel_SetAnchorParent = function(self, frame)
+    self.___anchorParent = frame;
+    self:SetEffect(self.currentEffect);
+end
+
+local EffectModel_OnShow = function(self)
+    self.FX:UpdateEffect();
+end
+
+local EffectModel_UpdateEffect = function(self)
+    local effect = self.currentEffect;
+    local effectTable = self.___fx[effect];
+    self:ClearModel();
+    self:SetModel(effectTable[1]);
+end
+
+local EffectModel_SetEffect = function(self, effectName)
+    effectName = effectName or self.currentEffect;
+    local effectTable = self.___fx[effectName];
+    local parent = self.___anchorParent;
+    self:ClearAllPoints();
+    self:SetPoint("TOPLEFT", parent, "TOPLEFT", effectTable[2], effectTable[3]);
+    self:SetPoint("BOTTOMRIGHT", parent, "BOTTOMRIGHT", effectTable[4], effectTable[5]);
+    self:ClearModel();
+    self:SetModel(effectTable[1]);
+    self:SetCamDistanceScale(effectTable[6]);
+    self:SetPosition(0, effectTable[7], effectTable[8]);
+    self:SetPortraitZoom(0);
+    self.currentEffect = effectName;
+end
+
+--[[ LIB METHODS ]]--
+
+function lib:Register(request, modelFile, leftX, leftY, rightX, rightY, zoom, posX, posY)
+    if(type(request) == 'string') then
+      request = request:lower();
+      modelFile = modelFile or DEFAULT_MODEL;
+      leftX = leftX or 0;
+      leftY = leftY or 0;
+      rightX = rightX or 0;
+      rightY = rightY or 0;
+      zoom = zoom or 0.75;
+      posX = posX or 0;
+      posY = posY or 0;
+      rawset(EFFECTS_LIST, request, {modelFile, leftX, leftY, rightX, rightY, zoom, posX, posY})
+    elseif(request.SetAnimation) then
+      request.___routines = {};
+      setmetatable(request.___routines, { __index = ANIMATION_IDS });
+      request.___frameIndex = 0;
+      request.___maxIndex = 2000;
+      request.___currentAnimation = "idle";
+      request.UseAnimation = CharacterModel_UseAnimation;
+    end
+end;
+
+function lib:SetFXFrame(parent, defaultEffect, noScript, anchorParent)
+    defaultEffect = defaultEffect or "default"
+    local model = CreateFrame("PlayerModel", nil, parent);
+    model.___fx = {};
+    setmetatable(model.___fx, { __index = EFFECTS_LIST });
+    model.___anchorParent = anchorParent or parent;
+    model.SetEffect = EffectModel_SetEffect;
+    model.SetAnchorParent = EffectModel_SetAnchorParent;
+    model.UpdateEffect = EffectModel_UpdateEffect;
+    model.currentEffect = defaultEffect;
+    parent.FX = model;
+    --print(defaultEffect)
+    EffectModel_SetEffect(model, defaultEffect)
+
+    if(not noScript) then
+        if(parent:GetScript("OnShow")) then
+            parent:HookScript("OnShow", EffectModel_OnShow)
+        else
+            parent:SetScript("OnShow", EffectModel_OnShow)
+        end
+    end
+end
+
+--[[ MODEL FILES FOUND FOR EFFECTS ]]--
+
+-- [[Spells\Fel_fire_precast_high_hand.m2]]
+-- [[Spells\Fire_precast_high_hand.m2]]
+-- [[Spells\Fire_precast_low_hand.m2]]
+-- [[Spells\Focused_casting_state.m2]]
+-- [[Spells\Fill_holy_cast_01.m2]]
+-- [[Spells\Fill_fire_cast_01.m2]]
+-- [[Spells\Paladin_healinghands_state_01.m2]]
+-- [[Spells\Fill_magma_cast_01.m2]]
+-- [[Spells\Fill_shadow_cast_01.m2]]
+-- [[Spells\Fill_arcane_precast_01.m2]]
+-- [[Spells\Ice_cast_low_hand.m2]]
+-- [[Spells\Immolate_state.m2]]
+-- [[Spells\Immolate_state_v2_illidari.m2]]
+-- [[Spells\Intervenetrail.m2]]
+-- [[Spells\Invisibility_impact_base.m2]]
+-- [[Spells\Fire_dot_state_chest.m2]]
+-- [[Spells\Fire_dot_state_chest_jade.m2]]
+-- [[Spells\Cast_arcane_01.m2]]
+-- [[Spells\Spellsteal_missile.m2]]
+-- [[Spells\Missile_bomb.m2]]
+-- [[Spells\Shadow_frost_weapon_effect.m2]]
+-- [[Spells\Shadow_precast_high_base.m2]]
+-- [[Spells\Shadow_precast_high_hand.m2]]
+-- [[Spells\Shadow_precast_low_hand.m2]]
+-- [[Spells\Shadow_precast_med_base.m2]]
+-- [[Spells\Shadow_precast_uber_hand.m2]]
+-- [[Spells\Shadow_strikes_state_hand.m2]]
+-- [[Spells\Shadowbolt_missile.m2]]
+-- [[Spells\Shadowworddominate_chest.m2]]
+-- [[Spells\Infernal_smoke_rec.m2]]
+-- [[Spells\Largebluegreenradiationfog.m2]]
+-- [[Spells\Leishen_lightning_fill.m2]]
+-- [[Spells\Mage_arcanebarrage_missile.m2]]
+-- [[Spells\Mage_firestarter.m2]]
+-- [[Spells\Mage_greaterinvis_state_chest.m2]]
+-- [[Spells\Magicunlock.m2]]
+-- [[Spells\Chiwave_impact_hostile.m2]]
+-- [[Spells\Cripple_state_base.m2]]
+-- [[Spells\Monk_expelharm_missile.m2]]
+-- [[Spells\Monk_forcespere_orb.m2]]
+-- [[Spells\Fill_holy_cast_01.m2]]
+-- [[Spells\Fill_fire_cast_01.m2]]
+-- [[Spells\Fill_lightning_cast_01.m2]]
+-- [[Spells\Fill_magma_cast_01.m2]]
+-- [[Spells\Fill_shadow_cast_01.m2]]
+-- [[Spells\Sprint_impact_chest.m2]]
+-- [[Spells\Spellsteal_missile.m2]]
+-- [[Spells\Warlock_destructioncharge_impact_chest.m2]]
+-- [[Spells\Warlock_destructioncharge_impact_chest_fel.m2]]
+-- [[Spells\Xplosion_twilight_impact_noflash.m2]]
+-- [[Spells\Warlock_bodyofflames_medium_state_shoulder_right_purple.m2]]
+-- [[Spells\Blink_impact_chest.m2]]
+-- [[Spells\Christmassnowrain.m2]]
+-- [[Spells\Detectinvis_impact_base.m2]]
+-- [[Spells\Eastern_plaguelands_beam_effect.m2]]
+-- [[Spells\battlemasterglow_high.m2]]
+-- [[Spells\blueflame_low.m2]]
+-- [[Spells\greenflame_low.m2]]
+-- [[Spells\purpleglow_high.m2]]
+-- [[Spells\redflame_low.m2]]
+-- [[Spells\poisondrip.m2]]
+-- [[Spells\savageryglow_high.m2]]
+-- [[Spells\spellsurgeglow_high.m2]]
+-- [[Spells\sunfireglow_high.m2]]
+-- [[Spells\whiteflame_low.m2]]
+-- [[Spells\yellowflame_low.m2]]
+-- [[Spells\Food_healeffect_base.m2]]
+-- [[Spells\Bloodlust_state_hand.m2]]
+-- [[Spells\Deathwish_state_hand.m2]]
+-- [[Spells\Disenchant_precast_hand.m2]]
+-- [[Spells\Enchant_cast_hand.m2]]
+-- [[Spells\Eviscerate_cast_hands.m2]]
+-- [[Spells\Fire_blue_precast_hand.m2]]
+-- [[Spells\Fire_blue_precast_high_hand.m2]]
+-- [[Spells\Fire_precast_hand.m2]]
+-- [[Spells\Fire_precast_hand_pink.m2]]
+-- [[Spells\Fire_precast_hand_sha.m2]]
+-- [[Spells\Fire_precast_high_hand.m2]]
+-- [[Spells\Fire_precast_low_hand.m2]]
+-- [[Spells\Ice_precast_high_hand.m2]]
+-- [[Spells\Sand_precast_hand.m2]]
+-- [[Spells\Solar_precast_hand.m2]]
+-- [[Spells\Twilight_fire_precast_high_hand.m2]]
+-- [[Spells\Vengeance_state_hand.m2]]
+-- [[Spells\Fel_djinndeath_fire_02.m2]]
diff --git a/SVUI_!Core/libs/_SVUI_Lib/Timers.lua b/SVUI_!Core/libs/_SVUI_Lib/Timers.lua
new file mode 100644
index 0000000..ac9ce61
--- /dev/null
+++ b/SVUI_!Core/libs/_SVUI_Lib/Timers.lua
@@ -0,0 +1,140 @@
+--[[
+ /$$$$$$$$/$$
+|__  $$__/__/
+   | $$   /$$ /$$$$$$/$$$$   /$$$$$$   /$$$$$$  /$$$$$$$
+   | $$  | $$| $$_  $$_  $$ /$$__  $$ /$$__  $$/$$_____/
+   | $$  | $$| $$ \ $$ \ $$| $$$$$$$$| $$  \__/  $$$$$$
+   | $$  | $$| $$ | $$ | $$| $$_____/| $$      \____  $$
+   | $$  | $$| $$ | $$ | $$|  $$$$$$$| $$      /$$$$$$$/
+   |__/  |__/|__/ |__/ |__/ \_______/|__/     |_______/
+--]]
+
+--[[ LOCALIZED GLOBALS ]]--
+--GLOBAL NAMESPACE
+local _G = getfenv(0);
+--LUA
+local select        = _G.select;
+local type          = _G.type;
+local pairs         = _G.pairs;
+local assert        = _G.assert;
+local rawset        = _G.rawset;
+local rawget        = _G.rawget;
+local getmetatable  = _G.getmetatable;
+local setmetatable  = _G.setmetatable;
+local string        = _G.string;
+local math          = _G.math;
+local table         = _G.table;
+--[[ STRING METHODS ]]--
+local format = string.format;
+--[[ MATH METHODS ]]--
+local abs, ceil, floor, round = math.abs, math.ceil, math.floor, math.round;
+--[[ TABLE METHODS ]]--
+local tremove = table.remove;
+--BLIZZARD API
+local wipe          = _G.wipe;
+local GetLocale     = _G.GetLocale;
+
+--[[ LIB CONSTRUCT ]]--
+
+local lib = Librarian:NewLibrary("Timers")
+
+if not lib then return end -- No upgrade needed
+
+--[[ LIB EVENT LISTENER ]]--
+
+lib.Handler = CreateFrame("Frame", nil)
+
+--[[ LOCAL VARS ]]--
+
+local TimerQueue = {};
+local TimerCount = 0;
+
+local ExeTimerManager_OnUpdate = function(self, elapsed)
+    if(TimerCount > 0) then
+        for id,_ in pairs(TimerQueue) do
+            local callback = TimerQueue[id]
+            if(callback.f) then
+                if callback.t > elapsed then
+                    local newTime = callback.t - elapsed
+                    TimerQueue[id].t = newTime
+                else
+                    callback.f()
+                    if(callback.x) then
+                        TimerQueue[id].t = callback.x
+                    else
+                        TimerQueue[id] = nil
+                        TimerCount = TimerCount - 1;
+                    end
+                end
+            end
+        end
+    end
+end
+
+local Timers_EventHandler = function(self, event)
+    if(event == "PLAYER_REGEN_DISABLED") then
+        self:SetScript("OnUpdate", nil)
+    else
+        self:SetScript("OnUpdate", ExeTimerManager_OnUpdate)
+    end
+end
+
+--[[ PUBLIC METHODS ]]--
+
+function lib:ExecuteTimer(timeOutFunction, duration, idCheck)
+    if(type(duration) == "number" and type(timeOutFunction) == "function") then
+        if(idCheck and TimerQueue[idCheck]) then
+            TimerQueue[idCheck].t = duration
+            return idCheck
+        else
+            TimerCount = TimerCount + 1
+            local id = "LOOP" .. TimerCount;
+            TimerQueue[id] = {t = duration, f = timeOutFunction}
+            return id
+        end
+    end
+    return false
+end
+
+function lib:RemoveTimer(id)
+    if(TimerQueue[id]) then
+        TimerQueue[id] = nil
+        TimerCount = TimerCount - 1;
+    end
+end
+
+function lib:ExecuteLoop(timeOutFunction, duration, idCheck)
+    if(type(duration) == "number" and type(timeOutFunction) == "function") then
+        if(idCheck and TimerQueue[idCheck]) then
+            TimerQueue[idCheck].x = duration
+            TimerQueue[idCheck].t = duration
+            return idCheck
+        else
+            TimerCount = TimerCount + 1
+            local id = "LOOP" .. TimerCount;
+            TimerQueue[id] = {x = duration, t = duration, f = timeOutFunction}
+            return id
+        end
+    end
+    return false
+end
+
+function lib:RemoveLoop(id)
+    if(TimerQueue[id]) then
+        TimerQueue[id] = nil
+        TimerCount = TimerCount - 1;
+    end
+end
+
+function lib:ClearAllTimers()
+    wipe(TimerQueue)
+    self.Handler:SetScript("OnUpdate", nil)
+    self.Handler:SetScript("OnUpdate", ExeTimerManager_OnUpdate)
+end
+
+function lib:Initialize()
+    self.Handler:RegisterEvent('PLAYER_REGEN_ENABLED')
+    self.Handler:RegisterEvent('PLAYER_REGEN_DISABLED')
+    self.Handler:SetScript("OnEvent", Timers_EventHandler)
+    self.Handler:SetScript("OnUpdate", ExeTimerManager_OnUpdate)
+end
diff --git a/SVUI_!Core/libs/_SVUI_Lib/_SVUI_Lib.xml b/SVUI_!Core/libs/_SVUI_Lib/_SVUI_Lib.xml
new file mode 100644
index 0000000..0fd4cfc
--- /dev/null
+++ b/SVUI_!Core/libs/_SVUI_Lib/_SVUI_Lib.xml
@@ -0,0 +1,11 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+	<Script file="LUA.lua"/>
+	<Script file="External.lua"/>
+	<Script file="Linguist.lua"/>
+	<Script file="Registry.lua"/>
+	<Script file="Events.lua"/>
+	<Script file="Timers.lua"/>
+	<Script file="Animate.lua"/>
+	<Script file="Sounds.lua"/>
+	<Script file="SpecialFX.lua"/>
+</Ui>
\ No newline at end of file
diff --git a/SVUI_!Core/libs/_load.xml b/SVUI_!Core/libs/_load.xml
new file mode 100644
index 0000000..8032db0
--- /dev/null
+++ b/SVUI_!Core/libs/_load.xml
@@ -0,0 +1,9 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+	<Script file="_Librarian\Librarian.lua"/>
+	<Script file="CallbackHandler-1.0\CallbackHandler-1.0.lua"/>
+	<Script file="LibSharedMedia-3.0\LibSharedMedia-3.0.lua"/>
+	<Include file="_SVUI_Lib\_SVUI_Lib.xml"/>
+	<Include file="AceGUI-3.0\AceGUI-3.0.xml"/>
+	<Include file="AceConfig-3.0\AceConfig-3.0.xml"/>
+	<Include file="AceVillain-1.0\AceVillain-1.0.xml"/>
+</Ui>
diff --git a/SVUI_!Core/setup/_load.xml b/SVUI_!Core/setup/_load.xml
new file mode 100644
index 0000000..6324606
--- /dev/null
+++ b/SVUI_!Core/setup/_load.xml
@@ -0,0 +1,5 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+    <Script file="installer.lua"/>
+    <Script file="theme_select.lua"/>
+    <Script file="presets.lua"/>
+</Ui>
\ No newline at end of file
diff --git a/SVUI_!Core/setup/installer.lua b/SVUI_!Core/setup/installer.lua
new file mode 100644
index 0000000..bc20f6b
--- /dev/null
+++ b/SVUI_!Core/setup/installer.lua
@@ -0,0 +1,1243 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pcall         = _G.pcall;
+local print         = _G.print;
+local ipairs        = _G.ipairs;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local rawset        = _G.rawset;
+local rawget        = _G.rawget;
+local tostring      = _G.tostring;
+local tonumber      = _G.tonumber;
+local string 	= _G.string;
+local table     = _G.table;
+local format = string.format;
+local tcopy = table.copy;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...)
+local SVUILib = Librarian("Registry");
+local L = SV.L;
+--[[
+##########################################################
+LOCAL VARS
+##########################################################
+]]--
+local CURRENT_PAGE, MAX_PAGE, XOFF = 0, 9, (GetScreenWidth() * 0.025)
+local okToResetMOVE = false;
+local mungs = false;
+local user_music_vol = GetCVar("Sound_MusicVolume") or 0;
+local musicIsPlaying;
+local PageData, OnClickData;
+local SetCVar = _G.SetCVar;
+local ToggleChatColorNamesByClassGroup = _G.ToggleChatColorNamesByClassGroup;
+local ChatFrame_AddMessageGroup = _G.ChatFrame_AddMessageGroup;
+--[[
+##########################################################
+SETUP CLASS OBJECT
+##########################################################
+]]--
+SV.Setup = {};
+SV.media.button = {
+	["option"] 		= [[Interface\AddOns\SVUI_!Core\assets\textures\SETUP-OPTION]],
+	["arrow"] 		= [[Interface\AddOns\SVUI_!Core\assets\textures\SETUP-ARROW]],
+	["theme"] 		= [[Interface\AddOns\SVUI_!Core\assets\textures\THEME-DEFAULT]]
+};
+local preset_mediastyle = "default";
+local preset_barstyle = "default";
+local preset_unitstyle = "default";
+local preset_groupstyle = "default";
+local preset_aurastyle = "default";
+--[[
+##########################################################
+LOCAL FUNCTIONS
+##########################################################
+]]--
+local function PlayThemeSong()
+	if(not musicIsPlaying) then
+		SetCVar("Sound_MusicVolume", 100)
+		SetCVar("Sound_EnableMusic", 1)
+		StopMusic()
+		PlayMusic([[Interface\AddOns\SVUI_!Core\assets\sounds\SuperVillain.mp3]])
+		musicIsPlaying = true
+	end
+end
+
+local function SetInstallButton(button)
+    if(not button) then return end
+    button.Left:SetAlpha(0)
+    button.Middle:SetAlpha(0)
+    button.Right:SetAlpha(0)
+    button:SetNormalTexture("")
+    button:SetPushedTexture("")
+    button:SetPushedTexture("")
+    button:SetDisabledTexture("")
+    button:RemoveTextures()
+    button:SetFrameLevel(button:GetFrameLevel() + 1)
+end
+
+local function forceCVars()
+	SetCVar("statusTextDisplay","BOTH")
+	SetCVar("ShowClassColorInNameplate",1)
+	SetCVar("screenshotQuality",10)
+	SetCVar("chatMouseScroll",1)
+	SetCVar("chatStyle","classic")
+	SetCVar("WholeChatWindowClickable",0)
+	SetCVar("showTutorials",0)
+	SetCVar("UberTooltips",1)
+	SetCVar("threatWarning",3)
+	SetCVar('alwaysShowActionBars',1)
+	SetCVar('lockActionBars',1)
+	SetCVar('SpamFilter',0)
+	InterfaceOptionsActionBarsPanelPickupActionKeyDropDown:SetValue('SHIFT')
+	InterfaceOptionsActionBarsPanelPickupActionKeyDropDown:RefreshValue()
+end
+
+local function ShowLayout(show)
+	if(not SV.UnitFrames) then return end
+	if(not _G["SVUI_Raid"] or (show and _G["SVUI_Raid"].forceShow == true)) then return end
+	if(not show and _G["SVUI_Raid"].forceShow ~= true) then return end
+	SV.UnitFrames:ViewGroupFrames(_G["SVUI_Raid"], show)
+end
+
+local function ShowAuras(show)
+	if(not SV.UnitFrames) then return end
+	if(not _G["SVUI_Player"] or (show and _G["SVUI_Player"].forceShowAuras)) then return end
+	if(not show and not _G["SVUI_Player"].forceShowAuras) then return end
+	_G["SVUI_Player"].forceShowAuras = show
+	SV.UnitFrames:SetUnitFrame("player")
+end
+
+local function BarShuffle()
+	if(not SV.ActionBars) then return end
+	local bS = SV.db.ActionBars.Bar1.buttonspacing;
+
+	SV:ReAnchor("SVUI_ActionBar2", "BOTTOM", SVUI_ActionBar1, "TOP", 0, -bS);
+	SV:ReAnchor("SVUI_ActionBar3", "BOTTOMLEFT", SVUI_ActionBar1, "BOTTOMRIGHT", 4, 0);
+	SV:ReAnchor("SVUI_ActionBar5", "BOTTOMRIGHT", SVUI_ActionBar1, "BOTTOMLEFT", -4, 0);
+	SV:ReAnchor("SVUI_PetActionBar", "BOTTOMLEFT", SVUI_ActionBarMainAnchor, "TOPLEFT", 0, 4);
+	SV:ReAnchor("SVUI_StanceBar", "BOTTOMRIGHT", SVUI_ActionBarMainAnchor, "TOPRIGHT", 0, 4);
+	SV:ReAnchor("SVUI_SpecialAbility", "BOTTOM", SVUI_ActionBarMainAnchor, "TOP", 0, 75);
+end
+
+local function UFMoveBottomQuadrant(toggle)
+	if(not SV.UnitFrames) then return end
+	local x, y, x2, y2, x3, y3;
+	if(SV.LowRez) then
+		x, y, x2, y2, x3, y3 = 80, 135, 136, 285, 495, 135;
+	elseif(not toggle) then
+		x, y, x2, y2, x3, y3 = 80, 182, 310, 432, 495, 182;
+	else
+		x, y, x2, y2, x3, y3 = 80, 210, 310, 432, 495, 210;
+	end
+
+	SV:ReAnchor("SVUI_Player", "BOTTOMRIGHT", SV.Screen, "BOTTOM", -x, y);
+	SV:ReAnchor("SVUI_PlayerCastbar", "BOTTOMRIGHT", SV.Screen, "BOTTOM", -x, y-60);
+	SV:ReAnchor("SVUI_Pet", "RIGHT", SVUI_Player, "LEFT", -2, 0);
+	SV:ReAnchor("SVUI_Target", "BOTTOMLEFT", SV.Screen, "BOTTOM", x, y);
+	SV:ReAnchor("SVUI_TargetCastbar", "BOTTOMLEFT", SV.Screen, "BOTTOM", x, y-60);
+	SV:ReAnchor("SVUI_TargetTarget", "LEFT", SVUI_Target, "RIGHT", 2, 0);
+	SV:ReAnchor("SVUI_Focus", "BOTTOMLEFT", SV.Screen, "BOTTOM", x2, y2);
+	SV:ReAnchor("SVUI_ThreatBar", "BOTTOMRIGHT", SV.Screen, "BOTTOMRIGHT", -x3, y3);
+end
+
+local function UFMoveLeftQuadrant(toggle)
+	if(not SV.UnitFrames) then return end
+	local dH = SV.db.Dock.dockLeftHeight + 60
+	local x, y1, y2, y3;
+	if(not toggle) then
+		x, y1, y2, y3 = XOFF, 325, 250, 175;
+	else
+		x, y1, y2, y3 = 4, 325, 250, 175;
+	end
+
+	SV:ReAnchor("SVUI_Party", "BOTTOMLEFT", SV.Screen, "BOTTOMLEFT", x, dH);
+	SV:ReAnchor("SVUI_Raid", "BOTTOMLEFT", SV.Screen, "BOTTOMLEFT", x, dH);
+	SV:ReAnchor("SVUI_Raidpet", "TOPLEFT", SV.Screen, "TOPLEFT", x, -y1);
+	SV:ReAnchor("SVUI_Assist", "TOPLEFT", SV.Screen, "TOPLEFT", x, -y2);
+	SV:ReAnchor("SVUI_Tank", "TOPLEFT", SV.Screen, "TOPLEFT", x, -y3);
+end
+
+local function UFMoveTopQuadrant(toggle)
+	if(not SV.UnitFrames) then return end
+	local x1, x2, y1, y2, y3, y4;
+	if(not toggle) then
+		x1, x2, y1, y2, y3, y4 = 250, 4, 25, 350, 40, 250;
+	else
+		x1, x2, y1, y2, y3, y4 = 344, 4, 25, 254, 40, 250;
+	end
+
+	SV:ReAnchor("TicketStatusFrame", "TOPLEFT", SV.Screen, "TOPLEFT", x1, -y1);
+	SV:ReAnchor("SVUI_LootFrame", "BOTTOM", SV.Screen, "BOTTOM", 0, y2);
+	SV:ReAnchor("SVUI_AltPowerBar", "TOP", SV.Screen, "TOP", 0, -y3);
+	SV:ReAnchor("BattleNetToasts", "TOPRIGHT", SV.Screen, "TOPRIGHT", x2, -y4);
+end
+
+local function UFMoveRightQuadrant(toggle)
+	if(not SV.UnitFrames) then return end
+	local dH = SV.db.Dock.dockRightHeight + 60
+	local x, x2;
+	if(not toggle) then
+		x, x2 = 105, 284;
+	else
+		x, x2 = 105, 284;
+	end
+
+	SV:ReAnchor("SVUI_BossHolder", "RIGHT", SV.Screen, "RIGHT", -x, 0);
+	SV:ReAnchor("SVUI_ArenaHolder", "RIGHT", SV.Screen, "RIGHT", -x, 0);
+	if(SV.Tooltip) then
+		SV:ReAnchor("SVUI_ToolTip", "BOTTOMRIGHT", SV.Screen, "BOTTOMRIGHT", -x2, dH);
+	end
+end
+--[[
+##########################################################
+GLOBAL/MODULE FUNCTIONS
+##########################################################
+]]--
+function SV.Setup:UserScreen(rez, preserve)
+	if not preserve then
+		if okToResetMOVE then
+			SV:ResetAnchors("")
+			okToResetMOVE = false;
+		end
+		SV:ResetData("UnitFrames")
+	end
+
+	if rez == "low" then
+		if not preserve then
+			SV.db.Dock.dockLeftWidth = 350;
+			SV.db.Dock.dockLeftHeight = 180;
+			SV.db.Dock.dockRightWidth = 350;
+			SV.db.Dock.dockRightHeight = 180;
+			if(SV.Auras) then
+				SV.db.Auras.wrapAfter = 10;
+			end
+			if(SV.UnitFrames) then
+				SV.db.UnitFrames.fontSize = 10;
+				SV.db.UnitFrames.player.width = 150;
+				SV.db.UnitFrames.player.castbar.width = 150;
+				SV.db.UnitFrames.player.classbar.fill = "fill"
+				SV.db.UnitFrames.player.health.tags = "[health:color][health:current]"
+				SV.db.UnitFrames.target.width = 150;
+				SV.db.UnitFrames.target.castbar.width = 150;
+				SV.db.UnitFrames.target.health.tags = "[health:color][health:current]"
+				SV.db.UnitFrames.pet.power.enable = false;
+				SV.db.UnitFrames.pet.width = 75;
+				SV.db.UnitFrames.targettarget.debuffs.enable = false;
+				SV.db.UnitFrames.targettarget.power.enable = false;
+				SV.db.UnitFrames.targettarget.width = 75;
+				SV.db.UnitFrames.boss.width = 150;
+				SV.db.UnitFrames.boss.castbar.width = 150;
+				SV.db.UnitFrames.arena.width = 150;
+				SV.db.UnitFrames.arena.castbar.width = 150
+			end
+		end
+		SV.LowRez = true
+	else
+		SV:ResetData("Dock")
+		SV:ResetData("Auras")
+		SV.LowRez = nil
+	end
+
+	if(not preserve and not mungs) then
+		-- BarShuffle()
+    SV:UpdateAnchors()
+		SVUILib:RefreshModule('Dock')
+		SVUILib:RefreshModule('Auras')
+		SVUILib:RefreshModule('ActionBars')
+		SVUILib:RefreshModule('UnitFrames')
+		SV:SavedPopup()
+	end
+end
+
+function SV.Setup:ChatConfigs(mungs)
+	forceCVars()
+
+	if(SV.Chat) then
+		SV.Chat:ResetChatWindows()
+	else
+		for i=1, NUM_CHAT_WINDOWS do
+			local chatFrame = _G["ChatFrame"..i];
+			if(chatFrame) then
+				chatFrame.isUninteractable = false;
+				chatFrame:SetMovable(true);
+			end
+		end
+
+		FCF_ResetChatWindows()
+		FCF_SetLocked(ChatFrame1, true)
+		FCF_SetLocked(ChatFrame2, true)
+		FCF_OpenNewWindow(LOOT)
+		FCF_SetLocked(ChatFrame3, true)
+
+		for i = 1, NUM_CHAT_WINDOWS do
+			local chat = _G["ChatFrame"..i]
+			local chatID = chat:GetID()
+			if i == 1 and SV.Chat then
+				chat:ClearAllPoints()
+				chat:SetAllPoints(SV.Chat.Dock);
+			end
+			FCF_SavePositionAndDimensions(chat)
+			FCF_StopDragging(chat)
+			FCF_SetChatWindowFontSize(nil, chat, 12)
+			if i == 1 then
+				FCF_SetWindowName(chat, GENERAL)
+			elseif i == 2 then
+				FCF_SetWindowName(chat, GUILD_EVENT_LOG)
+			elseif i == 3 then
+				FCF_SetWindowName(chat, LOOT)
+			end
+		end
+
+		ChatFrame_RemoveAllMessageGroups(ChatFrame1)
+		ChatFrame_AddMessageGroup(ChatFrame1, "SAY")
+		ChatFrame_AddMessageGroup(ChatFrame1, "EMOTE")
+		ChatFrame_AddMessageGroup(ChatFrame1, "YELL")
+		ChatFrame_AddMessageGroup(ChatFrame1, "GUILD")
+		ChatFrame_AddMessageGroup(ChatFrame1, "OFFICER")
+		ChatFrame_AddMessageGroup(ChatFrame1, "GUILD_ACHIEVEMENT")
+		ChatFrame_AddMessageGroup(ChatFrame1, "WHISPER")
+		ChatFrame_AddMessageGroup(ChatFrame1, "MONSTER_SAY")
+		ChatFrame_AddMessageGroup(ChatFrame1, "MONSTER_EMOTE")
+		ChatFrame_AddMessageGroup(ChatFrame1, "MONSTER_YELL")
+		ChatFrame_AddMessageGroup(ChatFrame1, "MONSTER_BOSS_EMOTE")
+		ChatFrame_AddMessageGroup(ChatFrame1, "PARTY")
+		ChatFrame_AddMessageGroup(ChatFrame1, "PARTY_LEADER")
+		ChatFrame_AddMessageGroup(ChatFrame1, "RAID")
+		ChatFrame_AddMessageGroup(ChatFrame1, "RAID_LEADER")
+		ChatFrame_AddMessageGroup(ChatFrame1, "RAID_WARNING")
+		ChatFrame_AddMessageGroup(ChatFrame1, "INSTANCE_CHAT")
+		ChatFrame_AddMessageGroup(ChatFrame1, "INSTANCE_CHAT_LEADER")
+		ChatFrame_AddMessageGroup(ChatFrame1, "BATTLEGROUND")
+		ChatFrame_AddMessageGroup(ChatFrame1, "BATTLEGROUND_LEADER")
+		ChatFrame_AddMessageGroup(ChatFrame1, "BG_HORDE")
+		ChatFrame_AddMessageGroup(ChatFrame1, "BG_ALLIANCE")
+		ChatFrame_AddMessageGroup(ChatFrame1, "BG_NEUTRAL")
+		ChatFrame_AddMessageGroup(ChatFrame1, "SYSTEM")
+		ChatFrame_AddMessageGroup(ChatFrame1, "ERRORS")
+		ChatFrame_AddMessageGroup(ChatFrame1, "AFK")
+		ChatFrame_AddMessageGroup(ChatFrame1, "DND")
+		ChatFrame_AddMessageGroup(ChatFrame1, "IGNORED")
+		ChatFrame_AddMessageGroup(ChatFrame1, "ACHIEVEMENT")
+		ChatFrame_AddMessageGroup(ChatFrame1, "BN_WHISPER")
+		ChatFrame_AddMessageGroup(ChatFrame1, "BN_CONVERSATION")
+		ChatFrame_AddMessageGroup(ChatFrame1, "BN_INLINE_TOAST_ALERT")
+		ChatFrame_AddMessageGroup(ChatFrame1, "COMBAT_FACTION_CHANGE")
+		ChatFrame_AddMessageGroup(ChatFrame1, "SKILL")
+		ChatFrame_AddMessageGroup(ChatFrame1, "LOOT")
+		ChatFrame_AddMessageGroup(ChatFrame1, "MONEY")
+		ChatFrame_AddMessageGroup(ChatFrame1, "COMBAT_XP_GAIN")
+		ChatFrame_AddMessageGroup(ChatFrame1, "COMBAT_HONOR_GAIN")
+		ChatFrame_AddMessageGroup(ChatFrame1, "COMBAT_GUILD_XP_GAIN")
+
+		ChatFrame_RemoveAllMessageGroups(ChatFrame3)
+		ChatFrame_AddMessageGroup(ChatFrame3, "COMBAT_FACTION_CHANGE")
+		ChatFrame_AddMessageGroup(ChatFrame3, "SKILL")
+		ChatFrame_AddMessageGroup(ChatFrame3, "LOOT")
+		ChatFrame_AddMessageGroup(ChatFrame3, "MONEY")
+		ChatFrame_AddMessageGroup(ChatFrame3, "COMBAT_XP_GAIN")
+		ChatFrame_AddMessageGroup(ChatFrame3, "COMBAT_HONOR_GAIN")
+		ChatFrame_AddMessageGroup(ChatFrame3, "COMBAT_GUILD_XP_GAIN")
+
+		ChatFrame_AddChannel(ChatFrame1, GENERAL)
+
+		ToggleChatColorNamesByClassGroup(true, "SAY")
+		ToggleChatColorNamesByClassGroup(true, "EMOTE")
+		ToggleChatColorNamesByClassGroup(true, "YELL")
+		ToggleChatColorNamesByClassGroup(true, "GUILD")
+		ToggleChatColorNamesByClassGroup(true, "OFFICER")
+		ToggleChatColorNamesByClassGroup(true, "GUILD_ACHIEVEMENT")
+		ToggleChatColorNamesByClassGroup(true, "ACHIEVEMENT")
+		ToggleChatColorNamesByClassGroup(true, "WHISPER")
+		ToggleChatColorNamesByClassGroup(true, "PARTY")
+		ToggleChatColorNamesByClassGroup(true, "PARTY_LEADER")
+		ToggleChatColorNamesByClassGroup(true, "RAID")
+		ToggleChatColorNamesByClassGroup(true, "RAID_LEADER")
+		ToggleChatColorNamesByClassGroup(true, "RAID_WARNING")
+		ToggleChatColorNamesByClassGroup(true, "BATTLEGROUND")
+		ToggleChatColorNamesByClassGroup(true, "BATTLEGROUND_LEADER")
+		ToggleChatColorNamesByClassGroup(true, "INSTANCE_CHAT")
+		ToggleChatColorNamesByClassGroup(true, "INSTANCE_CHAT_LEADER")
+		ToggleChatColorNamesByClassGroup(true, "CHANNEL1")
+		ToggleChatColorNamesByClassGroup(true, "CHANNEL2")
+		ToggleChatColorNamesByClassGroup(true, "CHANNEL3")
+		ToggleChatColorNamesByClassGroup(true, "CHANNEL4")
+		ToggleChatColorNamesByClassGroup(true, "CHANNEL5")
+		ToggleChatColorNamesByClassGroup(true, "CHANNEL6")
+		ToggleChatColorNamesByClassGroup(true, "CHANNEL7")
+		ToggleChatColorNamesByClassGroup(true, "CHANNEL8")
+		ToggleChatColorNamesByClassGroup(true, "CHANNEL9")
+		ToggleChatColorNamesByClassGroup(true, "CHANNEL10")
+		ToggleChatColorNamesByClassGroup(true, "CHANNEL11")
+
+		ChangeChatColor("CHANNEL1", 195 / 255, 230 / 255, 232 / 255)
+		ChangeChatColor("CHANNEL2", 232 / 255, 158 / 255, 121 / 255)
+		ChangeChatColor("CHANNEL3", 232 / 255, 228 / 255, 121 / 255)
+	end
+
+	if not mungs then
+		if SV.Chat then
+			SV.Chat:ReLoad(true)
+			if(SV.private.Docks.LeftFaded or SV.private.Docks.RightFaded) then
+				ToggleSuperDocks()
+			end
+		end
+		SV:SavedPopup()
+	end
+end
+
+function SV.Setup:RandomBackdrops()
+	self:GenerateBackdrops()
+	SV:UpdateSharedMedia()
+	if(SV.UnitFrames) then SVUILib:RefreshModule('UnitFrames') end
+end
+
+function SV.Setup:ColorTheme(style, preserve)
+	preset_mediastyle = style or "default";
+
+	if not preserve then
+		SV:ResetData("media")
+	end
+
+	self:CopyPreset("media", preset_mediastyle)
+	SVUILib:SaveSafeData("preset_mediastyle", preset_mediastyle);
+
+	if(SV.UnitFrames) then
+		if(preset_mediastyle == "default") then
+			SV.db.UnitFrames.healthclass = true;
+		else
+			SV.db.UnitFrames.healthclass = false;
+		end
+	end
+
+	if(not mungs) then
+		SV:UpdateSharedMedia()
+		SVUILib:RefreshModule('Dock')
+		if(SV.UnitFrames) then SVUILib:RefreshModule('UnitFrames') end
+		if(not preserve) then
+			SV:SavedPopup()
+		end
+	end
+end
+
+function SV.Setup:UnitframeLayout(style, preserve)
+	if(not SV.UnitFrames) then return end
+	preset_unitstyle = style or "default";
+
+	if not preserve then
+		SV:ResetData("UnitFrames")
+		SV:ResetData("Dock")
+		if okToResetMOVE then
+			SV:ResetAnchors('')
+			okToResetMOVE = false
+		end
+	end
+
+	self:CopyPreset("units", preset_unitstyle)
+	SVUILib:SaveSafeData("preset_unitstyle", preset_unitstyle);
+
+	if(preset_mediastyle == "default") then
+		SV.db.UnitFrames.healthclass = true;
+	end
+
+	if(not mungs) then
+		if(not preserve) then
+			if preset_barstyle and (preset_barstyle == "twosmall" or preset_barstyle == "twobig") then
+				UFMoveBottomQuadrant(true)
+			else
+				UFMoveBottomQuadrant()
+			end
+			SV:UpdateAnchors()
+		end
+		if(not preserve) then
+			--BarShuffle()
+			SV:UpdateAnchors()
+		end
+		SVUILib:RefreshModule('Dock')
+		SVUILib:RefreshModule('ActionBars')
+		SVUILib:RefreshModule('UnitFrames')
+		if(not preserve) then
+			SV:SavedPopup()
+		end
+	end
+end
+
+function SV.Setup:GroupframeLayout(style, preserve)
+	if(not SV.UnitFrames) then return end
+	preset_groupstyle = style or "default";
+	self:CopyPreset("layouts", preset_groupstyle)
+	SVUILib:SaveSafeData("preset_groupstyle", preset_groupstyle);
+
+	if(not mungs) then
+		SVUILib:RefreshModule('UnitFrames')
+		if(not preserve) then
+			SV:SavedPopup()
+		end
+	end
+end
+
+function SV.Setup:BarLayout(style, preserve)
+	if(not SV.ActionBars) then return end
+	preset_barstyle = style or "default";
+
+	if not preserve then
+		SV:ResetData("ActionBars")
+		if okToResetMOVE then
+			SV:ResetAnchors('')
+			okToResetMOVE=false
+		end
+	end
+
+	self:CopyPreset("bars", preset_barstyle)
+	SVUILib:SaveSafeData("preset_barstyle", preset_barstyle);
+
+	if(not mungs) then
+		if(not preserve) then
+			if(preset_barstyle == 'twosmall' or preset_barstyle == 'twobig') then
+				UFMoveBottomQuadrant("shift")
+			else
+				UFMoveBottomQuadrant()
+			end
+		end
+		SVUILib:RefreshModule('Dock')
+		SVUILib:RefreshModule('ActionBars')
+		if(not preserve) then
+			--BarShuffle()
+			SV:UpdateAnchors()
+			SV:SavedPopup()
+		end
+	end
+end
+
+function SV.Setup:Auralayout(style, preserve)
+	if(not SV.UnitFrames) then return end
+	preset_aurastyle = style or "default";
+
+	self:CopyPreset("auras", preset_aurastyle)
+
+	SVUILib:SaveSafeData("preset_aurastyle", preset_aurastyle);
+
+	if(not mungs) then
+		SVUILib:RefreshModule('UnitFrames')
+		if(not preserve) then
+			SV:SavedPopup()
+		end
+	end
+end
+
+function SV.Setup:EZDefault()
+	mungs = true;
+	okToResetMOVE = false;
+
+	self:SetAllDefaults()
+
+	self:ChatConfigs(true);
+	self:UserScreen()
+	self:ColorTheme("default", true);
+	self:UnitframeLayout("default", true);
+	self:GroupframeLayout("default", true);
+	self:BarLayout("default", true);
+	self:Auralayout("default", true);
+
+	SV.db.FunStuff.comix = '1';
+	SV.db.FunStuff.gamemenu = '1';
+	SV.db.FunStuff.afk = '1';
+
+	SV.db.general.woot = true;
+	SV.db.general.arenadrink = true;
+	SV.db.general.stupidhat = true;
+
+	SV.db.Dock.backdrop = true;
+	SV.db.Reports.backdrop = true;
+
+	if(SV.Auras) then
+		SV.db.Auras.hyperBuffsEnabled = true;
+	end
+	if(SV.Inventory) then
+		SV.db.Inventory.bagTools = true;
+		SV.db.Inventory.enable = true;
+	end
+	if(SV.Maps) then
+		SV.db.Maps.customIcons = true;
+		SV.db.Maps.bordersize = 6;
+		SV.db.Maps.locationText = "";
+		SV.db.Maps.playercoords = "";
+	end
+	if(SV.NamePlates) then
+		SV.db.NamePlates.themed = true;
+	end
+	if(SV.Tooltip) then
+		SV.db.Tooltip.themed = true;
+	end
+	if(SV.UnitFrames) then
+		SV.db.UnitFrames.themed = true;
+	end
+	SVUILib:SaveSafeData("install_version", SV.Version)
+	StopMusic()
+	SetCVar("Sound_MusicVolume", user_music_vol or 0)
+	ReloadUI()
+end
+
+function SV.Setup:Minimalist()
+	mungs = true;
+	okToResetMOVE = false;
+	self:SetAllDefaults()
+	self:ChatConfigs(true);
+	self:UserScreen()
+	self:ColorTheme("classy", true);
+	self:UnitframeLayout("compact", true);
+	self:GroupframeLayout("grid", true);
+	self:BarLayout("default", true);
+	self:Auralayout("default", true);
+
+	SV.db.general.comix = false;
+	SV.db.general.gamemenu = false;
+	SV.db.general.afk = false;
+	SV.db.general.woot = false;
+	SV.db.general.arenadrink = false;
+	SV.db.general.stupidhat = false;
+
+	SV.db.Dock.backdrop = false;
+	SV.db.Reports.backdrop = false;
+	if(SV.Auras) then
+		SV.db.Auras.hyperBuffsEnabled = false;
+	end
+	if(SV.Inventory) then
+		SV.db.Inventory.bagTools = false;
+		SV.db.Inventory.enable = false;
+	end
+	if(SV.Maps) then
+		SV.db.Maps.customIcons = false;
+		SV.db.Maps.bordersize = 0;
+		SV.db.Maps.bordercolor = "dark";
+		SV.db.Maps.locationText = "SIMPLE";
+		SV.db.Maps.playercoords = "HIDE";
+	end
+	if(SV.NamePlates) then
+		SV.db.NamePlates.themed = false;
+	end
+	if(SV.Tooltip) then
+		SV.db.Tooltip.themed = false;
+	end
+	if(SV.UnitFrames) then
+		SV.db.UnitFrames.themed = false;
+		SV.db.UnitFrames.player.height = 22;
+		SV.db.UnitFrames.player.power.height = 6;
+		SV.db.UnitFrames.target.height = 22;
+		SV.db.UnitFrames.target.power.height = 6;
+		SV.db.UnitFrames.targettarget.height = 22;
+		SV.db.UnitFrames.targettarget.power.height = 6;
+		SV.db.UnitFrames.pet.height = 22;
+		SV.db.UnitFrames.pet.power.height = 6;
+		SV.db.UnitFrames.focus.height = 22;
+		SV.db.UnitFrames.focus.power.height = 6;
+		SV.db.UnitFrames.boss.height = 22;
+		SV.db.UnitFrames.boss.power.height = 6;
+		UFMoveBottomQuadrant()
+	end
+
+	SVUILib:SaveSafeData("install_version", SV.Version)
+	StopMusic()
+	SetCVar("Sound_MusicVolume", user_music_vol or 0)
+	ReloadUI()
+end
+
+function SV.Setup:Complete()
+	SVUILib:SaveSafeData("install_version", SV.Version)
+	StopMusic()
+	SetCVar("Sound_MusicVolume", user_music_vol or 0)
+	okToResetMOVE = false;
+	ReloadUI()
+end
+
+function SV.Setup:NewSettings()
+	CURRENT_PAGE = 2;
+	SVUI_InstallerFrame:SetPage(CURRENT_PAGE)
+end
+
+local OptionButton_OnClick = function(self)
+	local fn = self.FuncName
+	if(self.ClickIndex) then
+		for option, text in pairs(self.ClickIndex) do
+			SVUI_InstallerFrame[option]:SetText(text)
+		end
+	end
+	if(SV.Setup[fn] and type(SV.Setup[fn]) == "function") then
+		SV.Setup[fn](SV.Setup, self.Arg)
+	end
+end
+
+local InstallerFrame_PreparePage = function(self)
+	self.Option01:Hide()
+	self.Option01:SetScript("OnClick",nil)
+	self.Option01:SetText("")
+	self.Option01.FuncName = nil
+	self.Option01.Arg = nil
+	self.Option01.ClickIndex = nil
+	self.Option01:SetWidth(160)
+	self.Option01.texture:SetSize(160, 160)
+	self.Option01.texture:SetPoint("CENTER", self.Option01, "BOTTOM", 0, -(160 * 0.09))
+	self.Option01:ClearAllPoints()
+	self.Option01:SetPoint("BOTTOM", 0, 15)
+
+	self.Option02:Hide()
+	self.Option02:SetScript("OnClick",nil)
+	self.Option02:SetText("")
+	self.Option02.FuncName = nil
+	self.Option02.Arg = nil
+	self.Option02.ClickIndex = nil
+	self.Option02:ClearAllPoints()
+	self.Option02:SetPoint("BOTTOMLEFT", self, "BOTTOM", 4, 15)
+
+	self.Option03:Hide()
+	self.Option03:SetScript("OnClick",nil)
+	self.Option03:SetText("")
+	self.Option03.FuncName = nil
+	self.Option03.Arg = nil
+	self.Option03.ClickIndex = nil
+
+	self.Option1:Hide()
+	self.Option1:SetScript("OnClick",nil)
+	self.Option1:SetText("")
+	self.Option1.FuncName = nil
+	self.Option1.Arg = nil
+	self.Option1.ClickIndex = nil
+	self.Option1:SetWidth(160)
+	self.Option1.texture:SetSize(160, 160)
+	self.Option1.texture:SetPoint("CENTER", self.Option1, "BOTTOM", 0, -(160 * 0.09))
+	self.Option1:ClearAllPoints()
+	self.Option1:SetPoint("BOTTOM", 0, 15)
+
+	self.Option2:Hide()
+	self.Option2:SetScript('OnClick',nil)
+	self.Option2:SetText('')
+	self.Option2.FuncName = nil
+	self.Option2.Arg = nil
+	self.Option2.ClickIndex = nil
+	self.Option2:SetWidth(120)
+	self.Option2.texture:SetSize(120, 120)
+	self.Option2.texture:SetPoint("CENTER", self.Option2, "BOTTOM", 0, -(120 * 0.09))
+	self.Option2:ClearAllPoints()
+	self.Option2:SetPoint("BOTTOMLEFT", self, "BOTTOM", 4, 15)
+
+	self.Option3:Hide()
+	self.Option3:SetScript('OnClick',nil)
+	self.Option3:SetText('')
+	self.Option3.FuncName = nil
+	self.Option3.Arg = nil
+	self.Option3.ClickIndex = nil
+	self.Option3:SetWidth(120)
+	self.Option3.texture:SetSize(120, 120)
+	self.Option3.texture:SetPoint("CENTER", self.Option3, "BOTTOM", 0, -(120 * 0.09))
+	self.Option3:ClearAllPoints()
+	self.Option3:SetPoint("LEFT", self.Option2, "RIGHT", 4, 0)
+
+	self.Option4:Hide()
+	self.Option4:SetScript('OnClick',nil)
+	self.Option4:SetText('')
+	self.Option4.FuncName = nil
+	self.Option4.Arg = nil
+	self.Option4.ClickIndex = nil
+	self.Option4:SetWidth(110)
+	self.Option4.texture:SetSize(110, 110)
+	self.Option4.texture:SetPoint("CENTER", self.Option4, "BOTTOM", 0, -(110 * 0.09))
+	self.Option4:ClearAllPoints()
+	self.Option4:SetPoint("LEFT", self.Option3, "RIGHT", 4, 0)
+
+	self.SubTitle:SetText("")
+	self.Desc1:SetText("")
+	self.Desc2:SetText("")
+	self.Desc3:SetText("")
+
+	if CURRENT_PAGE == 1 then
+		self.Prev:Disable()
+		self.Prev:Hide()
+	else
+		self.Prev:Enable()
+		self.Prev:Show()
+	end
+
+	if CURRENT_PAGE == MAX_PAGE then
+		self.Next:Disable()
+		self.Next:Hide()
+		self:SetSize(550, 350)
+	else
+		self.Next:Enable()
+		self.Next:Show()
+		self:SetSize(550,400)
+	end
+end
+
+local InstallerFrame_SetPage = function(self, newPage)
+	PageData, MAX_PAGE = SV.Setup:CopyPage(newPage)
+	CURRENT_PAGE = newPage;
+	local willShowLayout = CURRENT_PAGE == 5 or CURRENT_PAGE == 6;
+	local willShowAuras = CURRENT_PAGE == 8;
+
+	self:PreparePage()
+	self.Status:SetText(CURRENT_PAGE.."  /  "..MAX_PAGE)
+
+	ShowLayout(willShowLayout)
+	ShowAuras(willShowAuras)
+
+	for option, data in pairs(PageData) do
+		if(self[option]) then
+			if(type(data) == "table" and data[1]) then
+				if(type(data[1]) == 'function') then
+					local n,fn = data[1]()
+					self[option]:SetText(n)
+					self[option].FuncName = fn
+					self[option].Arg = nil
+				else
+					if(not data[2]) then return end
+					self[option]:SetText(data[1])
+					self[option].FuncName = data[2]
+					self[option].Arg = data[3]
+				end
+				self[option]:Show()
+				local postclickIndex = ("%d_%s"):format(newPage, option)
+				self[option].ClickIndex = SV.Setup:CopyOnClick(postclickIndex)
+				self[option]:SetScript("OnClick", OptionButton_OnClick)
+			elseif(type(data) == "function") then
+				local optionText = data()
+				self[option]:SetText(optionText)
+			else
+				self[option]:SetText(data)
+			end
+		end
+	end
+end
+
+local NextPage_OnClick = function(self)
+	if CURRENT_PAGE ~= MAX_PAGE then
+		CURRENT_PAGE = CURRENT_PAGE + 1;
+		self.parent:SetPage(CURRENT_PAGE)
+	end
+end
+
+local PreviousPage_OnClick = function(self)
+	if CURRENT_PAGE ~= 1 then
+		CURRENT_PAGE = CURRENT_PAGE - 1;
+		self.parent:SetPage(CURRENT_PAGE)
+	end
+end
+
+function SV.Setup:Reset()
+	SVUILib:WipeDatabase()
+
+	mungs = true;
+	okToResetMOVE = false;
+	self:ChatConfigs(true);
+	self:UserScreen()
+
+	local old = SVUILib:GetSafeData()
+    preset_mediastyle = old.preset_mediastyle or "default";
+	preset_barstyle = old.preset_barstyle or "default";
+	preset_unitstyle = old.preset_unitstyle or "default";
+	preset_groupstyle = old.preset_groupstyle or "default";
+	preset_aurastyle = old.preset_aurastyle or "default";
+
+	self:ColorTheme(preset_mediastyle)
+    self:BarLayout(preset_barstyle)
+    self:UnitframeLayout(preset_unitstyle)
+    self:GroupframeLayout(preset_groupstyle)
+    self:Auralayout(preset_aurastyle)
+
+	SVUILib:SaveSafeData("install_version", SV.Version);
+	ReloadUI()
+end
+
+function SV.Setup:Install(autoLoaded)
+	local mp = SVUILib:CheckMasterProfile();
+	if(mp) then
+    	SV.SystemAlert["MASTER_PROFILE_PROMPT"].OnAccept = function() SVUILib:CopyDatabase(mp) end
+		SV.SystemAlert["MASTER_PROFILE_PROMPT"].OnCancel = function() SV.Setup:LoadInstaller(autoLoaded) end
+    	SV:StaticPopup_Show("MASTER_PROFILE_PROMPT")
+	else
+		SV.Setup:LoadInstaller(autoLoaded)
+	end
+end
+
+function SV.Setup:LoadInstaller(autoLoaded)
+	local old = SVUILib:GetSafeData()
+  preset_mediastyle = old.preset_mediastyle or "default";
+	preset_barstyle = old.preset_barstyle or "default";
+	preset_unitstyle = old.preset_unitstyle or "default";
+	preset_groupstyle = old.preset_groupstyle or "default";
+	preset_aurastyle = old.preset_aurastyle or "default";
+
+	if not SVUI_InstallerFrame then
+		local frame = CreateFrame("Button", "SVUI_InstallerFrame", UIParent)
+		frame:SetSize(550, 400)
+		frame:SetStyle("Frame", "Window2")
+		frame:SetPoint("TOP", SV.Screen, "TOP", 0, -150)
+		frame:SetFrameStrata("TOOLTIP")
+
+		frame.SetPage = InstallerFrame_SetPage;
+		frame.PreparePage = InstallerFrame_PreparePage;
+
+		--[[ NEXT PAGE BUTTON ]]--
+
+		frame.Next = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
+		frame.Next:RemoveTextures()
+		frame.Next:SetSize(110, 25)
+		frame.Next:SetPoint("BOTTOMRIGHT", 50, 5)
+		SetInstallButton(frame.Next)
+		frame.Next.texture = frame.Next:CreateTexture(nil, "BORDER")
+		frame.Next.texture:SetSize(110, 75)
+		frame.Next.texture:SetPoint("RIGHT")
+		frame.Next.texture:SetTexture(SV.media.button.arrow)
+		frame.Next.texture:SetVertexColor(1, 0.5, 0)
+		frame.Next.text = frame.Next:CreateFontString(nil, "OVERLAY")
+		frame.Next.text:SetFont(SV.media.font.flash, 18, "OUTLINE")
+		frame.Next.text:SetPoint("CENTER")
+		frame.Next.text:SetText(CONTINUE)
+		frame.Next:Disable()
+		frame.Next.parent = frame
+		frame.Next:SetScript("OnClick", NextPage_OnClick)
+		frame.Next:SetScript("OnEnter", function(this)
+			this.texture:SetVertexColor(1, 1, 0)
+		end)
+		frame.Next:SetScript("OnLeave", function(this)
+			this.texture:SetVertexColor(1, 0.5, 0)
+		end)
+
+		--[[ PREVIOUS PAGE BUTTON ]]--
+
+		frame.Prev = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
+		frame.Prev:RemoveTextures()
+		frame.Prev:SetSize(110, 25)
+		frame.Prev:SetPoint("BOTTOMLEFT", -50, 5)
+		SetInstallButton(frame.Prev)
+		frame.Prev.texture = frame.Prev:CreateTexture(nil, "BORDER")
+		frame.Prev.texture:SetSize(110, 75)
+		frame.Prev.texture:SetPoint("LEFT")
+		frame.Prev.texture:SetTexture(SV.media.button.arrow)
+		frame.Prev.texture:SetTexCoord(1, 0, 1, 1, 0, 0, 0, 1)
+		frame.Prev.texture:SetVertexColor(1, 0.5, 0)
+		frame.Prev.text = frame.Prev:CreateFontString(nil, "OVERLAY")
+		frame.Prev.text:SetFont(SV.media.font.flash, 18, "OUTLINE")
+		frame.Prev.text:SetPoint("CENTER")
+		frame.Prev.text:SetText(PREVIOUS)
+		frame.Prev:Disable()
+		frame.Prev.parent = frame
+		frame.Prev:SetScript("OnClick", PreviousPage_OnClick)
+		frame.Prev:SetScript("OnEnter", function(this)
+			this.texture:SetVertexColor(1, 1, 0)
+		end)
+		frame.Prev:SetScript("OnLeave", function(this)
+			this.texture:SetVertexColor(1, 0.5, 0)
+		end)
+
+		--[[ OPTION 01 ]]--
+
+		frame.Option01 = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
+		frame.Option01:RemoveTextures()
+		frame.Option01:SetSize(160, 30)
+		frame.Option01:SetPoint("BOTTOM", 0, 15)
+		frame.Option01:SetText("")
+		SetInstallButton(frame.Option01)
+		frame.Option01.texture = frame.Option01:CreateTexture(nil, "BORDER")
+		frame.Option01.texture:SetSize(160, 160)
+		frame.Option01.texture:SetPoint("CENTER", frame.Option01, "BOTTOM", 0, -15)
+		frame.Option01.texture:SetTexture(SV.media.button.option)
+		frame.Option01.texture:SetGradient("VERTICAL", 0, 0.3, 0, 0, 0.7, 0)
+		frame.Option01:SetScript("OnEnter", function(this)
+			this.texture:SetVertexColor(0.5, 1, 0.4)
+		end)
+		frame.Option01:SetScript("OnLeave", function(this)
+			this.texture:SetGradient("VERTICAL", 0, 0.3, 0, 0, 0.7, 0)
+		end)
+		frame.Option01:SetFrameLevel(frame.Option01:GetFrameLevel() + 10)
+		frame.Option01:Hide()
+
+		--[[ OPTION 02 ]]--
+
+		frame.Option02 = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
+		frame.Option02:RemoveTextures()
+		frame.Option02:SetSize(130, 30)
+		frame.Option02:SetPoint("BOTTOMLEFT", frame, "BOTTOM", 4, 15)
+		frame.Option02:SetText("")
+		SetInstallButton(frame.Option02)
+		frame.Option02.texture = frame.Option02:CreateTexture(nil, "BORDER")
+		frame.Option02.texture:SetSize(130, 110)
+		frame.Option02.texture:SetPoint("CENTER", frame.Option02, "BOTTOM", 0, -15)
+		frame.Option02.texture:SetTexture(SV.media.button.option)
+		frame.Option02.texture:SetGradient("VERTICAL", 0, 0.1, 0.3, 0, 0.5, 0.7)
+		frame.Option02:SetScript("OnEnter", function(this)
+			this.texture:SetVertexColor(0.5, 1, 0.4)
+		end)
+		frame.Option02:SetScript("OnLeave", function(this)
+			this.texture:SetGradient("VERTICAL", 0, 0.1, 0.3, 0, 0.5, 0.7)
+		end)
+		frame.Option02:SetScript("OnShow", function(self)
+			if(not frame.Option03:IsShown()) then
+				frame.Option01:SetWidth(130)
+				frame.Option01.texture:SetSize(130, 130)
+				frame.Option01.texture:SetPoint("CENTER", frame.Option01, "BOTTOM", 0, -(130 * 0.09))
+				frame.Option01:ClearAllPoints()
+				frame.Option01:SetPoint("BOTTOMRIGHT", frame, "BOTTOM", -4, 15)
+
+				self:SetWidth(130)
+				self.texture:SetSize(130, 130)
+			end
+		end)
+		frame.Option02:SetFrameLevel(frame.Option01:GetFrameLevel() + 10)
+		frame.Option02:Hide()
+
+		--[[ OPTION 03 ]]--
+
+		frame.Option03 = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
+		frame.Option03:RemoveTextures()
+		frame.Option03:SetSize(130, 30)
+		frame.Option03:SetPoint("BOTTOM", frame, "BOTTOM", 0, 15)
+		frame.Option03:SetText("")
+		SetInstallButton(frame.Option03)
+		frame.Option03.texture = frame.Option03:CreateTexture(nil, "BORDER")
+		frame.Option03.texture:SetSize(130, 110)
+		frame.Option03.texture:SetPoint("CENTER", frame.Option03, "BOTTOM", 0, -15)
+		frame.Option03.texture:SetTexture(SV.media.button.option)
+		frame.Option03.texture:SetGradient("VERTICAL", 0.3, 0, 0, 0.7, 0, 0)
+		frame.Option03:SetScript("OnEnter", function(this)
+			this.texture:SetVertexColor(0.2, 0.5, 1)
+		end)
+		frame.Option03:SetScript("OnLeave", function(this)
+			this.texture:SetGradient("VERTICAL", 0.3, 0, 0, 0.7, 0, 0)
+		end)
+		frame.Option03:SetScript("OnShow", function(this)
+			this:SetWidth(130)
+			this.texture:SetSize(130, 130)
+			this.texture:SetPoint("CENTER", this, "BOTTOM", 0, -(130 * 0.09))
+
+			frame.Option01:SetWidth(130)
+			frame.Option01.texture:SetSize(130, 130)
+			frame.Option01.texture:SetPoint("CENTER", frame.Option01, "BOTTOM", 0, -(130 * 0.09))
+			frame.Option01:ClearAllPoints()
+			frame.Option01:SetPoint("RIGHT", this, "LEFT", -8, 0)
+
+			frame.Option02:SetWidth(130)
+			frame.Option02.texture:SetSize(130, 130)
+			frame.Option02.texture:SetPoint("CENTER", frame.Option02, "BOTTOM", 0, -(130 * 0.09))
+			frame.Option02:ClearAllPoints()
+			frame.Option02:SetPoint("LEFT", this, "RIGHT", 8, 0)
+		end)
+		frame.Option03:SetFrameLevel(frame.Option01:GetFrameLevel() + 10)
+		frame.Option03:Hide()
+
+		--[[ OPTION 1 ]]--
+
+		frame.Option1 = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
+		frame.Option1:RemoveTextures()
+		frame.Option1:SetSize(160, 30)
+		frame.Option1:SetPoint("BOTTOM", 0, 15)
+		frame.Option1:SetText("")
+		SetInstallButton(frame.Option1)
+		frame.Option1.texture = frame.Option1:CreateTexture(nil, "BORDER")
+		frame.Option1.texture:SetSize(160, 160)
+		frame.Option1.texture:SetPoint("CENTER", frame.Option1, "BOTTOM", 0, -15)
+		frame.Option1.texture:SetTexture(SV.media.button.option)
+		frame.Option1.texture:SetGradient("VERTICAL", 0.3, 0.3, 0.3, 0.7, 0.7, 0.7)
+		frame.Option1:SetScript("OnEnter", function(this)
+			this.texture:SetVertexColor(0.5, 1, 0.4)
+		end)
+		frame.Option1:SetScript("OnLeave", function(this)
+			this.texture:SetGradient("VERTICAL", 0.3, 0.3, 0.3, 0.7, 0.7, 0.7)
+		end)
+		frame.Option1:SetFrameLevel(frame.Option1:GetFrameLevel() + 10)
+		frame.Option1:Hide()
+
+		--[[ OPTION 2 ]]--
+
+		frame.Option2 = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
+		frame.Option2:RemoveTextures()
+		frame.Option2:SetSize(120, 30)
+		frame.Option2:SetPoint("BOTTOMLEFT", frame, "BOTTOM", 4, 15)
+		frame.Option2:SetText("")
+		SetInstallButton(frame.Option2)
+		frame.Option2.texture = frame.Option2:CreateTexture(nil, "BORDER")
+		frame.Option2.texture:SetSize(120, 110)
+		frame.Option2.texture:SetPoint("CENTER", frame.Option2, "BOTTOM", 0, -15)
+		frame.Option2.texture:SetTexture(SV.media.button.option)
+		frame.Option2.texture:SetGradient("VERTICAL", 0.3, 0.3, 0.3, 0.7, 0.7, 0.7)
+		frame.Option2:SetScript("OnEnter", function(this)
+			this.texture:SetVertexColor(0.5, 1, 0.4)
+		end)
+		frame.Option2:SetScript("OnLeave", function(this)
+			this.texture:SetGradient("VERTICAL", 0.3, 0.3, 0.3, 0.7, 0.7, 0.7)
+		end)
+		frame.Option2:SetScript("OnShow", function()
+			if(not frame.Option3:IsShown() and (not frame.Option4:IsShown())) then
+				frame.Option1:SetWidth(120)
+				frame.Option1.texture:SetSize(120, 120)
+				frame.Option1.texture:SetPoint("CENTER", frame.Option1, "BOTTOM", 0, -(120 * 0.09))
+				frame.Option1:ClearAllPoints()
+				frame.Option1:SetPoint("BOTTOMRIGHT", frame, "BOTTOM", -4, 15)
+			end
+		end)
+		frame.Option2:SetFrameLevel(frame.Option1:GetFrameLevel() + 10)
+		frame.Option2:Hide()
+
+		--[[ OPTION 3 ]]--
+
+		frame.Option3 = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
+		frame.Option3:RemoveTextures()
+		frame.Option3:SetSize(110, 30)
+		frame.Option3:SetPoint("LEFT", frame.Option2, "RIGHT", 4, 0)
+		frame.Option3:SetText("")
+		SetInstallButton(frame.Option3)
+		frame.Option3.texture = frame.Option3:CreateTexture(nil, "BORDER")
+		frame.Option3.texture:SetSize(110, 100)
+		frame.Option3.texture:SetPoint("CENTER", frame.Option3, "BOTTOM", 0, -9)
+		frame.Option3.texture:SetTexture(SV.media.button.option)
+		frame.Option3.texture:SetGradient("VERTICAL", 0.3, 0.3, 0.3, 0.7, 0.7, 0.7)
+		frame.Option3:SetScript("OnEnter", function(this)
+			this.texture:SetVertexColor(0.5, 1, 0.4)
+		end)
+		frame.Option3:SetScript("OnLeave", function(this)
+			this.texture:SetGradient("VERTICAL", 0.3, 0.3, 0.3, 0.7, 0.7, 0.7)
+		end)
+		frame.Option3:SetScript("OnShow", function(this)
+			if(not frame.Option4:IsShown()) then
+				frame.Option2:SetWidth(110)
+				frame.Option2.texture:SetSize(110, 110)
+				frame.Option2.texture:SetPoint("CENTER", frame.Option2, "BOTTOM", 0, -(110 * 0.09))
+				frame.Option2:ClearAllPoints()
+				frame.Option2:SetPoint("BOTTOM", frame, "BOTTOM", 0, 15)
+
+				frame.Option1:SetWidth(110)
+				frame.Option1.texture:SetSize(110, 110)
+				frame.Option1.texture:SetPoint("CENTER", frame.Option1, "BOTTOM", 0, -(110 * 0.09))
+				frame.Option1:ClearAllPoints()
+				frame.Option1:SetPoint("RIGHT", frame.Option2, "LEFT", -4, 0)
+
+				this:SetWidth(110)
+				this.texture:SetSize(110, 110)
+				this.texture:SetPoint("CENTER", this, "BOTTOM", 0, -(110 * 0.09))
+				this:ClearAllPoints()
+				this:SetPoint("LEFT", frame.Option2, "RIGHT", 4, 0)
+			end
+		end)
+		frame.Option3:SetFrameLevel(frame.Option1:GetFrameLevel() + 10)
+		frame.Option3:Hide()
+
+		--[[ OPTION 4 ]]--
+
+		frame.Option4 = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
+		frame.Option4:RemoveTextures()
+		frame.Option4:SetSize(110, 30)
+		frame.Option4:SetPoint("LEFT", frame.Option3, "RIGHT", 4, 0)
+		frame.Option4:SetText("")
+		SetInstallButton(frame.Option4)
+		frame.Option4.texture = frame.Option4:CreateTexture(nil, "BORDER")
+		frame.Option4.texture:SetSize(110, 100)
+		frame.Option4.texture:SetPoint("CENTER", frame.Option4, "BOTTOM", 0, -9)
+		frame.Option4.texture:SetTexture(SV.media.button.option)
+		frame.Option4.texture:SetGradient("VERTICAL", 0.3, 0.3, 0.3, 0.7, 0.7, 0.7)
+		frame.Option4:SetScript("OnEnter", function(this)
+			this.texture:SetVertexColor(0.5, 1, 0.4)
+		end)
+		frame.Option4:SetScript("OnLeave", function(this)
+			this.texture:SetGradient("VERTICAL", 0.3, 0.3, 0.3, 0.7, 0.7, 0.7)
+		end)
+		frame.Option4:SetScript("OnShow", function()
+
+			frame.Option2:SetWidth(110)
+			frame.Option2.texture:SetSize(110, 110)
+			frame.Option2.texture:SetPoint("CENTER", frame.Option2, "BOTTOM", 0, -(110 * 0.09))
+			frame.Option2:ClearAllPoints()
+			frame.Option2:SetPoint("BOTTOMRIGHT", frame, "BOTTOM", -4, 15)
+
+			frame.Option1:SetWidth(110)
+			frame.Option1.texture:SetSize(110, 110)
+			frame.Option1.texture:SetPoint("CENTER", frame.Option1, "BOTTOM", 0, -(110 * 0.09))
+			frame.Option1:ClearAllPoints()
+			frame.Option1:SetPoint("RIGHT", frame.Option2, "LEFT", -4, 0)
+
+			frame.Option3:SetWidth(110)
+			frame.Option3.texture:SetSize(110, 110)
+			frame.Option3.texture:SetPoint("CENTER", frame.Option3, "BOTTOM", 0, -(110 * 0.09))
+			frame.Option3:ClearAllPoints()
+			frame.Option3:SetPoint("LEFT", frame.Option2, "RIGHT", 4, 0)
+		end)
+
+		frame.Option4:SetFrameLevel(frame.Option1:GetFrameLevel() + 10)
+		frame.Option4:Hide()
+
+		--[[ TEXT HOLDERS ]]--
+
+		local statusHolder = CreateFrame("Frame", nil, frame)
+		statusHolder:SetFrameLevel(statusHolder:GetFrameLevel() + 2)
+		statusHolder:SetSize(150, 30)
+		statusHolder:SetPoint("BOTTOM", frame, "TOP", 0, 2)
+
+		frame.Status = statusHolder:CreateFontString(nil, "OVERLAY")
+		frame.Status:SetFont(SV.media.font.number, 22, "OUTLINE")
+		frame.Status:SetPoint("CENTER")
+		frame.Status:SetText(CURRENT_PAGE.."  /  "..MAX_PAGE)
+
+		local titleHolder = frame:CreateFontString(nil, "OVERLAY")
+		titleHolder:SetFont(SV.media.font.dialog, 22, "OUTLINE")
+		titleHolder:SetPoint("TOP", 0, -5)
+		titleHolder:SetText(L["SVUI Installation"])
+
+		frame.SubTitle = frame:CreateFontString(nil, "OVERLAY")
+		frame.SubTitle:SetFont(SV.media.font.alert, 16, "OUTLINE")
+		frame.SubTitle:SetPoint("TOP", 0, -40)
+
+		frame.Desc1 = frame:CreateFontString(nil, "OVERLAY")
+		frame.Desc1:SetFont(SV.media.font.default, 14, "OUTLINE")
+		frame.Desc1:SetPoint("TOPLEFT", 20, -75)
+		frame.Desc1:SetWidth(frame:GetWidth()-40)
+
+		frame.Desc2 = frame:CreateFontString(nil, "OVERLAY")
+		frame.Desc2:SetFont(SV.media.font.default, 14, "OUTLINE")
+		frame.Desc2:SetPoint("TOPLEFT", 20, -125)
+		frame.Desc2:SetWidth(frame:GetWidth()-40)
+
+		frame.Desc3 = frame:CreateFontString(nil, "OVERLAY")
+		frame.Desc3:SetFont(SV.media.font.default, 14, "OUTLINE")
+		frame.Desc3:SetPoint("TOPLEFT", 20, -175)
+		frame.Desc3:SetWidth(frame:GetWidth()-40)
+
+		--[[ MISC ]]--
+
+		local closeButton = CreateFrame("Button", nil, frame, "UIPanelCloseButton")
+		closeButton:SetPoint("TOPRIGHT", frame, "TOPRIGHT")
+		closeButton:SetScript("OnClick", function() frame:Hide() end)
+
+		local tutorialImage = frame:CreateTexture(nil, "OVERLAY")
+		tutorialImage:SetSize(256, 128)
+		tutorialImage:SetTexture(SV.SplashImage)
+		tutorialImage:SetPoint("BOTTOM", 0, 70)
+	end
+
+	SVUI_InstallerFrame:SetScript("OnHide", function()
+		StopMusic()
+		SetCVar("Sound_MusicVolume", 0)
+		musicIsPlaying = nil;
+		ShowLayout()
+		ShowAuras()
+	end)
+
+	SVUI_InstallerFrame:Show()
+	SVUI_InstallerFrame:SetPage(1)
+	if(not autoLoaded) then
+		PlayThemeSong()
+	else
+		SV.Timers:ExecuteTimer(PlayThemeSong, 5)
+	end
+end
diff --git a/SVUI_!Core/setup/presets.lua b/SVUI_!Core/setup/presets.lua
new file mode 100644
index 0000000..03e75f6
--- /dev/null
+++ b/SVUI_!Core/setup/presets.lua
@@ -0,0 +1,1114 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pcall         = _G.pcall;
+local print         = _G.print;
+local ipairs        = _G.ipairs;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local rawset        = _G.rawset;
+local rawget        = _G.rawget;
+local tostring      = _G.tostring;
+local tonumber      = _G.tonumber;
+local string 	= _G.string;
+local table     = _G.table;
+local format = string.format;
+local tcopy = table.copy;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...)
+local SVUILib = Librarian("Registry")
+local L = SV.L;
+--[[
+##########################################################
+LOCAL VARS
+##########################################################
+]]--
+local CUSTOM_CLASS_COLORS = _G.CUSTOM_CLASS_COLORS
+local RAID_CLASS_COLORS = _G.RAID_CLASS_COLORS
+
+local CONTINUED = _G.CONTINUED
+local SETTINGS = _G.SETTINGS
+local HIGH = _G.HIGH
+local LOW = _G.LOW
+local scc = CUSTOM_CLASS_COLORS[SV.class];
+local rcc = RAID_CLASS_COLORS[SV.class];
+local r2 = .1 + (rcc.r * .1)
+local g2 = .1 + (rcc.g * .1)
+local b2 = .1 + (rcc.b * .1)
+--[[
+##########################################################
+LAYOUT PRESETS
+##########################################################
+]]--
+local hasOldConfigs = function()
+	local installed = SVUILib:GetSafeData("install_version")
+	if(installed) then
+		return USE.."\nSaved\n"..SETTINGS, "Complete"
+	else
+		return "Select\n"..NEW.."\n"..SETTINGS, "NewSettings"
+	end
+end
+
+local isLowRez = function()
+	if SV.LowRez then
+		return L["This resolution requires that you change some settings to get everything to fit on your screen."].." "..L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."].." "..L["You may need to further alter these settings depending how low your resolution is."]
+	else
+		return L["This resolution doesn't require that you change settings for the UI to fit on your screen."].." "..L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."].." "..L["This is completely optional."]
+	end
+end
+
+local PRESET_DATA, CLICK_DIALOG, PAGE_DIALOG;
+
+local ColorThemes = {
+	["data"] = {
+		["link"] = "media",
+		["default"] = {
+			["color"] = {
+				["special"] = {.37, .32, .29, 1},
+				["specialdark"] = {.23, .22, .21, 1},
+			},
+			["shared"] = {
+				["background"] = {
+					["pattern"] 	= {file = "SVUI Backdrop 2", 	size = 0, tiled = false},
+					["premium"] 	= {file = "SVUI Artwork 2", 	size = 0, tiled = false},
+					["unitlarge"] 	= {file = "SVUI UnitBG 2", 		size = 0, tiled = false},
+					["unitsmall"] 	= {file = "SVUI SmallUnitBG 2", size = 0, tiled = false},
+				}
+			},
+			["unitframes"] = {
+				["buff_bars"] = {.91, .91, .31, 1},
+				["health"] = {.1, .6, .02, 1},
+				["casting"] = {0, 0.92, 1, 1},
+				["spark"] = {0, 0.42, 1, 1},
+			},
+		},
+		["kaboom"] = {
+			["color"] = {
+				["special"] = {.28, .31, .32, 1},
+				["specialdark"] = {.21, .22, .23, 1},
+			},
+			["shared"] = {
+				["background"] = {
+					["pattern"] 	= {file = "SVUI Backdrop 13", 	size = 0, tiled = false},
+					["premium"] 	= {file = "SVUI Artwork 13", 	size = 0, tiled = false},
+					["unitlarge"] 	= {file = "SVUI UnitBG 13", 		size = 0, tiled = false},
+					["unitsmall"] 	= {file = "SVUI SmallUnitBG 13", size = 0, tiled = false},
+				}
+			},
+			["unitframes"] = {
+				["buff_bars"] = {.51, .79, 0, 1},
+				["health"] = {.16, .86, .22, 1},
+				["casting"] = {0, 0.92, 1, 1},
+				["spark"] = {0, 0.42, 1, 1},
+			},
+		},
+		["classy"] = {
+			["color"] = {
+				["special"] = {r2, g2, b2, 1},
+				["specialdark"] = {(r2 * 0.75), (g2 * 0.75), (b2 * 0.75), 1},
+			},
+			["shared"] = {
+				["background"] = {
+					["pattern"] 	= {file = "SVUI Backdrop 9", 	size = 0, tiled = false},
+					["premium"] 	= {file = "SVUI Artwork 9", 	size = 0, tiled = false},
+					["unitlarge"] 	= {file = "SVUI UnitBG 9", 		size = 0, tiled = false},
+					["unitsmall"] 	= {file = "SVUI SmallUnitBG 9", size = 0, tiled = false},
+				}
+			},
+			["unitframes"] = {
+				["buff_bars"] = {scc.r, scc.g, scc.b, 1},
+				["health"] = {.16, .86, .22, 1},
+				["casting"] = {0, 0.92, 1, 1},
+				["spark"] = {0, 0.42, 1, 1},
+			},
+		},
+		["dark"] = {
+			["color"] = {
+				["special"] = {.09, .09, .09, 1},
+				["specialdark"] = {.07, .08, .09, 1},
+			},
+			["shared"] = {
+				["background"] = {
+					["pattern"] 	= {file = "SVUI Backdrop 3", 	size = 0, tiled = false},
+					["premium"] 	= {file = "SVUI Artwork 3", 	size = 0, tiled = false},
+					["unitlarge"] 	= {file = "SVUI UnitBG 3", 		size = 0, tiled = false},
+					["unitsmall"] 	= {file = "SVUI SmallUnitBG 3", size = 0, tiled = false},
+				}
+			},
+			["unitframes"] = {
+				["buff_bars"] = {.45, .55, .15, 1},
+				["health"] = {.06, .06, .06, 1},
+				["casting"] = {0, 0.92, 1, 1},
+				["spark"] = {0, 0.42, 1, 1},
+			},
+		},
+	},
+	["dialog"] = {
+		["SubTitle"] = COLOR.." "..SETTINGS,
+		["Desc1"] = L["Choose a theme layout you wish to use for your initial setup."],
+		["Desc2"] = L["You can always change fonts and colors of any element of SVUI from the in-game configuration."],
+		["Desc3"] = L["CHOOSE_OR_DIE"],
+		["Option1"] = {L["Kaboom!"], "ColorTheme", "kaboom"},
+		["Option2"] = {L["Darkness"], "ColorTheme", "dark"},
+		["Option3"] = {L["Class" .. "\n" .. "Colors"], "ColorTheme", "classy"},
+		["Option4"] = {L["Vintage"], "ColorTheme"},
+	},
+	["clicktext"] = {
+		["Option1"] = {
+			["Desc1"] = L["|cffFF9F00KABOOOOM!|r"],
+			["Desc2"] = L["This theme tells the world that you are a villain who can put on a show"]..CONTINUED,
+			["Desc3"] = CONTINUED..L["or better yet, you ARE the show!"],
+		},
+		["Option2"] = {
+			["Desc1"] = L["|cffAF30FFThe Darkest Night|r"],
+			["Desc2"] = L["This theme indicates that you have no interest in wasting time"]..CONTINUED,
+			["Desc3"] = CONTINUED..L[" the dying begins NOW!"],
+		},
+		["Option3"] = {
+			["Desc1"] = L["|cffFFFF00"..CLASS_COLORS.."|r"],
+			["Desc2"] = L["This theme is for villains who take pride in their class"]..CONTINUED,
+			["Desc3"] = CONTINUED..L[" villains know how to reprezent!"],
+		},
+		["Option4"] = {
+			["Desc1"] = L["|cff00FFFFPlain and Simple|r"],
+			["Desc2"] = L["This theme is for any villain who sticks to their traditions"]..CONTINUED,
+			["Desc3"] = CONTINUED..L["you don't need fancyness to kick some ass!"],
+		},
+	}
+};
+
+local function LoadPresetData()
+	PRESET_DATA = {
+		["media"] = ColorThemes.data,
+		["auras"] = {
+			["link"] = "UnitFrames",
+			["default"] = {
+				["player"] = {
+					["buffs"] = {
+						enable = true,
+						useBars = false,
+						attachTo = "FRAME",
+						anchorPoint = 'TOPLEFT',
+						verticalGrowth = 'UP',
+						horizontalGrowth = 'RIGHT',
+					},
+					["debuffs"] = {
+						enable = true,
+						useBars = false,
+						attachTo = "BUFFS",
+						anchorPoint = 'TOPLEFT',
+						verticalGrowth = 'UP',
+						horizontalGrowth = 'RIGHT',
+					},
+				},
+				["target"] = {
+					["buffs"] = {
+						enable = true,
+						useBars = false,
+						attachTo = "FRAME",
+						anchorPoint = 'TOPRIGHT',
+						verticalGrowth = 'UP',
+						horizontalGrowth = 'LEFT',
+					},
+					["debuffs"] = {
+						enable = true,
+						useBars = false,
+						attachTo = "BUFFS",
+						anchorPoint = 'TOPRIGHT',
+						verticalGrowth = 'UP',
+						horizontalGrowth = 'LEFT',
+					},
+				},
+				["targettarget"] = {
+					["buffs"] = {
+						enable = true,
+						attachTo = "FRAME",
+						anchorPoint = 'TOPRIGHT',
+						verticalGrowth = 'UP',
+						horizontalGrowth = 'LEFT',
+					},
+					["debuffs"] = {
+						enable = true,
+						attachTo = "BUFFS",
+						anchorPoint = 'TOPRIGHT',
+						verticalGrowth = 'UP',
+						horizontalGrowth = 'LEFT',
+					},
+				},
+				["focus"] = {
+					["buffs"] = {
+						enable = true,
+						useBars = false,
+						attachTo = "FRAME",
+						anchorPoint = 'TOPRIGHT',
+						verticalGrowth = 'UP',
+						horizontalGrowth = 'LEFT',
+					},
+					["debuffs"] = {
+						enable = true,
+						useBars = false,
+						attachTo = "BUFFS",
+						anchorPoint = 'TOPRIGHT',
+						verticalGrowth = 'UP',
+						horizontalGrowth = 'LEFT',
+					},
+				},
+				["focustarget"] = {
+					["buffs"] = {
+						enable = true,
+						attachTo = "FRAME",
+						anchorPoint = 'TOPRIGHT',
+						verticalGrowth = 'UP',
+						horizontalGrowth = 'LEFT',
+					},
+					["debuffs"] = {
+						enable = true,
+						attachTo = "BUFFS",
+						anchorPoint = 'TOPRIGHT',
+						verticalGrowth = 'UP',
+						horizontalGrowth = 'LEFT',
+					},
+				}
+			},
+			["bars"] = {
+				["player"] = {
+					["buffs"] = {
+						enable = true,
+						useBars = true,
+						attachTo = "FRAME",
+						anchorPoint = 'TOPLEFT',
+						verticalGrowth = 'UP',
+						horizontalGrowth = 'RIGHT',
+					},
+					["debuffs"] = {
+						enable = true,
+						useBars = true,
+						attachTo = "BUFFS",
+						anchorPoint = 'TOPLEFT',
+						verticalGrowth = 'UP',
+						horizontalGrowth = 'RIGHT',
+					},
+				},
+				["target"] = {
+					["buffs"] = {
+						enable = true,
+						useBars = true,
+						attachTo = "FRAME",
+						anchorPoint = 'TOPRIGHT',
+						verticalGrowth = 'UP',
+						horizontalGrowth = 'LEFT',
+					},
+					["debuffs"] = {
+						enable = true,
+						useBars = true,
+						attachTo = "BUFFS",
+						anchorPoint = 'TOPRIGHT',
+						verticalGrowth = 'UP',
+						horizontalGrowth = 'LEFT',
+					},
+				},
+				["targettarget"] = {
+					["buffs"] = {
+						enable = true,
+						attachTo = "FRAME",
+						anchorPoint = 'TOPRIGHT',
+						verticalGrowth = 'UP',
+						horizontalGrowth = 'LEFT',
+					},
+					["debuffs"] = {
+						enable = true,
+						attachTo = "BUFFS",
+						anchorPoint = 'TOPRIGHT',
+						verticalGrowth = 'UP',
+						horizontalGrowth = 'LEFT',
+					},
+				},
+				["focus"] = {
+					["buffs"] = {
+						enable = true,
+						useBars = true,
+						attachTo = "FRAME",
+						anchorPoint = 'TOPRIGHT',
+						verticalGrowth = 'UP',
+						horizontalGrowth = 'LEFT',
+					},
+					["debuffs"] = {
+						enable = true,
+						useBars = true,
+						attachTo = "BUFFS",
+						anchorPoint = 'TOPRIGHT',
+						verticalGrowth = 'UP',
+						horizontalGrowth = 'LEFT',
+					},
+				},
+				["focustarget"] = {
+					["buffs"] = {
+						enable = true,
+						attachTo = "FRAME",
+						anchorPoint = 'TOPRIGHT',
+						verticalGrowth = 'UP',
+						horizontalGrowth = 'LEFT',
+					},
+					["debuffs"] = {
+						enable = true,
+						attachTo = "BUFFS",
+						anchorPoint = 'TOPRIGHT',
+						verticalGrowth = 'UP',
+						horizontalGrowth = 'LEFT',
+					},
+				}
+			},
+		},
+		["bars"] = {
+			["link"] = "ActionBars",
+			["default"] = {
+				["Bar1"] = {
+					buttonsize = 32
+				},
+				["Bar2"] = {
+					enable = false
+				},
+				["Bar3"] = {
+					buttons = 6,
+					buttonspacing = 2,
+					buttonsPerRow = 6,
+					buttonsize = 32
+				},
+				["Bar5"] = {
+					buttons = 6,
+					buttonspacing = 2,
+					buttonsPerRow = 6,
+					buttonsize = 32
+				}
+			},
+			["onebig"] = {
+				["Bar1"] = {
+					buttonsize = 40
+				},
+				["Bar2"] = {
+					enable = false
+				},
+				["Bar3"] = {
+					buttons = 6,
+					buttonspacing = 2,
+					buttonsPerRow = 6,
+					buttonsize = 40
+				},
+				["Bar5"] = {
+					buttons = 6,
+					buttonspacing = 2,
+					buttonsPerRow = 6,
+					buttonsize = 40
+				}
+			},
+			["twosmall"] = {
+				["Bar1"] = {
+					buttonsize = 32
+				},
+				["Bar2"] = {
+					enable = true,
+					buttonsize = 32
+				},
+				["Bar3"] = {
+					buttons = 12,
+					buttonspacing = 2,
+					buttonsPerRow = 6,
+					buttonsize = 32
+				},
+				["Bar5"] = {
+					buttons = 12,
+					buttonspacing = 2,
+					buttonsPerRow = 6,
+					buttonsize = 32
+				}
+			},
+			["twobig"] = {
+				["Bar1"] = {
+					buttonsize = 40
+				},
+				["Bar2"] = {
+					enable = true,
+					buttonsize = 40
+				},
+				["Bar3"] = {
+					buttons = 12,
+					buttonspacing = 2,
+					buttonsPerRow = 6,
+					buttonsize = 40
+				},
+				["Bar5"] = {
+					buttons = 12,
+					buttonspacing = 2,
+					buttonsPerRow = 6,
+					buttonsize = 40
+				}
+			},
+		},
+		["units"] = {
+			["link"] = "UnitFrames",
+			["default"] = {
+				["player"] = {
+					portrait = {
+						enable = true,
+						overlay = true,
+						style = "3DOVERLAY",
+					}
+				},
+				["target"] = {
+					portrait = {
+						enable = true,
+						overlay = true,
+						style = "3DOVERLAY",
+					}
+				},
+				["pet"] = {
+					portrait = {
+						enable = true,
+						overlay = true,
+						style = "3DOVERLAY",
+					},
+				},
+				["targettarget"] = {
+					portrait = {
+						enable = true,
+						overlay = true,
+						style = "3DOVERLAY",
+					},
+				},
+				["boss"] = {
+					portrait = {
+						enable = true,
+						overlay = true,
+						style = "3DOVERLAY",
+					}
+				},
+				["party"] = {
+					portrait = {
+						enable = true,
+						overlay = true,
+						style = "3DOVERLAY",
+					},
+				},
+			},
+			["super"] = {
+				["player"] = {
+					portrait = {
+						enable = true,
+						overlay = true,
+						style = "3DOVERLAY",
+					}
+				},
+				["target"] = {
+					portrait = {
+						enable = true,
+						overlay = true,
+						style = "3DOVERLAY",
+					}
+				},
+				["pet"] = {
+					portrait = {
+						enable = true,
+						overlay = true,
+						style = "3DOVERLAY",
+					},
+				},
+				["targettarget"] = {
+					portrait = {
+						enable = true,
+						overlay = true,
+						style = "3DOVERLAY",
+					},
+				},
+				["boss"] = {
+					portrait = {
+						enable = true,
+						overlay = true,
+						style = "3DOVERLAY",
+					}
+				},
+				["party"] = {
+					portrait = {
+						enable = true,
+						overlay = true,
+						style = "3DOVERLAY",
+					},
+				},
+			},
+			["simple"] = {
+				["player"] = {
+					["portrait"] = {
+						["enable"] = true,
+						["overlay"] = false,
+						["style"] = "2D",
+					},
+				},
+				["target"] = {
+					["portrait"] = {
+						["enable"] = true,
+						["overlay"] = false,
+						["style"] = "2D",
+					},
+				},
+				["pet"] = {
+					["portrait"] = {
+						["enable"] = true,
+						["overlay"] = false,
+						["style"] = "2D",
+					},
+				},
+				["targettarget"] = {
+					["portrait"] = {
+						["enable"] = false,
+						["overlay"] = false,
+						["style"] = "2D",
+					},
+				},
+				["boss"] = {
+					["portrait"] = {
+						["enable"] = true,
+						["overlay"] = false,
+						["style"] = "2D",
+					},
+				},
+				["party"] = {
+					["portrait"] = {
+						["enable"] = true,
+						["overlay"] = false,
+						["style"] = "2D",
+					},
+				},
+			},
+			["compact"] = {
+				["player"] = {
+					["portrait"] = {
+						["enable"] = false
+					}
+				},
+				["target"] = {
+					["portrait"] = {
+						["enable"] = false
+					}
+				},
+				["pet"] = {
+					["portrait"] = {
+						["enable"] = false
+					},
+				},
+				["targettarget"] = {
+					["portrait"] = {
+						["enable"] = false
+					},
+				},
+				["boss"] = {
+					["portrait"] = {
+						["enable"] = false
+					}
+				},
+				["party"] = {
+					["portrait"] = {
+						["enable"] = false
+					},
+				},
+			},
+		},
+		["layouts"] = {
+			["link"] = "UnitFrames",
+			["default"] = {
+				["party"] = {
+					["width"] = 75,
+					["height"] = 60,
+					["wrapXOffset"] = 9,
+					["wrapYOffset"] = 13,
+					["portrait"] = {
+						["enable"] = true,
+						["overlay"] = true,
+						["style"] = "3DOVERLAY",
+					},
+					["icons"] = {
+						["roleIcon"] = {
+							["attachTo"] = "INNERBOTTOMRIGHT",
+							["xOffset"] = 0,
+							["yOffset"] = 0,
+						},
+					},
+					name = {
+						["font"] = "SVUI Default Font",
+						["fontOutline"] = "OUTLINE",
+						["position"] = "INNERTOPLEFT",
+						["xOffset"] = 0,
+						["yOffset"] = 0,
+					},
+					["grid"] = {
+						["enable"] = false,
+					},
+				},
+				["raid"] = {
+					["width"] = 50,
+					["height"] = 30,
+					["gRowCol"] = 1,
+					["wrapXOffset"] = 9,
+					["wrapYOffset"] = 13,
+					["showBy"] = "RIGHT_DOWN",
+					["power"] = {
+						["enable"] = false,
+					},
+					["icons"] = {
+						["roleIcon"] = {
+							["attachTo"] = "INNERBOTTOMLEFT",
+							["xOffset"] = 8,
+							["yOffset"] = 1,
+						},
+					},
+					["name"] = {
+						["font"] = "SVUI Default Font",
+						["position"] = "INNERTOPLEFT",
+						["xOffset"] = 8,
+						["yOffset"] = 0,
+					},
+					["grid"] = {
+						["enable"] = false,
+					},
+				},
+			},
+			["healer"] = {
+				["party"] = {
+					["width"] = 75,
+					["height"] = 60,
+					["wrapXOffset"] = 9,
+					["wrapYOffset"] = 13,
+					["portrait"] = {
+						["enable"] = true,
+						["overlay"] = true,
+						["style"] = "3DOVERLAY",
+					},
+					["power"] = {
+						["enable"] = true,
+					},
+					["icons"] = {
+						["roleIcon"] = {
+							["attachTo"] = "INNERBOTTOMRIGHT",
+							["xOffset"] = 0,
+							["yOffset"] = 0,
+						},
+					},
+					["name"] = {
+						["font"] = "SVUI Default Font",
+						["fontOutline"] = "OUTLINE",
+						["position"] = "INNERTOPLEFT",
+						["xOffset"] = 0,
+						["yOffset"] = 0,
+					},
+					["grid"] = {
+						["enable"] = false,
+					},
+				},
+				["raid"] = {
+					["width"] = 50,
+					["height"] = 30,
+					["showBy"] = "DOWN_RIGHT",
+					["gRowCol"] = 1,
+					["wrapXOffset"] = 4,
+					["wrapYOffset"] = 4,
+					["power"] = {
+						["enable"] = true,
+					},
+					["icons"] = {
+						["roleIcon"] = {
+							["attachTo"] = "INNERBOTTOMLEFT",
+							["xOffset"] = 8,
+							["yOffset"] = 0,
+						},
+					},
+					["name"] = {
+						["font"] = "SVUI Default Font",
+						["position"] = "INNERTOPLEFT",
+						["xOffset"] = 8,
+						["yOffset"] = 0,
+					},
+					["grid"] = {
+						["enable"] = false,
+					},
+				},
+			},
+			["dps"] = {
+				["party"] = {
+					["width"] = 115,
+					["height"] = 50,
+					["wrapXOffset"] = 9,
+					["wrapYOffset"] = 13,
+					["power"] = {
+						["enable"] = false,
+					},
+					["portrait"] = {
+						["enable"] = false,
+						["overlay"] = false,
+						["style"] = "2D",
+						["width"] = 35,
+					},
+					["icons"] = {
+						["roleIcon"] = {
+							["attachTo"] = "LEFT",
+							["xOffset"] = -2,
+							["yOffset"] = 0,
+						},
+					},
+					["name"] = {
+						["font"] = "SVUI Default Font",
+						["fontOutline"] = "NONE",
+						["position"] = "CENTER",
+						["xOffset"] = 0,
+						["yOffset"] = 1,
+					},
+					["grid"] = {
+						["enable"] = false,
+					},
+				},
+				["raid"] = {
+					["showBy"] = "UP_RIGHT",
+					["gRowCol"] = 4,
+					["wrapXOffset"] = 4,
+					["wrapYOffset"] = 4,
+					["power"] = {
+						["enable"] = false,
+					},
+					["icons"] = {
+						["roleIcon"] = {
+							["attachTo"] = "INNERLEFT",
+							["xOffset"] = 10,
+							["yOffset"] = 1,
+						},
+					},
+					["name"] = {
+						["font"] = "SVUI Default Font",
+						["position"] = "CENTER",
+						["xOffset"] = 0,
+						["yOffset"] = 1,
+					},
+					["width"] = 80,
+					["height"] = 20,
+					["grid"] = {
+						["enable"] = false,
+					},
+				},
+			},
+			["grid"] = {
+				["party"] = {
+					["wrapXOffset"] = 6,
+					["wrapYOffset"] = 6,
+					["power"] = {
+						["enable"] = false,
+					},
+					["portrait"] = {
+						["enable"] = false,
+					},
+					["grid"] = {
+						["enable"] = true,
+						["size"] = 45,
+					},
+				},
+				["raid"] = {
+					["wrapXOffset"] = 6,
+					["wrapYOffset"] = 6,
+					["gRowCol"] = 1,
+					["showBy"] = "RIGHT_DOWN",
+					["grid"] = {
+						["enable"] = true,
+						["size"] = 34,
+					},
+				},
+				["raidpet"] = {
+					["wrapXOffset"] = 6,
+					["wrapYOffset"] = 6,
+					["gRowCol"] = 1,
+					["showBy"] = "RIGHT_DOWN",
+					["grid"] = {
+						["enable"] = true,
+						["size"] = 34,
+					},
+				},
+				["tank"] = {
+					["grid"] = {
+						["enable"] = true,
+						["size"] = 45,
+					},
+				},
+				["assist"] = {
+					["grid"] = {
+						["enable"] = true,
+						["size"] = 45,
+					},
+				},
+			},
+		}
+	};
+end
+
+local function LoadPageData()
+	PAGE_DIALOG = {
+		--PAGE 1
+		{
+			["SubTitle"] = (L["This is SVUI version %s!"]):format(SV.Version),
+
+			["Desc1"] = L["Before I can turn you loose, persuing whatever villainy you feel will advance your professional career... I need to ask some questions and turn a few screws first."],
+			["Desc2"] = L["At any time you can get to the config options by typing the command  / sv. For quick changes to frame, bar or color sets, call your henchman by clicking the button on the bottom right of your screen. (Its the one with his stupid face on it)"],
+			["Desc3"] = L["CHOOSE_OR_DIE"],
+
+			["Option01"] = {USE.."\n"..DEFAULT.."\n"..SETTINGS, "EZDefault"},
+			["Option02"] = {hasOldConfigs},
+		},
+		--PAGE 2
+		{
+			["SubTitle"] = CHAT,
+
+			["Desc1"] = L["Whether you want to or not, you will be needing a communicator so other villains can either update you on their doings-of-evil or inform you about the MANY abilities of Chuck Norris"],
+			["Desc2"] = L["The chat windows function the same as standard chat windows, you can right click the tabs and drag them, rename them, slap them around, you know... whatever. Clickity-click to setup your chat windows."],
+			["Desc3"] = L["CHOOSE_OR_DIE"],
+
+			["Option1"] = {CHAT_DEFAULTS, "ChatConfigs"},
+		},
+		--PAGE 3
+		{
+			["SubTitle"] = RESOLUTION,
+
+			["Desc1"] = (L["Your current resolution is %s, this is considered a %s resolution."]):format(GetCVar("gxFullscreenResolution"), (SV.LowRez and LOW or HIGH)),
+			["Desc2"] = isLowRez,
+			["Desc3"] = L["CHOOSE_OR_DIE"],
+
+			["Option1"] = {HIGH, "UserScreen", "high"},
+			["Option2"] = {LOW, "UserScreen", "low"},
+		},
+		--PAGE 4
+		{
+
+		},
+		--PAGE 5
+		{
+			["REQUIRED"] = "UnitFrames",
+			["SubTitle"] = UNITFRAME_LABEL.." "..SETTINGS,
+
+			["Desc1"] = L["You can now choose what primary unitframe style you wish to use."],
+			["Desc2"] = L["This will change the layout of your unitframes (ie.. Player, Target, Pet, Party, Raid ...etc)."],
+			["Desc3"] = L["CHOOSE_OR_DIE"],
+
+			["Option1"] = {L["Super"], "UnitframeLayout", "super"},
+			["Option2"] = {L["Simple"], "UnitframeLayout", "simple"},
+			["Option3"] = {L["Compact"], "UnitframeLayout", "compact"},
+		},
+		--PAGE 6
+		{
+			["REQUIRED"] = "UnitFrames",
+			["SubTitle"] = "Group Layout",
+
+			["Desc1"] = L["You can now choose what group layout you prefer."],
+			["Desc2"] = L["This will adjust various settings on group units, attempting to make certain roles more usable"],
+			["Desc3"] = L["CHOOSE_OR_DIE"],
+
+			["Option1"] = {L["Standard"], "GroupframeLayout", "default"},
+			["Option2"] = {L["Healer"], "GroupframeLayout", "healer"},
+			["Option3"] = {L["DPS"], "GroupframeLayout", "dps"},
+			["Option4"] = {L["Grid"], "GroupframeLayout", "grid"},
+		},
+		--PAGE 7
+		{
+			["REQUIRED"] = "ActionBars",
+			["SubTitle"] = ACTIONBAR_LABEL.." "..SETTINGS,
+
+			["Desc1"] = L["Choose a layout for your action bars."],
+			["Desc2"] = L["Sometimes you need big buttons, sometimes you don't. Your choice here."],
+			["Desc3"] = L["CHOOSE_OR_DIE"],
+
+			["Option1"] = {L["Small" .. "\n" .. "Row"], "BarLayout", "default"},
+			["Option2"] = {L["2 Small" .. "\n" .. "Rows"], "BarLayout", "twosmall"},
+			["Option3"] = {L["Big" .. "\n" .. "Row"], "BarLayout", "onebig"},
+			["Option4"] = {L["2 Big" .. "\n" .. "Rows"], "BarLayout", "twobig"},
+		},
+		--PAGE 8
+		{
+			["REQUIRED"] = "UnitFrames",
+			["SubTitle"] = AURAS.." "..SETTINGS,
+
+			["Desc1"] = L["Select an aura layout. \"Icons\" will display only icons and aurabars won't be used. \"Bars\" will display only aurabars and icons won't be used (duh)."],
+			["Desc2"] = L["If you have an aura that you don't want to display simply hold down shift and right click the icon for it to suffer a painful death."],
+			["Desc3"] = L["CHOOSE_OR_DIE"],
+
+			["Option1"] = {L["Icons"], "Auralayout", "default"},
+			["Option2"] = {L["Bars"], "Auralayout", "bars"},
+		},
+		--PAGE 9
+		{
+			["SubTitle"] = BASIC_OPTIONS_TOOLTIP..CONTINUED..AUCTION_TIME_LEFT0,
+
+			["Desc1"] = L["Thats it! All done! Now we just need to hand these choices off to the henchmen so they can get you ready to (..insert evil tasks here..)!"],
+			["Desc2"] = L["Click the button below to reload and get on your way! Good luck villain!"],
+
+			["Option1"] = {L["THE_BUTTON_BELOW"], "Complete"},
+		},
+	};
+
+	PAGE_DIALOG[4] = ColorThemes.dialog;
+end
+
+local function LoadOnClickData()
+	CLICK_DIALOG = {
+		["Page3_Option1"] = {
+			["Desc1"] = L["|cffFF9F00"..HIGH.." "..RESOLUTION.."!|r"],
+			["Desc2"] = L["So what you think your better than me with your big monitor? HUH?!?!"],
+			["Desc3"] = L["Dont forget whos in charge here! But enjoy the incredible detail."],
+		},
+		["Page3_Option2"] = {
+			["Desc1"] = L["|cffFF9F00"..LOW.." "..RESOLUTION.."|r"],
+			["Desc2"] = L["Why are you playing this on what I would assume is a calculator display?"],
+			["Desc3"] = L["Enjoy the ONE incredible pixel that fits on this screen."],
+		},
+		["Page5_Option1"] = {
+			["Desc1"] = L["|cff00FFFFLets Do This|r"],
+			["Desc2"] = L["This layout is anything but minimal! Using this is like being at a rock concert"]..CONTINUED,
+			["Desc3"] = CONTINUED..L["then annihilating the crowd with frickin lazer beams!"],
+		},
+		["Page5_Option2"] = {
+			["Desc1"] = L["|cff00FFFFSimply Simple|r"],
+			["Desc2"] = L["This layout is for the villain who just wants to get things done!"]..CONTINUED,
+			["Desc3"] = CONTINUED..L["but he still wants to see your face before he hits you!"],
+		},
+		["Page5_Option3"] = {
+			["Desc1"] = L["|cff00FFFFEl Compacto|r"],
+			["Desc2"] = L["Just the necessities so you can see more of the world around you"]..CONTINUED,
+			["Desc3"] = CONTINUED..L["you dont need no fanciness getting in the way of world domination do you?"],
+		},
+		["Page6_Option1"] = {
+			["Desc1"] = L["|cff00FFFFStandard|r"],
+			["Desc2"] = L["You are good to go with the default layout"]..CONTINUED,
+			["Desc3"] = CONTINUED..L["frames schmames, lets kill some stuff!"],
+		},
+		["Page6_Option2"] = {
+			["Desc1"] = L["|cff00FFFFMEDIC!!|r"],
+			["Desc2"] = L["You are pretty helpful.. for a VILLAIN!"]..CONTINUED,
+			["Desc3"] = CONTINUED..L["Hey, even a super villain gets his ass kicked once in awhile. We need the likes of you!"],
+		},
+		["Page6_Option3"] = {
+			["Desc1"] = L["|cff00FFFFDeath Dealer|r"],
+			["Desc2"] = L["You are the kings of our craft. Handing out pain like its halloween candy."]..CONTINUED,
+			["Desc3"] = CONTINUED..L["I will move and squeeze group frames out of your way so you have more room for BOOM!"],
+		},
+		["Page6_Option4"] = {
+			["Desc1"] = L["|cff00FFFFCubed|r"],
+			["Desc2"] = L["You are cold and calculated, your frames should reflect as much."]..CONTINUED,
+			["Desc3"] = CONTINUED..L["I'm gonna make these frames so precise that you can cut your finger on them!"],
+		},
+		["Page7_Option1"] = {
+			["Desc1"] = L["|cff00FFFFLean And Clean|r"],
+			["Desc2"] = L["Lets keep it slim and deadly, not unlike a ninja sword."],
+			["Desc3"] = L["You dont ever even look at your bar hardly, so pick this one!"],
+		},
+		["Page7_Option2"] = {
+			["Desc1"] = L["|cff00FFFFMore For Less|r"],
+			["Desc2"] = L["Granted, you dont REALLY need the buttons due to your hotkey-leetness, you just like watching cooldowns!"],
+			["Desc3"] = L["Sure thing cowboy, your secret is safe with me!"],
+		},
+		["Page7_Option3"] = {
+			["Desc1"] = L["|cff00FFFFWhat Big Buttons You Have|r"],
+			["Desc2"] = L["The better to PEW-PEW you with my dear!"],
+			["Desc3"] = L["When you have little time for mouse accuracy, choose this set!"],
+		},
+		["Page7_Option4"] = {
+			["Desc1"] = L["|cff00FFFFThe Double Down|r"],
+			["Desc2"] = L["Lets be honest for a moment. Who doesnt like a huge pair in their face?"],
+			["Desc3"] = L["Double your bars then double their size for maximum button goodness!"],
+		},
+	};
+
+	for key, data in pairs(ColorThemes.clicktext) do
+		local optionKey = "Page4_" .. key;
+		CLICK_DIALOG[optionKey] = data;
+	end
+end
+--[[
+##########################################################
+LOCAL FUNCTIONS
+##########################################################
+]]--
+local function _copyPresets(saved, preset)
+	if not saved then return end
+	if(type(preset) == 'table') then
+        for key,val in pairs(preset) do
+        	if(not saved[key]) then saved[key] = {} end
+    		if(type(val) == "table") then
+    			_copyPresets(saved[key], val)
+    		elseif(saved[key]) then
+            	saved[key] = val
+            end
+        end
+    else
+    	saved = preset
+    end
+end
+
+function SV.Setup:SetAllDefaults()
+	_copyPresets(SV.db, SV.defaults)
+end
+
+function SV.Setup:GenerateBackdrops()
+	local BG_INDEX = math.random(1, SV.MaxBackdrops.Pattern);
+	local ART_INDEX = math.random(1, SV.MaxBackdrops.Art);
+	local UNIT_INDEX = math.random(1, SV.MaxBackdrops.Unit);
+
+	local preset = {
+		["pattern"] = {file = "SVUI Backdrop "..BG_INDEX, size = 0, tiled = false},
+		["premium"] = {file = "SVUI Artwork "..ART_INDEX, size = 0, tiled = false},
+		["unitlarge"] = {file = "SVUI UnitBG "..UNIT_INDEX, size = 0, tiled = false},
+		["unitsmall"] = {file = "SVUI SmallUnitBG "..UNIT_INDEX, size = 0, tiled = false}
+	}
+	_copyPresets(SV.media.shared.background, preset)
+end
+
+function SV.Setup:CopyPreset(category, theme)
+	if(not PRESET_DATA) then LoadPresetData() end
+	if(PRESET_DATA and PRESET_DATA[category] and PRESET_DATA[category]["link"]) then
+		theme = theme or "default"
+		local saved = PRESET_DATA[category]["link"]
+		local preset =  PRESET_DATA[category][theme]
+		local data
+		if(saved == "media") then
+			data = SV.media
+		else
+			data = SV.db[saved]
+		end
+
+		if(data) then
+    	_copyPresets(data, preset)
+    end
+	end
+end
+
+function SV.Setup:CopyPage(pageNum)
+	if(not PAGE_DIALOG) then LoadPageData() end
+	if(PAGE_DIALOG and PAGE_DIALOG[pageNum]) then
+		local req = PAGE_DIALOG[pageNum].REQUIRED
+		if(req and not SV[req]) then
+			return SV.Setup:CopyPage(pageNum + 1)
+		else
+			return PAGE_DIALOG[pageNum], #PAGE_DIALOG
+		end
+	end
+end
+
+function SV.Setup:CopyOnClick(index)
+	if(not CLICK_DIALOG) then LoadOnClickData() end
+	if(CLICK_DIALOG and CLICK_DIALOG[index]) then
+		return CLICK_DIALOG[index]
+	end
+end
diff --git a/SVUI_!Core/setup/theme_select.lua b/SVUI_!Core/setup/theme_select.lua
new file mode 100644
index 0000000..9aa2a67
--- /dev/null
+++ b/SVUI_!Core/setup/theme_select.lua
@@ -0,0 +1,96 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pcall         = _G.pcall;
+local print         = _G.print;
+local ipairs        = _G.ipairs;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local rawset        = _G.rawset;
+local rawget        = _G.rawget;
+local tostring      = _G.tostring;
+local tonumber      = _G.tonumber;
+local string 	= _G.string;
+local table     = _G.table;
+local format = string.format;
+local tcopy = table.copy;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...)
+local SVUILib = Librarian("Registry");
+local L = SV.L;
+
+function SV.Setup:SelectTheme()
+	if not SVUI_ThemeSelectFrame then
+		local frame = CreateFrame("Button", "SVUI_ThemeSelectFrame", UIParent)
+		frame:SetSize(350, 145)
+		frame:SetStyle("Frame", "Window2")
+		frame:SetPoint("CENTER", SV.Screen, "CENTER", 0, 0)
+		frame:SetFrameStrata("TOOLTIP");
+
+		local closeButton = CreateFrame("Button", nil, frame, "UIPanelCloseButton")
+		closeButton:SetPoint("TOPRIGHT", frame, "TOPRIGHT")
+		closeButton:SetScript("OnClick", function() frame:Hide() end)
+		SV.API:Set("CloseButton", closeButton)
+	end
+
+	local count = 0;
+	for themeName, _ in pairs(SV.AvailableThemes) do
+		local yOffset = ((125 * count) + 10) * -1;
+		local icon = SV.media.icon[themeName] or SV.media.icon.theme
+		local themeButton = SVUI_ThemeSelectFrame[themeName]
+		if(not themeButton) then
+			themeButton = CreateFrame("Frame", nil, SVUI_ThemeSelectFrame)
+			themeButton:SetSize(125, 125)
+			themeButton:SetPoint("TOP", SVUI_ThemeSelectFrame, "TOP", 0, yOffset)
+			themeButton.texture = themeButton:CreateTexture(nil, "BORDER")
+			themeButton.texture:SetAllPoints()
+			themeButton.texture:SetTexture(icon)
+			themeButton.texture:SetVertexColor(1, 1, 1)
+			themeButton.text = themeButton:CreateFontString(nil, "OVERLAY")
+			themeButton.text:SetFont(SV.media.font.zone, 18, "OUTLINE")
+			themeButton.text:SetPoint("BOTTOM")
+			themeButton.text:SetText(themeName .. " Theme")
+			themeButton.text:SetTextColor(0.1, 0.5, 1)
+			themeButton:EnableMouse(true)
+			themeButton:SetScript("OnMouseDown", function(self)
+				SVUILib:SaveSafeData("THEME", themeName)
+				SV:StaticPopup_Show("RL_CLIENT");
+			end)
+			themeButton:SetScript("OnEnter", function(this)
+				this.texture:SetVertexColor(0, 1, 1)
+				this.text:SetTextColor(1, 1, 0)
+			end)
+			themeButton:SetScript("OnLeave", function(this)
+				this.texture:SetVertexColor(1, 1, 1)
+				this.text:SetTextColor(0.1, 0.5, 1)
+			end)
+			SVUI_ThemeSelectFrame[themeName] = themeButton
+		end
+
+		count = count + 1
+	end
+
+	if(count > 1) then
+		SVUI_ThemeSelectFrame:ClearAllPoints()
+		SVUI_ThemeSelectFrame:SetSize(350, (135 * count) + 20)
+		SVUI_ThemeSelectFrame:SetPoint("CENTER", SV.Screen, "CENTER", 0, 0)
+		SVUI_ThemeSelectFrame:Show()
+	else
+		SVUI_ThemeSelectFrame:Hide()
+		SV:AddonMessage("You do not have any themes installed")
+	end
+end
diff --git a/SVUI_!Core/system/_docklets/breakstuff.lua b/SVUI_!Core/system/_docklets/breakstuff.lua
new file mode 100644
index 0000000..8a97b5c
--- /dev/null
+++ b/SVUI_!Core/system/_docklets/breakstuff.lua
@@ -0,0 +1,376 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+local pairs   = _G.pairs;
+local ipairs  = _G.ipairs;
+local print   = _G.print;
+local table   = _G.table;
+local match   = string.match;
+--[[ TABLE METHODS ]]--
+local tremove, tcopy, twipe, tsort, tcat = table.remove, table.copy, table.wipe, table.sort, table.concat;
+--BLIZZARD API
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+local GameTooltip           = _G.GameTooltip;
+local ReloadUI              = _G.ReloadUI;
+local hooksecurefunc        = _G.hooksecurefunc;
+local GetItemInfo      		= _G.GetItemInfo;
+local GetItemCount          = _G.GetItemCount;
+local GetSpellInfo      	= _G.GetSpellInfo;
+local IsSpellKnown      	= _G.IsSpellKnown;
+local IsEquippableItem  	= _G.IsEquippableItem;
+local GetSpellBookItemInfo  = _G.GetSpellBookItemInfo;
+local ERR_NOT_IN_COMBAT     = _G.ERR_NOT_IN_COMBAT;
+local ITEM_MILLABLE     	= _G.ITEM_MILLABLE;
+local ITEM_PROSPECTABLE   	= _G.ITEM_PROSPECTABLE;
+
+local GetMouseFocus  				= _G.GetMouseFocus;
+local GetContainerItemLink  		= _G.GetContainerItemLink;
+local AutoCastShine_AutoCastStart  	= _G.AutoCastShine_AutoCastStart;
+local AutoCastShine_AutoCastStop  	= _G.AutoCastShine_AutoCastStop;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...)
+local L = SV.L;
+local MOD = SV.Dock;
+--[[
+##########################################################
+LOCAL VARS
+##########################################################
+]]--
+local BreakStuff_Cache = {}
+local DE, PICK, SMITH, BreakStuffParser;
+
+local BreakStuffButton = CreateFrame("Button", "BreakStuffButton", UIParent);
+BreakStuffButton.icon = BreakStuffButton:CreateTexture(nil,"OVERLAY")
+BreakStuffButton.icon:InsetPoints(BreakStuffButton,2,2)
+BreakStuffButton.icon:SetGradient("VERTICAL", 0.5, 0.53, 0.55, 0.8, 0.8, 1)
+BreakStuffButton.ttText = "BreakStuff : OFF";
+BreakStuffButton.subText = "";
+
+local BreakStuffHandler = CreateFrame('Button', "BreakStuffHandler", UIParent, 'SecureActionButtonTemplate, AutoCastShineTemplate')
+BreakStuffHandler:SetScript('OnEvent', function(self, event, ...) self[event](self, ...) end)
+BreakStuffHandler:SetPoint("LEFT",UIParent,"RIGHT",500)
+BreakStuffHandler.TipLines = {}
+BreakStuffHandler.TTextLeft = ""
+BreakStuffHandler.TTextRight = ""
+BreakStuffHandler.ReadyToSmash = false;
+--[[
+##########################################################
+ITEM PARSING
+##########################################################
+]]--
+do
+  local SkellyKeys = {
+	[GetSpellInfo(130100)] = true, -- Ghostly Skeleton Key
+	[GetSpellInfo(94574)] = true, -- Obsidium Skeleton Key
+	[GetSpellInfo(59403)] = true, -- Titanium Skeleton Key
+	[GetSpellInfo(59404)] = true, -- Colbat Skeleton Key
+	[GetSpellInfo(20709)] = true, -- Arcanite Skeleton Key
+	[GetSpellInfo(19651)] = true, -- Truesilver Skeleton Key
+	[GetSpellInfo(19649)] = true, -- Golden Skeleton Key
+	[GetSpellInfo(19646)] = true, -- Silver Skeleton Key
+  }
+  local BreakableFilter = {
+	["Pickables"]={['68729']=true,['63349']=true,['45986']=true,['43624']=true,['43622']=true,['43575']=true,['31952']=true,['12033']=true,['29569']=true,['5760']=true,['13918']=true,['5759']=true,['16885']=true,['5758']=true,['13875']=true,['4638']=true,['16884']=true,['4637']=true,['4636']=true,['6355']=true,['16883']=true,['4634']=true,['4633']=true,['6354']=true,['16882']=true,['4632']=true,['88165']=true,['88567']=true},["SafeItems"]={['89392']=true,['89393']=true,['89394']=true,['89395']=true,['89396']=true,['89397']=true,['89398']=true,['89399']=true,['89400']=true,['83260']=true,['83261']=true,['83262']=true,['83263']=true,['83264']=true,['83265']=true,['83266']=true,['83267']=true,['83268']=true,['83269']=true,['83270']=true,['83271']=true,['83274']=true,['83275']=true,['82706']=true,['82707']=true,['82708']=true,['82709']=true,['82710']=true,['82711']=true,['82712']=true,['82713']=true,['82714']=true,['82715']=true,['82716']=true,['82717']=true,['82720']=true,['82721']=true,['81671']=true,['81672']=true,['81673']=true,['81674']=true,['81675']=true,['81676']=true,['81677']=true,['81678']=true,['81679']=true,['81680']=true,['81681']=true,['81682']=true,['81685']=true,['81686']=true,['64377']=true,['64489']=true,['64880']=true,['64885']=true,['62454']=true,['62455']=true,['62456']=true,['62457']=true,['62458']=true,['62459']=true,['62460']=true,['68740']=true,['49888']=true,['49497']=true,['49301']=true,['72980']=true,['72981']=true,['72989']=true,['72990']=true,['72991']=true,['72992']=true,['72993']=true,['72994']=true,['72995']=true,['72996']=true,['72997']=true,['72998']=true,['72999']=true,['73000']=true,['73001']=true,['73002']=true,['73003']=true,['73006']=true,['73007']=true,['73008']=true,['73009']=true,['73010']=true,['73011']=true,['73012']=true,['73325']=true,['73326']=true,['73336']=true,['88622']=true,['88648']=true,['88649']=true,['64460']=true,['44050']=true,['44173']=true,['44174']=true,['44192']=true,['44193']=true,['44199']=true,['44244']=true,['44245']=true,['44249']=true,['44250']=true,['44051']=true,['44052']=true,['44053']=true,['44108']=true,['44166']=true,['44187']=true,['44214']=true,['44241']=true,['38454']=true,['38455']=true,['38456']=true,['38457']=true,['38460']=true,['38461']=true,['38464']=true,['38465']=true,['29115']=true,['29130']=true,['29133']=true,['29137']=true,['29138']=true,['29166']=true,['29167']=true,['29185']=true,['34665']=true,['34666']=true,['34667']=true,['34670']=true,['34671']=true,['34672']=true,['34673']=true,['34674']=true,['29121']=true,['29124']=true,['29125']=true,['29151']=true,['29152']=true,['29153']=true,['29155']=true,['29156']=true,['29165']=true,['29171']=true,['29175']=true,['29182']=true,['30830']=true,['30832']=true,['29456']=true,['29457']=true,['25835']=true,['25836']=true,['25823']=true,['25825']=true,['77559']=true,['77570']=true,['77583']=true,['77586']=true,['77587']=true,['77588']=true,['21392']=true,['21395']=true,['21398']=true,['21401']=true,['21404']=true,['21407']=true,['21410']=true,['21413']=true,['21416']=true,['38632']=true,['38633']=true,['38707']=true,['34661']=true,['11290']=true,['11289']=true,['45858']=true,['84661']=true,['11288']=true,['28164']=true,['11287']=true,['44180']=true,['44202']=true,['44302']=true,['44200']=true,['44256']=true,['44104']=true,['44116']=true,['44196']=true,['44061']=true,['44062']=true,['29117']=true,['29129']=true,['29174']=true,['30836']=true,['35328']=true,['35329']=true,['35330']=true,['35331']=true,['35332']=true,['35333']=true,['35334']=true,['35335']=true,['35336']=true,['35337']=true,['35338']=true,['35339']=true,['35340']=true,['35341']=true,['35342']=true,['35343']=true,['35344']=true,['35345']=true,['35346']=true,['35347']=true,['35464']=true,['35465']=true,['35466']=true,['35467']=true,['30847']=true,['29122']=true,['29183']=true,['90079']=true,['90080']=true,['90081']=true,['90082']=true,['90083']=true,['90084']=true,['90085']=true,['90086']=true,['90110']=true,['90111']=true,['90112']=true,['90113']=true,['90114']=true,['90115']=true,['90116']=true,['90117']=true,['90136']=true,['90137']=true,['90138']=true,['90139']=true,['90140']=true,['90141']=true,['90142']=true,['90143']=true,['64643']=true,['77678']=true,['77679']=true,['77682']=true,['77692']=true,['77694']=true,['77695']=true,['77709']=true,['77710']=true,['77712']=true,['77886']=true,['77889']=true,['77890']=true,['77899']=true,['77900']=true,['77901']=true,['77917']=true,['77919']=true,['77920']=true,['77680']=true,['77681']=true,['77683']=true,['77690']=true,['77691']=true,['77693']=true,['77708']=true,['77711']=true,['77713']=true,['77887']=true,['77888']=true,['77891']=true,['77898']=true,['77902']=true,['77903']=true,['77916']=true,['77918']=true,['77921']=true,['77778']=true,['77779']=true,['77784']=true,['77795']=true,['77796']=true,['77800']=true,['77801']=true,['77844']=true,['77845']=true,['77846']=true,['77850']=true,['77777']=true,['77781']=true,['77782']=true,['77785']=true,['77797']=true,['77798']=true,['77799']=true,['77802']=true,['77847']=true,['77848']=true,['77851']=true,['77852']=true,['77724']=true,['77725']=true,['77728']=true,['77729']=true,['77732']=true,['77733']=true,['77773']=true,['77783']=true,['77803']=true,['77804']=true,['77843']=true,['77849']=true,['77614']=true,['77615']=true,['77616']=true,['77617']=true,['77618']=true,['77619']=true,['77620']=true,['77627']=true,['77628']=true,['77629']=true,['77630']=true,['77631']=true,['77632']=true,['77647']=true,['77648']=true,['77649']=true,['77650']=true,['77651']=true,['77652']=true,['77770']=true,['77771']=true,['77772']=true,['77774']=true,['77775']=true,['77776']=true,['77786']=true,['77789']=true,['77790']=true,['77791']=true,['77792']=true,['77793']=true,['77794']=true,['77837']=true,['77838']=true,['77839']=true,['77840']=true,['77841']=true,['77842']=true,['20406']=true,['20407']=true,['20408']=true,['77787']=true,['77788']=true,['28155']=true,['22986']=true,['22991']=true,['33292']=true,['86566']=true,['95517']=true,['95518']=true,['95523']=true,['95526']=true,['95527']=true,['95532']=true,['83158']=true,['83162']=true,['83167']=true,['83171']=true,['83176']=true,['83180']=true,['83185']=true,['83189']=true,['83194']=true,['83198']=true,['83203']=true,['83207']=true,['83212']=true,['83216']=true,['83221']=true,['83225']=true,['82614']=true,['82618']=true,['82623']=true,['82627']=true,['82632']=true,['82636']=true,['82641']=true,['82645']=true,['82650']=true,['82654']=true,['82659']=true,['82663']=true,['82668']=true,['82672']=true,['82677']=true,['82681']=true,['81579']=true,['81583']=true,['81588']=true,['81592']=true,['81597']=true,['81601']=true,['81606']=true,['81610']=true,['81615']=true,['81619']=true,['81624']=true,['81628']=true,['81633']=true,['81637']=true,['81642']=true,['81646']=true,['70118']=true,['62364']=true,['62386']=true,['62450']=true,['62441']=true,['62356']=true,['62406']=true,['62424']=true,['72621']=true,['72622']=true,['72623']=true,['72624']=true,['72625']=true,['72626']=true,['72627']=true,['72628']=true,['72638']=true,['72639']=true,['72640']=true,['72641']=true,['72642']=true,['72643']=true,['72644']=true,['72645']=true,['72646']=true,['72647']=true,['72648']=true,['72649']=true,['72650']=true,['72651']=true,['72652']=true,['72653']=true,['72655']=true,['72656']=true,['72657']=true,['72658']=true,['72659']=true,['72660']=true,['72661']=true,['72662']=true,['44180']=true,['44202']=true,['44302']=true,['44200']=true,['44256']=true,['44181']=true,['44203']=true,['44297']=true,['44303']=true,['44179']=true,['44194']=true,['44258']=true,['44106']=true,['44170']=true,['44190']=true,['44117']=true,['44054']=true,['44055']=true,['29116']=true,['29131']=true,['29141']=true,['29142']=true,['29147']=true,['29148']=true,['35356']=true,['35357']=true,['35358']=true,['35359']=true,['35360']=true,['35361']=true,['35362']=true,['35363']=true,['35364']=true,['35365']=true,['35366']=true,['35367']=true,['35368']=true,['35369']=true,['35370']=true,['35371']=true,['35372']=true,['35373']=true,['35374']=true,['35375']=true,['35468']=true,['35469']=true,['35470']=true,['35471']=true,['25838']=true,['90059']=true,['90060']=true,['90061']=true,['90062']=true,['90063']=true,['90064']=true,['90065']=true,['90066']=true,['90088']=true,['90089']=true,['90090']=true,['90091']=true,['90092']=true,['90093']=true,['90094']=true,['90095']=true,['90119']=true,['90120']=true,['90121']=true,['90122']=true,['90123']=true,['90124']=true,['90125']=true,['90126']=true,['77667']=true,['77670']=true,['77671']=true,['77697']=true,['77700']=true,['77701']=true,['77874']=true,['77876']=true,['77878']=true,['77907']=true,['77908']=true,['77909']=true,['77666']=true,['77668']=true,['77669']=true,['77696']=true,['77698']=true,['77699']=true,['77875']=true,['77877']=true,['77879']=true,['77904']=true,['77905']=true,['77906']=true,['77742']=true,['77746']=true,['77748']=true,['77752']=true,['77813']=true,['77815']=true,['77819']=true,['77820']=true,['77744']=true,['77745']=true,['77749']=true,['77811']=true,['77812']=true,['77818']=true,['77821']=true,['77720']=true,['77721']=true,['77730']=true,['77731']=true,['77747']=true,['77750']=true,['77816']=true,['77817']=true,['77598']=true,['77599']=true,['77600']=true,['77601']=true,['77602']=true,['77603']=true,['77604']=true,['77633']=true,['77634']=true,['77635']=true,['77636']=true,['77637']=true,['77638']=true,['77639']=true,['77736']=true,['77737']=true,['77738']=true,['77739']=true,['77740']=true,['77741']=true,['77743']=true,['77805']=true,['77806']=true,['77807']=true,['77808']=true,['77809']=true,['77810']=true,['77814']=true,['77605']=true,['77640']=true,['77753']=true,['77822']=true,['28158']=true,['22987']=true,['22992']=true,['95519']=true,['95521']=true,['95528']=true,['95530']=true,['83159']=true,['83163']=true,['83168']=true,['83172']=true,['83177']=true,['83181']=true,['83186']=true,['83190']=true,['83195']=true,['83199']=true,['83204']=true,['83208']=true,['83213']=true,['83217']=true,['83222']=true,['83226']=true,['82615']=true,['82619']=true,['82624']=true,['82628']=true,['82633']=true,['82637']=true,['82642']=true,['82646']=true,['82651']=true,['82655']=true,['82660']=true,['82664']=true,['82669']=true,['82673']=true,['82678']=true,['82682']=true,['81580']=true,['81584']=true,['81589']=true,['81593']=true,['81598']=true,['81602']=true,['81607']=true,['81611']=true,['81616']=true,['81620']=true,['81625']=true,['81629']=true,['81634']=true,['81638']=true,['81643']=true,['81647']=true,['70114']=true,['70122']=true,['62417']=true,['62420']=true,['62431']=true,['62433']=true,['62358']=true,['62381']=true,['62446']=true,['62374']=true,['62404']=true,['62405']=true,['62425']=true,['62426']=true,['72664']=true,['72665']=true,['72666']=true,['72667']=true,['72668']=true,['72669']=true,['72670']=true,['72671']=true,['72672']=true,['72673']=true,['72674']=true,['72675']=true,['72676']=true,['72677']=true,['72678']=true,['72679']=true,['72681']=true,['72682']=true,['72683']=true,['72684']=true,['72685']=true,['72686']=true,['72687']=true,['72688']=true,['72689']=true,['72690']=true,['72691']=true,['72692']=true,['72693']=true,['72694']=true,['72695']=true,['72696']=true,['88614']=true,['88615']=true,['88616']=true,['88617']=true,['88618']=true,['88619']=true,['88620']=true,['88621']=true,['88623']=true,['88624']=true,['88625']=true,['88626']=true,['88627']=true,['88628']=true,['88629']=true,['88630']=true,['44181']=true,['44203']=true,['44297']=true,['44303']=true,['44179']=true,['44194']=true,['44258']=true,['44182']=true,['44204']=true,['44295']=true,['44305']=true,['44248']=true,['44257']=true,['44109']=true,['44110']=true,['44122']=true,['44171']=true,['44189']=true,['44059']=true,['44060']=true,['29135']=true,['29136']=true,['29180']=true,['30835']=true,['35376']=true,['35377']=true,['35378']=true,['35379']=true,['35380']=true,['35381']=true,['35382']=true,['35383']=true,['35384']=true,['35385']=true,['35386']=true,['35387']=true,['35388']=true,['35389']=true,['35390']=true,['35391']=true,['35392']=true,['35393']=true,['35394']=true,['35395']=true,['35472']=true,['35473']=true,['35474']=true,['35475']=true,['64644']=true,['90068']=true,['90069']=true,['90070']=true,['90071']=true,['90072']=true,['90073']=true,['90074']=true,['90075']=true,['90127']=true,['90128']=true,['90129']=true,['90130']=true,['90131']=true,['90132']=true,['90133']=true,['90134']=true,['77673']=true,['77674']=true,['77676']=true,['77704']=true,['77705']=true,['77707']=true,['77880']=true,['77882']=true,['77883']=true,['77910']=true,['77913']=true,['77914']=true,['77672']=true,['77675']=true,['77677']=true,['77702']=true,['77703']=true,['77706']=true,['77881']=true,['77884']=true,['77885']=true,['77911']=true,['77912']=true,['77915']=true,['77642']=true,['77645']=true,['77762']=true,['77763']=true,['77765']=true,['77766']=true,['77831']=true,['77832']=true,['77641']=true,['77643']=true,['77760']=true,['77761']=true,['77768']=true,['77769']=true,['77829']=true,['77834']=true,['77644']=true,['77646']=true,['77722']=true,['77723']=true,['77764']=true,['77767']=true,['77830']=true,['77833']=true,['77606']=true,['77607']=true,['77608']=true,['77609']=true,['77610']=true,['77611']=true,['77612']=true,['77754']=true,['77755']=true,['77756']=true,['77757']=true,['77758']=true,['77759']=true,['77823']=true,['77824']=true,['77825']=true,['77826']=true,['77827']=true,['77828']=true,['77835']=true,['28162']=true,['22985']=true,['22993']=true,['95522']=true,['95525']=true,['95531']=true,['95534']=true,['83160']=true,['83164']=true,['83169']=true,['83173']=true,['83178']=true,['83182']=true,['83187']=true,['83191']=true,['83196']=true,['83200']=true,['83205']=true,['83209']=true,['83214']=true,['83218']=true,['83223']=true,['83227']=true,['82616']=true,['82620']=true,['82625']=true,['82629']=true,['82634']=true,['82638']=true,['82643']=true,['82647']=true,['82652']=true,['82656']=true,['82661']=true,['82665']=true,['82670']=true,['82674']=true,['82679']=true,['82683']=true,['81581']=true,['81585']=true,['81590']=true,['81594']=true,['81599']=true,['81603']=true,['81608']=true,['81612']=true,['81617']=true,['81621']=true,['81626']=true,['81630']=true,['81635']=true,['81639']=true,['81644']=true,['81648']=true,['70115']=true,['70123']=true,['62363']=true,['62385']=true,['62380']=true,['62409']=true,['62429']=true,['62445']=true,['62353']=true,['62407']=true,['62423']=true,['62439']=true,['72698']=true,['72699']=true,['72700']=true,['72701']=true,['72702']=true,['72703']=true,['72704']=true,['72705']=true,['72889']=true,['72890']=true,['72891']=true,['72892']=true,['72893']=true,['72894']=true,['72895']=true,['72896']=true,['72902']=true,['72903']=true,['72904']=true,['72905']=true,['72906']=true,['72907']=true,['72908']=true,['72909']=true,['72910']=true,['72911']=true,['72912']=true,['72913']=true,['72914']=true,['72915']=true,['72916']=true,['72917']=true,['44182']=true,['44204']=true,['44295']=true,['44305']=true,['44248']=true,['44257']=true,['44183']=true,['44205']=true,['44296']=true,['44306']=true,['44176']=true,['44195']=true,['44198']=true,['44201']=true,['44247']=true,['44111']=true,['44112']=true,['44120']=true,['44121']=true,['44123']=true,['44197']=true,['44239']=true,['44240']=true,['44243']=true,['44057']=true,['44058']=true,['40440']=true,['40441']=true,['40442']=true,['40443']=true,['40444']=true,['29127']=true,['29134']=true,['29184']=true,['35402']=true,['35403']=true,['35404']=true,['35405']=true,['35406']=true,['35407']=true,['35408']=true,['35409']=true,['35410']=true,['35411']=true,['35412']=true,['35413']=true,['35414']=true,['35415']=true,['35416']=true,['35476']=true,['35477']=true,['35478']=true,['90049']=true,['90050']=true,['90051']=true,['90052']=true,['90053']=true,['90054']=true,['90055']=true,['90056']=true,['90096']=true,['90097']=true,['90098']=true,['90099']=true,['90100']=true,['90101']=true,['90102']=true,['90103']=true,['90147']=true,['90148']=true,['90149']=true,['90150']=true,['90151']=true,['90152']=true,['90153']=true,['90154']=true,['77687']=true,['77688']=true,['77689']=true,['77714']=true,['77715']=true,['77718']=true,['77892']=true,['77894']=true,['77897']=true,['77923']=true,['77924']=true,['77927']=true,['77684']=true,['77685']=true,['77686']=true,['77716']=true,['77717']=true,['77719']=true,['77893']=true,['77895']=true,['77896']=true,['77922']=true,['77925']=true,['77926']=true,['77664']=true,['77665']=true,['77859']=true,['77867']=true,['77868']=true,['77869']=true,['77871']=true,['77872']=true,['38661']=true,['38663']=true,['38665']=true,['38666']=true,['38667']=true,['38668']=true,['38669']=true,['38670']=true,['77661']=true,['77662']=true,['77663']=true,['77858']=true,['77864']=true,['77865']=true,['77866']=true,['77873']=true,['77726']=true,['77727']=true,['77734']=true,['77735']=true,['77862']=true,['77863']=true,['77928']=true,['77929']=true,['77621']=true,['77622']=true,['77623']=true,['77624']=true,['77625']=true,['77626']=true,['77653']=true,['77654']=true,['77655']=true,['77656']=true,['77657']=true,['77658']=true,['77659']=true,['77853']=true,['77854']=true,['77855']=true,['77856']=true,['77857']=true,['77860']=true,['77861']=true,['34648']=true,['34649']=true,['34650']=true,['34651']=true,['34652']=true,['34653']=true,['34655']=true,['34656']=true,['77660']=true,['95520']=true,['95524']=true,['95529']=true,['95533']=true,['83161']=true,['83165']=true,['83166']=true,['83170']=true,['83174']=true,['83175']=true,['83179']=true,['83183']=true,['83184']=true,['83188']=true,['83192']=true,['83193']=true,['83197']=true,['83201']=true,['83202']=true,['83206']=true,['83210']=true,['83211']=true,['83215']=true,['83219']=true,['83220']=true,['83224']=true,['83228']=true,['83229']=true,['82617']=true,['82621']=true,['82622']=true,['82626']=true,['82630']=true,['82631']=true,['82635']=true,['82639']=true,['82640']=true,['82644']=true,['82648']=true,['82649']=true,['82653']=true,['82657']=true,['82658']=true,['82662']=true,['82666']=true,['82667']=true,['82671']=true,['82675']=true,['82676']=true,['82680']=true,['82684']=true,['82685']=true,['81582']=true,['81586']=true,['81587']=true,['81591']=true,['81595']=true,['81596']=true,['81600']=true,['81604']=true,['81605']=true,['81609']=true,['81613']=true,['81614']=true,['81618']=true,['81622']=true,['81623']=true,['81627']=true,['81631']=true,['81632']=true,['81636']=true,['81640']=true,['81641']=true,['81645']=true,['81649']=true,['81650']=true,['70108']=true,['70116']=true,['70117']=true,['70120']=true,['70121']=true,['62365']=true,['62384']=true,['62418']=true,['62432']=true,['62448']=true,['62449']=true,['62359']=true,['62382']=true,['62408']=true,['62410']=true,['62428']=true,['62430']=true,['62355']=true,['62438']=true,['72918']=true,['72919']=true,['72920']=true,['72921']=true,['72922']=true,['72923']=true,['72924']=true,['72925']=true,['72929']=true,['72930']=true,['72931']=true,['72932']=true,['72933']=true,['72934']=true,['72935']=true,['72936']=true,['72937']=true,['72938']=true,['72939']=true,['72940']=true,['72941']=true,['72942']=true,['72943']=true,['72944']=true,['72945']=true,['72946']=true,['72947']=true,['72948']=true,['72949']=true,['72950']=true,['72951']=true,['72952']=true,['72955']=true,['72956']=true,['72957']=true,['72958']=true,['72959']=true,['72960']=true,['72961']=true,['72962']=true,['72963']=true,['72964']=true,['72965']=true,['72966']=true,['72967']=true,['72968']=true,['72969']=true,['72970']=true,['72971']=true,['72972']=true,['72973']=true,['72974']=true,['72975']=true,['72976']=true,['72977']=true,['72978']=true,['44183']=true,['44205']=true,['44296']=true,['44306']=true,['44176']=true,['44195']=true,['44198']=true,['44201']=true,['44247']=true,['29278']=true,['29282']=true,['29286']=true,['29291']=true,['31113']=true,['34675']=true,['34676']=true,['34677']=true,['34678']=true,['34679']=true,['34680']=true,['29128']=true,['29132']=true,['29139']=true,['29140']=true,['29145']=true,['29146']=true,['29168']=true,['29169']=true,['29173']=true,['29179']=true,['29276']=true,['29280']=true,['29284']=true,['29288']=true,['30841']=true,['32538']=true,['32539']=true,['29277']=true,['29281']=true,['29285']=true,['29289']=true,['32864']=true,['31341']=true,['29119']=true,['29123']=true,['29126']=true,['29170']=true,['29172']=true,['29176']=true,['29177']=true,['29181']=true,['32770']=true,['32771']=true,['30834']=true,['25824']=true,['25826']=true,['21200']=true,['21205']=true,['21210']=true,['52252']=true,['21199']=true,['21204']=true,['21209']=true,['49052']=true,['49054']=true,['21198']=true,['21203']=true,['21208']=true,['32695']=true,['38662']=true,['38664']=true,['38671']=true,['38672']=true,['38674']=true,['38675']=true,['39320']=true,['39322']=true,['32694']=true,['21394']=true,['21397']=true,['21400']=true,['21403']=true,['21406']=true,['21409']=true,['21412']=true,['21415']=true,['21418']=true,['21197']=true,['21202']=true,['21207']=true,['21393']=true,['21396']=true,['21399']=true,['21402']=true,['21405']=true,['21408']=true,['21411']=true,['21414']=true,['21417']=true,['17904']=true,['17909']=true,['21196']=true,['21201']=true,['21206']=true,['65274']=true,['65360']=true,['17902']=true,['17903']=true,['17907']=true,['17908']=true,['40476']=true,['40477']=true,['17690']=true,['17691']=true,['17900']=true,['17901']=true,['17905']=true,['17906']=true,['34657']=true,['34658']=true,['34659']=true,['38147']=true,['21766']=true,['64886']=true,['64887']=true,['64888']=true,['64889']=true,['64890']=true,['64891']=true,['64892']=true,['64893']=true,['64894']=true,['64895']=true,['64896']=true,['64897']=true,['64898']=true,['64899']=true,['64900']=true,['64901']=true,['64902']=true,['64903']=true,['64905']=true,['64906']=true,['64907']=true,['64908']=true,['64909']=true,['64910']=true,['64911']=true,['64912']=true,['64913']=true,['64914']=true,['64915']=true,['64916']=true,['64917']=true,['64918']=true,['64919']=true,['64920']=true,['64921']=true,['64922']=true,['4614']=true,['22990']=true,['34484']=true,['34486']=true,['23705']=true,['23709']=true,['38309']=true,['38310']=true,['38311']=true,['38312']=true,['38313']=true,['38314']=true,['40643']=true,['43300']=true,['43348']=true,['43349']=true,['98162']=true,['35279']=true,['35280']=true,['40483']=true,['46874']=true,['89401']=true,['89784']=true,['89795']=true,['89796']=true,['89797']=true,['89798']=true,['89799']=true,['89800']=true,['95591']=true,['95592']=true,['97131']=true,['50384']=true,['50386']=true,['50387']=true,['50388']=true,['52570']=true,['50375']=true,['50376']=true,['50377']=true,['50378']=true,['52569']=true,['72982']=true,['72983']=true,['72984']=true,['73004']=true,['73005']=true,['73013']=true,['73014']=true,['73015']=true,['73016']=true,['73017']=true,['73018']=true,['73019']=true,['73020']=true,['73021']=true,['73022']=true,['73023']=true,['73024']=true,['73025']=true,['73026']=true,['73027']=true,['73042']=true,['73060']=true,['73061']=true,['73062']=true,['73063']=true,['73064']=true,['73065']=true,['73066']=true,['73067']=true,['73068']=true,['73101']=true,['73102']=true,['73103']=true,['73104']=true,['73105']=true,['73106']=true,['73107']=true,['73108']=true,['73109']=true,['73110']=true,['73111']=true,['73112']=true,['73113']=true,['73114']=true,['73115']=true,['73116']=true,['73117']=true,['73118']=true,['73119']=true,['73120']=true,['73121']=true,['73122']=true,['73123']=true,['73124']=true,['73125']=true,['73126']=true,['73127']=true,['73128']=true,['73129']=true,['73130']=true,['73131']=true,['73132']=true,['73133']=true,['73134']=true,['73135']=true,['73136']=true,['73137']=true,['73138']=true,['73139']=true,['73140']=true,['73141']=true,['73142']=true,['73143']=true,['73144']=true,['73145']=true,['73146']=true,['73147']=true,['73148']=true,['73149']=true,['73150']=true,['73151']=true,['73152']=true,['73153']=true,['73154']=true,['73155']=true,['73156']=true,['73157']=true,['73158']=true,['73159']=true,['73160']=true,['73161']=true,['73162']=true,['73163']=true,['73164']=true,['73165']=true,['73166']=true,['73167']=true,['73168']=true,['73169']=true,['73170']=true,['73306']=true,['73307']=true,['73308']=true,['73309']=true,['73310']=true,['73311']=true,['73312']=true,['73313']=true,['73314']=true,['73315']=true,['73316']=true,['73317']=true,['73318']=true,['73319']=true,['73320']=true,['73321']=true,['73322']=true,['73323']=true,['73324']=true,['88632']=true,['88633']=true,['88634']=true,['88635']=true,['88636']=true,['88637']=true,['88638']=true,['88639']=true,['88640']=true,['88641']=true,['88642']=true,['88643']=true,['88644']=true,['88645']=true,['88646']=true,['88647']=true,['88667']=true,['44073']=true,['44074']=true,['44283']=true,['44167']=true,['44188']=true,['44216']=true,['44242']=true,['38452']=true,['38453']=true,['38458']=true,['38459']=true,['38462']=true,['38463']=true,['29297']=true,['29301']=true,['29305']=true,['29309']=true,['29296']=true,['29308']=true,['32485']=true,['32486']=true,['32487']=true,['32488']=true,['32489']=true,['32490']=true,['32491']=true,['32492']=true,['32493']=true,['32649']=true,['32757']=true,['29295']=true,['29299']=true,['29303']=true,['29306']=true,['29300']=true,['29304']=true,['29279']=true,['29283']=true,['29287']=true,['29290']=true,['29294']=true,['29298']=true,['29302']=true,['29307']=true,['29278']=true,['29282']=true,['29286']=true,['29291']=true,['98146']=true,['98147']=true,['98148']=true,['98149']=true,['98150']=true,['98335']=true,['92782']=true,['92783']=true,['92784']=true,['92785']=true,['92786']=true,['92787']=true,['93391']=true,['93392']=true,['93393']=true,['93394']=true,['93395']=true,['95425']=true,['95427']=true,['95428']=true,['95429']=true,['95430']=true,['88166']=true,['88167']=true,['88168']=true,['88169']=true,['75274']=true,['83230']=true,['83231']=true,['83232']=true,['83233']=true,['83234']=true,['83235']=true,['83236']=true,['83237']=true,['83238']=true,['83239']=true,['83245']=true,['83246']=true,['83247']=true,['83248']=true,['83249']=true,['83255']=true,['83256']=true,['83257']=true,['83258']=true,['83259']=true,['83272']=true,['83273']=true,['86567']=true,['86570']=true,['86572']=true,['86576']=true,['86579']=true,['86585']=true,['86587']=true,['87780']=true,['82686']=true,['82687']=true,['82688']=true,['82689']=true,['82690']=true,['82691']=true,['82692']=true,['82693']=true,['82694']=true,['82695']=true,['82696']=true,['82697']=true,['82698']=true,['82699']=true,['82700']=true,['82701']=true,['82702']=true,['82703']=true,['82704']=true,['82705']=true,['82718']=true,['82719']=true,['81651']=true,['81652']=true,['81653']=true,['81654']=true,['81655']=true,['81656']=true,['81657']=true,['81658']=true,['81659']=true,['81660']=true,['81661']=true,['81662']=true,['81663']=true,['81664']=true,['81665']=true,['81666']=true,['81667']=true,['81668']=true,['81669']=true,['81670']=true,['81683']=true,['81684']=true,['70105']=true,['70106']=true,['70107']=true,['70110']=true,['70112']=true,['70113']=true,['70119']=true,['70124']=true,['70126']=true,['70127']=true,['70141']=true,['70142']=true,['70143']=true,['70144']=true,['58483']=true,['62362']=true,['62383']=true,['62416']=true,['62434']=true,['62447']=true,['62463']=true,['62464']=true,['62465']=true,['62466']=true,['62467']=true,['64645']=true,['64904']=true,['68775']=true,['68776']=true,['68777']=true,['69764']=true,['62348']=true,['62350']=true,['62351']=true,['62352']=true,['62357']=true,['62361']=true,['62378']=true,['62415']=true,['62427']=true,['62440']=true,['62354']=true,['62375']=true,['62376']=true,['62377']=true,['62436']=true,['62437']=true,['65175']=true,['65176']=true,['50398']=true,['50400']=true,['50402']=true,['50404']=true,['52572']=true,['50397']=true,['50399']=true,['50401']=true,['50403']=true,['52571']=true}
+	}
+
+	local AllowedItemIDs = {
+		['109129']='OVERRIDE_MILLABLE',
+		['109128']='OVERRIDE_MILLABLE',
+		['109127']='OVERRIDE_MILLABLE',
+		['109126']='OVERRIDE_MILLABLE',
+		['109125']='OVERRIDE_MILLABLE',
+		['109124']='OVERRIDE_MILLABLE',
+		-- ['109119']='OVERRIDE_PROSPECTABLE',
+	}
+
+	local function IsThisBreakable(link)
+		local _, _, quality = GetItemInfo(link)
+		if(IsEquippableItem(link) and quality and quality > 1 and quality < 5) then
+			return not BreakableFilter["SafeItems"][match(link, 'item:(%d+):')]
+		end
+	end
+
+	local function IsThisOpenable(link)
+		return BreakableFilter["Pickables"][match(link, 'item:(%d+)')]
+	end
+
+	local function ScanTooltip(self, itemLink)
+		for index = 1, self:NumLines() do
+			local info = BreakStuff_Cache[_G['GameTooltipTextLeft' .. index]:GetText()]
+			if(info) then
+				return unpack(info)
+			end
+		end
+		local itemID = itemLink:match(":(%w+)")
+		local override = AllowedItemIDs[itemID]
+		if(override and BreakStuff_Cache[override]) then
+			return unpack(BreakStuff_Cache[override])
+		end
+	end
+
+	local function CloneTooltip()
+		twipe(BreakStuffHandler.TipLines)
+		for index = 1, GameTooltip:NumLines() do
+			local text = _G['GameTooltipTextLeft' .. index]:GetText()
+			if(text) then
+				BreakStuffHandler.TipLines[#BreakStuffHandler.TipLines+1] = text
+			end
+		end
+	end
+
+	local function DoIHaveAKey()
+		for key in pairs(SkellyKeys) do
+			if(GetItemCount(key) > 0) then
+				return key
+			end
+		end
+	end
+
+	local function ApplyButton(itemLink, spell, r, g, b)
+		local slot = GetMouseFocus()
+		local bag = slot:GetParent():GetID()
+
+		if(GetContainerItemLink(bag, slot:GetID()) == itemLink) then
+			--CloneTooltip()
+			BreakStuffHandler:SetAttribute('spell', spell)
+			BreakStuffHandler:SetAttribute('target-bag', bag)
+			BreakStuffHandler:SetAttribute('target-slot', slot:GetID())
+			BreakStuffHandler:SetAllPoints(slot)
+			BreakStuffHandler:Show()
+
+			AutoCastShine_AutoCastStart(BreakStuffHandler, r, g, b)
+		end
+	end
+
+	function BreakStuffParser(self)
+		local item, link = self:GetItem()
+		if(item and not InCombatLockdown() and (BreakStuffHandler.ReadyToSmash == true)) then
+			local spell, r, g, b = ScanTooltip(self, link)
+			local rr, gg, bb = 1, 1, 1
+			if(spell) then
+				ApplyButton(link, spell, r, g, b)
+			else
+				spell = "Open"
+				if(DE and IsThisBreakable(link)) then
+					rr, gg, bb = 0.5, 0.5, 1
+					ApplyButton(link, DE, rr, gg, bb)
+				elseif(PICK and IsThisOpenable(link)) then
+					rr, gg, bb = 0, 1, 1
+					ApplyButton(link, PICK, rr, gg, bb)
+				elseif(SMITH and IsThisOpenable(link)) then
+					rr, gg, bb = 0, 1, 1
+					local hasKey = DoIHaveAKey()
+					ApplyButton(link, hasKey, rr, gg, bb)
+				end
+			end
+			BreakStuffHandler.TTextLeft = spell
+			BreakStuffHandler.TTextRight = item
+		end
+	end
+end
+--[[
+##########################################################
+BUILD FOR PACKAGE
+##########################################################
+]]--
+local BreakStuff_OnModifier = function(self, arg)
+	if(not self:IsShown() and not arg and (self.ReadyToSmash == false)) then return; end
+	if(InCombatLockdown()) then
+		self:SetAlpha(0)
+		self:RegisterEvent('PLAYER_REGEN_ENABLED')
+	else
+		self:ClearAllPoints()
+		self:SetAlpha(1)
+		self:Hide()
+		AutoCastShine_AutoCastStop(self)
+	end
+end
+
+BreakStuffHandler.MODIFIER_STATE_CHANGED = BreakStuff_OnModifier;
+
+local BreakStuff_OnHide = function()
+	BreakStuffHandler.ReadyToSmash = false
+	BreakStuffButton.ttText = "BreakStuff : OFF";
+end
+
+local BreakStuff_OnEnter = function(self)
+	GameTooltip:SetOwner(self,"ANCHOR_TOP",0,4)
+	GameTooltip:ClearLines()
+	GameTooltip:AddLine(self.ttText)
+	GameTooltip:AddLine(self.subText)
+	if self.ttText2 then
+		GameTooltip:AddLine(' ')
+		GameTooltip:AddDoubleLine(self.ttText2,self.ttText2desc,1,1,1)
+	end
+	if BreakStuffHandler.ReadyToSmash ~= true then
+		self:SetPanelColor("class")
+		self.icon:SetGradient(unpack(SV.media.gradient.highlight))
+	end
+	GameTooltip:Show()
+end
+
+local BreakStuff_OnLeave = function(self)
+	if BreakStuffHandler.ReadyToSmash ~= true then
+		self:SetPanelColor("default")
+		self.icon:SetGradient("VERTICAL", 0.5, 0.53, 0.55, 0.8, 0.8, 1)
+		GameTooltip:Hide()
+	end
+end
+
+local BreakStuff_OnClick = function(self)
+	if InCombatLockdown() then print(ERR_NOT_IN_COMBAT) return end
+	if BreakStuffHandler.ReadyToSmash == true then
+		BreakStuffHandler:MODIFIER_STATE_CHANGED()
+		BreakStuffHandler.ReadyToSmash = false
+		self.ttText = "BreakStuff : OFF";
+		self:SetPanelColor("default")
+		self.icon:SetGradient("VERTICAL", 0.5, 0.53, 0.55, 0.8, 0.8, 1)
+	else
+		BreakStuffHandler.ReadyToSmash = true
+		self.ttText = "BreakStuff : ON";
+		self:SetPanelColor("green")
+		self.icon:SetGradient(unpack(SV.media.gradient.green))
+		if(SV.Inventory and SV.Inventory.MasterFrame) then
+			if(not SV.Inventory.MasterFrame:IsShown()) then
+				GameTooltip:Hide()
+				SV.Inventory.MasterFrame:Show()
+				SV.Inventory.MasterFrame:RefreshBags()
+				if(SV.Tooltip) then
+					SV.Tooltip.GameTooltip_SetDefaultAnchor(GameTooltip,self)
+				end
+			end
+		end
+	end
+	GameTooltip:ClearLines()
+	GameTooltip:AddLine(self.ttText)
+	GameTooltip:AddLine(self.subText)
+end
+
+function BreakStuffHandler:PLAYER_REGEN_ENABLED()
+	self:UnregisterEvent('PLAYER_REGEN_ENABLED')
+	BreakStuff_OnModifier(self)
+end
+
+function MOD:PLAYER_REGEN_ENABLED()
+	self:UnregisterEvent('PLAYER_REGEN_ENABLED')
+	self:LoadBreakStuff()
+end
+
+local SetClonedTip = function(self)
+	GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT", 0, 4)
+	GameTooltip:ClearLines()
+	GameTooltip:AddDoubleLine(self.TTextLeft, self.TTextRight, 0,1,0,1,1,1)
+	-- for index = 1, #self.TipLines do
+	-- 	GameTooltip:AddLine(self.TipLines[index])
+	-- end
+
+	GameTooltip:Show()
+end
+
+local function LoadToolBreakStuff()
+	if(InCombatLockdown()) then MOD:RegisterEvent("PLAYER_REGEN_ENABLED"); return end
+	local allowed, spellListing, spellName, _ = false, {};
+
+	if(IsSpellKnown(51005)) then
+		--print("Milling")
+		allowed = true
+		spellName,_ = GetSpellInfo(51005)
+		BreakStuff_Cache[ITEM_MILLABLE] = {spellName, 0.5, 1, 0.5}
+		BreakStuff_Cache['OVERRIDE_MILLABLE'] = {spellName, 0.5, 1, 0.5}
+    local count = #spellListing + 1;
+    spellListing[count] = spellName;
+	end
+
+	if(IsSpellKnown(31252)) then
+		--print("Prospecting")
+		allowed = true
+		spellName,_ = GetSpellInfo(31252)
+		BreakStuff_Cache[ITEM_PROSPECTABLE] = {spellName, 1, 0.33, 0.33}
+		-- BreakStuff_Cache['OVERRIDE_PROSPECTABLE'] = {spellName, 1, 0.33, 0.33}
+    local count = #spellListing + 1;
+    spellListing[count] = spellName;
+	end
+
+	if(IsSpellKnown(13262)) then
+		--print("Enchanting")
+		allowed = true
+		DE,_ = GetSpellInfo(13262)
+    local count = #spellListing + 1;
+    spellListing[count] = DE;
+	end
+
+	if(IsSpellKnown(1804)) then
+		--print("Lockpicking")
+		allowed = true
+		PICK,_ = GetSpellInfo(1804)
+    local count = #spellListing + 1;
+    spellListing[count] = PICK;
+	end
+
+	if(IsSpellKnown(2018)) then
+		--print("Blacksmithing")
+		allowed = true
+		SMITH,_ = GetSpellBookItemInfo((GetSpellInfo(2018)))
+    local count = #spellListing + 1;
+    spellListing[count] = SMITH;
+	end
+
+	MOD.BreakStuffLoaded = true;
+
+	if not allowed then return end
+
+	BreakStuffButton:SetParent(MOD.BottomRight.Bar.ToolBar)
+	local size = MOD.BottomRight.Bar.ToolBar:GetHeight()
+	BreakStuffButton:SetSize(size, size)
+	BreakStuffButton:SetPoint("RIGHT", MOD.BottomRight.Bar.ToolBar, "LEFT", -6, 0)
+	BreakStuffButton.icon:SetTexture(SV.media.dock.breakStuffIcon)
+	BreakStuffButton:Show();
+	BreakStuffButton:SetStyle("DockButton")
+
+	BreakStuffButton:SetScript("OnEnter", BreakStuff_OnEnter);
+	BreakStuffButton:SetScript("OnLeave", BreakStuff_OnLeave);
+	BreakStuffButton:SetScript("OnClick", BreakStuff_OnClick);
+	BreakStuffButton:SetScript("OnHide", BreakStuff_OnHide)
+	BreakStuffButton.subText = tcat(spellListing,"\n");
+
+	BreakStuffHandler:RegisterForClicks('AnyUp')
+	BreakStuffHandler:SetFrameStrata("TOOLTIP")
+	BreakStuffHandler:SetAttribute("type1","spell")
+	BreakStuffHandler:SetScript("OnEnter", SetClonedTip)
+	BreakStuffHandler:SetScript("OnLeave", BreakStuff_OnModifier)
+	BreakStuffHandler:RegisterEvent("MODIFIER_STATE_CHANGED")
+	BreakStuffHandler:Hide()
+
+	GameTooltip:HookScript('OnTooltipSetItem', BreakStuffParser)
+
+	for _, sparks in pairs(BreakStuffHandler.sparkles) do
+		sparks:SetHeight(sparks:GetHeight() * 3)
+		sparks:SetWidth(sparks:GetWidth() * 3)
+	end
+end
+
+function MOD:CloseBreakStuff()
+	if((not SV.db.Dock.dockTools.breakstuff) or self.BreakStuffLoaded) then return end
+	BreakStuffHandler:MODIFIER_STATE_CHANGED()
+	BreakStuffHandler.ReadyToSmash = false
+	BreakStuffButton.ttText = "BreakStuff : OFF";
+	BreakStuffButton.icon:SetGradient("VERTICAL", 0.5, 0.53, 0.55, 0.8, 0.8, 1)
+end
+
+function MOD:LoadBreakStuff()
+	if((not SV.db.Dock.dockTools.breakstuff) or self.BreakStuffLoaded) then return end
+	SV.Timers:ExecuteTimer(LoadToolBreakStuff, 5)
+end
diff --git a/SVUI_!Core/system/_docklets/garrison.lua b/SVUI_!Core/system/_docklets/garrison.lua
new file mode 100644
index 0000000..f13bcf3
--- /dev/null
+++ b/SVUI_!Core/system/_docklets/garrison.lua
@@ -0,0 +1,329 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pcall         = _G.pcall;
+local print         = _G.print;
+local ipairs        = _G.ipairs;
+local pairs         = _G.pairs;
+local tostring      = _G.tostring;
+local tonumber      = _G.tonumber;
+
+--STRING
+local string        = _G.string;
+local upper         = string.upper;
+local format        = string.format;
+local find          = string.find;
+local match         = string.match;
+local gsub          = string.gsub;
+--TABLE
+local table 				= _G.table;
+local tremove       = _G.tremove;
+local twipe 				= _G.wipe;
+--MATH
+local math      		= _G.math;
+local min 					= math.min;
+local floor         = math.floor
+local ceil          = math.ceil
+
+local time          = _G.time;
+local wipe          = _G.wipe;
+--BLIZZARD API
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+local GameTooltip           = _G.GameTooltip;
+local ReloadUI              = _G.ReloadUI;
+local hooksecurefunc        = _G.hooksecurefunc;
+local IsAltKeyDown          = _G.IsAltKeyDown;
+local IsShiftKeyDown        = _G.IsShiftKeyDown;
+local IsControlKeyDown      = _G.IsControlKeyDown;
+local IsModifiedClick       = _G.IsModifiedClick;
+local PlaySound             = _G.PlaySound;
+local PlaySoundFile         = _G.PlaySoundFile;
+local PlayMusic             = _G.PlayMusic;
+local StopMusic             = _G.StopMusic;
+local ToggleFrame           = _G.ToggleFrame;
+local ERR_NOT_IN_COMBAT     = _G.ERR_NOT_IN_COMBAT;
+local RAID_CLASS_COLORS     = _G.RAID_CLASS_COLORS;
+local CUSTOM_CLASS_COLORS   = _G.CUSTOM_CLASS_COLORS;
+
+local C_Garrison            = _G.C_Garrison;
+local GetTime         		= _G.GetTime;
+local GetItemCooldown       = _G.GetItemCooldown;
+local GetItemCount         	= _G.GetItemCount;
+local GetItemInfo          	= _G.GetItemInfo;
+local GetSpellInfo         	= _G.GetSpellInfo;
+local IsSpellKnown         	= _G.IsSpellKnown;
+local GetGarrison       	= _G.GetGarrison;
+local GetProfessionInfo    	= _G.GetProfessionInfo;
+local GetCurrencyInfo    	= _G.GetCurrencyInfo;
+--[[
+##########################################################
+ADDON
+##########################################################
+]]--
+local SV = select(2, ...)
+local L = SV.L
+local MOD = SV.Dock;
+local GarrisonData = {};
+--[[
+##########################################################
+LOCALS
+##########################################################
+]]--
+local function GetDockCooldown(itemID)
+	local start,duration = GetItemCooldown(itemID)
+	local expires = duration - (GetTime() - start)
+	if expires > 0.05 then
+		local timeLeft = 0;
+		local calc = 0;
+		if expires < 4 then
+			return format("|cffff0000%.1f|r", expires)
+		elseif expires < 60 then
+			return format("|cffffff00%d|r", floor(expires))
+		elseif expires < 3600 then
+			timeLeft = ceil(expires / 60);
+			calc = floor((expires / 60) + .5);
+			return format("|cffff9900%dm|r", timeLeft)
+		elseif expires < 86400 then
+			timeLeft = ceil(expires / 3600);
+			calc = floor((expires / 3600) + .5);
+			return format("|cff66ffff%dh|r", timeLeft)
+		else
+			timeLeft = ceil(expires / 86400);
+			calc = floor((expires / 86400) + .5);
+			return format("|cff6666ff%dd|r", timeLeft)
+		end
+	else
+		return "|cff6666ffReady|r"
+	end
+end
+
+local GarrisonButton_OnEvent = function(self, event, ...)
+	if(not InCombatLockdown()) then
+		if (event == "GARRISON_HIDE_LANDING_PAGE") then
+			self:SetDocked()
+		elseif (event == "GARRISON_SHOW_LANDING_PAGE") then
+			self:SetDocked(true)
+		end
+	end
+	if((not self.StartAlert) or (not self.StopAlert)) then return end
+	if ( event == "GARRISON_BUILDING_ACTIVATABLE" ) then
+		self:StartAlert();
+	elseif ( event == "GARRISON_BUILDING_ACTIVATED" or event == "GARRISON_ARCHITECT_OPENED") then
+		self:StopAlert();
+	elseif ( event == "GARRISON_MISSION_FINISHED" ) then
+		self:StartAlert();
+	elseif ( event == "GARRISON_MISSION_NPC_OPENED" ) then
+		self:StopAlert();
+	elseif (event == "GARRISON_INVASION_AVAILABLE") then
+		self:StartAlert();
+	elseif (event == "GARRISON_INVASION_UNAVAILABLE") then
+		self:StopAlert();
+	elseif (event == "SHIPMENT_UPDATE") then
+		local shipmentStarted = ...;
+		if (shipmentStarted) then
+			self:StartAlert();
+		end
+	end
+end
+
+local function getColoredString(text, color)
+	local hex = SV:HexColor(color)
+	return ("|cff%s%s|r"):format(hex, text)
+end
+
+local function GetSafeData(fn)
+	local t = fn(1) or {}
+	for k,v in pairs(fn(2) or {}) do
+		t[#t+1] = v
+	end
+	return t
+end
+
+local function GetActiveMissions()
+	wipe(GarrisonData)
+	local hasMission = false
+
+	GameTooltip:AddLine(" ", 1, 1, 1)
+	GameTooltip:AddLine("Active Missions", 1, 0.7, 0)
+
+	for key,data in pairs(GetSafeData(C_Garrison.GetInProgressMissions)) do
+		GarrisonData[data.missionID] = {
+			name = data.name,
+			level = data.level,
+			seconds = data.durationSeconds,
+			timeLeft = data.timeLeft,
+			completed = false,
+			isRare = data.isRare,
+			type = data.type,
+		}
+		hasMission = true
+	end
+
+	for key,data in pairs(GetSafeData(C_Garrison.GetCompleteMissions)) do
+		if(GarrisonData[data.missionID]) then
+			GarrisonData[data.missionID].completed = true
+		end
+	end
+
+	for key,data in pairs(GarrisonData) do
+		local hex = data.isRare and "blue" or "green"
+		local mission = ("%s|cff888888 - |r%s"):format(getColoredString(data.level, "yellow"), getColoredString(data.name, hex));
+		local remaining
+		if (data.completed) then
+			remaining = L["Complete!"]
+		else
+			remaining = ("%s %s"):format(data.timeLeft, getColoredString(" ("..SV:ParseSeconds(data.seconds)..")", "lightgrey"))
+		end
+
+		GameTooltip:AddDoubleLine(mission, remaining, 0, 1, 0, 1, 1, 1)
+		hasMission = true
+	end
+
+	if(not hasMission) then
+		GameTooltip:AddLine("None", 1, 0, 0)
+	end
+end
+
+local function GetBuildingData()
+	local hasBuildings = false
+	local now = time();
+	local prefixed = false;
+
+	local buildings = GetSafeData(C_Garrison.GetBuildings)
+	for i = 1, #buildings do
+		local buildingID = buildings[i].buildingID
+		local plotID = buildings[i].plotID
+
+		local id, name, texPrefix, icon, rank, isBuilding, timeStart, buildTime, canActivate, canUpgrade, isPrebuilt = C_Garrison.GetOwnedBuildingInfoAbbrev(plotID)
+		local remaining;
+
+		if(isBuilding) then
+			local timeLeft = buildTime - (now - timeStart);
+			if(canActivate or timeLeft < 0) then
+				remaining = L["Complete!"]
+			else
+				remaining = ("Building %s"):format(getColoredString("("..SV:ParseSeconds(timeLeft)..")", "lightgrey"))
+			end
+		else
+			local name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, itemName, itemIcon, itemQuality, itemID = C_Garrison.GetLandingPageShipmentInfo(buildingID)
+			if(shipmentsReady and shipmentsReady > 0) then
+				timeleftString = timeleftString or 'Unknown'
+				remaining = ("Ready: %s, Next: %s"):format(getColoredString(shipmentsReady, "green"), getColoredString(timeleftString, "lightgrey"))
+			elseif(timeleftString) then
+				remaining = ("Next: %s"):format(getColoredString(timeleftString, "lightgrey"))
+			end
+		end
+
+		if(remaining) then
+			if(not prefixed) then
+				GameTooltip:AddLine(" ", 1, 1, 1)
+				GameTooltip:AddLine("Buildings / Work Orders", 1, 0.7, 0)
+				prefixed = true
+			end
+			local building = ("|cffFF5500%s|r|cff888888 - |r|cffFFFF00Rank %s|r"):format(name, rank);
+			GameTooltip:AddDoubleLine(building, remaining, 0, 1, 0, 1, 1, 1)
+		end
+	end
+end
+
+local SetGarrisonTooltip = function(self)
+	if(not InCombatLockdown()) then C_Garrison.RequestLandingPageShipmentInfo() end
+	local name, amount, tex, week, weekmax, maxed, discovered = GetCurrencyInfo(824)
+	local texStr = ("\124T%s:12\124t %d"):format(tex, amount)
+	GameTooltip:AddDoubleLine(name, texStr, 1, 1, 0, 1, 1, 1)
+	name, amount, tex, week, weekmax, maxed, discovered = GetCurrencyInfo(1101)
+	texStr = ("\124T%s:12\124t %d"):format(tex, amount)
+	GameTooltip:AddDoubleLine(name, texStr, 1, 1, 0, 1, 1, 1)
+	GetActiveMissions()
+	GetBuildingData()
+	if(self.StopAlert) then
+		self:StopAlert()
+	end
+	local text1 = self:GetAttribute("tipText")
+	local text2 = self:GetAttribute("tipExtraText")
+	GameTooltip:AddLine(" ", 1, 1, 1)
+	GameTooltip:AddDoubleLine("[Left-Click]", text1, 0, 1, 0, 1, 1, 1)
+	if InCombatLockdown() then return end
+	if(text2) then
+		local remaining = GetDockCooldown(110560)
+		GameTooltip:AddDoubleLine("[Right Click]", text2, 0, 1, 0, 1, 1, 1)
+		GameTooltip:AddDoubleLine(L["Time Remaining"], remaining, 1, 0.5, 0, 1, 1, 1)
+	end
+end
+
+local function LoadToolBarGarrison()
+	local mmButton = _G.GarrisonLandingPageMinimapButton;
+	if((not SV.db.Dock.dockTools.garrison) or (not mmButton) or MOD.GarrisonLoaded) then return end
+
+	mmButton:FadeOut()
+
+	if(InCombatLockdown()) then
+		MOD.GarrisonNeedsUpdate = true;
+		MOD:RegisterEvent("PLAYER_REGEN_ENABLED");
+		return
+	end
+
+	local garrison = SV.Dock:SetDockButton("BottomLeft", L["Garrison Landing Page"], "SVUI_Garrison", SV.media.dock.garrisonToolIcon, SetGarrisonTooltip, "SecureActionButtonTemplate")
+	garrison:SetAttribute("type1", "click")
+	garrison:SetAttribute("clickbutton", mmButton)
+
+	local garrisonStone = GetItemInfo(110560);
+	if(garrisonStone and type(garrisonStone) == "string") then
+		garrison:SetAttribute("tipExtraText", L["Garrison Hearthstone"])
+		garrison:SetAttribute("type2", "macro")
+		garrison:SetAttribute("macrotext", "/use [nomod] " .. garrisonStone)
+	end
+
+	mmButton:RemoveTextures()
+	mmButton:ClearAllPoints()
+	mmButton:SetAllPoints(garrison)
+	mmButton:SetNormalTexture("")
+	mmButton:SetPushedTexture("")
+	mmButton:SetHighlightTexture("")
+	mmButton:EnableMouse(false)
+
+	garrison:RegisterEvent("GARRISON_HIDE_LANDING_PAGE");
+	garrison:RegisterEvent("GARRISON_SHOW_LANDING_PAGE");
+	garrison:RegisterEvent("GARRISON_BUILDING_ACTIVATABLE");
+	garrison:RegisterEvent("GARRISON_BUILDING_ACTIVATED");
+	garrison:RegisterEvent("GARRISON_ARCHITECT_OPENED");
+	garrison:RegisterEvent("GARRISON_MISSION_FINISHED");
+	garrison:RegisterEvent("GARRISON_MISSION_NPC_OPENED");
+	garrison:RegisterEvent("GARRISON_INVASION_AVAILABLE");
+	garrison:RegisterEvent("GARRISON_INVASION_UNAVAILABLE");
+	garrison:RegisterEvent("SHIPMENT_UPDATE");
+
+	garrison:SetScript("OnEvent", GarrisonButton_OnEvent);
+
+	if(not mmButton:IsShown()) then
+		garrison:SetDocked()
+	end
+
+	C_Garrison.RequestLandingPageShipmentInfo();
+	MOD.GarrisonLoaded = true
+end
+--[[
+##########################################################
+BUILD/UPDATE
+##########################################################
+]]--
+function MOD:UpdateGarrisonTool()
+	if((not SV.db.Dock.dockTools.garrison) or self.GarrisonLoaded) then return end
+	LoadToolBarGarrison()
+end
+
+function MOD:LoadGarrisonTool()
+	if((not SV.db.Dock.dockTools.garrison) or self.GarrisonLoaded or (not _G.GarrisonLandingPageMinimapButton)) then return end
+	SV.Timers:ExecuteTimer(LoadToolBarGarrison, 5)
+end
diff --git a/SVUI_!Core/system/_docklets/misc.lua b/SVUI_!Core/system/_docklets/misc.lua
new file mode 100644
index 0000000..7ef72f1
--- /dev/null
+++ b/SVUI_!Core/system/_docklets/misc.lua
@@ -0,0 +1,342 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pcall         = _G.pcall;
+local print         = _G.print;
+local ipairs        = _G.ipairs;
+local pairs         = _G.pairs;
+local tostring      = _G.tostring;
+local tonumber      = _G.tonumber;
+
+--STRING
+local string        = _G.string;
+local upper         = string.upper;
+local format        = string.format;
+local find          = string.find;
+local match         = string.match;
+local gsub          = string.gsub;
+--TABLE
+local table 		= _G.table;
+local tinsert       = _G.tinsert;
+local tremove       = _G.tremove;
+local twipe 		= _G.wipe;
+--MATH
+local math      	= _G.math;
+local min 			= math.min;
+local floor         = math.floor
+local ceil          = math.ceil
+--BLIZZARD API
+local Quit         			= _G.Quit;
+local Logout         		= _G.Logout;
+local ReloadUI         		= _G.ReloadUI;
+local GameTooltip          	= _G.GameTooltip;
+local InCombatLockdown     	= _G.InCombatLockdown;
+local CreateFrame          	= _G.CreateFrame;
+local GetTime         		= _G.GetTime;
+local GetItemCooldown       = _G.GetItemCooldown;
+local GetItemCount         	= _G.GetItemCount;
+local GetItemInfo          	= _G.GetItemInfo;
+local GetSpellInfo         	= _G.GetSpellInfo;
+local IsSpellKnown         	= _G.IsSpellKnown;
+local GetProfessions       	= _G.GetProfessions;
+local GetProfessionInfo    	= _G.GetProfessionInfo;
+local IsAltKeyDown          = _G.IsAltKeyDown;
+local IsShiftKeyDown        = _G.IsShiftKeyDown;
+local IsControlKeyDown      = _G.IsControlKeyDown;
+local IsModifiedClick       = _G.IsModifiedClick;
+local hooksecurefunc     	= _G.hooksecurefunc;
+local GetSpecialization    	= _G.GetSpecialization;
+local GetNumSpecGroups    	= _G.GetNumSpecGroups;
+local GetActiveSpecGroup    = _G.GetActiveSpecGroup;
+local SetActiveSpecGroup    = _G.SetActiveSpecGroup;
+local GetSpecializationInfo = _G.GetSpecializationInfo;
+--[[
+##########################################################
+ADDON
+##########################################################
+]]--
+local SV = select(2, ...)
+local L = SV.L
+
+local MOD = SV.Dock;
+--[[
+##########################################################
+LOCALS
+##########################################################
+]]--
+local HEARTH_SPELLS = {556,50977,18960,126892};
+local HEARTH_ITEMS = {6948,110560,64488,54452,93672,28585,128353};
+local HEARTH_LEFT_CLICK, HEARTH_RIGHT_CLICK = 6948, 110560;
+local HEARTH_HEADER = "HearthStone";
+
+local function GetMacroCooldown(itemID)
+	local start,duration = GetItemCooldown(itemID)
+	local expires = duration - (GetTime() - start)
+	if expires > 0.05 then
+		local timeLeft = 0;
+		local calc = 0;
+		if expires < 4 then
+			return format("|cffff0000%.1f|r", expires)
+		elseif expires < 60 then
+			return format("|cffffff00%d|r", floor(expires))
+		elseif expires < 3600 then
+			timeLeft = ceil(expires / 60);
+			calc = floor((expires / 60) + .5);
+			return format("|cffff9900%dm|r", timeLeft)
+		elseif expires < 86400 then
+			timeLeft = ceil(expires / 3600);
+			calc = floor((expires / 3600) + .5);
+			return format("|cff66ffff%dh|r", timeLeft)
+		else
+			timeLeft = ceil(expires / 86400);
+			calc = floor((expires / 86400) + .5);
+			return format("|cff6666ff%dd|r", timeLeft)
+		end
+	else
+		return "|cff6666ffReady|r"
+	end
+end
+
+local function GetHearthOption(selected)
+	local option,found;
+	for i = 1, #HEARTH_SPELLS do
+		if(not found) then
+			local optionID = HEARTH_SPELLS[i];
+			if(optionID == selected) then
+				found = true;
+				if(IsSpellKnown(optionID)) then
+					option = GetSpellInfo(optionID);
+				end
+			end
+		end
+	end
+	if(not option) then
+		for i = 1, #HEARTH_ITEMS do
+			if(not found) then
+				local optionID = HEARTH_ITEMS[i];
+				if(optionID == selected) then
+					found = true;
+					local test = GetItemInfo(optionID);
+					if(test and type(test) == 'string') then
+						local owned = GetItemCount(optionID,false)
+						if(owned and owned > 0) then
+							option = test;
+						end
+					end
+				end
+			end
+		end
+	end
+	return option;
+end
+
+local function UpdateHearthOptions()
+	HEARTH_LEFT_CLICK = SV.db.Dock.hearthOptions.left;
+	HEARTH_RIGHT_CLICK = SV.db.Dock.hearthOptions.right;
+
+	local leftClick = GetHearthOption(HEARTH_LEFT_CLICK);
+	if(leftClick and type(leftClick) == "string") then
+		SVUI_Hearth:SetAttribute("tipText", leftClick)
+		SVUI_Hearth:SetAttribute("macrotext1", "/use [nomod]" .. leftClick)
+	end
+
+	local rightClick = GetHearthOption(HEARTH_RIGHT_CLICK);
+	if(rightClick and type(rightClick) == "string") then
+		SVUI_Hearth:SetAttribute("tipExtraText", rightClick)
+		SVUI_Hearth:SetAttribute("macrotext2", "/use [nomod]" .. rightClick)
+	end
+end
+
+local Hearth_OnEnter = function(self)
+	GameTooltip:AddLine(HELPFRAME_STUCK_HEARTHSTONE_HEADER, 1, 1, 0)
+	GameTooltip:AddLine(" ", 1, 1, 1)
+	local location = GetBindLocation()
+	GameTooltip:AddDoubleLine(LOCATION_COLON, location, 1, 0.5, 0, 1, 1, 1)
+	if InCombatLockdown() then return end
+	local remaining = GetMacroCooldown(6948)
+	GameTooltip:AddDoubleLine(L["Time Remaining"], remaining, 1, 0.5, 0, 1, 1, 1)
+	local text1 = self:GetAttribute("tipText")
+	local text2 = self:GetAttribute("tipExtraText")
+	GameTooltip:AddLine(" ", 1, 1, 1)
+	GameTooltip:AddDoubleLine("[Left-Click]", text1, 0, 1, 0, 1, 1, 1)
+	if(text2 and text2 ~= "") then
+		GameTooltip:AddDoubleLine("[Right-Click]", text2, 0, 1, 0, 1, 1, 1)
+	end
+	GameTooltip:AddLine(" ", 1, 1, 1)
+	GameTooltip:AddDoubleLine("|cff0099FFSHIFT|r + Left-Click", "Left Click Options", 0, 1, 0, 0.5, 1, 0.5)
+	GameTooltip:AddDoubleLine("|cff0099FFSHIFT|r + Right-Click", "Right Click Options", 0, 1, 0, 0.5, 1, 0.5)
+end
+
+local Hearth_OnShiftLeftClick = function(self)
+	if(IsShiftKeyDown()) then
+
+		local t = {};
+		tinsert(t, { title = "Left Click Options", divider = true });
+		for i = 1, #HEARTH_SPELLS do
+			local optionID = HEARTH_SPELLS[i];
+			if(IsSpellKnown(optionID)) then
+				local hearthOption = GetSpellInfo(optionID);
+				if(hearthOption and type(hearthOption) == 'string') then
+					tinsert(t, { text = hearthOption, func = function() SV.db.Dock.hearthOptions.left = optionID; UpdateHearthOptions(); end });
+				end
+			end
+		end
+		for i = 1, #HEARTH_ITEMS do
+			local optionID = HEARTH_ITEMS[i];
+			local hearthOption = GetItemInfo(optionID);
+			if(hearthOption and type(hearthOption) == 'string') then
+				local owned = GetItemCount(optionID,false)
+				if(owned and owned > 0) then
+					tinsert(t, { text = hearthOption, func = function() SV.db.Dock.hearthOptions.left = optionID; UpdateHearthOptions(); end });
+				end
+			end
+		end
+
+		SV.Dropdown:Open(self, t, HEARTH_HEADER);
+	end
+end
+
+local Hearth_OnShiftRightClick = function(self)
+	if(IsShiftKeyDown()) then
+
+		local t = {};
+		tinsert(t, { title = "Right Click Options", divider = true });
+		for i = 1, #HEARTH_SPELLS do
+			local optionID = HEARTH_SPELLS[i];
+			if(IsSpellKnown(optionID)) then
+				local hearthOption = GetSpellInfo(optionID);
+				if(hearthOption and type(hearthOption) == 'string') then
+					tinsert(t, { text = hearthOption, func = function() SV.db.Dock.hearthOptions.right = optionID; UpdateHearthOptions(); end });
+				end
+			end
+		end
+		for i = 1, #HEARTH_ITEMS do
+			local optionID = HEARTH_ITEMS[i];
+			local hearthOption = GetItemInfo(optionID);
+			if(hearthOption and type(hearthOption) == 'string') then
+				local owned = GetItemCount(optionID,false)
+				if(owned and owned > 0) then
+					tinsert(t, { text = hearthOption, func = function() SV.db.Dock.hearthOptions.right = optionID; UpdateHearthOptions(); end });
+				end
+			end
+		end
+
+		SV.Dropdown:Open(self, t, HEARTH_HEADER);
+	end
+end
+
+local SpecSwap_OnClick = function(self)
+	if InCombatLockdown() then return end
+	local current = GetActiveSpecGroup()
+	if(current == 2) then
+		SetActiveSpecGroup(1)
+	else
+		SetActiveSpecGroup(2)
+	end
+end
+
+local SpecSwap_OnEnter = function(self)
+	local currentGroup = GetActiveSpecGroup()
+	local currentSpec = GetSpecialization(false, false, currentGroup);
+	local text1 = currentSpec and select(2, GetSpecializationInfo(currentSpec)) or "None"
+	local otherGroup = 1;
+	local activeText = SPECIALIZATION_SECONDARY_ACTIVE;
+	local otherText = SPECIALIZATION_PRIMARY;
+	if(currentGroup == 1) then
+		otherGroup = 2
+		activeText = SPECIALIZATION_PRIMARY_ACTIVE;
+		otherText = SPECIALIZATION_SECONDARY;
+	end
+	local otherSpec = GetSpecialization(false, false, otherGroup);
+	local text2 = otherSpec and select(2, GetSpecializationInfo(otherSpec)) or "None"
+	GameTooltip:AddLine(GARRISON_SWITCH_SPECIALIZATIONS, 1, 1, 0)
+	GameTooltip:AddLine(" ", 1, 1, 1)
+	GameTooltip:AddDoubleLine(activeText, text1, 1, 0.5, 0, 1, 1, 1)
+	GameTooltip:AddDoubleLine(otherText, text2, 1, 0.5, 0, 1, 1, 1)
+end
+
+local PowerButton_OnLeftClick = function(self)
+	if(IsShiftKeyDown()) then
+		ReloadUI()
+	else
+		Logout()
+	end
+end
+
+local PowerButton_OnRightClick = function(self)
+	if(IsShiftKeyDown()) then
+		Quit()
+	end
+end
+
+local PowerButton_OnEnter = function(self)
+	GameTooltip:AddLine(OTHER .. " " .. OPTIONS_MENU, 1, 1, 0)
+	GameTooltip:AddLine(" ", 1, 1, 1)
+	GameTooltip:AddDoubleLine("[Left-Click]", LOGOUT, 0, 1, 0, 1, 1, 1)
+	GameTooltip:AddDoubleLine("[SHIFT + Left-Click]", RELOADUI, 0, 1, 0, 1, 1, 1)
+	GameTooltip:AddDoubleLine("[SHIFT + Right-Click]", EXIT_GAME, 0, 1, 0, 1, 1, 1)
+end
+
+local function LoadMiscTools()
+	if(InCombatLockdown()) then
+		MOD.MiscNeedsUpdate = true;
+		MOD:RegisterEvent("PLAYER_REGEN_ENABLED");
+		return
+	end
+
+	-- HEARTH BUTTON
+	HEARTH_HEADER = GetHearthOption(6948);
+
+	if(SV.db.Dock.dockTools.hearth and (not SVUI_Hearth)) then
+		if(HEARTH_HEADER and type(HEARTH_HEADER) == "string") then
+			local hearth = SV.Dock:SetDockButton("BottomLeft", HEARTH_HEADER, "SVUI_Hearth", SV.media.dock.hearthIcon, Hearth_OnEnter, "SecureActionButtonTemplate")
+			hearth.Icon:SetTexCoord(0,0.5,0,1)
+			hearth:SetAttribute("type1", "macro")
+			hearth:SetAttribute("type2", "macro")
+
+			UpdateHearthOptions();
+
+			hearth:SetClickCallbacks(Hearth_OnShiftLeftClick, Hearth_OnShiftRightClick)
+		end
+	end
+
+	-- SPEC BUTTON
+	if(SV.db.Dock.dockTools.specswap and (not SVUI_SpecSwap)) then
+		local numSpecGroups = GetNumSpecGroups()
+		if(numSpecGroups and numSpecGroups == 2) then
+			local specSwap = SV.Dock:SetDockButton("BottomLeft", L["Spec Swap"], "SVUI_SpecSwap", SV.media.dock.specSwapIcon, SpecSwap_OnEnter)
+			specSwap:SetClickCallbacks(SpecSwap_OnClick);
+		end
+	end
+
+	-- POWER BUTTON
+	if(SV.db.Dock.dockTools.power and (not SVUI_PowerButton)) then
+		local power = SV.Dock:SetDockButton("BottomLeft", L["Power Button"], "SVUI_PowerButton", SV.media.dock.powerIcon, PowerButton_OnEnter)
+		power:SetClickCallbacks(PowerButton_OnLeftClick, PowerButton_OnRightClick);
+	end
+
+	MOD.MiscToolsLoaded = true
+end
+--[[
+##########################################################
+BUILD/UPDATE
+##########################################################
+]]--
+function MOD:UpdateMiscTools()
+	LoadMiscTools()
+end
+
+function MOD:LoadAllMiscTools()
+	if(self.MiscToolsLoaded) then return end
+	SV.Timers:ExecuteTimer(LoadMiscTools, 5)
+end
diff --git a/SVUI_!Core/system/_docklets/profession.lua b/SVUI_!Core/system/_docklets/profession.lua
new file mode 100644
index 0000000..e147e6e
--- /dev/null
+++ b/SVUI_!Core/system/_docklets/profession.lua
@@ -0,0 +1,198 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pcall         = _G.pcall;
+local print         = _G.print;
+local ipairs        = _G.ipairs;
+local pairs         = _G.pairs;
+local tostring      = _G.tostring;
+local tonumber      = _G.tonumber;
+
+--STRING
+local string        = _G.string;
+local upper         = string.upper;
+local format        = string.format;
+local find          = string.find;
+local match         = string.match;
+local gsub          = string.gsub;
+--TABLE
+local table 		= _G.table;
+local tremove       = _G.tremove;
+local twipe 		= _G.wipe;
+--MATH
+local math      	= _G.math;
+local min 			= math.min;
+local floor         = math.floor
+local ceil          = math.ceil
+--BLIZZARD API
+local GameTooltip          	= _G.GameTooltip;
+local InCombatLockdown     	= _G.InCombatLockdown;
+local CreateFrame          	= _G.CreateFrame;
+local GetTime         		= _G.GetTime;
+local GetItemCooldown       = _G.GetItemCooldown;
+local GetItemCount         	= _G.GetItemCount;
+local GetItemInfo          	= _G.GetItemInfo;
+local GetSpellInfo         	= _G.GetSpellInfo;
+local IsSpellKnown         	= _G.IsSpellKnown;
+local GetProfessions       	= _G.GetProfessions;
+local GetProfessionInfo    	= _G.GetProfessionInfo;
+local hooksecurefunc     	= _G.hooksecurefunc;
+--[[
+##########################################################
+ADDON
+##########################################################
+]]--
+local SV = select(2, ...)
+local L = SV.L
+
+local MOD = SV.Dock;
+--[[
+##########################################################
+LOCALS
+##########################################################
+]]--
+local LastAddedMacro;
+local MacroCount = 0;
+
+local function GetMacroCooldown(itemID)
+	local start,duration = GetItemCooldown(itemID)
+	local expires = duration - (GetTime() - start)
+	if expires > 0.05 then
+		local timeLeft = 0;
+		local calc = 0;
+		if expires < 4 then
+			return format("|cffff0000%.1f|r", expires)
+		elseif expires < 60 then
+			return format("|cffffff00%d|r", floor(expires))
+		elseif expires < 3600 then
+			timeLeft = ceil(expires / 60);
+			calc = floor((expires / 60) + .5);
+			return format("|cffff9900%dm|r", timeLeft)
+		elseif expires < 86400 then
+			timeLeft = ceil(expires / 3600);
+			calc = floor((expires / 3600) + .5);
+			return format("|cff66ffff%dh|r", timeLeft)
+		else
+			timeLeft = ceil(expires / 86400);
+			calc = floor((expires / 86400) + .5);
+			return format("|cff6666ff%dd|r", timeLeft)
+		end
+	else
+		return "|cff6666ffReady|r"
+	end
+end
+
+local MacroButton_OnEnter = function(self)
+	local text1 = self:GetAttribute("tipText")
+	local text2 = self:GetAttribute("tipExtraText")
+	GameTooltip:AddLine(text1, 1, 1, 0)
+	GameTooltip:AddLine(" ", 1, 1, 1)
+	GameTooltip:AddDoubleLine("[Left-Click]", text1, 0, 1, 0, 1, 1, 1)
+	if(text2) then
+		GameTooltip:AddDoubleLine("[Right-Click]", "Use " .. text2, 0, 1, 0, 1, 1, 1)
+		if InCombatLockdown() then return end
+		if(self.ItemToUse) then
+			GameTooltip:AddLine(" ", 1, 1, 1)
+			local remaining = GetMacroCooldown(self.ItemToUse)
+			GameTooltip:AddDoubleLine(text2, remaining, 1, 0.5, 0, 0, 1, 1)
+		end
+	end
+end
+
+local function CreateMacroToolButton(proName, proID, itemID)
+	local data = SV.media.dock.professionIconCoords[proID]
+	if(not data) then return end
+
+	local globalName = ("SVUI_%s"):format(proName)
+	local button = SV.Dock:SetDockButton("BottomRight", proName, globalName, SV.media.dock.professionIconFile, MacroButton_OnEnter, "SecureActionButtonTemplate")
+
+	button.Icon:SetTexCoord(data[1], data[2], data[3], data[4])
+
+	if proID == 186 then proName = GetSpellInfo(2656) end
+
+	--button:RegisterForClicks("AnyDown")
+	button:SetAttribute("type1", "macro")
+	button:SetAttribute("macrotext1", "/cast [nomod]" .. proName)
+
+	if(data[5]) then
+		local rightClick
+		if(data[6] and GetItemCount(data[6], true) > 0) then
+			rightClick = GetItemInfo(data[6])
+			button.ItemToUse = data[6]
+		else
+			rightClick = GetSpellInfo(data[5])
+		end
+		button:SetAttribute("tipExtraText", rightClick)
+		button:SetAttribute("type2", "macro")
+		button:SetAttribute("macrotext2", "/cast [nomod] " .. rightClick)
+	end
+end
+
+local function LoadToolBarProfessions()
+	if(MOD.ToolBarLoaded) then return end
+
+	if(InCombatLockdown()) then
+		MOD.ProfessionNeedsUpdate = true;
+		MOD:RegisterEvent("PLAYER_REGEN_ENABLED");
+		return
+	end
+
+	-- PROFESSION BUTTONS
+	local proName, proID
+	local prof1, prof2, archaeology, _, cooking, firstAid = GetProfessions()
+
+	if(firstAid ~= nil and (SV.db.Dock.dockTools.firstAid)) then
+		proName, _, _, _, _, _, proID = GetProfessionInfo(firstAid)
+		CreateMacroToolButton(proName, proID, firstAid)
+	end
+
+	if(archaeology ~= nil and (SV.db.Dock.dockTools.archaeology)) then
+		proName, _, _, _, _, _, proID = GetProfessionInfo(archaeology)
+		CreateMacroToolButton(proName, proID, archaeology)
+	end
+
+	if(cooking ~= nil and (SV.db.Dock.dockTools.cooking)) then
+		proName, _, _, _, _, _, proID = GetProfessionInfo(cooking)
+		CreateMacroToolButton(proName, proID, cooking)
+	end
+
+	if(prof2 ~= nil and (SV.db.Dock.dockTools.secondary)) then
+		proName, _, _, _, _, _, proID = GetProfessionInfo(prof2)
+		if(proID ~= 182 and proID ~= 393) then
+			CreateMacroToolButton(proName, proID, prof2)
+		end
+	end
+
+	if(prof1 ~= nil and (SV.db.Dock.dockTools.primary)) then
+		proName, _, _, _, _, _, proID = GetProfessionInfo(prof1)
+		if(proID ~= 182 and proID ~= 393) then
+			CreateMacroToolButton(proName, proID, prof1)
+		end
+	end
+
+	MOD.ToolBarLoaded = true
+end
+--[[
+##########################################################
+BUILD/UPDATE
+##########################################################
+]]--
+function MOD:UpdateProfessionTools()
+	if(self.ToolBarLoaded) then return end
+	LoadToolBarProfessions()
+end
+
+function MOD:LoadProfessionTools()
+	if(self.ToolBarLoaded) then return end
+	SV.Timers:ExecuteTimer(LoadToolBarProfessions, 5)
+end
diff --git a/SVUI_!Core/system/_docklets/raidleader.lua b/SVUI_!Core/system/_docklets/raidleader.lua
new file mode 100644
index 0000000..7937bcb
--- /dev/null
+++ b/SVUI_!Core/system/_docklets/raidleader.lua
@@ -0,0 +1,234 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+--BLIZZARD API
+local Quit         			= _G.Quit;
+local Logout         		= _G.Logout;
+local ReloadUI         		= _G.ReloadUI;
+local GameTooltip          	= _G.GameTooltip;
+local InCombatLockdown     	= _G.InCombatLockdown;
+local CreateFrame          	= _G.CreateFrame;
+local IsInRaid              = _G.IsInRaid;
+local IsInGroup             = _G.IsInGroup;
+local IsInInstance          = _G.IsInInstance;
+local ROLE_POLL          	= _G.ROLE_POLL;
+local READY_CHECK          	= _G.READY_CHECK;
+local RAID_CONTROL          = _G.RAID_CONTROL;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...)
+local L = SV.L
+local MOD = SV.Dock;
+--[[
+##########################################################
+LOCALS
+##########################################################
+]]--
+local function CheckRaidStatus()
+	local inInstance, instanceType = IsInInstance()
+	if ((IsInGroup() and not IsInRaid()) or UnitIsGroupLeader('player') or UnitIsGroupAssistant("player")) and not (inInstance and (instanceType == "pvp" or instanceType == "arena")) then
+		return true
+	else
+		return false
+	end
+end
+
+local Button_OnEnter = function(self)
+	self:SetPanelColor("highlight")
+end
+
+local Button_OnLeave = function(self)
+	self:SetPanelColor("default")
+	GameTooltip:Hide()
+end
+
+local ToolButton_OnEnter = function(self, ...)
+	SVUI_RaidToolDockButton:SetPanelColor("highlight")
+	SVUI_RaidToolDockButton.Icon:SetGradient(unpack(SV.media.gradient.highlight))
+
+	GameTooltip:SetOwner(self, "ANCHOR_BOTTOMLEFT", 0, 4)
+	GameTooltip:ClearLines()
+	GameTooltip:AddDoubleLine("[Left-Click]", RAID_CONTROL, 0, 1, 0, 1, 1, 1)
+	GameTooltip:Show()
+end
+
+local ToolButton_OnLeave = function(self, ...)
+	SVUI_RaidToolDockButton:SetPanelColor("default")
+	SVUI_RaidToolDockButton.Icon:SetGradient(unpack(SV.media.gradient.icon))
+
+	GameTooltip:Hide()
+end
+
+local function NewToolButton(name, parent, template, width, height, point, relativeto, point2, xOfs, yOfs, textDisplay)
+	local button = CreateFrame("Button", name, parent, template)
+	button:RemoveTextures(true)
+	button:SetWidth(width)
+	button:SetHeight(height)
+	button:SetPoint(point, relativeto, point2, xOfs, yOfs)
+	button:SetStyle("DockButton")
+
+	if(textDisplay) then
+		local text = button:CreateFontString(nil,"OVERLAY")
+		text:SetFont(SV.media.font.default, 14, "NONE")
+		text:SetAllPoints(button)
+		text:SetJustifyH("CENTER")
+		text:SetText(textDisplay)
+
+		button:SetFontString(text)
+	end
+
+	button:HookScript("OnEnter", Button_OnEnter)
+	button:HookScript("OnLeave", Button_OnLeave)
+
+	return button;
+end
+
+function MOD:UpdateRaidLeader(event)
+	if InCombatLockdown() then
+		self.RaidLeaderNeedsUpdate = true;
+		self:RegisterEvent("PLAYER_REGEN_ENABLED");
+		return
+	end
+	if CheckRaidStatus() then
+		self.RaidTool:SetDocked(true)
+		if self.RaidTool.Menu.toggled == true then
+			self.RaidTool.Menu:Show()
+		else
+			self.RaidTool.Menu:Hide()
+		end
+	else
+		self.RaidTool:SetDocked()
+		self.RaidTool.Menu:Hide()
+	end
+end
+
+function MOD:LoadRaidLeaderTools()
+	if(not SV.db.Dock.dockTools.leader) then return end
+
+	self.RaidTool = SV.Dock:SetDockButton("TopLeft", RAID_CONTROL, "SVUI_RaidToolDockButton", SV.media.dock.raidToolIcon);
+
+	local dock = self.RaidTool.Parent
+
+	self.RaidTool.Menu = CreateFrame("Frame", "SVUI_RaidToolMenu", self.RaidTool, "SecureHandlerClickTemplate");
+	self.RaidTool.Menu:SetStyle("Frame", 'Transparent');
+	self.RaidTool.Menu:SetWidth(120);
+	self.RaidTool.Menu:SetHeight(140);
+	self.RaidTool.Menu:SetPoint("TOPLEFT", dock.ToolBar, "BOTTOMLEFT", 0, -2);
+	self.RaidTool.Menu:SetFrameLevel(3);
+	self.RaidTool.Menu.toggled = false;
+	self.RaidTool.Menu:SetFrameStrata("HIGH");
+
+	local SVUI_RaidToolToggle = CreateFrame("Button", "SVUI_RaidToolToggle", self.RaidTool, "SecureHandlerClickTemplate")
+	SVUI_RaidToolToggle:SetAllPoints(self.RaidTool)
+	SVUI_RaidToolToggle:RemoveTextures()
+	SVUI_RaidToolToggle:SetNormalTexture("")
+	SVUI_RaidToolToggle:SetPushedTexture("")
+	SVUI_RaidToolToggle:SetHighlightTexture("")
+	SVUI_RaidToolToggle:SetFrameRef("SVUI_RaidToolMenu", SVUI_RaidToolMenu)
+	SVUI_RaidToolToggle:SetAttribute("_onclick", [=[
+		local raidUtil = self:GetFrameRef("SVUI_RaidToolMenu");
+		local closeButton = self:GetFrameRef("SVUI_RaidToolCloseButton");
+		raidUtil:Show();
+		local point = self:GetPoint();
+		local raidUtilPoint, raidUtilRelative, closeButtonPoint, closeButtonRelative
+		if point:find("BOTTOM") then
+			raidUtilPoint = "BOTTOMLEFT"
+			raidUtilRelative = "TOPLEFT"
+		else
+			raidUtilPoint = "TOPLEFT"
+			raidUtilRelative = "BOTTOMLEFT"
+		end
+		raidUtil:ClearAllPoints()
+		closeButton:ClearAllPoints()
+		raidUtil:SetPoint(raidUtilPoint, self, raidUtilRelative, 2, -2)
+		closeButton:SetPoint("BOTTOM", raidUtil, "BOTTOM", 0, 2)
+	]=]);
+	SVUI_RaidToolToggle:SetScript("PostClick", function(self) self:RemoveTextures(); SVUI_RaidToolMenu.toggled = true end);
+	SVUI_RaidToolToggle:HookScript("OnEnter", ToolButton_OnEnter)
+	SVUI_RaidToolToggle:HookScript("OnLeave", ToolButton_OnLeave)
+	SV:ManageVisibility(self.RaidTool);
+
+	--Close Button
+	local close = NewToolButton("SVUI_RaidToolCloseButton", self.RaidTool.Menu, "UIMenuButtonStretchTemplate, SecureHandlerClickTemplate", 30, 18, "BOTTOM", self.RaidTool.Menu, "BOTTOM", 0, 2, "X");
+	close:SetAttribute("_onclick", [=[ self:GetParent():Hide(); ]=]);
+	SVUI_RaidToolToggle:SetFrameRef("SVUI_RaidToolCloseButton", close)
+	close:SetScript("PostClick", function() SVUI_RaidToolMenu.toggled = false end);
+
+	local disband = NewToolButton("SVUI_RaidToolDisbandButton", self.RaidTool.Menu, "UIMenuButtonStretchTemplate", 109, 18, "TOP", self.RaidTool.Menu, "TOP", 0, -5, L['Disband Group'])
+	disband:SetScript("OnMouseUp", function(self)
+		if CheckRaidStatus() then
+			SV:StaticPopup_Show("DISBAND_RAID")
+		end
+	end)
+
+	local rolecheck = NewToolButton("SVUI_RaidToolRoleButton", self.RaidTool.Menu, "UIMenuButtonStretchTemplate", 109, 18, "TOP", disband, "BOTTOM", 0, -5, ROLE_POLL)
+	rolecheck:SetScript("OnMouseUp", function(self)
+		if CheckRaidStatus() then
+			InitiateRolePoll()
+		end
+	end)
+
+	local ready = NewToolButton("SVUI_RaidToolReadyButton", self.RaidTool.Menu, "UIMenuButtonStretchTemplate", 109, 18, "TOP", rolecheck, "BOTTOM", 0, -5, READY_CHECK)
+	ready:SetScript("OnMouseUp", function(self)
+		if CheckRaidStatus() then
+			DoReadyCheck()
+		end
+	end)
+
+	local control = NewToolButton("SVUI_RaidToolControlButton", self.RaidTool.Menu, "UIMenuButtonStretchTemplate", 109, 18, "TOP", ready, "BOTTOM", 0, -5, L['Raid Menu'])
+	control:SetScript("OnMouseUp", function(self)
+		ToggleFriendsFrame(4)
+	end)
+
+	local markerButton = _G["CompactRaidFrameManagerDisplayFrameLeaderOptionsRaidWorldMarkerButton"];
+	local oldReadyCheck = _G["CompactRaidFrameManagerDisplayFrameLeaderOptionsInitiateReadyCheck"];
+	local oldRollCheck = _G["CompactRaidFrameManagerDisplayFrameLeaderOptionsInitiateRolePoll"];
+
+	if(markerButton) then
+		markerButton:ClearAllPoints()
+		markerButton:SetPoint("TOP", control, "BOTTOM", 0, -5)
+		markerButton:SetParent(self.RaidTool.Menu)
+		markerButton:SetHeight(18)
+		markerButton:SetWidth(109)
+		markerButton:RemoveTextures(true)
+		markerButton:SetStyle("DockButton")
+
+		local markersText = markerButton:CreateFontString(nil,"OVERLAY")
+		markersText:SetFont(SV.media.font.default, 14, "NONE")
+		markersText:SetAllPoints(markerButton)
+		markersText:SetJustifyH("CENTER")
+		markersText:SetText("World Markers")
+
+		markerButton:SetFontString(markersText)
+
+		markerButton:HookScript("OnEnter", Button_OnEnter)
+		markerButton:HookScript("OnLeave", Button_OnLeave)
+	end
+
+	if(oldReadyCheck) then
+		oldReadyCheck:ClearAllPoints()
+		oldReadyCheck:SetPoint("BOTTOMLEFT", CompactRaidFrameManagerDisplayFrameLockedModeToggle, "TOPLEFT", 0, 1)
+		oldReadyCheck:SetPoint("BOTTOMRIGHT", CompactRaidFrameManagerDisplayFrameHiddenModeToggle, "TOPRIGHT", 0, 1)
+		if(oldRollCheck) then
+			oldRollCheck:ClearAllPoints()
+			oldRollCheck:SetPoint("BOTTOMLEFT", oldReadyCheck, "TOPLEFT", 0, 1)
+			oldRollCheck:SetPoint("BOTTOMRIGHT", oldReadyCheck, "TOPRIGHT", 0, 1)
+		end
+	end
+
+	self:RegisterEvent("GROUP_ROSTER_UPDATE", "UpdateRaidLeader")
+	self:RegisterEvent("PLAYER_ENTERING_WORLD", "UpdateRaidLeader")
+	self:UpdateRaidLeader()
+end
diff --git a/SVUI_!Core/system/_reports/bags.lua b/SVUI_!Core/system/_reports/bags.lua
new file mode 100644
index 0000000..ccdc99b
--- /dev/null
+++ b/SVUI_!Core/system/_reports/bags.lua
@@ -0,0 +1,93 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local ipairs 	= _G.ipairs;
+local type 		= _G.type;
+local error 	= _G.error;
+local pcall 	= _G.pcall;
+local assert 	= _G.assert;
+local tostring 	= _G.tostring;
+local tonumber 	= _G.tonumber;
+local string 	= _G.string;
+local math 		= _G.math;
+local table 	= _G.table;
+--[[ STRING METHODS ]]--
+local lower, upper = string.lower, string.upper;
+local find, format, len, split = string.find, string.format, string.len, string.split;
+local match, sub, join = string.match, string.sub, string.join;
+local gmatch, gsub = string.gmatch, string.gsub;
+--[[ MATH METHODS ]]--
+local abs, ceil, floor, round = math.abs, math.ceil, math.floor, math.round;  -- Basic
+--[[ TABLE METHODS ]]--
+local twipe, tsort = table.wipe, table.sort;
+
+local NUM_BAG_SLOTS             = _G.NUM_BAG_SLOTS;
+local CURRENCY          		= _G.CURRENCY;
+local GetContainerNumFreeSlots  = _G.GetContainerNumFreeSlots;
+local GetContainerNumSlots      = _G.GetContainerNumSlots;
+local ToggleAllBags     		= _G.ToggleAllBags;
+local MAX_WATCHED_TOKENS        = _G.MAX_WATCHED_TOKENS;
+local GetBackpackCurrencyInfo  = _G.GetBackpackCurrencyInfo;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...)
+local L = SV.L
+local Reports = SV.Reports;
+--[[
+##########################################################
+BAG STATS
+##########################################################
+]]--
+local hexColor = "22FFFF"
+local bags_text = "%s|cff%s%d / %d|r";
+
+local Report = Reports:NewReport("Bags", {
+	type = "data source",
+	text = "Bags Info",
+	icon = [[Interface\Addons\SVUI_!Core\assets\icons\SVUI]]
+});
+
+Report.events = {"PLAYER_ENTERING_WORLD", "BAG_UPDATE"};
+
+Report.OnEvent = function(self, event, ...)
+	local f, g, h = 0, 0, 0;
+	for i = 0, NUM_BAG_SLOTS do
+		f, g = f + GetContainerNumFreeSlots(i),
+		g + GetContainerNumSlots(i)
+	end
+	h = g - f;
+	self.text:SetFormattedText(bags_text, L["Bags"]..": ", hexColor, h, g)
+end
+
+Report.OnClick = function(self, button)
+	ToggleAllBags()
+end
+
+Report.OnEnter = function(self)
+	Reports:SetDataTip(self)
+	for i = 1, MAX_WATCHED_TOKENS do
+		local l, m, n, o, p = GetBackpackCurrencyInfo(i)
+		if l and i == 1 then
+			Reports.ToolTip:AddLine(CURRENCY)
+			Reports.ToolTip:AddLine(" ")
+		end
+		if l and m then
+			Reports.ToolTip:AddDoubleLine(l, m, 1, 1, 1)
+		end
+	end
+	Reports:ShowDataTip()
+end
diff --git a/SVUI_!Core/system/_reports/cta.lua b/SVUI_!Core/system/_reports/cta.lua
new file mode 100644
index 0000000..a1d5f4d
--- /dev/null
+++ b/SVUI_!Core/system/_reports/cta.lua
@@ -0,0 +1,141 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local ipairs 	= _G.ipairs;
+local type 		= _G.type;
+local error 	= _G.error;
+local pcall 	= _G.pcall;
+local assert 	= _G.assert;
+local tostring 	= _G.tostring;
+local tonumber 	= _G.tonumber;
+local string 	= _G.string;
+local math 		= _G.math;
+local table 	= _G.table;
+--[[ STRING METHODS ]]--
+local lower, upper = string.lower, string.upper;
+local find, format, len, split = string.find, string.format, string.len, string.split;
+local match, sub, join = string.match, string.sub, string.join;
+local gmatch, gsub = string.gmatch, string.gsub;
+--[[ MATH METHODS ]]--
+local abs, ceil, floor, round = math.abs, math.ceil, math.floor, math.round;  -- Basic
+--[[ TABLE METHODS ]]--
+local twipe, tsort = table.wipe, table.sort;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...)
+local L = SV.L
+local Reports = SV.Reports;
+--[[
+##########################################################
+CALL TO ARMS STATS
+##########################################################
+]]--
+local REPORT_NAME = "Call to Arms";
+local HEX_COLOR = "22FFFF";
+local TEXT_PATTERN = ("%s: N/A"):format(BATTLEGROUND_HOLIDAY);
+local TEXT_FORMATTING = function(tanks, heals, dps)
+	local result = ""
+	if tanks then
+		result = result.."|TInterface\\AddOns\\SVUI_!Core\\assets\\textures\\default\\tank.tga:14:14|t"
+	end
+	if heals then
+		result = result.."|TInterface\\AddOns\\SVUI_!Core\\assets\\textures\\default\\healer.tga:14:14|t"
+	end
+	if dps then
+		result = result.."|TInterface\\AddOns\\SVUI_!Core\\assets\\textures\\default\\dps.tga:14:14|t"
+	end
+	return result
+end
+
+local Report = Reports:NewReport(REPORT_NAME, {
+	type = "data source",
+	text = REPORT_NAME .. " Info",
+	icon = [[Interface\Addons\SVUI_!Core\assets\icons\SVUI]]
+});
+
+Report.events = {"PLAYER_ENTERING_WORLD", "LFG_UPDATE_RANDOM_INFO"};
+
+Report.OnEvent = function(self, event, ...)
+	local isTank = false;
+	local isHeal = false;
+	local isDPS = false;
+	local isNormal = true;
+	for r = 1, GetNumRandomDungeons()do
+		local id, name = GetLFGRandomDungeonInfo(r)
+		for i = 1, LFG_ROLE_NUM_SHORTAGE_TYPES do
+			local eligible, forTank, forHealer, forDamage, itemCount = GetLFGRoleShortageRewards(id, i)
+			if eligible then
+				isNormal = false
+			end
+			if eligible and forTank and itemCount > 0 then
+				isTank = true;
+			end
+			if eligible and forHealer and itemCount > 0 then
+				isHeal = true;
+			end
+			if eligible and forDamage and itemCount > 0 then
+				isDPS = true;
+			end
+		end
+	end
+	if isNormal then
+		self.text:SetText(TEXT_PATTERN)
+	else
+		self.text:SetText(BATTLEGROUND_HOLIDAY..": "..TEXT_FORMATTING(isTank, isHeal, isDPS))
+	end
+end
+
+Report.OnClick = function(self, button)
+	ToggleFrame(LFDParentFrame)
+end
+
+Report.OnEnter = function(self)
+	Reports:SetDataTip(self)
+	local counter = 0;
+	for r = 1, GetNumRandomDungeons()do
+		local isTank = false;
+		local isHeal = false;
+		local isDPS = false;
+		local isNormal = true;
+		local id, name = GetLFGRandomDungeonInfo(r)
+		for i = 1, LFG_ROLE_NUM_SHORTAGE_TYPES do
+			local eligible, forTank, forHealer, forDamage, itemCount = GetLFGRoleShortageRewards(id, i)
+			if eligible then
+				isNormal = false
+			end
+			if eligible and forTank and itemCount > 0 then
+				isTank = true;
+			end
+			if eligible and forHealer and itemCount > 0 then
+				isHeal = true;
+			end
+			if eligible and forDamage and itemCount > 0 then
+				isDPS = true;
+			end
+		end
+		if not isNormal then
+			local text = TEXT_FORMATTING(isTank, isHeal, isDPS)
+			if text ~= "" then
+				Reports.ToolTip:AddDoubleLine(name..":", text, 1, 1, 1)
+			end
+			if isTank or isHeal or isDPS then
+				counter = counter + 1
+			end
+		end
+	end
+	Reports:ShowDataTip()
+end
diff --git a/SVUI_!Core/system/_reports/dps.lua b/SVUI_!Core/system/_reports/dps.lua
new file mode 100644
index 0000000..233dcb2
--- /dev/null
+++ b/SVUI_!Core/system/_reports/dps.lua
@@ -0,0 +1,141 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+
+local select 	= _G.select;
+local string 	= _G.string;
+--[[ STRING METHODS ]]--
+local match, sub, join = string.match, string.sub, string.join;
+local time      = _G.time;
+local wipe      = _G.wipe;
+local UnitGUID  = _G.UnitGUID;
+local UNIT_PET  = _G.UNIT_PET;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...)
+local L = SV.L
+local Reports = SV.Reports;
+--[[
+##########################################################
+DPS STATS
+##########################################################
+]]--
+local REPORT_NAME = "DPS";
+local HEX_COLOR = "22FFFF";
+local TEXT_PATTERN1 = "|cff%s%.1f|r";
+local TEXT_PATTERN2 = "%s |cff00CCFF%s|r";
+local PlayerEvents = {
+	["SWING_DAMAGE"] = true,
+	["RANGE_DAMAGE"] = true,
+	["SPELL_DAMAGE"] = true,
+	["SPELL_PERIODIC_DAMAGE"] = true,
+	["DAMAGE_SHIELD"] = true,
+	["DAMAGE_SPLIT"] = true,
+	["SPELL_EXTRA_ATTACKS"] = true
+	};
+local playerID, petID = UnitGUID('player');
+
+local Report = Reports:NewReport(REPORT_NAME, {
+	type = "data source",
+	text = REPORT_NAME .. " Info",
+	icon = [[Interface\Addons\SVUI_!Core\assets\icons\SVUI]],
+});
+
+Report.events = {"PLAYER_ENTERING_WORLD", "COMBAT_LOG_EVENT_UNFILTERED", "PLAYER_LEAVE_COMBAT", "PLAYER_REGEN_DISABLED", "UNIT_PET"};
+
+Report.OnInit = function(self)
+	playerID = UnitGUID('player')
+	petID = UnitGUID("pet")
+
+	if(not self.InnerData) then
+		self.InnerData = {}
+	end
+
+	self.InnerData.thistime = 0
+	self.InnerData.lasttime = 0
+	self.InnerData.totaltime = 0
+	self.InnerData.lastamount = 0
+	self.InnerData.totalamount = 0
+end
+
+Report.OnEvent = function(self, event, ...)
+	local data = self.InnerData
+	if event == "PLAYER_ENTERING_WORLD" then
+		playerID = UnitGUID('player')
+	elseif event == 'PLAYER_REGEN_DISABLED' or event == "PLAYER_LEAVE_COMBAT" then
+		local now = time()
+		if now - data.lasttime > 20 then --time since the last segment
+			data.thistime = 0
+			data.totaltime = 0
+			data.totalamount = 0
+			data.lastamount = 0
+		end
+		data.lasttime = now
+	elseif event == 'COMBAT_LOG_EVENT_UNFILTERED' then
+		local newTime, event, _, srcGUID, srcName, srcFlags, sourceRaidFlags, dstGUID, dstName, dstFlags, destRaidFlags, lastDMG, spellName = ...
+		if not PlayerEvents[event] then return end
+		if(srcGUID == playerID or srcGUID == petID) then
+			if data.thistime == 0 then data.thistime = newTime end
+			data.lasttime = data.thistime
+			data.totaltime = newTime - data.thistime
+			if event ~= "SWING_DAMAGE" then
+				data.lastamount = select(15, ...)
+			else
+				data.lastamount = lastDMG
+			end
+			data.totalamount = data.totalamount + data.lastamount
+		end
+	elseif event == UNIT_PET then
+		data.petID = UnitGUID("pet")
+	end
+
+	if data.totalamount == 0 or data.totaltime == 0 then
+		self.text:SetText(TEXT_PATTERN2:format(L["DPS"], "..PAUSED"))
+		self.TText = "No Damage Done"
+		self.TText2 = "Go smack something so \nthat I can do the maths!"
+	else
+		local DPS = (data.totalamount) / (data.totaltime)
+		self.text:SetFormattedText(TEXT_PATTERN1, HEX_COLOR, DPS)
+		self.TText = "DPS:"
+		self.TText2 = DPS
+	end
+end
+
+Report.OnClick = function(self, button)
+	local data = self.InnerData
+	data.thistime = 0
+	data.totaltime = 0
+	data.totalamount = 0
+	data.lastamount = 0
+	if data.totalamount == 0 or data.totaltime == 0 then
+		self.text:SetText(TEXT_PATTERN2:format(L["DPS"], "..PAUSED"))
+		self.TText = "No Damage Done"
+		self.TText2 = "Go smack something so \nthat I can do the maths!"
+	else
+		local DPS = (data.totalamount) / (data.totaltime)
+		self.text:SetFormattedText(TEXT_PATTERN1, HEX_COLOR, DPS)
+		self.TText = "DPS:"
+		self.TText2 = DPS
+	end
+end
+
+Report.OnEnter = function(self)
+	Reports:SetDataTip(self)
+	Reports.ToolTip:AddDoubleLine("Damage Total:", self.InnerData.totalamount, 1, 1, 1)
+	Reports.ToolTip:AddLine(" ", 1, 1, 1)
+	Reports.ToolTip:AddDoubleLine(self.TText, self.TText2, 1, 1, 1)
+	Reports.ToolTip:AddLine(" ", 1, 1, 1)
+	Reports.ToolTip:AddDoubleLine("[Click]", "Clear DPS", 0,1,0, 0.5,1,0.5)
+	Reports:ShowDataTip(true)
+end
\ No newline at end of file
diff --git a/SVUI_!Core/system/_reports/durability.lua b/SVUI_!Core/system/_reports/durability.lua
new file mode 100644
index 0000000..f7dd029
--- /dev/null
+++ b/SVUI_!Core/system/_reports/durability.lua
@@ -0,0 +1,163 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local ipairs 	= _G.ipairs;
+local type 		= _G.type;
+local error 	= _G.error;
+local pcall 	= _G.pcall;
+local assert 	= _G.assert;
+local tostring 	= _G.tostring;
+local tonumber 	= _G.tonumber;
+local string 	= _G.string;
+local math 		= _G.math;
+local table 	= _G.table;
+--[[ STRING METHODS ]]--
+local lower, upper = string.lower, string.upper;
+local find, format, len, split = string.find, string.format, string.len, string.split;
+local match, sub, join = string.match, string.sub, string.join;
+local gmatch, gsub = string.gmatch, string.gsub;
+--[[ MATH METHODS ]]--
+local abs, ceil, floor, round = math.abs, math.ceil, math.floor, math.round;  -- Basic
+--[[ TABLE METHODS ]]--
+local twipe, tsort = table.wipe, table.sort;
+local ToggleCharacter      			= _G.ToggleCharacter;
+local GetInventoryItemDurability    = _G.GetInventoryItemDurability;
+local GetInventorySlotInfo  		= _G.GetInventorySlotInfo;
+local DURABILITY  					= _G.DURABILITY;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...)
+local L = SV.L
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local Reports = SV.Reports;
+--[[
+##########################################################
+DURABILITY STATS
+##########################################################
+]]--
+local displayString = "%s: |cff%s%d%%|r";
+local overall = 0;
+local min, max, currentObject;
+local equipment = {}
+local inventoryMap = {
+	["SecondaryHandSlot"] = L["Offhand"],
+	["MainHandSlot"] = L["Main Hand"],
+	["FeetSlot"] = L["Feet"],
+	["LegsSlot"] = L["Legs"],
+	["HandsSlot"] = L["Hands"],
+	["WristSlot"] = L["Wrist"],
+	["WaistSlot"] = L["Waist"],
+	["ChestSlot"] = L["Chest"],
+	["ShoulderSlot"] = L["Shoulder"],
+	["HeadSlot"] = L["Head"]
+}
+local HEX_COLOR = "22FFFF";
+local TEXT_PATTERN = "|cff%s%s|r";
+--[[
+##########################################################
+STANDARD TYPE
+##########################################################
+]]--
+local REPORT_NAME = "Durability";
+local Report = Reports:NewReport(REPORT_NAME, {
+	type = "data source",
+	text = REPORT_NAME .. " Info",
+	icon = [[Interface\Addons\SVUI_!Core\assets\icons\SVUI]]
+});
+
+Report.events = {"PLAYER_ENTERING_WORLD", "UPDATE_INVENTORY_DURABILITY", "MERCHANT_SHOW"};
+
+Report.OnEvent = function(self, event, ...)
+	overall = 100;
+	if self.barframe:IsShown() then
+		self.text:SetAllPoints(self)
+		self.text:SetJustifyH("CENTER")
+		self.barframe:Hide()
+	end
+	for slot,name in pairs(inventoryMap)do
+		local slotID = GetInventorySlotInfo(slot)
+		min,max = GetInventoryItemDurability(slotID)
+		if min then
+			equipment[name] = min / max * 100;
+			if min / max * 100 < overall then
+				overall = min / max * 100
+			end
+		end
+	end
+	self.text:SetFormattedText(displayString, DURABILITY, HEX_COLOR, overall)
+end
+
+Report.OnClick = function(self, button)
+	ToggleCharacter("PaperDollFrame")
+end
+
+Report.OnEnter = function(self)
+	Reports:SetDataTip(self)
+	for name,amt in pairs(equipment)do
+		Reports.ToolTip:AddDoubleLine(name, format("%d%%", amt),1, 1, 1, SV:ColorGradient(amt * 0.01, 1, 0, 0, 1, 1, 0, 0, 1, 0))
+	end
+	Reports:ShowDataTip()
+end
+--[[
+##########################################################
+BAR TYPE
+##########################################################
+]]--
+local BAR_NAME = "Durability Bar";
+local ReportBar = Reports:NewReport(BAR_NAME, {
+	type = "data source",
+	text = BAR_NAME,
+	icon = [[Interface\Addons\SVUI_!Core\assets\icons\SVUI]]
+});
+
+ReportBar.events = {"PLAYER_ENTERING_WORLD", "UPDATE_INVENTORY_DURABILITY", "MERCHANT_SHOW"};
+
+ReportBar.OnEvent = function(self, event, ...)
+	overall = 100;
+	if not self.barframe:IsShown() then
+		self.barframe:Show()
+		self.barframe.icon.texture:SetTexture(SV.media.dock.durabilityLabel)
+	end
+	for slot,name in pairs(inventoryMap)do
+		local slotID = GetInventorySlotInfo(slot)
+		min,max = GetInventoryItemDurability(slotID)
+		if min then
+			equipment[name] = min / max * 100;
+			if min / max * 100 < overall then
+				overall = min / max * 100
+			end
+		end
+	end
+	local newRed = (100 - overall) * 0.01;
+	local newGreen = overall * 0.01;
+	self.barframe.bar:SetMinMaxValues(0, 100)
+	self.barframe.bar:SetValue(overall)
+	self.barframe.bar:SetStatusBarColor(newRed, newGreen, 0)
+	self.text:SetText('')
+end
+
+ReportBar.OnClick = function(self, button)
+	ToggleCharacter("PaperDollFrame")
+end
+
+ReportBar.OnEnter = function(self)
+	Reports:SetDataTip(self)
+	for name,amt in pairs(equipment)do
+		Reports.ToolTip:AddDoubleLine(name, format("%d%%", amt),1, 1, 1, SV:ColorGradient(amt * 0.01, 1, 0, 0, 1, 1, 0, 0, 1, 0))
+	end
+	Reports:ShowDataTip()
+end
diff --git a/SVUI_!Core/system/_reports/experience.lua b/SVUI_!Core/system/_reports/experience.lua
new file mode 100644
index 0000000..ca85b65
--- /dev/null
+++ b/SVUI_!Core/system/_reports/experience.lua
@@ -0,0 +1,306 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+
+local select 	= _G.select;
+local string 	= _G.string;
+--[[ STRING METHODS ]]--
+local format = string.format;
+local gsub = string.gsub;
+--MATH
+local math      = _G.math;
+local min       = math.min
+local UnitXP    = _G.UnitXP;
+local UnitXPMax = _G.UnitXPMax;
+local GetXPExhaustion  = _G.GetXPExhaustion;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...)
+local L = SV.L;
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local Reports = SV.Reports;
+--[[
+##########################################################
+EXPERIENCE STATS
+##########################################################
+]]--
+local HEX_COLOR = "22FFFF";
+local TEXT_PATTERN = "|cff%s%s|r";
+local playerName = UnitName("player");
+local maxPlayerLevel = GetMaxPlayerLevel();
+
+local function FormatExp(subset, value, maxValue, remain, exhaust)
+	local trunc, calc;
+
+	if(maxPlayerLevel == UnitLevel("player")) then return "|cff11CC00Max Level|r" end
+
+	local expString,prefix,suffix = "","","";
+	if(exhaust and exhaust > 0) then
+		prefix = "|cff1188FF";
+		suffix = "|r";
+	end
+
+	if(subset:find("XP")) then
+	    if value >= 1e9 then
+	        trunc = ("%.1fb"):format(value/1e9):gsub("%.?0+([kmb])$","%1")
+	    elseif value >= 1e6 then
+	        trunc = ("%.1fm"):format(value/1e6):gsub("%.?0+([kmb])$","%1")
+	    elseif value >= 1e3 or value <= -1e3 then
+	        trunc = ("%.1fk"):format(value/1e3):gsub("%.?0+([kmb])$","%1")
+	    else
+	        trunc = value
+	    end
+
+	    if(exhaust and exhaust > 0) then
+			trunc = "|cff1188FF" .. trunc .. "|r";
+		end
+
+		if(subset:find("_Percent")) then
+		    if(maxValue > 0) then
+				if(value > 0) then
+	    			calc = (value / maxValue) * 100
+	    			calc = ("%d%%"):format(calc)
+				else
+					calc = 100
+				end
+		    else
+		    	calc = 100
+		    end
+		    expString = prefix .. trunc .. suffix .. "  |cffAAAAAA=|r  " .. calc
+		else
+			expString = prefix .. trunc .. suffix .. "  |cffAAAAAA/|r  " .. maxValue
+		end
+	end
+
+	if(subset:find("Remaining")) then
+	    if(maxValue > 0) then
+			remain = remain or (maxValue - value);
+			if remain >= 1e9 then
+				trunc = ("%.1fb"):format(remain/1e9):gsub("%.?0+([kmb])$","%1")
+		    elseif remain >= 1e6 then
+				trunc = ("%.1fm"):format(remain/1e6):gsub("%.?0+([kmb])$","%1")
+		    elseif remain >= 1e3 or value <= -1e3 then
+				trunc = ("%.1fk"):format(remain/1e3):gsub("%.?0+([kmb])$","%1")
+		    else
+				trunc = remain
+		    end
+		else
+			remain = 0
+			trunc = 0;
+		end
+
+		if(subset:find("_Percent")) then
+		    if(maxValue > 0) then
+				if(remain > 0) then
+					calc = (remain / maxValue) * 100
+					calc = ("%d%%"):format(calc)
+				else
+					calc = 100
+				end
+		    else
+		    	calc = 100
+		    end
+		    expString = prefix .. trunc .. suffix .. "  |cffAAAAAA=|r  " .. calc
+		else
+			expString = prefix .. trunc .. suffix .. "  |cffAAAAAA/|r  " .. maxValue
+		end
+	end
+
+    return expString
+end
+
+local function FetchExperience()
+	local xp = UnitXP("player")
+	if((not xp) or (xp <= 0)) then
+		xp = 1
+	end
+
+	local mxp = UnitXPMax("player")
+	if((not mxp) or (mxp <= 0)) then
+		mxp = 1
+	end
+
+	local exp = GetXPExhaustion()
+	if(not exp) then
+		exp = 0
+	end
+
+	local rxp = mxp - xp;
+
+	return xp,mxp,exp,rxp
+end
+
+local function CacheRepData(data)
+	local nextIndex = #data+1;
+	data[nextIndex] = {text = factionName, func = fn};
+	tsort(data, function(a,b) return a.text < b.text end)
+end
+--[[
+##########################################################
+STANDARD TYPE
+##########################################################
+]]--
+local REPORT_NAME = "Experience";
+local Report = Reports:NewReport(REPORT_NAME, {
+	type = "data source",
+	text = REPORT_NAME .. " Info",
+	icon = [[Interface\Addons\SVUI_!Core\assets\icons\SVUI]]
+});
+
+Report.events = {"PLAYER_ENTERING_WORLD", "PLAYER_XP_UPDATE", "PLAYER_LEVEL_UP", "DISABLE_XP_GAIN", "ENABLE_XP_GAIN", "UPDATE_EXHAUSTION"};
+
+Report.OnClick = function(self, button)
+  SV.Dropdown:Open(self, self.InnerData, "Select Format")
+end
+
+Report.OnEvent = function(self, event, ...)
+	local subset = self.ExpKey or "XP";
+	if self.barframe:IsShown()then
+		self.text:SetAllPoints(self)
+		self.text:SetJustifyH("CENTER")
+		self.barframe:Hide()
+	end
+
+	local XP, maxXP, exhaust, remaining = FetchExperience();
+	local text = FormatExp(subset, XP, maxXP, remaining, exhaust);
+
+	self.text:SetText(text)
+end
+
+Report.OnEnter = function(self)
+	local subset = self.ExpKey or "XP";
+	Reports:SetDataTip(self)
+	local XP, maxXP, exhaust, remaining = FetchExperience();
+	Reports.ToolTip:AddLine(L["Experience"])
+	Reports.ToolTip:AddLine(" ")
+
+	if((XP > 0) and (maxXP > 0)) then
+		local calc1 = (XP / maxXP) * 100;
+		local r_percent = (remaining / maxXP) * 100;
+		local r_bars = r_percent / 5;
+		Reports.ToolTip:AddDoubleLine(L["XP:"], (" %d  /  %d (%d%%)"):format(XP, maxXP, calc1), 1, 1, 1)
+		Reports.ToolTip:AddDoubleLine(L["Remaining:"], (" %d (%d%% - %d "..L["Bars"]..")"):format(remaining, r_percent, r_bars), 1, 1, 1)
+		if(exhaust > 0) then
+			local calc = (exhaust / maxXP) * 100;
+			Reports.ToolTip:AddDoubleLine(L["Rested:"], format(" + %d (%d%%)", exhaust, calc), 1, 1, 1)
+		end
+	end
+	Reports.ToolTip:AddLine(" ")
+  	Reports.ToolTip:AddDoubleLine("[Click]", "Change XP Format", 0,1,0, 0.5,1,0.5)
+	Reports:ShowDataTip()
+end
+--[[
+##########################################################
+BAR TYPE
+##########################################################
+]]--
+local BAR_NAME = "Experience Bar";
+local ReportBar = Reports:NewReport(BAR_NAME, {
+	type = "data source",
+	text = BAR_NAME,
+	icon = [[Interface\Addons\SVUI_!Core\assets\icons\SVUI]]
+});
+
+ReportBar.events = {"PLAYER_ENTERING_WORLD", "PLAYER_XP_UPDATE", "PLAYER_LEVEL_UP", "DISABLE_XP_GAIN", "ENABLE_XP_GAIN", "UPDATE_EXHAUSTION"};
+
+ReportBar.OnEvent = function(self, event, ...)
+	if (not self.barframe:IsShown())then
+		self.barframe:Show()
+		self.barframe.icon.texture:SetTexture(SV.media.dock.experienceLabel)
+	end
+	if not self.barframe.bar.extra:IsShown() then
+		self.barframe.bar.extra:Show()
+	end
+	local bar = self.barframe.bar;
+	local XP, maxXP, exhaust = FetchExperience()
+
+	bar:SetMinMaxValues(0, maxXP)
+	bar:SetValue(XP)
+	bar:SetStatusBarColor(0, 0.5, 1)
+
+	if(exhaust > 0) then
+		local exhaust_value = min(XP + exhaust, maxXP);
+		bar.extra:SetMinMaxValues(0, maxXP)
+		bar.extra:SetValue(exhaust_value)
+		bar.extra:SetStatusBarColor(0.8, 0.5, 1)
+		bar.extra:SetAlpha(0.5)
+	else
+		bar.extra:SetMinMaxValues(0, 1)
+		bar.extra:SetValue(0)
+	end
+	self.text:SetText("")
+end
+
+ReportBar.OnEnter = function(self)
+	Reports:SetDataTip(self)
+	local XP, maxXP, exhaust, remaining = FetchExperience()
+	Reports.ToolTip:AddLine(L["Experience"])
+	Reports.ToolTip:AddLine(" ")
+
+	if((XP > 0) and (maxXP > 0)) then
+		local subset = self.ExpKey or "XP";
+		local calc1 = (XP / maxXP) * 100;
+		local r_percent = (remaining / maxXP) * 100;
+		local r_bars = r_percent / 5;
+		Reports.ToolTip:AddDoubleLine(L["XP:"], (" %d  /  %d (%d%%)"):format(XP, maxXP, calc1), 1, 1, 1)
+		Reports.ToolTip:AddDoubleLine(L["Remaining:"], (" %d (%d%% - %d "..L["Bars"]..")"):format(remaining, r_percent, r_bars), 1, 1, 1)
+		if(exhaust > 0) then
+			local calc = (exhaust / maxXP) * 100;
+			Reports.ToolTip:AddDoubleLine(L["Rested:"], format(" + %d (%d%%)", exhaust, calc), 1, 1, 1)
+		end
+	end
+	Reports:ShowDataTip()
+end
+
+Report.OnInit = function(self)
+  if(not self.InnerData) then
+    self.InnerData = {}
+  end
+
+  Reports:SetSubSettingsData('experience', 'table', {})
+
+  local key = self:GetName()
+
+  Reports.SubSettings["experience"][playerName][key] = Reports.SubSettings["experience"][playerName][key] or "XP";
+  self.ExpKey = Reports.SubSettings["experience"][playerName][key]
+
+  local fn1 = function()
+    Reports.SubSettings["experience"][playerName][key] = "XP";
+    self.ExpKey = "XP"
+    Report.OnEvent(self)
+  end
+
+  local fn2 = function()
+    Reports.SubSettings["experience"][playerName][key] = "XP_Percent";
+    self.ExpKey = "XP_Percent"
+    Report.OnEvent(self)
+  end
+
+  local fn3 = function()
+    Reports.SubSettings["experience"][playerName][key] = "Remaining";
+    self.ExpKey = "Remaining"
+    Report.OnEvent(self)
+  end
+
+  local fn4 = function()
+    Reports.SubSettings["experience"][playerName][key] = "Remaining_Percent";
+    self.ExpKey = "Remaining_Percent"
+    Report.OnEvent(self)
+  end
+
+  tinsert(self.InnerData, {text = "XP", func = fn1});
+  tinsert(self.InnerData, {text = "XP_Percent", func = fn2});
+  tinsert(self.InnerData, {text = "Remaining", func = fn3});
+  tinsert(self.InnerData, {text = "Remaining_Percent", func = fn4});
+end
diff --git a/SVUI_!Core/system/_reports/friends.lua b/SVUI_!Core/system/_reports/friends.lua
new file mode 100644
index 0000000..c13a988
--- /dev/null
+++ b/SVUI_!Core/system/_reports/friends.lua
@@ -0,0 +1,472 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local ipairs 	= _G.ipairs;
+local type 		= _G.type;
+local error 	= _G.error;
+local pcall 	= _G.pcall;
+local assert 	= _G.assert;
+local tostring 	= _G.tostring;
+local tonumber 	= _G.tonumber;
+local string 	= _G.string;
+local math 		= _G.math;
+local table 	= _G.table;
+--[[ STRING METHODS ]]--
+local lower, upper = string.lower, string.upper;
+local find, format, len, split = string.find, string.format, string.len, string.split;
+local match, sub, join = string.match, string.sub, string.join;
+local gmatch, gsub = string.gmatch, string.gsub;
+--[[ MATH METHODS ]]--
+local abs, ceil, floor, round = math.abs, math.ceil, math.floor, math.round;  -- Basic
+--[[ TABLE METHODS ]]--
+local wipe, tsort = table.wipe, table.sort;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...)
+local L = SV.L
+local Reports = SV.Reports;
+--[[
+##########################################################
+FRIENDS HELPERS
+##########################################################
+]]--
+local TEXT_PATTERN0 = "|cff%02x%02x%02x%s|r";
+local TEXT_PATTERN1 = "%s: |cff22FFFF%d|r";
+local TEXT_PATTERN2 = "|cff%02x%02x%02x%s|r |cff%02x%02x%02x%d|r";
+local TEXT_PATTERN3 = "%s |cff%02x%02x%02x%d|r %s";
+local TEXT_PATTERN4 = FRIENDS_LIST_ONLINE .. ": %s/%s";
+local ONLINE_MSG = gsub(ERR_FRIEND_ONLINE_SS, "\124Hplayer:%%s\124h%[%%s%]\124h", "");
+local OFFLINE_MSG = gsub(ERR_FRIEND_OFFLINE_S, "%%s", "");
+local MATCH_COLOR = {r = 0.25, g = 0.9, b = 0.08};
+local MISMATCH_COLOR = {r = 0.47, g = 0.47, b = 0.47};
+local BATTLENET_LABELS = {};
+local UpdateFriendsData;
+local COUNT_GENERAL = 0;
+local ONLINE_GENERAL = 0;
+local COUNT_BNET = 0;
+local ONLINE_BNET = 0;
+local COUNT_TOTAL = 0;
+local ONLINE_TOTAL = 0;
+local FRIEND_DATA = {
+  ['General'] = {},
+};
+local UPDATE_REQUIRED = false;
+
+do
+  	local AFK_INSERT = "|cffFFFFFF[|r|cffFF0000"..L['AFK'].."|r|cffFFFFFF]|r";
+  	local DND_INSERT = "|cffFFFFFF[|r|cffFF0000"..L['DND'].."|r|cffFFFFFF]|r";
+
+	local function _reg(a, b)
+		if(a.NAME and b.NAME) then
+		  return a.NAME < b.NAME
+		end
+	end
+
+	local function _bn(a, b)
+		if(a.BNET_NAME and b.BNET_NAME) then
+			if(a.BNET_NAME == b.BNET_NAME and (a.NAME and b.NAME)) then
+	    return a.NAME < b.NAME;
+	  end
+			return a.BNET_NAME < b.BNET_NAME
+		end
+	end
+
+  	local function _update()
+		local generalUpdated, bnetUpdated = false, false;
+
+		if(COUNT_GENERAL and (COUNT_GENERAL > 0)) then
+		  wipe(FRIEND_DATA.General);
+
+			for i = 1, COUNT_GENERAL do
+				local toonName, level, class, zoneName, isOnline, status, noteText = GetFriendInfo(i)
+
+				if(isOnline) then
+				if(status) then
+					if(status:find(AFK)) then
+						status = AFK_INSERT
+					elseif(status:find(DND)) then
+						status = DND_INSERT
+					end
+				end
+
+		      	local classUpdated = false;
+
+				for k,v in pairs(LOCALIZED_CLASS_NAMES_MALE) do
+					if class == v then
+					  class = k;
+					  classUpdated = true;
+					end
+				end
+
+				if(not classUpdated) then
+					for k,v in pairs(LOCALIZED_CLASS_NAMES_FEMALE) do
+					  if class == v then
+					    class = k;
+					  end
+					end
+				end
+
+				FRIEND_DATA.General[#FRIEND_DATA.General + 1] = {
+		            ONLINE = isOnline,
+		            CLIENT = BNET_CLIENT_WOW,
+		            NAME = toonName,
+		            CLASS = class,
+		            LOC = zoneName,
+		            LVL = level,
+		            STATUS = status,
+		            REALM = false,
+		            FACTION = false,
+		            RACE = false,
+		            BNET_ID = false,
+		            BNET_NAME = false,
+		            ID = false,
+		            NOTES = noteText,
+		         };
+
+		      	generalUpdated = true;
+				end
+			end
+		end
+
+		if(COUNT_BNET and (COUNT_BNET > 0)) then
+			wipe(FRIEND_DATA[BNET_CLIENT_WOW])
+			wipe(FRIEND_DATA[BNET_CLIENT_D3])
+			wipe(FRIEND_DATA[BNET_CLIENT_SC2])
+			wipe(FRIEND_DATA[BNET_CLIENT_WTCG])
+			wipe(FRIEND_DATA[BNET_CLIENT_HEROES])
+			wipe(FRIEND_DATA[BATTLENET_OPTIONS_LABEL])
+
+			for i = 1, COUNT_BNET do
+				local presenceID, presenceName, battleTag, isBattleTagPresence, toonName, toonID, client, isOnline, lastOnline, isAFK, isDND, messageText, noteText, isRIDFriend, messageTime, canSoR = BNGetFriendInfo(i)
+		        local _, hasFocus, realmName, realmID, faction, race, class, guild, zoneName, level, gameText, broadcastText, broadcastTime;
+		        if(toonID) then
+		          	hasFocus, toonName, client, realmName, realmID, faction, race, class, guild, zoneName, level, gameText, broadcastText, broadcastTime = BNGetGameAccountInfo(toonID);
+		        else
+		          	hasFocus, toonName, client, realmName, realmID, faction, race, class, guild, zoneName, level, gameText, broadcastText, broadcastTime = BNGetGameAccountInfo(presenceID);
+		        end
+
+		        if(not client or (client == BNET_CLIENT_APP)) then
+		        	client = BATTLENET_OPTIONS_LABEL
+		        end
+
+				if(isOnline and FRIEND_DATA[client]) then
+		          	local classUpdated = false;
+
+		    		for k,v in pairs(LOCALIZED_CLASS_NAMES_MALE) do
+						if class == v then
+						  class = k;
+						  classUpdated = true;
+						end
+					end
+
+					if(not classUpdated) then
+						for k,v in pairs(LOCALIZED_CLASS_NAMES_FEMALE) do
+						  if class == v then
+						    class = k;
+						  end
+						end
+					end
+
+		          	local status = "";
+		          	if(isAFK) then
+		      			status = AFK_INSERT
+		      		elseif(isDND) then
+		      			status = DND_INSERT
+		      		end
+
+					FRIEND_DATA[client][#FRIEND_DATA[client] + 1] = {
+						ONLINE = isOnline,
+						CLIENT = client,
+						NAME = toonName,
+						CLASS = class,
+						LOC = zoneName,
+						LVL = level,
+						STATUS = status,
+						REALM = realmName,
+						FACTION = faction,
+						RACE = race,
+						BNET_ID = presenceID,
+						BNET_NAME = presenceName,
+						ID = toonID,
+						NOTES = noteText,
+					};
+
+		          	bnetUpdated = true;
+				end
+			end
+		end
+
+		if(generalUpdated) then
+		  	tsort(FRIEND_DATA.General, _reg);
+		end
+
+    	if(bnetUpdated) then
+	      tsort(FRIEND_DATA[BNET_CLIENT_WOW], _bn)
+	      tsort(FRIEND_DATA[BNET_CLIENT_SC2], _bn)
+	      tsort(FRIEND_DATA[BNET_CLIENT_D3], _bn)
+	      tsort(FRIEND_DATA[BNET_CLIENT_WTCG], _bn)
+	      tsort(FRIEND_DATA[BNET_CLIENT_HEROES], _bn)
+	      tsort(FRIEND_DATA[BATTLENET_OPTIONS_LABEL], _bn)
+    	end
+  	end
+
+	function UpdateFriendsData(updateCache)
+		COUNT_GENERAL, ONLINE_GENERAL = GetNumFriends();
+		COUNT_BNET, ONLINE_BNET = BNGetNumFriends();
+		COUNT_TOTAL = COUNT_GENERAL + COUNT_BNET;
+		ONLINE_TOTAL = ONLINE_GENERAL + ONLINE_BNET;
+		if(updateCache) then
+		  _update()
+		end
+	end
+end
+--[[
+##########################################################
+FRIENDS MENUS
+##########################################################
+]]--
+SV.SystemAlert.SET_BN_BROADCAST={
+	text = BN_BROADCAST_TOOLTIP,
+	button1 = ACCEPT,
+	button2 = CANCEL,
+	hasEditBox = 1,
+	editBoxWidth = 350,
+	maxLetters = 127,
+	OnAccept = function(self) BNSetCustomMessage(self.editBox:GetText()) end,
+	OnShow = function(self) self.editBox:SetText(select(4, BNGetInfo()) ) self.editBox:SetFocus() end,
+	OnHide = ChatEdit_FocusActiveWindow,
+	EditBoxOnEnterPressed = function(self) BNSetCustomMessage(self:GetText()) self:GetParent():Hide() end,
+	EditBoxOnEscapePressed = function(self) self:GetParent():Hide() end,
+	timeout = 0,
+	exclusive = 1,
+	whileDead = 1,
+	hideOnEscape = 1,
+	preferredIndex = 3
+};
+
+local menuFrame = CreateFrame("Frame", "FriendDatatextRightClickMenu", SV.Screen, "UIDropDownMenuTemplate")
+local menuList = {
+	{ text = OPTIONS_MENU, isTitle = true, notCheckable = true},
+	{ text = INVITE, hasArrow = true, notCheckable = true, },
+	{ text = CHAT_MSG_WHISPER_INFORM, hasArrow = true, notCheckable = true, },
+	{ text = PLAYER_STATUS, hasArrow = true, notCheckable = true,
+		menuList = {
+			{ text = "|cff2BC226"..AVAILABLE.."|r", notCheckable = true, func = function() if IsChatAFK() then SendChatMessage("", "AFK") elseif IsChatDND() then SendChatMessage("", "DND") end end },
+			{ text = "|cffE7E716"..DND.."|r", notCheckable = true, func = function() if not IsChatDND() then SendChatMessage("", "DND") end end },
+			{ text = "|cffFF0000"..AFK.."|r", notCheckable = true, func = function() if not IsChatAFK() then SendChatMessage("", "AFK") end end },
+		},
+	},
+	{ text = BN_BROADCAST_TOOLTIP, notCheckable = true, func = function() SV:StaticPopup_Show("SET_BN_BROADCAST") end },
+}
+
+local function inviteClick(self, name)
+	menuFrame:Hide()
+
+	if type(name) ~= 'number' then
+		InviteUnit(name)
+	else
+		BNInviteFriend(name);
+	end
+end
+
+local function whisperClick(self, name, battleNet)
+	menuFrame:Hide()
+
+	if battleNet then
+		ChatFrame_SendSmartTell(name)
+	else
+		SetItemRef( "player:"..name, ("|Hplayer:%1$s|h[%1$s]|h"):format(name), "LeftButton" )
+	end
+end
+
+local REPORT_NAME = "Friends";
+
+local Report = Reports:NewReport(REPORT_NAME, {
+	type = "data source",
+	text = REPORT_NAME .. " Info",
+	icon = [[Interface\Addons\SVUI_!Core\assets\icons\SVUI]]
+});
+
+Report.events = {
+	"PLAYER_ENTERING_WORLD",
+	"BN_FRIEND_ACCOUNT_ONLINE",
+	"BN_FRIEND_ACCOUNT_OFFLINE",
+	"BN_FRIEND_INFO_CHANGED",
+	"BN_FRIEND_TOON_ONLINE",
+	"BN_FRIEND_TOON_OFFLINE",
+	"BN_TOON_NAME_UPDATED",
+	"FRIENDLIST_UPDATE",
+	"CHAT_MSG_SYSTEM"
+};
+
+Report.OnEvent = function(self, event, ...)
+	if event == "CHAT_MSG_SYSTEM" then
+		local message = select(1, ...)
+		if not (find(message, ONLINE_MSG) or find(message, OFFLINE_MSG)) then return end
+	end
+	UpdateFriendsData();
+	UPDATE_REQUIRED = true;
+	self.text:SetFormattedText(TEXT_PATTERN1, L['Friends'], ONLINE_TOTAL);
+end
+
+Report.OnClick = function(self, button)
+	Reports.ToolTip:Hide()
+
+	if button == "RightButton" then
+		local menuCountWhispers = 0;
+		local menuCountInvites = 0;
+
+		menuList[2].menuList = {}
+		menuList[3].menuList = {}
+
+		local currentFaction = UnitFactionGroup("player");
+
+		for client, cache in pairs(FRIEND_DATA) do
+			if(#cache > 0) then
+				for i = 1, #cache do
+					local friend = cache[i]
+					if (friend.ONLINE) then
+						local INVITE_TAG = friend.BNET_NAME or friend.NAME;
+						local INVITE_TEXT = format(TEXT_PATTERN0, 130.05, 197.115, 255, INVITE_TAG)
+						menuCountWhispers = menuCountWhispers + 1
+
+						if((client == 'General') or ((BNET_CLIENT_WOW == friend.CLIENT) and (currentFaction == friend.FACTION))) then
+							menuCountInvites = menuCountInvites + 1
+							local lC = GetQuestDifficultyColor(friend.LVL);
+							local cC = RAID_CLASS_COLORS[friend.CLASS] or lC;
+							INVITE_TEXT = format(TEXT_PATTERN2, cC.r*255, cC.g*255, cC.b*255, friend.NAME, lC.r*255, lC.g*255, lC.b*255, friend.LVL)
+						end
+
+						menuList[2].menuList[menuCountInvites] = {text = INVITE_TEXT, arg1 = INVITE_TAG, notCheckable = true, func = inviteClick}
+						menuList[3].menuList[menuCountWhispers] = {text = INVITE_TEXT, arg1 = INVITE_TAG, arg2 = true, notCheckable = true, func = whisperClick}
+					end
+				end
+			end
+		end
+
+		EasyMenu(menuList, menuFrame, "cursor", 0, 0, "MENU", 2)
+	else
+		ToggleFriendsFrame()
+	end
+end
+
+Report.OnEnter = function(self)
+	Reports:SetDataTip(self)
+
+	local groupString = "";
+	local numberOfFriends, onlineFriends = GetNumFriends()
+	local totalBNet, numBNetOnline = BNGetNumFriends()
+
+
+	if(UPDATE_REQUIRED) then
+		UpdateFriendsData(true);
+		UPDATE_REQUIRED = false;
+	end
+
+	if(ONLINE_TOTAL == 0) then return end
+
+	local zonec, classc, levelc, realmc;
+	Reports.ToolTip:AddDoubleLine(L['Friends List'], format(TEXT_PATTERN4, ONLINE_TOTAL, COUNT_TOTAL), 0.51, 0.773, 1, 0.51, 0.773, 1)
+	Reports.ToolTip:AddLine(' ')
+
+	local currentZone = GetRealZoneText();
+	local currentRealm = GetRealmName();
+
+	if(ONLINE_GENERAL > 0) then
+		local cache, addSpacer = FRIEND_DATA.General, false;
+
+		for i = 1, #cache do
+			local friend = cache[i];
+
+			if(friend.ONLINE) then
+				local zC = (currentZone == friend.LOC) and MATCH_COLOR or MISMATCH_COLOR;
+				local lC = GetQuestDifficultyColor(friend.LVL);
+				local cC = RAID_CLASS_COLORS[friend.CLASS] or lC;
+				local statusString = friend.STATUS;
+				if(UnitInParty(friend.NAME) or UnitInRaid(friend.NAME)) then statusString = "|cffaaaaaa*|r " .. statusString; end
+				local LEFT_TEXT = format(TEXT_PATTERN3, friend.NAME, lC.r*255, lC.g*255, lC.b*255, friend.LVL, statusString)
+				Reports.ToolTip:AddDoubleLine(LEFT_TEXT, friend.LOC, cC.r, cC.g, cC.b, zC.r, zC.g, zC.b)
+				addSpacer = true;
+			end
+		end
+
+		if(addSpacer) then
+			Reports.ToolTip:AddLine(' ')
+		end
+	end
+
+	if(ONLINE_BNET > 0) then
+
+		for client, cache in pairs(FRIEND_DATA) do
+			local GROUP_LABEL = BATTLENET_LABELS[client];
+
+			if(GROUP_LABEL and (#cache > 0)) then
+				Reports.ToolTip:AddLine(GROUP_LABEL .. client)
+
+				for i = 1, #cache do
+					local friend = cache[i]
+
+					if(friend.ONLINE) then
+						if friend.CLIENT == BNET_CLIENT_WOW then
+							local statusString = friend.STATUS;
+							if(UnitInParty(friend.NAME) or UnitInRaid(friend.NAME)) then statusString = "|cffaaaaaa*|r " .. statusString; end
+							local cC = RAID_CLASS_COLORS[friend.CLASS] or RAID_CLASS_COLORS["PRIEST"];
+							local LEFT_TEXT = "";
+							if(friend.LVL and (friend.LVL ~= '')) then
+								local lC = GetQuestDifficultyColor(friend.LVL);
+								LEFT_TEXT = format(TEXT_PATTERN3, friend.NAME, lC.r*255, lC.g*255, lC.b*255, friend.LVL, statusString)
+							else
+								LEFT_TEXT = friend.NAME .. statusString;
+							end
+
+							Reports.ToolTip:AddDoubleLine(LEFT_TEXT, friend.BNET_NAME, cC.r, cC.g, cC.b, 0.51, 0.773, 1)
+
+							if IsShiftKeyDown() then
+								local zC = (currentZone == friend.LOC) and MATCH_COLOR or MISMATCH_COLOR;
+								local rC = (currentRealm == friend.REALM) and MATCH_COLOR or MISMATCH_COLOR;
+								Reports.ToolTip:AddDoubleLine(friend.LOC, friend.REALM, zC.r, zC.g, zC.b, rC.r, rC.g, rC.b)
+							end
+						else
+							Reports.ToolTip:AddLine(friend.BNET_NAME, 0.51, 0.773, 1)
+						end
+					end
+				end
+			end
+		end
+	end
+
+	Reports:ShowDataTip()
+end
+
+Report.OnInit = function(self)
+	BATTLENET_LABELS = {
+		[BNET_CLIENT_WOW] = "|TInterface\\ChatFrame\\UI-ChatIcon-WOW:16:16:0:-1|t",
+		[BNET_CLIENT_SC2] = "|TInterface\\ChatFrame\\UI-ChatIcon-SC2:16:16:0:-1|t",
+		[BNET_CLIENT_D3] = "|TInterface\\ChatFrame\\UI-ChatIcon-D3:16:16:0:-1|t",
+		[BNET_CLIENT_WTCG] = "|TInterface\\ChatFrame\\UI-ChatIcon-WTCG:16:16:0:-1|t",
+		[BNET_CLIENT_HEROES] = "|TInterface\\ChatFrame\\UI-ChatIcon-HotS:16:16:0:-1|t",
+		[BATTLENET_OPTIONS_LABEL] = "|TInterface\\ChatFrame\\UI-ChatIcon-Battlenet:16:16:0:-1|t",
+	};
+	FRIEND_DATA[BATTLENET_OPTIONS_LABEL] = {}
+	FRIEND_DATA[BNET_CLIENT_WOW] = {}
+	FRIEND_DATA[BNET_CLIENT_D3] = {}
+	FRIEND_DATA[BNET_CLIENT_SC2] = {}
+	FRIEND_DATA[BNET_CLIENT_WTCG] = {}
+	FRIEND_DATA[BNET_CLIENT_HEROES] = {}
+	UpdateFriendsData();
+	UPDATE_REQUIRED = false;
+end
diff --git a/SVUI_!Core/system/_reports/gold.lua b/SVUI_!Core/system/_reports/gold.lua
new file mode 100644
index 0000000..da169b2
--- /dev/null
+++ b/SVUI_!Core/system/_reports/gold.lua
@@ -0,0 +1,141 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local ipairs 	= _G.ipairs;
+local type 		= _G.type;
+local error 	= _G.error;
+local pcall 	= _G.pcall;
+local assert 	= _G.assert;
+local tostring 	= _G.tostring;
+local tonumber 	= _G.tonumber;
+local string 	= _G.string;
+local math 		= _G.math;
+local table 	= _G.table;
+--[[ STRING METHODS ]]--
+local lower, upper = string.lower, string.upper;
+local find, format, len, split = string.find, string.format, string.len, string.split;
+local match, sub, join = string.match, string.sub, string.join;
+local gmatch, gsub = string.gmatch, string.gsub;
+--[[ MATH METHODS ]]--
+local abs, ceil, floor, round, mod = math.abs, math.ceil, math.floor, math.round, math.fmod;  -- Basic
+--[[ TABLE METHODS ]]--
+local twipe, tsort = table.wipe, table.sort;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...)
+local L = SV.L;
+local Reports = SV.Reports;
+--[[
+##########################################################
+GOLD STATS
+##########################################################
+]]--
+local REPORT_NAME = "Gold";
+local HEX_COLOR = "22FFFF";
+local TEXT_PATTERN = join("","|cffaaaaaa",L["Reset Data: Hold Left Ctrl + Shift then Click"],"|r");
+local playerName = UnitName("player");
+local playerRealm = GetRealmName();
+local gains = 0;
+local loss = 0;
+local recorded = 0;
+
+local Gold_OnEvent = function(self, event, ...)
+    if not IsLoggedIn() then return end
+	local current = GetMoney()
+	recorded = Reports.Accountant["gold"][playerName] or current;
+	local adjusted = current - recorded;
+	if recorded > current then
+		loss = loss - adjusted
+	else
+		gains = gains + adjusted
+	end
+	self.text:SetText(SV:FormatCurrency(current, SV.db.Reports.shortGold))
+	Reports.Accountant["gold"][playerName] = current
+end
+
+local Report = Reports:NewReport(REPORT_NAME, {
+	type = "data source",
+	text = REPORT_NAME .. " Info",
+	icon = [[Interface\Addons\SVUI_!Core\assets\icons\SVUI]]
+});
+
+Report.events = {"PLAYER_ENTERING_WORLD", "PLAYER_MONEY", "SEND_MAIL_MONEY_CHANGED", "SEND_MAIL_COD_CHANGED", "PLAYER_TRADE_MONEY", "TRADE_MONEY_CHANGED"};
+
+Report.OnEvent = Gold_OnEvent
+
+Report.OnClick = function(self, button)
+	if IsLeftControlKeyDown() and IsShiftKeyDown() then
+		Reports.Accountant["gold"] = {};
+		Reports.Accountant["gold"][playerName] = GetMoney();
+		Gold_OnEvent(self)
+		Reports.ToolTip:Hide()
+	else
+		ToggleAllBags()
+	end
+end
+
+Report.OnEnter = function(self)
+	Reports:SetDataTip(self)
+	Reports.ToolTip:AddLine(L['Session:'])
+	Reports.ToolTip:AddDoubleLine(L["Earned:"],SV:FormatCurrency(gains),1,1,1,1,1,1)
+	Reports.ToolTip:AddDoubleLine(L["Spent:"],SV:FormatCurrency(loss),1,1,1,1,1,1)
+	if gains < loss then
+		Reports.ToolTip:AddDoubleLine(L["Deficit:"],SV:FormatCurrency(gains - loss),1,0,0,1,1,1)
+	elseif (gains - loss) > 0 then
+		Reports.ToolTip:AddDoubleLine(L["Profit:"],SV:FormatCurrency(gains - loss),0,1,0,1,1,1)
+	end
+	Reports.ToolTip:AddLine(" ")
+	local networth = Reports.Accountant["gold"][playerName];
+	Reports.ToolTip:AddLine(L[playerName..": "])
+	Reports.ToolTip:AddDoubleLine(L["Total: "], SV:FormatCurrency(networth), 1,1,1,1,1,1)
+	Reports.ToolTip:AddLine(" ")
+
+	Reports.ToolTip:AddLine(L["Characters: "])
+	for name,amount in pairs(self.InnerData)do
+		if(name ~= playerName and name ~= 'total') then
+			networth = networth + amount;
+			Reports.ToolTip:AddDoubleLine(name, SV:FormatCurrency(amount), 1,1,1,1,1,1)
+		end
+	end
+
+	Reports.Accountant["networth"] = networth;
+
+	Reports.ToolTip:AddLine(" ")
+	Reports.ToolTip:AddLine(L["Server: "])
+	Reports.ToolTip:AddDoubleLine(L["Total: "], SV:FormatCurrency(networth), 1,1,1,1,1,1)
+	Reports.ToolTip:AddLine(" ")
+	Reports.ToolTip:AddLine(TEXT_PATTERN)
+	Reports:ShowDataTip()
+end
+
+Report.OnInit = function(self)
+	if(not self.InnerData) then
+		self.InnerData = {}
+	end
+	Reports:SetAccountantData('gold', 'number', 0);
+	Reports:SetAccountantData('networth', 'number', 0);
+
+	local totalGold = 0;
+	for name,amount in pairs(Reports.Accountant["gold"]) do
+		if(amount) then
+			self.InnerData[name] = amount;
+			totalGold = totalGold + amount
+		end
+	end
+
+	self.InnerData['total'] = totalGold;
+end
diff --git a/SVUI_!Core/system/_reports/guild.lua b/SVUI_!Core/system/_reports/guild.lua
new file mode 100644
index 0000000..ee56b7f
--- /dev/null
+++ b/SVUI_!Core/system/_reports/guild.lua
@@ -0,0 +1,310 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+
+local select 	= _G.select;
+local string 	= _G.string;
+local math 		= _G.math;
+local table 	= _G.table;
+--[[ STRING METHODS ]]--
+local format, join, gsub = string.format, string.join, string.gsub;
+--[[ MATH METHODS ]]--
+local ceil = math.ceil;
+local tsort = table.sort;
+local wipe = _G.wipe;
+local InCombatLockdown      = _G.InCombatLockdown;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...)
+local L = SV.L
+local Reports = SV.Reports;
+--[[
+##########################################################
+GUILD STATS
+##########################################################
+]]--
+local playerName = UnitName("player");
+local playerRealm = GetRealmName();
+
+local StatEvents = {"PLAYER_ENTERING_WORLD","GUILD_ROSTER_UPDATE","GUILD_XP_UPDATE","PLAYER_GUILD_UPDATE","GUILD_MOTD"};
+local HEX_COLOR = "22CFFF";
+local TEXT_PATTERN = "%s: |cff22CFFF%d|r";
+local pattern1 = ("|cff22CFFF%s"):format(GUILD_EXPERIENCE_CURRENT);
+local pattern2 = ("|cff22FFFF%s"):format(GUILD_EXPERIENCE_DAILY);
+local guildFormattedName = "%s: %d/%d";
+local guildFormattedXP = gsub(pattern1, ": ", ":|r |cffFFFFFF", 1);
+local guildFormattedDailyXP = gsub(pattern2, ": ", ":|r |cffFFFFFF", 1);
+local guildFormattedFaction = "|cff22FFFF%s:|r |cFFFFFFFF%s/%s (%s%%)";
+local guildFormattedOnline = join("+ %d ", FRIENDS_LIST_ONLINE, "...");
+local guildFormattedNote = "|cff999999   " .. LABEL_NOTE .. ":|r %s";
+local guildFormattedRank = "|cff999999   " .. GUILD_RANK1_DESC .. ":|r %s";
+local GuildStatMembers,GuildStatMOTD = {},"";
+local currentObject;
+
+local UnitFlagFormat = {
+	[0] = function()return "" end,
+	[1] = function()return ("|cffFFFFFF[|r|cffFF0000%s|r|cffFFFFFF]|r"):format(L["AFK"]) end,
+	[2] = function()return ("|cffFFFFFF[|r|cffFF0000%s|r|cffFFFFFF]|r"):format(L["DND"]) end
+};
+
+local MobileFlagFormat = {
+	[0] = function()return ChatFrame_GetMobileEmbeddedTexture(73/255, 177/255, 73/255) end,
+	[1] = function()return "|TInterface\\ChatFrame\\UI-ChatIcon-ArmoryChat-AwayMobile:14:14:0:0:16:16:0:16:0:16|t" end,
+	[2] = function()return "|TInterface\\ChatFrame\\UI-ChatIcon-ArmoryChat-BusyMobile:14:14:0:0:16:16:0:16:0:16|t" end
+};
+
+local GuildDatatTextRightClickMenu = CreateFrame("Frame", "GuildDatatTextRightClickMenu", SV.Screen, "UIDropDownMenuTemplate")
+
+local MenuMap = {
+	{text = OPTIONS_MENU,  isTitle = true,  notCheckable = true},
+	{text = INVITE,  hasArrow = true,  notCheckable = true},
+	{text = CHAT_MSG_WHISPER_INFORM,  hasArrow = true,  notCheckable = true}
+};
+
+local function TruncateString(value)
+    if value >= 1e9 then
+        return ("%.1fb"):format(value/1e9):gsub("%.?0+([kmb])$","%1")
+    elseif value >= 1e6 then
+        return ("%.1fm"):format(value/1e6):gsub("%.?0+([kmb])$","%1")
+    elseif value >= 1e3 or value <= -1e3 then
+        return ("%.1fk"):format(value/1e3):gsub("%.?0+([kmb])$","%1")
+    else
+        return value
+    end
+end
+
+local function SortGuildStatMembers(shift)
+	tsort(GuildStatMembers, function(arg1, arg2)
+		if arg1 and arg2 then
+			if shift then
+				return arg1[10] < arg2[10]
+			else
+				return arg1[1] < arg2[1]
+			end
+		end
+	end)
+end
+
+local function GetGuildStatMembers()
+	wipe(GuildStatMembers)
+	local statusFormat;
+	local _, name, rank, level, zone, note, officernote, online, status, classFileName, isMobile, rankIndex;
+	for i = 1, GetNumGuildMembers() do
+		name, rank, rankIndex, level, _, zone, note, officernote, online, status, classFileName, _, _, isMobile = GetGuildRosterInfo(i)
+		statusFormat = isMobile and MobileFlagFormat[status]() or UnitFlagFormat[status]()
+		zone = isMobile and not online and REMOTE_CHAT or zone;
+		if online or isMobile then
+			GuildStatMembers[#GuildStatMembers + 1] = { name, rank, level, zone, note, officernote, online, statusFormat, classFileName, rankIndex, isMobile}
+		end
+	end
+end
+
+local GuildStatEventHandler = {
+	["PLAYER_ENTERING_WORLD"] = function(arg1, arg2)
+		if not GuildFrame and IsInGuild() then
+			LoadAddOn("Blizzard_GuildUI")
+			GuildRoster()
+		end
+	end,
+	["GUILD_ROSTER_UPDATE"] = function(arg1, arg2)
+		if arg2 then
+			GuildRoster()
+		else
+			GetGuildStatMembers()
+			GuildStatMOTD = GetGuildRosterMOTD()
+			if GetMouseFocus() == arg1 then
+				arg1:GetScript("OnEnter")(arg1, nil, true)
+			end
+		end
+	end,
+	["PLAYER_GUILD_UPDATE"] = function(arg1, arg2)
+		GuildRoster()
+	end,
+	["GUILD_MOTD"] = function(arg1, arg2)
+		GuildStatMOTD = arg2
+	end,
+	["SVUI_FORCE_RUN"] = SV.fubar,
+	["SVUI_COLOR_UPDATE"] = SV.fubar
+};
+
+local function MenuInvite(self, unit)
+	GuildDatatTextRightClickMenu:Hide()
+	InviteUnit(unit)
+end
+
+local function MenuRightClick(self, unit)
+	GuildDatatTextRightClickMenu:Hide()
+	SetItemRef(("player:%s"):format(unit), ("|Hplayer:%1$s|h[%1$s]|h"):format(unit), "LeftButton")
+end
+
+local function MenuLeftClick()
+	if IsInGuild() then
+		if not GuildFrame then
+			LoadAddOn("Blizzard_GuildUI")
+		end
+		GuildFrame_Toggle()
+		GuildFrame_TabClicked(GuildFrameTab2)
+	else
+		if not LookingForGuildFrame then
+			LoadAddOn("Blizzard_LookingForGuildUI")
+		end
+		if LookingForGuildFrame then
+			LookingForGuildFrame_Toggle()
+		end
+	end
+end
+
+local REPORT_NAME = "Guild";
+
+local Report = Reports:NewReport(REPORT_NAME, {
+	type = "data source",
+	text = REPORT_NAME .. " Info",
+	icon = [[Interface\Addons\SVUI_!Core\assets\icons\SVUI]]
+});
+
+Report.events = {"PLAYER_ENTERING_WORLD","GUILD_ROSTER_UPDATE","GUILD_XP_UPDATE","PLAYER_GUILD_UPDATE","GUILD_MOTD"};
+
+Report.OnInit = function(self)
+	if(not self.InnerData) then
+		self.InnerData = {}
+	end
+	-- DO STUFF
+end
+
+Report.OnEvent = function(self, event, ...)
+	if IsInGuild() and GuildStatEventHandler[event] then
+		GuildStatEventHandler[event](self, select(1, ...))
+		self.text:SetFormattedText(TEXT_PATTERN, GUILD, #GuildStatMembers)
+	else
+		self.text:SetText(L['No Guild'])
+	end
+end
+
+Report.OnClick = function(self, button)
+	if button == "RightButton" and IsInGuild() then
+		Reports.ToolTip:Hide()
+
+
+		local classc, levelc, grouped, info
+		local menuCountWhispers = 0
+		local menuCountInvites = 0
+
+		MenuMap[2].menuList = {}
+		MenuMap[3].menuList = {}
+
+		for i = 1, #GuildStatMembers do
+			info = GuildStatMembers[i]
+			if info[7] and info[1] ~= playerName then
+				local classc, levelc = RAID_CLASS_COLORS[info[9]], GetQuestDifficultyColor(info[3])
+				if UnitInParty(info[1])or UnitInRaid(info[1]) then
+					grouped = "|cffaaaaaa*|r"
+				elseif not info[11] then
+					menuCountInvites = menuCountInvites + 1;
+					grouped = "";
+					MenuMap[2].menuList[menuCountInvites] = {
+						text = ("|cff%02x%02x%02x%d|r |cff%02x%02x%02x%s|r %s"):format(levelc.r*255, levelc.g*255, levelc.b*255, info[3], classc.r*255, classc.g*255, classc.b*255, info[1], ""),
+						arg1 = info[1],
+						notCheckable = true,
+						func = MenuInvite
+					}
+				end
+				menuCountWhispers = menuCountWhispers + 1;
+				if not grouped then
+					grouped = ""
+				end
+				MenuMap[3].menuList[menuCountWhispers] = {
+					text = ("|cff%02x%02x%02x%d|r |cff%02x%02x%02x%s|r %s"):format(levelc.r*255, levelc.g*255, levelc.b*255, info[3], classc.r*255, classc.g*255, classc.b*255, info[1], grouped),
+					arg1 = info[1],
+					notCheckable = true,
+					func = MenuRightClick
+				}
+			end
+		end
+		EasyMenu(MenuMap, GuildDatatTextRightClickMenu, "cursor", 0, 0, "MENU", 2)
+	else
+		MenuLeftClick()
+	end
+end
+
+Report.OnEnter = function(self)
+	if not IsInGuild() then
+		return
+	end
+	Reports:SetDataTip(self)
+	local members, online = GetNumGuildMembers()
+	if(members and online) then
+		if #GuildStatMembers == 0 then GetGuildStatMembers() end
+		SortGuildStatMembers(IsShiftKeyDown())
+
+		local guildName, guildRankName, guildRankIndex = GetGuildInfo('player')
+		if guildName and guildRankName then
+			Reports.ToolTip:AddDoubleLine(("%s "):format(guildName), guildFormattedName:format(GUILD, online, members), 0.4, 0.78, 1, 0.4, 0.78, 1)
+			Reports.ToolTip:AddLine(guildRankName, 0.4, 0.78, 1)
+		end
+
+		if GuildStatMOTD ~= "" then
+			Reports.ToolTip:AddLine(' ')
+			Reports.ToolTip:AddLine(("%s |cffaaaaaa- |cffffffff%s"):format(GUILD_MOTD, GuildStatMOTD), 0.75, 0.9, 1, 1)
+		end
+
+		local _, _, standingID, barMin, barMax, barValue = GetGuildFactionInfo()
+		if standingID ~= 8 then
+			barMax = barMax - barMin;
+			barValue = barValue - barMin;
+			barMin = 0;
+			Reports.ToolTip:AddLine(guildFormattedFaction:format(COMBAT_FACTION_CHANGE, TruncateString(barValue), TruncateString(barMax), ceil(barValue / barMax * 100)))
+		end
+
+		local zoneColor, classColor, questColor, member, groupFormat;
+		local counter = 0;
+
+		Reports.ToolTip:AddLine(' ')
+
+		for X = 1, #GuildStatMembers do
+			if((30 - counter) <= 1) then
+				if((online - 30) > 1) then
+					Reports.ToolTip:AddLine(guildFormattedOnline:format(online - 30), 0.75, 0.9, 1)
+				end
+				break
+			end
+			member = GuildStatMembers[X]
+			if GetRealZoneText() == member[4]then
+				zoneColor = {r=0.3,g=1.0,b=0.3}
+			else
+				zoneColor = {r=0.65,g=0.65,b=0.65}
+			end
+			classColor, questColor = RAID_CLASS_COLORS[member[9]], GetQuestDifficultyColor(member[3])
+			if UnitInParty(member[1]) or UnitInRaid(member[1]) then
+				groupFormat = "|cffaaaaaa*|r"
+			else
+				groupFormat = ""
+			end
+			if IsShiftKeyDown() then
+				Reports.ToolTip:AddDoubleLine(("%s |cff999999-|cffffffff %s"):format(member[1], member[2]), member[4], classColor.r, classColor.g, classColor.b, zoneColor.r, zoneColor.g, zoneColor.b)
+				if member[5] ~= ""then
+					Reports.ToolTip:AddLine(guildFormattedNote:format(member[5]), 0.75, 0.9, 1, 1)
+				end
+				if member[6] ~= ""then
+					Reports.ToolTip:AddLine(guildFormattedRank:format(member[6]), 0.3, 1, 0.3, 1)
+				end
+			else
+				Reports.ToolTip:AddDoubleLine(("|cff%02x%02x%02x%d|r %s%s %s"):format(questColor.r*255, questColor.g*255, questColor.b*255, member[3], member[1], groupFormat, member[8]), member[4], classColor.r, classColor.g, classColor.b, zoneColor.r, zoneColor.g, zoneColor.b)
+			end
+			counter = counter + 1
+		end
+		Reports:ShowDataTip()
+	else
+		GuildRoster()
+	end
+end
diff --git a/SVUI_!Core/system/_reports/hps.lua b/SVUI_!Core/system/_reports/hps.lua
new file mode 100644
index 0000000..4458613
--- /dev/null
+++ b/SVUI_!Core/system/_reports/hps.lua
@@ -0,0 +1,134 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+
+local select 	= _G.select;
+local string 	= _G.string;
+--[[ STRING METHODS ]]--
+local match, sub, join = string.match, string.sub, string.join;
+local max = math.max;
+local time      = _G.time;
+local wipe      = _G.wipe;
+local UnitGUID  = _G.UnitGUID;
+local UNIT_PET  = _G.UNIT_PET;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...)
+local L = SV.L
+local Reports = SV.Reports;
+--[[
+##########################################################
+HPS STATS
+##########################################################
+]]--
+local REPORT_NAME = "HPS";
+local HEX_COLOR = "22FFFF";
+local TEXT_PATTERN1 = "|cff%s%.1f|r";
+local TEXT_PATTERN2 = "%s |cff00CCFF%s|r";
+local PlayerEvents = {["SPELL_HEAL"] = true, ["SPELL_PERIODIC_HEAL"] = true};
+local playerID, petID = UnitGUID('player');
+
+local Report = Reports:NewReport(REPORT_NAME, {
+	type = "data source",
+	text = REPORT_NAME .. " Info",
+	icon = [[Interface\Addons\SVUI_!Core\assets\icons\SVUI]],
+});
+
+Report.events = {"PLAYER_ENTERING_WORLD", "COMBAT_LOG_EVENT_UNFILTERED", "PLAYER_LEAVE_COMBAT", "PLAYER_REGEN_DISABLED", "UNIT_PET"};
+
+Report.OnInit = function(self)
+	playerID = UnitGUID('player')
+	petID = UnitGUID("pet")
+
+	if(not self.InnerData) then
+		self.InnerData = {}
+	end
+
+	self.InnerData.thistime = 0
+	self.InnerData.lasttime = 0
+	self.InnerData.totaltime = 0
+	self.InnerData.lastamount = 0
+	self.InnerData.totalamount = 0
+	self.InnerData.overamount = 0
+end
+
+Report.OnEvent = function(self, event, ...)
+	local data = self.InnerData
+	if event == "PLAYER_ENTERING_WORLD" then
+		playerID = UnitGUID('player')
+	elseif event == 'PLAYER_REGEN_DISABLED' or event == "PLAYER_LEAVE_COMBAT" then
+		local now = time()
+		if now - data.lasttime > 20 then --time since the last segment
+			data.thistime = 0
+			data.totaltime = 0
+			data.totalamount = 0
+			data.lastamount = 0
+			data.overamount = 0
+		end
+		data.lasttime = now
+	elseif event == 'COMBAT_LOG_EVENT_UNFILTERED' then
+		local newTime, event, _, srcGUID, _, _, _, _, _, _, _, _, _, test, lastHealAmount, overHeal = ...
+		if not PlayerEvents[event] then return end
+		if(srcGUID == playerID or srcGUID == petID) then
+			if data.thistime == 0 then data.thistime = newTime end
+			data.lasttime = data.thistime
+			data.totaltime = newTime - data.thistime
+			data.lastamount = data.lastamount + (lastHealAmount - overHeal)
+			data.totalamount = data.totalamount + data.lastamount
+			data.overamount = data.overamount + overHeal
+		end
+	elseif event == UNIT_PET then
+		data.petID = UnitGUID("pet")
+	end
+
+	if data.totalamount == 0 or data.totaltime == 0 then
+		self.text:SetText(TEXT_PATTERN2:format(L["HPS"], "..PAUSED"))
+		self.TText = "No Healing Done"
+		self.TText2 = "Surely there is someone \nwith an ouchie somewhere!"
+	else
+		local HPS = (data.totalamount) / (data.totaltime)
+		self.text:SetFormattedText(TEXT_PATTERN1, HEX_COLOR, HPS)
+		self.TText = "HPS:"
+		self.TText2 = HPS
+	end
+end
+
+Report.OnClick = function(self, button)
+	local data = self.InnerData
+	data.thistime = 0
+	data.totaltime = 0
+	data.totalamount = 0
+	data.lastamount = 0
+	if data.totalamount == 0 or data.totaltime == 0 then
+		self.text:SetText(TEXT_PATTERN2:format(L["HPS"], "..PAUSED"))
+		self.TText = "No Healing Done"
+		self.TText2 = "Surely there is someone \nwith an ouchie somewhere!"
+	else
+		local HPS = (data.totalamount) / (data.totaltime)
+		self.text:SetFormattedText(TEXT_PATTERN1, HEX_COLOR, HPS)
+		self.TText = "HPS:"
+		self.TText2 = HPS
+	end
+end
+
+Report.OnEnter = function(self)
+	Reports:SetDataTip(self)
+	Reports.ToolTip:AddDoubleLine("Healing Total:", self.InnerData.totalamount, 1, 1, 1)
+	Reports.ToolTip:AddDoubleLine("OverHealing Total:", self.InnerData.overamount, 1, 1, 1)
+	Reports.ToolTip:AddLine(" ", 1, 1, 1)
+	Reports.ToolTip:AddDoubleLine(self.TText, self.TText2, 1, 1, 1)
+	Reports.ToolTip:AddLine(" ", 1, 1, 1)
+	Reports.ToolTip:AddDoubleLine("[Click]", "Clear HPS", 0,1,0, 0.5,1,0.5)
+	Reports:ShowDataTip(true)
+end
\ No newline at end of file
diff --git a/SVUI_!Core/system/_reports/reputation.lua b/SVUI_!Core/system/_reports/reputation.lua
new file mode 100644
index 0000000..4cfac70
--- /dev/null
+++ b/SVUI_!Core/system/_reports/reputation.lua
@@ -0,0 +1,235 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+
+local select 	= _G.select;
+local table     = _G.table;
+local twipe     = table.wipe;
+local tsort     = table.sort;
+--[[ STRING METHODS ]]--
+local format, gsub = string.format, string.gsub;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...)
+local L = SV.L;
+local Reports = SV.Reports;
+--[[
+##########################################################
+REPUTATION STATS
+##########################################################
+]]--
+local HEX_COLOR = "22FFFF";
+local TEXT_PATTERN = "|cff22EF5F%s|r|cff888888 - [|r%d%%|cff888888]|r";
+local standingName = {
+	[1] = "Hated",
+	[2] = "Hostile",
+	[3] = "Unfriendly",
+	[4] = "Neutral",
+	[5] = "Friendly",
+	[6] = "Honored",
+	[7] = "Revered",
+	[8] = "Exalted"
+}
+
+local function TruncateString(value)
+    if value >= 1e9 then
+        return ("%.1fb"):format(value/1e9):gsub("%.?0+([kmb])$","%1")
+    elseif value >= 1e6 then
+        return ("%.1fm"):format(value/1e6):gsub("%.?0+([kmb])$","%1")
+    elseif value >= 1e3 or value <= -1e3 then
+        return ("%.1fk"):format(value/1e3):gsub("%.?0+([kmb])$","%1")
+    else
+        return value
+    end
+end
+
+local sort_menu_fn = function(a,b) return a.text < b.text end;
+
+local function CacheRepData(data)
+	local count = 1;
+	local savedCount = #data;
+	local totalFactions = GetNumFactions();
+	local maxCount = totalFactions;
+	if(savedCount > totalFactions) then maxCount = savedCount; end
+	for i=1, maxCount do
+		if(i <= totalFactions) then
+			local factionName, description, standingID, barMin, barMax, barValue, _, _, _, _, hasRep, isWatched, isChild = GetFactionInfo(i)
+			if(standingID) then
+				local fn = function()
+					local active = GetWatchedFactionInfo()
+					if factionName ~= active then
+						SetWatchedFactionIndex(i)
+					end
+				end
+				data[count] = {text = factionName, func = fn};
+				count=count+1;
+			end
+		else
+			data[count] = nil;
+			count=count+1;
+		end
+	end
+	tsort(data, sort_menu_fn)
+end
+--[[
+##########################################################
+STANDARD TYPE
+##########################################################
+]]--
+local REPORT_NAME = "Reputation";
+local Report = Reports:NewReport(REPORT_NAME, {
+	type = "data source",
+	text = REPORT_NAME .. " Info",
+	icon = [[Interface\Addons\SVUI_!Core\assets\icons\SVUI]]
+});
+
+Report.events = {"PLAYER_ENTERING_WORLD", "UPDATE_FACTION"};
+
+Report.OnEvent = function(self, event, ...)
+	if self.barframe:IsShown()then
+		self.text:SetAllPoints(self)
+		self.text:SetJustifyH("CENTER")
+		self.barframe:Hide()
+		self.text:SetAlpha(1)
+		self.text:SetShadowOffset(2, -4)
+	end
+	local ID = 100
+	local friendText
+	local name, reaction, min, max, value = GetWatchedFactionInfo()
+	local numFactions = GetNumFactions();
+	if not name then
+		self.text:SetText("No watched factions")
+	else
+		for i=1, numFactions do
+			local factionName, description, standingID, barMin, barMax, barValue, _, _, _, _, hasRep, isWatched, isChild = GetFactionInfo(i);
+			local friendID, friendRep, friendMaxRep, _, _, _, friendTextLevel = GetFriendshipReputation(isChild);
+			if(not factionName or (name == "No watched factions") or (name == factionName)) then
+				if friendID ~= nil then
+					friendText = friendTextLevel
+				else
+					ID = standingID
+				end
+			end
+		end
+		friendText = friendText or _G["FACTION_STANDING_LABEL"..ID] or " ";
+		self.text:SetFormattedText(TEXT_PATTERN , friendText, ((value - min) / (max - min) * 100))
+	end
+end
+
+Report.OnClick = function(self, button)
+	CacheRepData(self.InnerData)
+	SV.Dropdown:Open(self, self.InnerData, "Select Faction")
+end
+
+Report.OnEnter = function(self)
+	Reports:SetDataTip(self)
+	local name, reaction, min, max, value, factionID = GetWatchedFactionInfo()
+	local friendID, _, _, _, _, _, friendTextLevel = GetFriendshipReputation(factionID);
+	if not name then
+		Reports.ToolTip:AddLine("No Watched Factions")
+	else
+		Reports.ToolTip:AddLine(name)
+		Reports.ToolTip:AddLine(' ')
+		Reports.ToolTip:AddDoubleLine(STANDING..':', friendID and friendTextLevel or _G['FACTION_STANDING_LABEL'..reaction], 1, 1, 1)
+		Reports.ToolTip:AddDoubleLine(REPUTATION..':', format('%d / %d (%d%%)', value - min, max - min, (value - min) / (max - min) * 100), 1, 1, 1)
+	end
+	Reports.ToolTip:AddLine(" ", 1, 1, 1)
+	Reports.ToolTip:AddDoubleLine("[Click]", "Change Watched Faction", 0,1,0, 0.5,1,0.5)
+	Reports:ShowDataTip(true)
+end
+
+Report.OnInit = function(self)
+	if(not self.InnerData) then
+		self.InnerData = {}
+	end
+	CacheRepData(self.InnerData)
+end
+--[[
+##########################################################
+BAR TYPE
+##########################################################
+]]--
+local BAR_NAME = "Reputation Bar";
+local ReportBar = Reports:NewReport(BAR_NAME, {
+	type = "data source",
+	text = BAR_NAME,
+	icon = [[Interface\Addons\SVUI_!Core\assets\icons\SVUI]]
+});
+
+ReportBar.events = {"PLAYER_ENTERING_WORLD", "UPDATE_FACTION"};
+
+ReportBar.OnEvent = function(self, event, ...)
+	if not self.barframe:IsShown()then
+		self.barframe:Show()
+		self.barframe.icon.texture:SetTexture(SV.media.dock.reputationLabel)
+		self.text:SetAlpha(1)
+		self.text:SetShadowOffset(1, -2)
+	end
+	local bar = self.barframe.bar;
+	local name, reaction, min, max, value = GetWatchedFactionInfo()
+	local numFactions = GetNumFactions();
+	if not name then
+		bar:SetStatusBarColor(0,0,0)
+		bar:SetMinMaxValues(0,1)
+		bar:SetValue(0)
+		self.text:SetText("No Faction")
+	else
+		for i=1, numFactions do
+			local factionName, description, standingID, barMin, barMax, barValue, _, _, _, _, hasRep, isWatched, isChild = GetFactionInfo(i);
+			if(isChild) then
+				local friendID, friendRep, friendMaxRep, _, _, _, friendTextLevel, friendThreshold, nextFriendThreshold = GetFriendshipReputation(isChild);
+				if friendID ~= nil then
+					min = friendThreshold
+					max = friendMaxRep
+					value = friendRep
+				end
+			end
+		end
+		local txt = standingName[reaction];
+		local color = FACTION_BAR_COLORS[reaction]
+		bar:SetStatusBarColor(color.r, color.g, color.b)
+		bar:SetMinMaxValues(min, max)
+		bar:SetValue(value)
+		self.text:SetText(txt)
+	end
+end
+
+ReportBar.OnClick = function(self, button)
+	CacheRepData(self.InnerData)
+	SV.Dropdown:Open(self, self.InnerData, "Select Faction")
+end
+
+ReportBar.OnEnter = function(self)
+	Reports:SetDataTip(self)
+	local name, reaction, min, max, value, factionID = GetWatchedFactionInfo()
+	local friendID, _, _, _, _, _, friendTextLevel = GetFriendshipReputation(factionID);
+	if not name then
+		Reports.ToolTip:AddLine("No Watched Factions")
+	else
+		Reports.ToolTip:AddLine(name)
+		Reports.ToolTip:AddLine(' ')
+		Reports.ToolTip:AddDoubleLine(STANDING..':', friendID and friendTextLevel or _G['FACTION_STANDING_LABEL'..reaction], 1, 1, 1)
+		Reports.ToolTip:AddDoubleLine(REPUTATION..':', format('%d / %d (%d%%)', value - min, max - min, (value - min) / (max - min) * 100), 1, 1, 1)
+	end
+	Reports.ToolTip:AddLine(" ", 1, 1, 1)
+	Reports.ToolTip:AddDoubleLine("[Click]", "Change Watched Faction", 0,1,0, 0.5,1,0.5)
+	Reports:ShowDataTip(true)
+end
+
+ReportBar.OnInit = function(self)
+	if(not self.InnerData) then
+		self.InnerData = {}
+	end
+	CacheRepData(self.InnerData)
+end
diff --git a/SVUI_!Core/system/_reports/system.lua b/SVUI_!Core/system/_reports/system.lua
new file mode 100644
index 0000000..e110642
--- /dev/null
+++ b/SVUI_!Core/system/_reports/system.lua
@@ -0,0 +1,209 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+
+local select 	= _G.select;
+local collectgarbage    = _G.collectgarbage;
+local string 	= _G.string;
+local math 		= _G.math;
+local table 	= _G.table;
+--[[ STRING METHODS ]]--
+local format = string.format;
+--[[ MATH METHODS ]]--
+local floor = math.floor
+--[[ TABLE METHODS ]]--
+local tsort = table.sort;
+local IsShiftKeyDown        = _G.IsShiftKeyDown;
+local IsAddOnLoaded         = _G.IsAddOnLoaded;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...)
+local L = SV.L;
+local Reports = SV.Reports;
+--[[
+##########################################################
+SYSTEM STATS (Credit: Elv)
+##########################################################
+]]--
+local REPORT_NAME = "System";
+local HEX_COLOR = "22FFFF";
+local TEXT_PATTERN = "|cff%s%s|r";
+local int, int2 = 6, 5
+local statusColors = {
+	"|cff0CD809",
+	"|cffE8DA0F",
+	"|cffFF9000",
+	"|cffD80909"
+}
+
+local enteredFrame = false;
+local bandwidthString = "%.2f Mbps"
+local percentageString = "%.2f%%"
+local homeLatencyString = "%d ms"
+local kiloByteString = "%d kb"
+local megaByteString = "%.2f mb"
+local totalMemory = 0
+local bandwidth = 0
+local memoryTable = {}
+local cpuTable = {}
+
+local function formatMem(memory)
+	local mult = 10^1
+	if memory > 999 then
+		local mem = ((memory/1024) * mult) / mult
+		return megaByteString:format(mem)
+	else
+		local mem = (memory * mult) / mult
+		return kiloByteString:format(mem)
+	end
+end
+
+local function RebuildAddonList()
+	local addOnCount = GetNumAddOns()
+	if (addOnCount == #memoryTable) then return end
+	memoryTable = {}
+	cpuTable = {}
+	for i = 1, addOnCount do
+		local addonName = select(2, GetAddOnInfo(i))
+		memoryTable[i] = { i, addonName, 0, IsAddOnLoaded(i) }
+		cpuTable[i] = { i, addonName, 0, IsAddOnLoaded(i) }
+	end
+end
+
+local function UpdateMemory()
+	UpdateAddOnMemoryUsage()
+	totalMemory = 0
+	for i = 1, #memoryTable do
+		memoryTable[i][3] = GetAddOnMemoryUsage(memoryTable[i][1])
+		totalMemory = totalMemory + memoryTable[i][3]
+	end
+	tsort(memoryTable, function(a, b)
+		if a and b then
+			return a[3] > b[3]
+		end
+	end)
+end
+
+local function UpdateCPU()
+	UpdateAddOnCPUUsage()
+	local addonCPU = 0
+	local totalCPU = 0
+	for i = 1, #cpuTable do
+		addonCPU = GetAddOnCPUUsage(cpuTable[i][1])
+		cpuTable[i][3] = addonCPU
+		totalCPU = totalCPU + addonCPU
+	end
+
+	tsort(cpuTable, function(a, b)
+		if a and b then
+			return a[3] > b[3]
+		end
+	end)
+
+	return totalCPU
+end
+
+local Report = Reports:NewReport(REPORT_NAME, {
+	type = "data source",
+	text = REPORT_NAME .. " Info",
+	icon = [[Interface\Addons\SVUI_!Core\assets\icons\SVUI]]
+});
+
+Report.OnClick = function(self, button)
+	collectgarbage("collect");
+	ResetCPUUsage();
+end
+
+Report.OnEnter = function(self)
+	enteredFrame = true;
+	local cpuProfiling = false
+	Reports:SetDataTip(self)
+
+	UpdateMemory()
+	bandwidth = GetAvailableBandwidth()
+
+	Reports.ToolTip:AddDoubleLine(L['Home Latency:'], homeLatencyString:format(select(3, GetNetStats())), 0.69, 0.31, 0.31,0.84, 0.75, 0.65)
+
+	if bandwidth ~= 0 then
+		local percent = GetDownloadedPercentage()
+		percent = percent * 100
+		Reports.ToolTip:AddDoubleLine(L['Bandwidth'] , bandwidthString:format(bandwidth), 0.69, 0.31, 0.31,0.84, 0.75, 0.65)
+		Reports.ToolTip:AddDoubleLine(L['Download'] , percentageString:format(percent), 0.69, 0.31, 0.31, 0.84, 0.75, 0.65)
+		Reports.ToolTip:AddLine(" ")
+	end
+
+	local totalCPU = nil
+	Reports.ToolTip:AddDoubleLine(L['Total Memory:'], formatMem(totalMemory), 0.69, 0.31, 0.31,0.84, 0.75, 0.65)
+	if cpuProfiling then
+		totalCPU = UpdateCPU()
+		Reports.ToolTip:AddDoubleLine(L['Total CPU:'], homeLatencyString:format(totalCPU), 0.69, 0.31, 0.31,0.84, 0.75, 0.65)
+	end
+
+	local red, green
+	if IsShiftKeyDown() or not cpuProfiling then
+		Reports.ToolTip:AddLine(" ")
+		for i = 1, #memoryTable do
+			if (memoryTable[i][4]) then
+				red = memoryTable[i][3] / totalMemory
+				green = 1 - red
+				Reports.ToolTip:AddDoubleLine(memoryTable[i][2], formatMem(memoryTable[i][3]), 1, 1, 1, red, green + .5, 0)
+			end
+		end
+	end
+
+	if cpuProfiling and not IsShiftKeyDown() then
+		Reports.ToolTip:AddLine(" ")
+		for i = 1, #cpuTable do
+			if (cpuTable[i][4]) then
+				red = cpuTable[i][3] / totalCPU
+				green = 1 - red
+				Reports.ToolTip:AddDoubleLine(cpuTable[i][2], homeLatencyString:format(cpuTable[i][3]), 1, 1, 1, red, green + .5, 0)
+			end
+		end
+
+		Reports.ToolTip:AddLine(" ")
+		Reports.ToolTip:AddLine(L['(Hold Shift) Memory Usage'])
+	end
+
+	Reports.ToolTip:Show()
+end
+
+Report.OnLeave = function(self, button)
+	enteredFrame = false;
+	Reports.ToolTip:Hide()
+end
+
+Report.OnUpdate = function(self, elapsed)
+	int = int - elapsed
+	int2 = int2 - elapsed
+
+	if int < 0 then
+		RebuildAddonList()
+		int = 10
+	end
+	if int2 < 0 then
+		local framerate = floor(GetFramerate())
+		local latency = select(4, GetNetStats())
+
+		self.text:SetFormattedText("FPS: %s%d|r MS: %s%d|r",
+			statusColors[framerate >= 30 and 1 or (framerate >= 20 and framerate < 30) and 2 or (framerate >= 10 and framerate < 20) and 3 or 4],
+			framerate,
+			statusColors[latency < 150 and 1 or (latency >= 150 and latency < 300) and 2 or (latency >= 300 and latency < 500) and 3 or 4],
+			latency)
+		int2 = 1
+		if enteredFrame then
+			Report.OnEnter(self)
+		end
+	end
+end
diff --git a/SVUI_!Core/system/_reports/template.lua b/SVUI_!Core/system/_reports/template.lua
new file mode 100644
index 0000000..9edd335
--- /dev/null
+++ b/SVUI_!Core/system/_reports/template.lua
@@ -0,0 +1,91 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local ipairs 	= _G.ipairs;
+local type 		= _G.type;
+local error 	= _G.error;
+local pcall 	= _G.pcall;
+local assert 	= _G.assert;
+local tostring 	= _G.tostring;
+local tonumber 	= _G.tonumber;
+local string 	= _G.string;
+local math 		= _G.math;
+local table 	= _G.table;
+--[[ STRING METHODS ]]--
+local lower, upper = string.lower, string.upper;
+local find, format, len, split = string.find, string.format, string.len, string.split;
+local match, sub, join = string.match, string.sub, string.join;
+local gmatch, gsub = string.gmatch, string.gsub;
+--[[ MATH METHODS ]]--
+local abs, ceil, floor, round = math.abs, math.ceil, math.floor, math.round;  -- Basic
+--[[ TABLE METHODS ]]--
+local twipe, tsort = table.wipe, table.sort;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...)
+local L = SV.L
+local Reports = SV.Reports;
+--[[
+##########################################################
+REPORT TEMPLATE
+##########################################################
+]]--
+local REPORT_NAME = "";
+local HEX_COLOR = "22FFFF";
+local TEXT_PATTERN = "|cff%s%s|r";
+--SV.media.color.green
+--SV.media.color.normal
+--r, g, b = 0.8, 0.8, 0.8
+--local c = SV.media.color.green
+--r, g, b = c[1], c[2], c[3]
+local Report = Reports:NewReport(REPORT_NAME, {
+	type = "data source",
+	text = REPORT_NAME .. " Info",
+	icon = [[Interface\Addons\SVUI_!Core\assets\icons\SVUI]]
+});
+
+Report.events = {"PLAYER_ENTERING_WORLD"};
+
+Report.OnInit = function(self)
+	if(not self.InnerData) then
+		self.InnerData = {}
+	end
+	-- DO STUFF
+end
+
+Report.OnEvent = function(self, event, ...)
+	-- DO STUFF
+	self.text:SetFormattedText(TEXT_PATTERN, HEX_COLOR, REPORT_NAME)
+end
+
+Report.OnClick = function(self, button)
+	-- DO STUFF
+end
+
+Report.OnEnter = function(self)
+	Reports:SetDataTip(self)
+	-- DO STUFF
+	Reports:ShowDataTip()
+end
+
+Report.OnLeave = function(self, button)
+	-- DO STUFF
+end
+
+Report.OnUpdate = function(self, button)
+	-- DO STUFF
+end
diff --git a/SVUI_!Core/system/_reports/time.lua b/SVUI_!Core/system/_reports/time.lua
new file mode 100644
index 0000000..973ad14
--- /dev/null
+++ b/SVUI_!Core/system/_reports/time.lua
@@ -0,0 +1,221 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+
+local select 	= _G.select;
+local type 		= _G.type;
+local string 	= _G.string;
+local math 		= _G.math;
+--[[ STRING METHODS ]]--
+local format, join = string.format, string.join;
+--[[ MATH METHODS ]]--
+local floor = math.floor;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...)
+local L = SV.L
+local Reports = SV.Reports;
+--[[
+##########################################################
+TIME STATS (Credit: Elv)
+##########################################################
+]]--
+local APM = { TIMEMANAGER_PM, TIMEMANAGER_AM }
+local TEXT_PATTERN1 = "%02d|cff22CFFF:|r%02d";
+local TEXT_PATTERN2 = "%d|cff22CFFF:|r%02d|cff22CFFF %s|r";
+local europeDisplayFormat_nocolor = join("", "%02d", ":|r%02d")
+local ukDisplayFormat_nocolor = join("", "", "%d", ":|r%02d", " %s|r")
+local timerLongFormat = "%d:%02d:%02d"
+local timerShortFormat = "%d:%02d"
+local lockoutInfoFormat = "%s%s |cffaaaaaa(%s, %s/%s)"
+local lockoutInfoFormatNoEnc = "%s%s |cffaaaaaa(%s)"
+local formatBattleGroundInfo = "%s: "
+local curHr, curMin, curAmPm
+local enteredFrame = false;
+local date = _G.date
+local localizedName, isActive, canQueue, startTime, canEnter, _
+local name, instanceID, reset, difficultyId, locked, extended, isRaid, maxPlayers, difficulty, numEncounters, encounterProgress
+
+local function ConvertTime(h, m)
+	local AmPm
+	if SV.db.Reports.time24 == true then
+		return h, m, -1
+	else
+		if h >= 12 then
+			if h > 12 then h = h - 12 end
+			AmPm = 1
+		else
+			if h == 0 then h = 12 end
+			AmPm = 2
+		end
+	end
+	return h, m, AmPm
+end
+
+local function CalculateTimeValues(tooltip)
+	if (tooltip and SV.db.Reports.localtime) or (not tooltip and not SV.db.Reports.localtime) then
+		return ConvertTime(GetGameTime())
+	else
+		local dateTable = date("*t")
+		return ConvertTime(dateTable["hour"], dateTable["min"])
+	end
+end
+--[[
+##########################################################
+REPORT TEMPLATE
+##########################################################
+]]--
+local REPORT_NAME = "Time";
+local HEX_COLOR = "22FFFF";
+
+local Report = Reports:NewReport(REPORT_NAME, {
+	type = "data source",
+	text = REPORT_NAME .. " Info",
+	icon = [[Interface\Addons\SVUI_!Core\assets\icons\SVUI]]
+});
+
+Report.events = {"UPDATE_INSTANCE_INFO"};
+
+Report.OnEvent = function(self, event, ...)
+	if event == "UPDATE_INSTANCE_INFO" and enteredFrame then
+		RequestRaidInfo()
+	end
+end
+
+Report.OnClick = function(self, button)
+	GameTimeFrame:Click();
+end
+
+Report.OnEnter = function(self)
+	Reports:SetDataTip(self)
+
+	if(not enteredFrame) then
+		enteredFrame = true;
+		RequestRaidInfo()
+	end
+
+	Reports.ToolTip:AddLine(VOICE_CHAT_BATTLEGROUND);
+	for i = 1, GetNumWorldPVPAreas() do
+		_, localizedName, isActive, canQueue, startTime, canEnter = GetWorldPVPAreaInfo(i)
+		if canEnter then
+			if isActive then
+				startTime = WINTERGRASP_IN_PROGRESS
+			elseif startTime == nil then
+				startTime = QUEUE_TIME_UNAVAILABLE
+			else
+				startTime = SecondsToTime(startTime, false, nil, 3)
+			end
+			Reports.ToolTip:AddDoubleLine(format(formatBattleGroundInfo, localizedName), startTime, 1, 1, 1, 0.8, 0.8, 0.8)
+		end
+	end
+
+	local oneraid;
+	local r, g, b = 0.8, 0.8, 0.8
+	for i = 1, GetNumSavedInstances() do
+		name, _, reset, difficultyId, locked, extended, _, isRaid, maxPlayers, difficulty, numEncounters, encounterProgress  = GetSavedInstanceInfo(i)
+		if isRaid and (locked or extended) and name then
+			if not oneraid then
+				Reports.ToolTip:AddLine(" ")
+				Reports.ToolTip:AddLine(L["Saved Raid(s)"])
+				oneraid = true
+			end
+			if extended then
+				local c = SV.media.color.green
+				r, g, b = c[1], c[2], c[3]
+			else
+				r, g, b = 0.8, 0.8, 0.8
+			end
+			local _, _, isHeroic, isChallengeMode, displayHeroic, displayMythic = GetDifficultyInfo(difficultyId)
+			local difficultyPrefix = "N";
+			if ( isHeroic or isChallengeMode or displayMythic or displayHeroic ) then
+				difficultyPrefix = "H"
+			end
+			if (numEncounters and numEncounters > 0) and (encounterProgress and encounterProgress > 0) then
+				Reports.ToolTip:AddDoubleLine(format(lockoutInfoFormat, maxPlayers, difficultyPrefix, name, encounterProgress, numEncounters), SecondsToTime(reset, false, nil, 3), 1, 1, 1, r, g, b)
+			else
+				Reports.ToolTip:AddDoubleLine(format(lockoutInfoFormatNoEnc, maxPlayers, difficultyPrefix, name), SecondsToTime(reset, false, nil, 3), 1, 1, 1, r, g, b)
+			end
+		end
+	end
+
+	local addedLine = false
+	for i = 1, GetNumSavedWorldBosses() do
+		name, instanceID, reset = GetSavedWorldBossInfo(i)
+		if(reset) then
+			if(not addedLine) then
+				Reports.ToolTip:AddLine(' ')
+				Reports.ToolTip:AddLine(RAID_INFO_WORLD_BOSS.."(s)")
+				addedLine = true
+			end
+			Reports.ToolTip:AddDoubleLine(name, SecondsToTime(reset, true, nil, 3), 1, 1, 1, 0.8, 0.8, 0.8)
+		end
+	end
+
+	local timeText
+	local Hr, Min, AmPm = CalculateTimeValues(true)
+
+	Reports.ToolTip:AddLine(" ")
+	if AmPm == -1 then
+		Reports.ToolTip:AddDoubleLine(SV.db.Reports.localtime and TIMEMANAGER_TOOLTIP_REALMTIME or TIMEMANAGER_TOOLTIP_LOCALTIME,
+			format(europeDisplayFormat_nocolor, Hr, Min), 1, 1, 1, 0.8, 0.8, 0.8)
+	else
+		Reports.ToolTip:AddDoubleLine(SV.db.Reports.localtime and TIMEMANAGER_TOOLTIP_REALMTIME or TIMEMANAGER_TOOLTIP_LOCALTIME,
+			format(ukDisplayFormat_nocolor, Hr, Min, APM[AmPm]), 1, 1, 1, 0.8, 0.8, 0.8)
+	end
+
+	Reports.ToolTip:Show()
+end
+
+Report.OnLeave = function(self, button)
+	Reports.ToolTip:Hide();
+	enteredFrame = false;
+end
+
+local int = 3
+local Time_OnUpdate = function(self, t)
+	int = int - t
+
+	if int > 0 then return end
+
+	if GameTimeFrame.flashInvite then
+		SV.Animate:Flash(self, 0.53)
+	else
+		SV.Animate:StopFlash(self)
+	end
+
+	if enteredFrame then
+		Report.OnEnter(self)
+	end
+
+	local Hr, Min, AmPm = CalculateTimeValues(false)
+
+	-- no update quick exit
+	if (Hr == curHr and Min == curMin and AmPm == curAmPm) and not (int < -15000) then
+		int = 5
+		return
+	end
+
+	curHr = Hr
+	curMin = Min
+	curAmPm = AmPm
+
+	if AmPm == -1 then
+		self.text:SetFormattedText(TEXT_PATTERN1, Hr, Min)
+	else
+		self.text:SetFormattedText(TEXT_PATTERN2, Hr, Min, APM[AmPm])
+	end
+	int = 5
+end
+
+Report.OnUpdate = Time_OnUpdate
diff --git a/SVUI_!Core/system/_reports/tokens.lua b/SVUI_!Core/system/_reports/tokens.lua
new file mode 100644
index 0000000..1621934
--- /dev/null
+++ b/SVUI_!Core/system/_reports/tokens.lua
@@ -0,0 +1,265 @@
+--[[
+##############################################################################
+S V U I By: Failcoder
+##############################################################################
+
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+
+local select = _G.select;
+local table = _G.table;
+local twipe = table.wipe;
+local tsort = table.sort;
+local GetCurrencyInfo = _G.GetCurrencyInfo;
+local GetNumWatchedTokens = _G.GetNumWatchedTokens;
+local GetBackpackCurrencyInfo = _G.GetBackpackCurrencyInfo;
+local GetProfessions = _G.GetProfessions;
+local IsLoggedIn = _G.IsLoggedIn;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...)
+local L = SV.L;
+local Reports = SV.Reports;
+--[[
+##########################################################
+GOLD STATS
+##########################################################
+]]--
+local REPORT_NAME = "Tokens";
+local HEX_COLOR = "22FFFF";
+local TEXT_PATTERN = "\124T%s:12\124t %s";
+local playerName = UnitName("player");
+local playerRealm = GetRealmName();
+
+local sort_menu_fn = function(a,b) return a.text < b.text end;
+
+local Tokens_OnEvent = function(self, event, ...)
+if(not IsLoggedIn() or (not self)) then return end
+local id = self.TokenKey or 738;
+local _, current, tex = GetCurrencyInfo(id)
+local currentText = TEXT_PATTERN:format(tex, current);
+self.text:SetText(currentText)
+end
+
+local function AddToTokenMenu(self, id, key)
+local itemName, _, tex, _, _, _, _ = GetCurrencyInfo(id)
+local fn = function()
+Reports.Accountant["tokens"][playerName][key] = id;
+self.TokenKey = id
+Tokens_OnEvent(self)
+end
+local nextIndex = #self.InnerData+1;
+self.InnerData[nextIndex] = {text = itemName, icon = "\124T"..tex..":12\124t ", func = fn};
+end
+
+local function CacheTokenData(self)
+twipe(self.InnerData);
+local prof1, prof2, archaeology, _, cooking = GetProfessions();
+local key = self:GetName();
+if archaeology then
+AddToTokenMenu(self, 398, key)
+AddToTokenMenu(self, 384, key)
+AddToTokenMenu(self, 393, key)
+AddToTokenMenu(self, 677, key)
+AddToTokenMenu(self, 400, key)
+AddToTokenMenu(self, 394, key)
+AddToTokenMenu(self, 397, key)
+AddToTokenMenu(self, 676, key)
+AddToTokenMenu(self, 401, key)
+AddToTokenMenu(self, 385, key)
+AddToTokenMenu(self, 399, key)
+AddToTokenMenu(self, 821, key)
+AddToTokenMenu(self, 829, key)
+AddToTokenMenu(self, 944, key)
+end
+if cooking then
+AddToTokenMenu(self, 81, key)
+AddToTokenMenu(self, 402, key)
+end
+if(prof1 == 9 or prof2 == 9) then
+AddToTokenMenu(self, 61, key)
+AddToTokenMenu(self, 361, key)
+AddToTokenMenu(self, 698, key)
+
+AddToTokenMenu(self, 910, key)
+AddToTokenMenu(self, 999, key)
+AddToTokenMenu(self, 1020, key)
+AddToTokenMenu(self, 1008, key)
+AddToTokenMenu(self, 1017, key)
+end
+AddToTokenMenu(self, 1166, key)
+AddToTokenMenu(self, 1129, key)
+AddToTokenMenu(self, 994, key)
+AddToTokenMenu(self, 697, key)
+AddToTokenMenu(self, 738, key)
+AddToTokenMenu(self, 615, key)
+AddToTokenMenu(self, 614, key)
+AddToTokenMenu(self, 395, key)
+AddToTokenMenu(self, 396, key)
+AddToTokenMenu(self, 390, key)
+AddToTokenMenu(self, 392, key)
+AddToTokenMenu(self, 391, key)
+AddToTokenMenu(self, 241, key)
+AddToTokenMenu(self, 416, key)
+AddToTokenMenu(self, 515, key)
+AddToTokenMenu(self, 776, key)
+AddToTokenMenu(self, 777, key)
+AddToTokenMenu(self, 789, key)
+AddToTokenMenu(self, 823, key)
+AddToTokenMenu(self, 824, key)
+AddToTokenMenu(self, 1101, key)
+
+tsort(self.InnerData, sort_menu_fn)
+end
+
+local function TokenInquiry(id, weekly, capped)
+--name, amount, texturePath, earnedThisWeek, weeklyMax, totalMax, isDiscovered = GetCurrencyInfo(id)
+local name, amount, tex, week, weekmax, maxed, discovered = GetCurrencyInfo(id)
+local r, g, b = 1, 1, 1
+for i = 1, GetNumWatchedTokens() do
+local _, _, _, itemID = GetBackpackCurrencyInfo(i)
+if id == itemID then r, g, b = 0.23, 0.88, 0.27 end
+end
+local texStr = ("\124T%s:12\124t %s"):format(tex, name)
+local altStr = ""
+if weekly then
+if discovered then
+if id == 390 then
+local pointsThisWeek, maxPointsThisWeek = GetPVPRewards();
+altStr = ("Current: %d | Weekly: %d / %d"):format(amount, pointsThisWeek, maxPointsThisWeek)
+else
+altStr = ("Current: %d / %d | Weekly: %d / %d"):format(amount, maxed, week, weekmax)
+end
+Reports.ToolTip:AddDoubleLine(texStr, altStr, r, g, b, r, g, b)
+end
+elseif capped then
+if id == 392 or id == 395 then maxed = 4000 end
+if id == 396 then maxed = 3000 end
+if id == 1129 then maxed = 10 end
+if discovered then
+altStr = ("%d / %d"):format(amount, maxed)
+Reports.ToolTip:AddDoubleLine(texStr, altStr, r, g, b, r, g, b)
+end
+else
+if discovered then
+Reports.ToolTip:AddDoubleLine(texStr, amount, r, g, b, r, g, b)
+end
+end
+end
+--[[
+##########################################################
+REPORT TEMPLATE
+##########################################################
+]]--
+local Report = Reports:NewReport(REPORT_NAME, {
+type = "data source",
+text = REPORT_NAME .. " Info",
+icon = [[Interface\Addons\SVUI_!Core\assets\icons\SVUI]]
+});
+
+Report.events = {"PLAYER_ENTERING_WORLD", "PLAYER_MONEY", "CURRENCY_DISPLAY_UPDATE"};
+
+Report.OnEvent = Tokens_OnEvent;
+
+Report.OnClick = function(self, button)
+CacheTokenData(self);
+SV.Dropdown:Open(self, self.InnerData, "Select Currency", 200)
+end
+
+Report.OnEnter = function(self)
+Reports:SetDataTip(self)
+Reports.ToolTip:AddLine(playerName .. "\'s Tokens")
+
+Reports.ToolTip:AddLine(" ")
+Reports.ToolTip:AddLine("Common")
+TokenInquiry(241)
+TokenInquiry(416)
+TokenInquiry(515)
+TokenInquiry(776)
+TokenInquiry(777)
+TokenInquiry(789)
+
+Reports.ToolTip:AddLine(" ")
+Reports.ToolTip:AddLine("Garrison")
+TokenInquiry(823)
+TokenInquiry(824)
+TokenInquiry(1101)
+TokenInquiry(910)
+TokenInquiry(999)
+TokenInquiry(1020)
+TokenInquiry(1008)
+TokenInquiry(1017)
+
+Reports.ToolTip:AddLine(" ")
+Reports.ToolTip:AddLine("Raiding and Dungeons")
+TokenInquiry(1166)
+TokenInquiry(1129, false, true)
+TokenInquiry(994, false, true)
+TokenInquiry(697, false, true)
+TokenInquiry(738)
+TokenInquiry(615)
+TokenInquiry(614)
+TokenInquiry(395, false, true)
+TokenInquiry(396, false, true)
+
+Reports.ToolTip:AddLine(" ")
+Reports.ToolTip:AddLine("PvP")
+TokenInquiry(390, true)
+TokenInquiry(392, false, true)
+TokenInquiry(391)
+
+local prof1, prof2, archaeology, _, cooking = GetProfessions()
+if(archaeology or cooking or prof1 == 9 or prof2 == 9) then
+Reports.ToolTip:AddLine(" ")
+Reports.ToolTip:AddLine("Professions")
+end
+if cooking then
+TokenInquiry(81)
+TokenInquiry(402)
+end
+if(prof1 == 9 or prof2 == 9) then
+TokenInquiry(61)
+TokenInquiry(361)
+TokenInquiry(698)
+end
+if archaeology then
+TokenInquiry(821)
+TokenInquiry(829)
+TokenInquiry(944)
+TokenInquiry(398)
+TokenInquiry(384)
+TokenInquiry(393)
+TokenInquiry(677)
+TokenInquiry(400)
+TokenInquiry(394)
+TokenInquiry(397)
+TokenInquiry(676)
+TokenInquiry(401)
+TokenInquiry(385)
+TokenInquiry(399)
+end
+Reports.ToolTip:AddLine(" ")
+Reports.ToolTip:AddDoubleLine("[Shift + Click]", "Change Watched Token", 0,1,0, 0.5,1,0.5)
+Reports:ShowDataTip(true)
+end
+
+Report.OnInit = function(self)
+if not IsAddOnLoaded("Blizzard_PVPUI") then
+LoadAddOn("Blizzard_PVPUI")
+end
+if(not self.InnerData) then
+self.InnerData = {}
+end
+Reports:SetAccountantData('tokens', 'table', {})
+local key = self:GetName()
+Reports.Accountant["tokens"][playerName][key] = Reports.Accountant["tokens"][playerName][key] or 738;
+self.TokenKey = Reports.Accountant["tokens"][playerName][key]
+CacheTokenData(self);
+end
\ No newline at end of file
diff --git a/SVUI_!Core/system/alerts.lua b/SVUI_!Core/system/alerts.lua
new file mode 100644
index 0000000..faad3f7
--- /dev/null
+++ b/SVUI_!Core/system/alerts.lua
@@ -0,0 +1,1076 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pcall         = _G.pcall;
+local print         = _G.print;
+local ipairs        = _G.ipairs;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local rawset        = _G.rawset;
+local rawget        = _G.rawget;
+local tostring      = _G.tostring;
+local tonumber      = _G.tonumber;
+local tinsert 	= _G.tinsert;
+local string 	= _G.string;
+local math 		= _G.math;
+local table     = _G.table;
+local tContains = _G.tContains
+--[[ STRING METHODS ]]--
+local find, format, len, split = string.find, string.format, string.len, string.split;
+--[[ MATH METHODS ]]--
+local random = math.random;
+local abs, ceil, floor, round, max = math.abs, math.ceil, math.floor, math.round, math.max;
+--[[ TABLE METHODS ]]--
+local tremove, twipe = table.remove, table.wipe;
+
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+local GameTooltip           = _G.GameTooltip;
+local ReloadUI              = _G.ReloadUI;
+local PlaySound             = _G.PlaySound;
+local PlaySoundFile         = _G.PlaySoundFile;
+local RAID_CLASS_COLORS     = _G.RAID_CLASS_COLORS;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...)
+local SVUILib = Librarian("Registry");
+local L = SV.L;
+--[[
+##########################################################
+LOCAL VARS
+##########################################################
+]]--
+local POSITION, ANCHOR_POINT, YOFFSET = "TOP", "BOTTOM", -10
+local FORCE_POSITION = false;
+local ACTIVE_ALERTS, BUFFER = {}, {};
+local NewHook = hooksecurefunc;
+
+local SVUI_AlertFrame = CreateFrame("Frame", "SVUI_AlertFrame", UIParent);
+SVUI_AlertFrame:SetPoint("TOP", SVUI_DockTopCenter, "BOTTOM", 0, -115);
+SVUI_AlertFrame:SetSize(180, 20);
+--[[
+##########################################################
+DEFINITIONS
+##########################################################
+]]--
+SV.SystemAlert["CLIENT_UPDATE_REQUEST"] = {
+	text = L["Detected that your SVUI Config addon is out of date. Update as soon as possible."],
+	button1 = OKAY,
+	OnAccept = SV.fubar,
+	state1 = 1
+};
+
+SV.SystemAlert["CHANGED_MANAGED_UISCALE"] = {
+	text = L["You have changed your UIScale, because you have enabled SVUI managed scaling, we will have to reload the UI to properly align everything."],
+	button1 = OKAY,
+	OnAccept = function() ReloadUI(); end,
+	timeout = 0,
+	whileDead = 1,
+	hideOnEscape = false,
+}
+SV.SystemAlert["TAINT_RL"] = {
+	text = L["SVUI has lost it's damned mind! I need to reload your UI to fix it."],
+	button1 = ACCEPT,
+	button2 = CANCEL,
+	OnAccept = function()ReloadUI()end,
+	timeout = 0,
+	whileDead = 1,
+	hideOnEscape = true
+};
+SV.SystemAlert["RL_CLIENT"] = {
+	text = L["A setting you have changed requires that you reload your User Interface."],
+	button1 = ACCEPT,
+	button2 = CANCEL,
+	OnAccept = function()ReloadUI()end,
+	timeout = 0,
+	whileDead = 1,
+	hideOnEscape = false
+};
+SV.SystemAlert["DISBAND_RAID"] = {
+	text = L["Are you sure you want to disband the group?"],
+	button1 = ACCEPT,
+	button2 = CANCEL,
+	OnAccept = function() SV:DisbandRaidGroup() end,
+	timeout = 0,
+	whileDead = 1,
+};
+SV.SystemAlert["RESETMOVERS_CHECK"] = {
+	text = L["Are you sure you want to reset every mover back to it's default position?"],
+	button1 = ACCEPT,
+	button2 = CANCEL,
+	OnAccept = function(a)SV:ResetUI(true)end,
+	timeout = 0,
+	whileDead = 1
+};
+SV.SystemAlert["RESET_UI_CHECK"] = {
+	text = L["I will attempt to preserve some of your basic settings but no promises. This will clean out everything else. Are you sure you want to reset everything?"],
+	button1 = ACCEPT,
+	button2 = CANCEL,
+	OnAccept = function(a)SV:ResetAllUI(true)end,
+	timeout = 0,
+	whileDead = 1
+};
+SV.SystemAlert["RESETDOCKS_CHECK"] = {
+	text = L["Are you sure you want to reset every dock button back to it's default position?"],
+	button1 = ACCEPT,
+	button2 = CANCEL,
+	OnAccept = function(a)SV.Dock:ResetAllButtons()end,
+	timeout = 0,
+	whileDead = 1
+};
+SV.SystemAlert["CONFIRM_LOOT_DISTRIBUTION"] = {
+	text = CONFIRM_LOOT_DISTRIBUTION,
+	button1 = YES,
+	button2 = NO,
+	timeout = 0,
+	hideOnEscape = 1
+};
+SV.SystemAlert["RESET_PROFILE_PROMPT"] = {
+	text = L["Are you sure you want to reset all the settings on this profile?"],
+	button1 = YES,
+	button2 = NO,
+	timeout = 0,
+	hideOnEscape = 1,
+	OnAccept = function()
+		SVUILib:WipeDatabase()
+		ReloadUI()
+	end
+};
+SV.SystemAlert["COPY_PROFILE_PROMPT"] = {
+	text = L["Are you sure you want to copy all settings from this profile?"],
+	button1 = YES,
+	button2 = NO,
+	timeout = 0,
+	hideOnEscape = 1,
+	OnAccept = SV.fubar
+};
+SV.SystemAlert["IMPORT_PROFILE_PROMPT"] = {
+	text = L["Are you certain that you have pasted the FULL block of encoded text?"],
+	button1 = YES,
+	button2 = NO,
+	timeout = 0,
+	hideOnEscape = 1,
+	OnAccept = SV.fubar
+};
+SV.SystemAlert["MASTER_PROFILE_PROMPT"] = {
+	text = L["This character need to have a profile installed and I can see that you have a master profile set. Would you like to use that instead of the installer?"],
+	button1 = YES,
+	button2 = NO,
+	timeout = 0,
+	hideOnEscape = 1,
+	noCancelOnEscape = 1,
+	OnAccept = SV.fubar,
+	OnCancel = SV.fubar
+};
+SV.SystemAlert["DELETE_GRAYS"] = {
+	text = L["Are you sure you want to delete all your gray items?"],
+	button1 = YES,
+	button2 = NO,
+	OnAccept = function() SV:VendorGrays(true) end,
+	OnShow = function(self) MoneyFrame_Update(self.moneyFrame, SV.SystemAlert["DELETE_GRAYS"].Money) end,
+	timeout = 0,
+	whileDead = 1,
+	hideOnEscape = false,
+	hasMoneyFrame = 1
+};
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+local MAX_STATIC_POPUPS = 4
+local SysPop_Event_Show = function(self)
+	PlaySound("igMainMenuOpen");
+
+	local dialog = SV.SystemAlert[self.which];
+	local OnShow = dialog.OnShow;
+
+	if ( OnShow ) then
+		OnShow(self, self.data);
+	end
+	if ( dialog.hasMoneyInputFrame ) then
+		_G[self:GetName().."MoneyInputFrameGold"]:SetFocus();
+	end
+	if ( dialog.enterClicksFirstButton ) then
+		self:SetScript("OnKeyDown", SysPop_Event_KeyDown);
+	end
+end
+
+local SysBox_Event_KeyEscape = function(self)
+	local closed = nil;
+	for _, frame in pairs(ACTIVE_ALERTS) do
+		if( frame:IsShown() and frame.hideOnEscape ) then
+			local standardDialog = SV.SystemAlert[frame.which];
+			if ( standardDialog ) then
+				local OnCancel = standardDialog.OnCancel;
+				local noCancelOnEscape = standardDialog.noCancelOnEscape;
+				if ( OnCancel and not noCancelOnEscape) then
+					OnCancel(frame, frame.data, "clicked");
+				end
+				frame:Hide();
+			else
+				SV:StaticPopupSpecial_Hide(frame);
+			end
+			closed = 1;
+		end
+	end
+	return closed;
+end
+
+local SysPop_Close_Unique = function(self)
+	SysPop_Close_Unique:Hide();
+	SysPop_Close_Table();
+end
+
+local SysPop_Close_Table = function()
+	local displayedFrames = ACTIVE_ALERTS;
+	local index = #displayedFrames;
+	while ( ( index >= 1 ) and ( not displayedFrames[index]:IsShown() ) ) do
+		tremove(displayedFrames, index);
+		index = index - 1;
+	end
+end
+
+local SysPop_Move = function(self)
+	if ( not tContains(ACTIVE_ALERTS, self) ) then
+		local lastFrame = ACTIVE_ALERTS[#ACTIVE_ALERTS];
+		if ( lastFrame ) then
+			self:SetPoint("TOP", lastFrame, "BOTTOM", 0, -4);
+		else
+			self:SetPoint("TOP", SV.Screen, "TOP", 0, -100);
+		end
+		tinsert(ACTIVE_ALERTS, self);
+	end
+end
+
+local SysPop_Event_KeyDown = function(self, key)
+	if ( GetBindingFromClick(key) == "TOGGLEGAMEMENU" ) then
+		return SysBox_Event_KeyEscape();
+	elseif ( GetBindingFromClick(key) == "SCREENSHOT" ) then
+		RunBinding("SCREENSHOT");
+		return;
+	end
+
+	local dialog = SV.SystemAlert[self.which];
+	if ( dialog ) then
+		if ( key == "ENTER" and dialog.enterClicksFirstButton ) then
+			local frameName = self:GetName();
+			local button;
+			local i = 1;
+			while ( true ) do
+				button = _G[frameName.."Button"..i];
+				if ( button ) then
+					if ( button:IsShown() ) then
+						SysPop_Event_Click(self, i);
+						return;
+					end
+					i = i + 1;
+				else
+					break;
+				end
+			end
+		end
+	end
+end
+
+local SysPop_Event_Click = function(self, index)
+	if ( not self:IsShown() ) then
+		return;
+	end
+	local which = self.which;
+	local info = SV.SystemAlert[which];
+	if ( not info ) then
+		return nil;
+	end
+	local hide = true;
+	if ( index == 1 ) then
+		local OnAccept = info.OnAccept;
+		if ( OnAccept ) then
+			hide = not OnAccept(self, self.data, self.data2);
+		end
+	elseif ( index == 3 ) then
+		local OnAlt = info.OnAlt;
+		if ( OnAlt ) then
+			OnAlt(self, self.data, "clicked");
+		end
+	else
+		local OnCancel = info.OnCancel;
+		if ( OnCancel ) then
+			hide = not OnCancel(self, self.data, "clicked");
+		end
+	end
+
+	if ( hide and (which == self.which) ) then
+		self:Hide();
+	end
+end
+
+local SysPop_Event_Hide = function(self)
+	PlaySound("igMainMenuClose");
+
+	SysPop_Close_Table();
+
+	local dialog = SV.SystemAlert[self.which];
+	local OnHide = dialog.OnHide;
+	if ( OnHide ) then
+		OnHide(self, self.data);
+	end
+	self.extraFrame:Hide();
+	if ( dialog.enterClicksFirstButton ) then
+		self:SetScript("OnKeyDown", nil);
+	end
+end
+
+local SysPop_Event_Update = function(self, elapsed)
+	if ( self.timeleft and self.timeleft > 0 ) then
+		local which = self.which;
+		local timeleft = self.timeleft - elapsed;
+		if ( timeleft <= 0 ) then
+			if ( not SV.SystemAlert[which].timeoutInformationalOnly ) then
+				self.timeleft = 0;
+				local OnCancel = SV.SystemAlert[which].OnCancel;
+				if ( OnCancel ) then
+					OnCancel(self, self.data, "timeout");
+				end
+				self:Hide();
+			end
+			return;
+		end
+		self.timeleft = timeleft;
+	end
+
+	if ( self.startDelay ) then
+		local which = self.which;
+		local timeleft = self.startDelay - elapsed;
+		if ( timeleft <= 0 ) then
+			self.startDelay = nil;
+			local text = _G[self:GetName().."Text"];
+			text:SetFormattedText(SV.SystemAlert[which].text, text.text_arg1, text.text_arg2);
+			local button1 = _G[self:GetName().."Button1"];
+			button1:Enable();
+			StaticPopup_Resize(self, which);
+			return;
+		end
+		self.startDelay = timeleft;
+	end
+
+	local onUpdate = SV.SystemAlert[self.which].OnUpdate;
+	if ( onUpdate ) then
+		onUpdate(self, elapsed);
+	end
+end
+
+local SysBox_Event_KeyEnter = function(self)
+	local EditBoxOnEnterPressed, which, dialog;
+	local parent = self:GetParent();
+	if ( parent.which ) then
+		which = parent.which;
+		dialog = parent;
+	elseif ( parent:GetParent().which ) then
+		-- This is needed if this is a money input frame since it's nested deeper than a normal edit box
+		which = parent:GetParent().which;
+		dialog = parent:GetParent();
+	end
+	if ( not self.autoCompleteParams or not AutoCompleteEditBox_OnEnterPressed(self) ) then
+		EditBoxOnEnterPressed = SV.SystemAlert[which].EditBoxOnEnterPressed;
+		if ( EditBoxOnEnterPressed ) then
+			EditBoxOnEnterPressed(self, dialog.data);
+		end
+	end
+end
+
+local SysBox_Event_KeyEscape = function(self)
+	local EditBoxOnEscapePressed = SV.SystemAlert[self:GetParent().which].EditBoxOnEscapePressed;
+	if ( EditBoxOnEscapePressed ) then
+		EditBoxOnEscapePressed(self, self:GetParent().data);
+	end
+end
+
+local SysBox_Event_Change = function(self, userInput)
+	if ( not self.autoCompleteParams or not AutoCompleteEditBox_OnTextChanged(self, userInput) ) then
+		local EditBoxOnTextChanged = SV.SystemAlert[self:GetParent().which].EditBoxOnTextChanged;
+		if ( EditBoxOnTextChanged ) then
+			EditBoxOnTextChanged(self, self:GetParent().data);
+		end
+	end
+end
+
+local SysPop_Size = function(self, which)
+	local info = SV.SystemAlert[which];
+	if ( not info ) then
+		return nil;
+	end
+
+	local text = _G[self:GetName().."Text"];
+	local editBox = _G[self:GetName().."EditBox"];
+	local button1 = _G[self:GetName().."Button1"];
+
+	local maxHeightSoFar, maxWidthSoFar = (self.maxHeightSoFar or 0), (self.maxWidthSoFar or 0);
+	local width = 320;
+
+	if ( self.numButtons == 3 ) then
+		width = 440;
+	elseif (info.showAlert or info.showAlertGear or info.closeButton) then
+		-- Widen
+		width = 420;
+	elseif ( info.editBoxWidth and info.editBoxWidth > 260 ) then
+		width = width + (info.editBoxWidth - 260);
+	end
+
+	if ( width > maxWidthSoFar )  then
+		self:SetWidth(width);
+		self.maxWidthSoFar = width;
+	end
+
+	local height = 32 + text:GetHeight() + 8 + button1:GetHeight();
+	if ( info.hasEditBox ) then
+		height = height + 8 + editBox:GetHeight();
+	elseif ( info.hasMoneyFrame ) then
+		height = height + 16;
+	elseif ( info.hasMoneyInputFrame ) then
+		height = height + 22;
+	end
+	if ( info.hasItemFrame ) then
+		height = height + 64;
+	end
+
+	if ( height > maxHeightSoFar ) then
+		self:SetHeight(height);
+		self.maxHeightSoFar = height;
+	end
+end
+
+local SysPop_Event_Listener = function(self)
+	self.maxHeightSoFar = 0;
+	SysPop_Size(self, self.which);
+end
+
+local SysPop_Find = function(which, data)
+	local info = SV.SystemAlert[which];
+	if ( not info ) then
+		return nil;
+	end
+	for index = 1, MAX_STATIC_POPUPS, 1 do
+		local frame = _G["SVUI_SystemAlert"..index];
+		if (frame and frame:IsShown() and (frame.which == which) and (not info.multiple or (frame.data == data)) ) then
+			return frame;
+		end
+	end
+	return nil;
+end
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+function SV:StaticPopupSpecial_Hide(frame)
+	frame:Hide();
+	SysPop_Close_Table();
+end
+
+function SV:StaticPopup_HideExclusive()
+	for _, frame in pairs(ACTIVE_ALERTS) do
+        if ( frame:IsShown() and frame.exclusive ) then
+            local standardDialog = self.SystemAlert[frame.which];
+            if ( standardDialog ) then
+                frame:Hide();
+                local OnCancel = standardDialog.OnCancel;
+                if ( OnCancel ) then
+                    OnCancel(frame, frame.data, "override");
+                end
+            else
+                self:StaticPopupSpecial_Hide(frame);
+            end
+            break;
+        end
+    end
+end
+
+function SV:StaticPopupSpecial_Show(frame)
+	if ( frame.exclusive ) then
+		self:StaticPopup_HideExclusive();
+	end
+	SysPop_Move(frame);
+	frame:Show();
+end
+
+function SV:StaticPopup_Show(which, text_arg1, text_arg2, data)
+	local info = SV.SystemAlert[which];
+	if ( not info ) then
+		return nil;
+	end
+	if ( UnitIsDeadOrGhost("player") and not info.whileDead ) then
+		if ( info.OnCancel ) then
+			info.OnCancel();
+		end
+		return nil;
+	end
+	if ( InCinematic() and not info.interruptCinematic ) then
+		if ( info.OnCancel ) then
+			info.OnCancel();
+		end
+		return nil;
+	end
+	if ( info.cancels ) then
+		for index = 1, MAX_STATIC_POPUPS, 1 do
+			local frame = _G["SVUI_SystemAlert"..index];
+			if ( frame:IsShown() and (frame.which == info.cancels) ) then
+				frame:Hide();
+				local OnCancel = SV.SystemAlert[frame.which].OnCancel;
+				if ( OnCancel ) then
+					OnCancel(frame, frame.data, "override");
+				end
+			end
+		end
+	end
+	local dialog = nil;
+	dialog = SysPop_Find(which, data);
+	if ( dialog ) then
+		if ( not info.noCancelOnReuse ) then
+			local OnCancel = info.OnCancel;
+			if ( OnCancel ) then
+				OnCancel(dialog, dialog.data, "override");
+			end
+		end
+		dialog:Hide();
+	end
+	if ( not dialog ) then
+		local index = 1;
+		if ( info.preferredIndex ) then
+			index = info.preferredIndex;
+		end
+		for i = index, MAX_STATIC_POPUPS do
+			local frame = _G["SVUI_SystemAlert"..i];
+			if (frame and not frame:IsShown() ) then
+				dialog = frame;
+				break;
+			end
+		end
+		if ( not dialog and info.preferredIndex ) then
+			for i = 1, info.preferredIndex do
+				local frame = _G["SVUI_SystemAlert"..i];
+				if ( not frame:IsShown() ) then
+					dialog = frame;
+					break;
+				end
+			end
+		end
+	end
+	if ( not dialog ) then
+		if ( info.OnCancel ) then
+			info.OnCancel();
+		end
+		return nil;
+	end
+	dialog.maxHeightSoFar, dialog.maxWidthSoFar = 0, 0;
+	local text = _G[dialog:GetName().."Text"];
+	text:SetFormattedText(info.text, text_arg1, text_arg2);
+	if ( info.closeButton ) then
+		local closeButton = _G[dialog:GetName().."CloseButton"];
+		if ( info.closeButtonIsHide ) then
+			closeButton:SetNormalTexture("Interface\\Buttons\\UI-Panel-HideButton-Up");
+			closeButton:SetPushedTexture("Interface\\Buttons\\UI-Panel-HideButton-Down");
+		else
+			closeButton:SetNormalTexture("Interface\\Buttons\\UI-Panel-MinimizeButton-Up");
+			closeButton:SetPushedTexture("Interface\\Buttons\\UI-Panel-MinimizeButton-Down");
+		end
+		closeButton:Show();
+	else
+		_G[dialog:GetName().."CloseButton"]:Hide();
+	end
+	local editBox = _G[dialog:GetName().."EditBox"];
+	if ( info.hasEditBox ) then
+		editBox:Show();
+		if ( info.maxLetters ) then
+			editBox:SetMaxLetters(info.maxLetters);
+			editBox:SetCountInvisibleLetters(info.countInvisibleLetters);
+		end
+		if ( info.maxBytes ) then
+			editBox:SetMaxBytes(info.maxBytes);
+		end
+		editBox:SetText("");
+		if ( info.editBoxWidth ) then
+			editBox:SetWidth(info.editBoxWidth);
+		else
+			editBox:SetWidth(130);
+		end
+	else
+		editBox:Hide();
+	end
+	if ( info.hasMoneyFrame ) then
+		_G[dialog:GetName().."MoneyFrame"]:Show();
+		_G[dialog:GetName().."MoneyInputFrame"]:Hide();
+	elseif ( info.hasMoneyInputFrame ) then
+		local moneyInputFrame = _G[dialog:GetName().."MoneyInputFrame"];
+		moneyInputFrame:Show();
+		_G[dialog:GetName().."MoneyFrame"]:Hide();
+		if ( info.EditBoxOnEnterPressed ) then
+			moneyInputFrame.gold:SetScript("OnEnterPressed", SysBox_Event_KeyEnter);
+			moneyInputFrame.silver:SetScript("OnEnterPressed", SysBox_Event_KeyEnter);
+			moneyInputFrame.copper:SetScript("OnEnterPressed", SysBox_Event_KeyEnter);
+		else
+			moneyInputFrame.gold:SetScript("OnEnterPressed", nil);
+			moneyInputFrame.silver:SetScript("OnEnterPressed", nil);
+			moneyInputFrame.copper:SetScript("OnEnterPressed", nil);
+		end
+	else
+		_G[dialog:GetName().."MoneyFrame"]:Hide();
+		_G[dialog:GetName().."MoneyInputFrame"]:Hide();
+	end
+	if ( info.hasItemFrame ) then
+		_G[dialog:GetName().."ItemFrame"]:Show();
+		if ( data and type(data) == "table" ) then
+			_G[dialog:GetName().."ItemFrame"].link = data.link
+			_G[dialog:GetName().."ItemFrameIconTexture"]:SetTexture(data.texture);
+			local nameText = _G[dialog:GetName().."ItemFrameText"];
+			nameText:SetTextColor(unpack(data.color or {1, 1, 1, 1}));
+			nameText:SetText(data.name);
+			if ( data.count and data.count > 1 ) then
+				_G[dialog:GetName().."ItemFrameCount"]:SetText(data.count);
+				_G[dialog:GetName().."ItemFrameCount"]:Show();
+			else
+				_G[dialog:GetName().."ItemFrameCount"]:Hide();
+			end
+		end
+	else
+		_G[dialog:GetName().."ItemFrame"]:Hide();
+	end
+	dialog.which = which;
+	dialog.timeleft = info.timeout;
+	dialog.hideOnEscape = info.hideOnEscape;
+	dialog.exclusive = info.exclusive;
+	dialog.enterClicksFirstButton = info.enterClicksFirstButton;
+	dialog.data = data;
+	local button1 = _G[dialog:GetName().."Button1"];
+	local button2 = _G[dialog:GetName().."Button2"];
+	local button3 = _G[dialog:GetName().."Button3"];
+	do
+		assert(#BUFFER == 0);
+		tinsert(BUFFER, button1);
+		tinsert(BUFFER, button2);
+		tinsert(BUFFER, button3);
+		for i=#BUFFER, 1, -1 do
+			BUFFER[i]:SetText(info["button"..i]);
+			BUFFER[i]:Hide();
+			BUFFER[i]:ClearAllPoints();
+			if ( not (info["button"..i] and ( not info["DisplayButton"..i] or info["DisplayButton"..i](dialog))) ) then
+				tremove(BUFFER, i);
+			end
+		end
+		local numButtons = #BUFFER;
+		dialog.numButtons = numButtons;
+		if ( numButtons == 3 ) then
+			BUFFER[1]:SetPoint("BOTTOMRIGHT", dialog, "BOTTOM", -72, 16);
+		elseif ( numButtons == 2 ) then
+			BUFFER[1]:SetPoint("BOTTOMRIGHT", dialog, "BOTTOM", -6, 16);
+		elseif ( numButtons == 1 ) then
+			BUFFER[1]:SetPoint("BOTTOM", dialog, "BOTTOM", 0, 16);
+		end
+		for i=1, numButtons do
+			if ( i > 1 ) then
+				BUFFER[i]:SetPoint("LEFT", BUFFER[i-1], "RIGHT", 13, 0);
+			end
+			local width = BUFFER[i]:GetTextWidth();
+			if ( width > 110 ) then
+				BUFFER[i]:SetWidth(width + 20);
+			else
+				BUFFER[i]:SetWidth(120);
+			end
+			BUFFER[i]:Enable();
+			BUFFER[i]:Show();
+		end
+		table.wipe(BUFFER);
+	end
+	local alertIcon = _G[dialog:GetName().."AlertIcon"];
+	if ( info.showAlert ) then
+		alertIcon:SetTexture(STATICPOPUP_TEXTURE_ALERT);
+		if ( button3:IsShown() )then
+			alertIcon:SetPoint("LEFT", 24, 10);
+		else
+			alertIcon:SetPoint("LEFT", 24, 0);
+		end
+		alertIcon:Show();
+	elseif ( info.showAlertGear ) then
+		alertIcon:SetTexture(STATICPOPUP_TEXTURE_ALERTGEAR);
+		if ( button3:IsShown() )then
+			alertIcon:SetPoint("LEFT", 24, 0);
+		else
+			alertIcon:SetPoint("LEFT", 24, 0);
+		end
+		alertIcon:Show();
+	else
+		alertIcon:SetTexture();
+		alertIcon:Hide();
+	end
+	if ( info.StartDelay ) then
+		dialog.startDelay = info.StartDelay();
+		button1:Disable();
+	else
+		dialog.startDelay = nil;
+		button1:Enable();
+	end
+	editBox.autoCompleteParams = info.autoCompleteParams;
+	editBox.autoCompleteRegex = info.autoCompleteRegex;
+	editBox.autoCompleteFormatRegex = info.autoCompleteFormatRegex;
+	editBox.addHighlightedText = true;
+	SysPop_Move(dialog);
+	dialog:Show();
+	SysPop_Size(dialog, which);
+	if (not dialog:IsShown() and info.sound) then
+		PlaySound(info.sound);
+	end
+	return dialog;
+end
+--[[
+##########################################################
+ALERT HOOKS
+##########################################################
+
+local _hook_AlertFrame_SetLootAnchors = function(self)
+	if MissingLootFrame:IsShown() then
+		MissingLootFrame:ClearAllPoints()
+		MissingLootFrame:SetPoint(POSITION, self, ANCHOR_POINT)
+		if GroupLootContainer:IsShown() then
+			GroupLootContainer:ClearAllPoints()
+			GroupLootContainer:SetPoint(POSITION, MissingLootFrame, ANCHOR_POINT, 0, YOFFSET)
+		end
+	elseif GroupLootContainer:IsShown() or FORCE_POSITION then
+		GroupLootContainer:ClearAllPoints()
+		GroupLootContainer:SetPoint(POSITION, self, ANCHOR_POINT)
+	end
+end
+
+local _hook_AlertFrame_SetLootWonAnchors = function(self)
+	for i = 1, #LOOT_WON_ALERT_FRAMES do
+		local frame = LOOT_WON_ALERT_FRAMES[i]
+		if(frame and frame:IsShown()) then
+			frame:ClearAllPoints()
+			frame:SetPoint(POSITION, self, ANCHOR_POINT, 0, YOFFSET)
+			self = frame
+		end
+	end
+end
+
+local _hook_AlertFrame_SetMoneyWonAnchors = function(self)
+	for i = 1, #MONEY_WON_ALERT_FRAMES do
+		local frame = MONEY_WON_ALERT_FRAMES[i]
+		if(frame and frame:IsShown()) then
+			frame:ClearAllPoints()
+			frame:SetPoint(POSITION, self, ANCHOR_POINT, 0, YOFFSET)
+			self = frame
+		end
+	end
+end
+
+local _hook_AlertFrame_SetAchievementAnchors = function(self)
+	if AchievementAlertFrame1 then
+		for i = 1, MAX_ACHIEVEMENT_ALERTS do
+			local frame = _G["AchievementAlertFrame"..i]
+			if(frame and frame:IsShown()) then
+				frame:ClearAllPoints()
+				frame:SetPoint(POSITION, self, ANCHOR_POINT, 0, YOFFSET)
+				self = frame
+			end
+		end
+	end
+end
+
+local _hook_AlertFrame_SetCriteriaAnchors = function(self)
+	if CriteriaAlertFrame1 then
+		for i = 1, MAX_ACHIEVEMENT_ALERTS do
+			local frame = _G["CriteriaAlertFrame"..i]
+			if(frame and frame:IsShown()) then
+				frame:ClearAllPoints()
+				frame:SetPoint(POSITION, self, ANCHOR_POINT, 0, YOFFSET)
+				self = frame
+			end
+		end
+	end
+end
+
+local _hook_AlertFrame_SetChallengeModeAnchors = function(self)
+	local frame = ChallengeModeAlertFrame1;
+	if(frame and frame:IsShown()) then
+		frame:ClearAllPoints()
+		frame:SetPoint(POSITION, self, ANCHOR_POINT, 0, YOFFSET)
+	end
+end
+
+local _hook_AlertFrame_SetDungeonCompletionAnchors = function(self)
+	local frame = DungeonCompletionAlertFrame1;
+	if(frame and frame:IsShown()) then
+		frame:ClearAllPoints()
+		frame:SetPoint(POSITION, self, ANCHOR_POINT, 0, YOFFSET)
+	end
+end
+
+local _hook_AlertFrame_SetStorePurchaseAnchors = function(self)
+	local frame = StorePurchaseAlertFrame;
+	if(frame and frame:IsShown()) then
+		frame:ClearAllPoints()
+		frame:SetPoint(POSITION, self, ANCHOR_POINT, 0, YOFFSET)
+	end
+end
+
+local _hook_AlertFrame_SetScenarioAnchors = function(self)
+	local frame = ScenarioAlertFrame1;
+	if(frame and frame:IsShown()) then
+		frame:ClearAllPoints()
+		frame:SetPoint(POSITION, self, ANCHOR_POINT, 0, YOFFSET)
+	end
+end
+
+local _hook_AlertFrame_SetGuildChallengeAnchors = function(self)
+	local frame = GuildChallengeAlertFrame;
+	if(frame and frame:IsShown()) then
+		frame:ClearAllPoints()
+		frame:SetPoint(POSITION, self, ANCHOR_POINT, 0, YOFFSET)
+	end
+end
+--
+local _hook_AlertFrame_SetDigsiteCompleteToastFrameAnchors = function(self)
+	local frame = DigsiteCompleteToastFrame;
+	if(frame and frame:IsShown()) then
+		frame:ClearAllPoints()
+		frame:SetPoint(POSITION, self, ANCHOR_POINT, 0, YOFFSET)
+	end
+end
+local _hook_AlertFrame_SetGarrisonBuildingAlertFrameAnchors = function(self)
+	local frame = GarrisonBuildingAlertFrame;
+	if(frame and frame:IsShown()) then
+		frame:ClearAllPoints()
+		frame:SetPoint(POSITION, self, ANCHOR_POINT, 0, YOFFSET)
+	end
+end
+local _hook_AlertFrame_SetGarrisonMissionAlertFrameAnchors = function(self)
+	local frame = GarrisonMissionAlertFrame;
+	if(frame and frame:IsShown()) then
+		frame:ClearAllPoints()
+		frame:SetPoint(POSITION, self, ANCHOR_POINT, 0, YOFFSET)
+	end
+end
+local _hook_AlertFrame_SetGarrisonShipMissionAlertFrameAnchors = function(self)
+	local frame = GarrisonShipMissionAlertFrame;
+	if(frame and frame:IsShown()) then
+		frame:ClearAllPoints()
+		frame:SetPoint(POSITION, self, ANCHOR_POINT, 0, YOFFSET)
+	end
+end
+local _hook_AlertFrame_SetGarrisonFollowerAlertFrameAnchors = function(self)
+	local frame = GarrisonFollowerAlertFrame;
+	if(frame and frame:IsShown()) then
+		frame:ClearAllPoints()
+		frame:SetPoint(POSITION, self, ANCHOR_POINT, 0, YOFFSET)
+	end
+end
+local _hook_AlertFrame_SetGarrisonShipFollowerAlertFrameAnchors = function(self)
+	local frame = GarrisonShipFollowerAlertFrame;
+	if(frame and frame:IsShown()) then
+		frame:ClearAllPoints()
+		frame:SetPoint(POSITION, self, ANCHOR_POINT, 0, YOFFSET)
+	end
+end
+]]--
+local AlertFramePostMove_Hook = function(forced)
+	local b, c = SVUI_AlertFrame_MOVE:GetCenter()
+	local d = SV.Screen:GetTop()
+	if(c > (d * 0.6)) then
+		POSITION = "TOP"
+		ANCHOR_POINT = "BOTTOM"
+		YOFFSET = -10;
+		SVUI_AlertFrame_MOVE:SetText(SVUI_AlertFrame_MOVE.textString.." (Grow Down)")
+	else
+		POSITION = "BOTTOM"
+		ANCHOR_POINT = "TOP"
+		YOFFSET = 10;
+		SVUI_AlertFrame_MOVE:SetText(SVUI_AlertFrame_MOVE.textString.." (Grow Up)")
+	end
+
+	-- if(SV.RollFrames and SV.RollFrames[1]) then
+	-- 	local lastFrame = SVUI_AlertFrame;
+	-- 	local newAnchor;
+	-- 	for index, rollFrame in pairs(SV.RollFrames) do
+	-- 		rollFrame:ClearAllPoints()
+	-- 		if(POSITION == "TOP") then
+	-- 			rollFrame:SetPoint("TOP", lastFrame, "BOTTOM", 0, -4)
+	-- 		else
+	-- 			rollFrame:SetPoint("BOTTOM", lastFrame, "TOP", 0, 4)
+	-- 		end
+	-- 		lastFrame = rollFrame;
+	-- 		if(rollFrame:IsShown()) then
+	-- 			newAnchor = rollFrame
+	-- 		end
+	-- 	end
+	-- 	AlertFrame:ClearAllPoints()
+	-- 	if(newAnchor) then
+	-- 		AlertFrame:SetAllPoints(newAnchor)
+	-- 	else
+	-- 		AlertFrame:SetPoint(POSITION, SVUI_AlertFrame, POSITION, 0, 0)
+	-- 	end
+	-- else
+	-- 	AlertFrame:ClearAllPoints()
+	-- 	AlertFrame:SetPoint(POSITION, SVUI_AlertFrame, POSITION, 0, 0)
+	-- end
+	AlertFrame:ClearAllPoints()
+	AlertFrame:SetPoint(POSITION, SVUI_AlertFrame, POSITION, 0, 0)
+end
+--[[
+##########################################################
+PACKAGE CALL
+##########################################################
+]]--
+function SV:StaticPopup_Hide(which, data)
+	for index = 1, MAX_STATIC_POPUPS, 1 do
+		local dialog = _G["SVUI_SystemAlert"..index];
+		if (dialog and (dialog.which == which) and (not data or (data == dialog.data)) ) then
+			dialog:Hide();
+		end
+	end
+end
+
+local function SetConfigAlertAnim(f)
+	local x = 50;
+	local y = 150;
+	f.trans = f:CreateAnimationGroup()
+	f.trans[1] = f.trans:CreateAnimation("Translation")
+	f.trans[1]:SetOrder(1)
+	f.trans[1]:SetDuration(0.3)
+	f.trans[1]:SetOffset(x,y)
+	f.trans[1]:SetScript("OnPlay",function()f:SetScale(0.01)f:Show()end)
+	f.trans[1]:SetScript("OnUpdate",function(self)f:SetScale(0.1+(1*f.trans[1]:GetProgress()))end)
+	f.trans[2] = f.trans:CreateAnimation("Translation")
+	f.trans[2]:SetOrder(2)
+	f.trans[2]:SetDuration(0.7)
+	f.trans[2]:SetOffset(x*.5,y*.5)
+	f.trans[3] = f.trans:CreateAnimation("Translation")
+	f.trans[3]:SetOrder(3)
+	f.trans[3]:SetDuration(0.1)
+	f.trans[3]:SetOffset(0,0)
+	f.trans[3]:SetScript("OnStop",function()f:Hide()end)
+	f.trans:SetScript("OnFinished",f.trans[3]:GetScript("OnStop"))
+end
+
+function SV:SavedPopup()
+	if not _G["SVUI_ConfigAlert"] then return end
+	local alert = _G["SVUI_ConfigAlert"]
+	local x = random(10,70)
+	local y = random(10,70)
+	if(alert:IsShown()) then
+		alert:Hide()
+	end
+	alert:Show()
+	alert.bg.anim:Play()
+	alert.bg.trans[1]:SetOffset(x,y)
+	alert.fg.trans[1]:SetOffset(x,y)
+	alert.bg.trans[2]:SetOffset(x*.5,y*.5)
+	alert.fg.trans[2]:SetOffset(x*.5,y*.5)
+	alert.bg.trans:Play()
+	alert.fg.trans:Play()
+
+	PlaySoundFile("Sound\\Interface\\uCharacterSheetOpen.wav")
+end
+
+local AlertButton_OnClick = function(self)
+	SysPop_Event_Click(self:GetParent(), self:GetID())
+end
+
+local function LoadSystemAlerts()
+	if not _G["SVUI_ConfigAlert"] then
+		local configAlert = CreateFrame("Frame", "SVUI_ConfigAlert", UIParent)
+		configAlert:SetFrameStrata("TOOLTIP")
+		configAlert:SetFrameLevel(979)
+		configAlert:SetSize(300, 300)
+		configAlert:SetPoint("CENTER", 200, -150)
+		configAlert:Hide()
+
+		configAlert.bg = CreateFrame("Frame", nil, configAlert)
+		configAlert.bg:SetSize(300, 300)
+		configAlert.bg:SetPoint("CENTER")
+		configAlert.bg:SetFrameStrata("TOOLTIP")
+		configAlert.bg:SetFrameLevel(979)
+		local bgtex = configAlert.bg:CreateTexture(nil, "BACKGROUND")
+		bgtex:SetAllPoints()
+		bgtex:SetTexture([[Interface\AddOns\SVUI_!Core\assets\textures\Alert\SAVED-BG]])
+		SetConfigAlertAnim(configAlert.bg)
+
+		configAlert.fg = CreateFrame("Frame", nil, configAlert)
+		configAlert.fg:SetSize(300, 300)
+		configAlert.fg:SetPoint("CENTER", bgtex, "CENTER")
+		configAlert.fg:SetFrameStrata("TOOLTIP")
+		configAlert.fg:SetFrameLevel(999)
+		local fgtex = configAlert.fg:CreateTexture(nil, "ARTWORK")
+		fgtex:SetAllPoints()
+		fgtex:SetTexture([[Interface\AddOns\SVUI_!Core\assets\textures\Alert\SAVED-FG]])
+		SetConfigAlertAnim(configAlert.fg)
+
+		SV.Animate:Orbit(configAlert.bg, 10, false, true)
+	end
+	for i = 1, 4 do
+		local alert = CreateFrame("Frame", "SVUI_SystemAlert"..i, UIParent, "StaticPopupTemplate")
+		alert:SetID(i)
+		alert:SetScript("OnShow", SysPop_Event_Show)
+		alert:SetScript("OnHide", SysPop_Event_Hide)
+		alert:SetScript("OnUpdate", SysPop_Event_Update)
+		alert:SetScript("OnEvent", SysPop_Event_Listener)
+		alert.input = _G["SVUI_SystemAlert"..i.."EditBox"];
+		alert.input:SetScript("OnEnterPressed", SysBox_Event_KeyEnter)
+		alert.input:SetScript("OnEscapePressed", SysBox_Event_KeyEscape)
+		alert.input:SetScript("OnTextChanged", SysBox_Event_Change)
+		alert.gold = _G["SVUI_SystemAlert"..i.."MoneyInputFrameGold"];
+		alert.silver = _G["SVUI_SystemAlert"..i.."MoneyInputFrameSilver"];
+		alert.copper = _G["SVUI_SystemAlert"..i.."MoneyInputFrameCopper"];
+		alert.buttons = {}
+		for b = 1, 3 do
+			local button = _G["SVUI_SystemAlert"..i.."Button"..b];
+			button:SetScript("OnClick", AlertButton_OnClick)
+			alert.buttons[b] = button
+		end
+		_G["SVUI_SystemAlert"..i.."ItemFrameNameFrame"]:Die()
+		_G["SVUI_SystemAlert"..i.."ItemFrame"]:GetNormalTexture():Die()
+		_G["SVUI_SystemAlert"..i.."ItemFrame"]:SetStyle("Button")
+		_G["SVUI_SystemAlert"..i.."ItemFrameIconTexture"]:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+		_G["SVUI_SystemAlert"..i.."ItemFrameIconTexture"]:InsetPoints()
+	end
+
+	SVUI_AlertFrame:SetSize(180, 20);
+	SVUI_AlertFrame.callbackOnEnter = true;
+	SV:NewAnchor(SVUI_AlertFrame, L["Loot / Alert Frames"], AlertFramePostMove_Hook)
+	NewHook(AlertFrame, "UpdateAnchors", AlertFramePostMove_Hook)
+	--AlertFrame:HookScript("UpdateAnchors", AlertFramePostMove_Hook)
+	--[[
+	NewHook('AlertFrame_FixAnchors', AlertFramePostMove_Hook)
+	NewHook('AlertFrame_SetLootAnchors', _hook_AlertFrame_SetLootAnchors)
+	NewHook('AlertFrame_SetLootWonAnchors', _hook_AlertFrame_SetLootWonAnchors)
+	NewHook('AlertFrame_SetMoneyWonAnchors', _hook_AlertFrame_SetMoneyWonAnchors)
+	NewHook('AlertFrame_SetAchievementAnchors', _hook_AlertFrame_SetAchievementAnchors)
+	NewHook('AlertFrame_SetCriteriaAnchors', _hook_AlertFrame_SetCriteriaAnchors)
+	NewHook('AlertFrame_SetChallengeModeAnchors', _hook_AlertFrame_SetChallengeModeAnchors)
+	NewHook('AlertFrame_SetDungeonCompletionAnchors', _hook_AlertFrame_SetDungeonCompletionAnchors)
+	NewHook('AlertFrame_SetScenarioAnchors', _hook_AlertFrame_SetScenarioAnchors)
+	NewHook('AlertFrame_SetGuildChallengeAnchors', _hook_AlertFrame_SetGuildChallengeAnchors)
+	NewHook('AlertFrame_SetStorePurchaseAnchors', _hook_AlertFrame_SetStorePurchaseAnchors)
+
+	NewHook('AlertFrame_SetDigsiteCompleteToastFrameAnchors', _hook_AlertFrame_SetDigsiteCompleteToastFrameAnchors)
+	NewHook('AlertFrame_SetGarrisonBuildingAlertFrameAnchors', _hook_AlertFrame_SetGarrisonBuildingAlertFrameAnchors)
+	NewHook('AlertFrame_SetGarrisonMissionAlertFrameAnchors', _hook_AlertFrame_SetGarrisonMissionAlertFrameAnchors)
+	NewHook('AlertFrame_SetGarrisonShipMissionAlertFrameAnchors', _hook_AlertFrame_SetGarrisonShipMissionAlertFrameAnchors)
+	NewHook('AlertFrame_SetGarrisonFollowerAlertFrameAnchors', _hook_AlertFrame_SetGarrisonFollowerAlertFrameAnchors)
+	NewHook('AlertFrame_SetGarrisonShipFollowerAlertFrameAnchors', _hook_AlertFrame_SetGarrisonShipFollowerAlertFrameAnchors)
+	]]--
+end
+
+SV.Events:On("LOAD_ALL_ESSENTIALS", LoadSystemAlerts);
diff --git a/SVUI_!Core/system/api.lua b/SVUI_!Core/system/api.lua
new file mode 100644
index 0000000..dd4dce6
--- /dev/null
+++ b/SVUI_!Core/system/api.lua
@@ -0,0 +1,2372 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack    = _G.unpack;
+local select    = _G.select;
+local pairs     = _G.pairs;
+local ipairs    = _G.ipairs;
+local type      = _G.type;
+local error     = _G.error;
+local pcall     = _G.pcall;
+local tostring          = _G.tostring;
+local tonumber          = _G.tonumber;
+local getmetatable      = _G.getmetatable;
+local setmetatable      = _G.setmetatable;
+local collectgarbage    = _G.collectgarbage;
+local table     = _G.table;
+local string    = _G.string;
+local math      = _G.math;
+local wipe      = _G.wipe;
+local tremove       = _G.tremove;
+--[[ MATH METHODS ]]--
+local floor, abs, min, max = math.floor, math.abs, math.min, math.max;
+local parsefloat, ceil = math.parsefloat, math.ceil;
+--[[ STRING METHODS ]]--
+local lower, upper = string.lower, string.upper;
+--[[ TABLE METHODS ]]--
+local tremove, tcopy, twipe, tsort, tconcat = table.remove, table.copy, table.wipe, table.sort, table.concat;
+--BLIZZARD API
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+local GameTooltip           = _G.GameTooltip;
+local ReloadUI              = _G.ReloadUI;
+local GetTime               = _G.GetTime;
+local hooksecurefunc        = _G.hooksecurefunc;
+local IsAltKeyDown          = _G.IsAltKeyDown;
+local IsShiftKeyDown        = _G.IsShiftKeyDown;
+local IsControlKeyDown      = _G.IsControlKeyDown;
+local IsModifiedClick       = _G.IsModifiedClick;
+local PlaySound             = _G.PlaySound;
+local PlaySoundFile         = _G.PlaySoundFile;
+local SetCVar               = _G.SetCVar;
+local GetCVar               = _G.GetCVar;
+local GetCVarBool           = _G.GetCVarBool;
+local SquareButton_SetIcon  = _G.SquareButton_SetIcon;
+local RAID_CLASS_COLORS     = _G.RAID_CLASS_COLORS;
+local CUSTOM_CLASS_COLORS   = _G.CUSTOM_CLASS_COLORS;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...)
+local L = SV.L;
+local SVUILib = Librarian("Registry");
+local MOD = SV:NewPackage("API", L["API"]);
+--[[
+##########################################################
+LOCALS
+##########################################################
+]]--
+local MAC_DISPLAY;
+local BASE_MOD = 0.64;
+local LIVE_UPDATE_FRAMES = {};
+--[[
+##########################################################
+LOOKUP TABLE
+##########################################################
+]]--
+MOD.Templates = {
+    ["Default"]     = "SVUI_CoreStyle_Default",
+    ["Transparent"] = "SVUI_CoreStyle_Transparent",
+    ["Button"]      = "SVUI_CoreStyle_Button",
+    ["EditBox"]     = "SVUI_CoreStyle_EditBox",
+    ["CheckButton"] = "SVUI_CoreStyle_CheckButton",
+    ["DockButton"]  = "SVUI_CoreStyle_DockButton",
+    ["ActionSlot"]  = "SVUI_CoreStyle_ActionSlot",
+    ["Lite"]        = "SVUI_CoreStyle_Lite",
+    ["Icon"]        = "SVUI_CoreStyle_Icon",
+    ["Bar"]         = "SVUI_CoreStyle_Bar",
+    ["Inset"]       = "SVUI_CoreStyle_Inset",
+    ["Blackout"]    = "SVUI_CoreStyle_Blackout",
+    ["Component"]   = "SVUI_CoreStyle_Component",
+    ["Paper"]       = "SVUI_CoreStyle_Paper",
+    ["Container"]   = "SVUI_CoreStyle_Container",
+    ["Pattern"]     = "SVUI_CoreStyle_Pattern",
+    ["Premium"]     = "SVUI_CoreStyle_Premium",
+    ["Model"]       = "SVUI_CoreStyle_Model",
+    ["UnitLarge"]   = "SVUI_CoreStyle_UnitLarge",
+    ["UnitSmall"]   = "SVUI_CoreStyle_UnitSmall",
+    ["Window"]      = "SVUI_CoreStyle_Window",
+    ["Window2"]     = "SVUI_CoreStyle_Window2",
+};
+MOD.Methods = {};
+MOD.Concepts = {};
+--[[
+##########################################################
+UI SCALING
+##########################################################
+]]--
+local function ScreenUpdate()
+    local rez = GetCVar("gxFullscreenResolution")
+    local height = rez:match("%d+x(%d+)")
+    local width = rez:match("(%d+)x%d+")
+    local gxHeight = tonumber(height)
+    local gxWidth = tonumber(width)
+    local gxMod = (768 / gxHeight)
+    local customScale = false;
+    if(IsMacClient()) then
+        if(not MAC_DISPLAY) then
+            MAC_DISPLAY = SVUILib:NewGlobal("Display");
+            if(not MAC_DISPLAY.Y or (MAC_DISPLAY.Y and type(MAC_DISPLAY.Y) ~= "number")) then
+                MAC_DISPLAY.Y = gxHeight;
+            end
+            if(not MAC_DISPLAY.X or (MAC_DISPLAY.X and type(MAC_DISPLAY.X) ~= "number")) then
+                MAC_DISPLAY.X = gxWidth;
+            end
+        end
+        if(MAC_DISPLAY and MAC_DISPLAY.Y and MAC_DISPLAY.X) then
+            if(gxHeight ~= MAC_DISPLAY.Y or gxWidth ~= MAC_DISPLAY.X) then
+                gxHeight = MAC_DISPLAY.Y;
+                gxWidth = MAC_DISPLAY.X;
+            end
+        end
+    end
+
+    local gxScale;
+    if(SV.db.screen.advanced) then
+        BASE_MOD = 0.64
+        local ADJUSTED_SCALE = SV.db.screen.scaleAdjust;
+        if(ADJUSTED_SCALE) then
+            if(type(ADJUSTED_SCALE) ~= "number") then
+                ADJUSTED_SCALE = tonumber(ADJUSTED_SCALE);
+            end
+            if(ADJUSTED_SCALE and ADJUSTED_SCALE ~= BASE_MOD) then
+                BASE_MOD = ADJUSTED_SCALE;
+                customScale = true;
+            end
+        end
+
+        gxScale = BASE_MOD;
+    else
+        -- local default_autoscale = true;
+		-- if(BlizzardOptionsPanel_GetCVarSafe("useUiScale") ~= 0) then
+        --     default_autoscale = false;
+		-- end
+        if(SV.db.screen.autoScale) then
+            gxScale = max(0.64, min(1.15, gxMod));
+        else
+            gxScale = max(0.64, min(1.15, GetCVar("uiScale") or UIParent:GetScale() or gxMod));
+        end
+    end
+
+    return gxWidth, gxHeight, gxScale, customScale
+end
+--[[
+##########################################################
+APPENDED POSITIONING METHODS
+##########################################################
+]]--
+local FIND_EDGES = {
+    CENTER = function(frame, x, y)
+        local xX,yY = frame:GetCenter();
+        return (xX + x),(yY + y);
+    end,
+    TOP = function(frame, x, y)
+        local yY = frame:GetTop() - UIParent:GetHeight() + y;
+        return x,yY;
+    end,
+    TOPLEFT = function(frame, x, y)
+        local xX = frame:GetLeft() + x;
+        local yY = frame:GetTop() - UIParent:GetHeight() + y;
+        return xX,yY;
+    end,
+    TOPRIGHT = function(frame, x, y)
+        local xX = frame:GetRight() - UIParent:GetWidth() + x;
+        local yY = frame:GetTop() - UIParent:GetHeight() + y;
+        return xX,yY;
+    end,
+    BOTTOM = function(frame, x, y)
+        local yY = frame:GetBottom() + y;
+        return x,yY;
+    end,
+    BOTTOMLEFT = function(frame, x, y)
+        local xX = frame:GetLeft() + x;
+        local yY = frame:GetBottom() + y;
+        return xX,yY;
+    end,
+    BOTTOMRIGHT = function(frame, x, y)
+        local xX = frame:GetRight() - UIParent:GetWidth() + x;
+        local yY = frame:GetBottom() + y;
+        return xX,yY;
+    end,
+};
+
+local function GetRelativeEdges(frame, anchor)
+    local x,y = 0,0;
+    if(FIND_EDGES[anchor]) then
+        x,y = FIND_EDGES[anchor](frame);
+    end
+    return x,y;
+end
+
+local ModSize = function(self, width, height)
+    if(type(width) == "number") then
+        local h = (height and type(height) == "number") and height or width
+        self:SetSize(width, h)
+    end
+end
+
+local WrapPoints = function(self, parent, x, y)
+    x = type(x) == "number" and x or 1
+    y = y or x
+    parent = parent or self:GetParent()
+    if self:GetPoint() then
+        self:ClearAllPoints()
+    end
+    self:SetPoint("TOPLEFT", parent, "TOPLEFT", -x, y)
+    self:SetPoint("BOTTOMRIGHT", parent, "BOTTOMRIGHT", x, -y)
+end
+
+local InsetPoints = function(self, parent, x, y)
+    x = type(x) == "number" and x or 1
+    y = y or x
+    parent = parent or self:GetParent()
+    if self:GetPoint() then
+        self:ClearAllPoints()
+    end
+    self:SetPoint("TOPLEFT", parent, "TOPLEFT", x, -y)
+    self:SetPoint("BOTTOMRIGHT", parent, "BOTTOMRIGHT", -x, y)
+end
+
+local SetSecurePoint = function(self, anchor1, parent, anchor2, x, y)
+    local pX,pY = x,y;
+    if(FIND_EDGES[anchor2]) then
+        pX,pY = FIND_EDGES[anchor2](parent, x, y);
+    end
+    self:SetPoint(anchor1, UIParent, anchor2, pX, pY);
+end
+
+local SetAllSecurePoints = function(self, parent)
+    local pX,pY = FIND_EDGES["TOPLEFT"](parent, 0, 0);
+    local w,h = parent:GetSize();
+    self:ClearAllPoints();
+    self:SetPoint("TOPLEFT", UIParent, "TOPLEFT", pX, pY);
+    self:SetSize(w,h);
+end
+--[[
+##########################################################
+APPENDED DESTROY METHODS
+##########################################################
+]]--
+local _purgatory = CreateFrame("Frame", nil)
+_purgatory:Hide()
+
+local Die = function(self)
+    if(self.UnregisterAllEvents) then
+        self:UnregisterAllEvents()
+        self:SetParent(_purgatory)
+    else
+        self:Hide()
+        self.Show = SV.fubar
+    end
+end
+
+local RemoveTextures = function(self, option)
+    if((not self.GetNumRegions) or (self.Panel and (not self.Panel.CanBeRemoved))) then return end
+    local region, layer, texture
+    for i = 1, self:GetNumRegions()do
+        region = select(i, self:GetRegions())
+        if(region and (region:GetObjectType() == "Texture")) then
+
+            layer = region:GetDrawLayer()
+            texture = region:GetTexture()
+
+            if(option) then
+                if(type(option) == "boolean") then
+                    if region.UnregisterAllEvents then
+                        region:UnregisterAllEvents()
+                        region:SetParent(_purgatory)
+                    else
+                        region.Show = region.Hide
+                    end
+                    region:Hide()
+                elseif(type(option) == "string" and ((layer == option) or (texture ~= option))) then
+                    region:SetTexture("")
+                end
+            else
+                region:SetTexture("")
+            end
+        end
+    end
+end
+--[[
+##########################################################
+SECURE FADING
+##########################################################
+]]--
+local FRAMES_TO_HIDE = {};
+local FRAMES_TO_SHOW = {};
+
+local FadeEventManager_OnEvent = function(self, event)
+    if(event == 'PLAYER_REGEN_ENABLED') then
+        self:UnregisterEvent("PLAYER_REGEN_ENABLED")
+        for frame in pairs(FRAMES_TO_HIDE) do
+            frame:Hide()
+        end
+        wipe(FRAMES_TO_HIDE)
+        for frame in pairs(FRAMES_TO_SHOW) do
+            frame:Show()
+        end
+        wipe(FRAMES_TO_SHOW)
+    end
+end
+
+local FadeEventManager = CreateFrame('Frame')
+FadeEventManager:SetScript("OnEvent", FadeEventManager_OnEvent)
+
+local SecureFade_OnUpdate = function(self, elasped)
+    local frame = self.owner;
+    if(frame) then
+        local state = frame.___fadeset;
+        state[4] = (state[4] or 0) + elasped;
+        if(state[4] < state[3]) then
+
+            if(frame.___fademode == "IN") then
+                frame:SetAlpha((state[4] / state[3]) * (state[2] - state[1]) + state[1])
+            elseif(frame.___fademode == "OUT") then
+                frame:SetAlpha(((state[3] - state[4]) / state[3]) * (state[1] - state[2]) + state[2])
+            end
+
+        else
+            state[4] = 0
+            frame:SetAlpha(state[2])
+            local canfade = (not InCombatLockdown()) or (InCombatLockdown() and (not frame:IsProtected()))
+            if(frame.___fadehide) then
+                if(canfade) then
+                    frame:Hide()
+                else
+                    frame:SetAlpha(state[2])
+                    FRAMES_TO_HIDE[frame] = true;
+                    FadeEventManager:RegisterEvent("PLAYER_REGEN_ENABLED");
+                end
+            end
+
+            if(frame.___fadefunc and canfade) then
+                local _, catch = pcall(frame.___fadefunc, frame)
+                if(not catch) then
+                    frame.___fadefunc = nil
+                end
+            end
+
+            self.Running = false;
+            self:SetScript("OnUpdate", nil);
+        end
+    end
+end
+
+local SecureFadeIn = function(self, duration, alphaStart, alphaEnd)
+    if(self.___visibilityLocked) then return end
+    local alpha1 = alphaStart or 0;
+    local alpha2 = alphaEnd or 1;
+    local timer = duration or 0.1;
+
+    local canfade = (not InCombatLockdown()) or (InCombatLockdown() and (not self:IsProtected()))
+    if((not self:IsShown()) and canfade) then
+        self:Show()
+    end
+
+    if((not self:IsShown()) and (not canfade)) then
+        FRAMES_TO_SHOW[self] = true
+    end
+
+    if(self:IsShown() and self:GetAlpha() == alpha2) then return end
+    if(not self.___fadehandler) then
+        self.___fadehandler = CreateFrame("Frame", nil)
+        self.___fadehandler.owner = self;
+    end
+    if(not self.___fademode or (self.___fademode and self.___fademode ~= "IN")) then
+        if(FRAMES_TO_HIDE[self]) then
+            FRAMES_TO_HIDE[self] = nil
+        end
+
+        self.___fademode = "IN";
+        self.___fadehide = nil;
+        self.___fadefunc = self.___fadeshowfunc;
+
+        if(not self.___fadeset) then
+            self.___fadeset = {};
+        end
+        self.___fadeset[1] = alpha1;
+        self.___fadeset[2] = alpha2;
+        self.___fadeset[3] = timer;
+
+        self:SetAlpha(alpha1)
+    end
+    if(not self.___fadehandler.Running) then
+        self.___fadehandler.Running = true;
+        self.___fadehandler:SetScript("OnUpdate", SecureFade_OnUpdate)
+    end
+end
+
+local SecureFadeOut = function(self, duration, alphaStart, alphaEnd, hideOnFinished)
+    if(self.___visibilityLocked) then return end
+    local alpha1 = alphaStart or 1;
+    local alpha2 = alphaEnd or 0;
+    local timer = duration or 0.1;
+
+    if((not self:IsShown()) or self:GetAlpha() == alpha2) then return end
+    if(not self.___fadehandler) then
+        self.___fadehandler = CreateFrame("Frame", nil)
+        self.___fadehandler.owner = self;
+    end
+    if(not self.___fademode or (self.___fademode and self.___fademode ~= "OUT")) then
+        if(FRAMES_TO_SHOW[self]) then
+            FRAMES_TO_SHOW[self] = nil
+        end
+
+        self.___fademode = "OUT";
+        self.___fadehide = hideOnFinished;
+        self.___fadefunc = self.___fadehidefunc;
+
+        if(not self.___fadeset) then
+            self.___fadeset = {};
+        end
+
+        self.___fadeset[1] = alpha1;
+        self.___fadeset[2] = alpha2;
+        self.___fadeset[3] = timer;
+
+        self:SetAlpha(alpha1)
+    end
+    if(not self.___fadehandler.Running) then
+        self.___fadehandler.Running = true;
+        self.___fadehandler:SetScript("OnUpdate", SecureFade_OnUpdate)
+    end
+end
+
+local SecureFadeCallback = function(self, callback, alwaysOnHide, alwaysOnShow)
+    if(alwaysOnHide) then
+        self.___fadehidefunc = callback;
+    elseif(alwaysOnShow) then
+        self.___fadeshowfunc = callback;
+    else
+        self.___fadefunc = callback;
+    end
+end
+--[[
+##########################################################
+TEMPLATE INTERNAL HANDLERS
+##########################################################
+]]--
+local HookPanelBorderColor = function(self,r,g,b,a)
+    if self.BorderLeft then
+        self.BorderLeft:SetVertexColor(r,g,b,a)
+        self.BorderRight:SetVertexColor(r,g,b,a)
+        self.BorderTop:SetVertexColor(r,g,b,a)
+        self.BorderBottom:SetVertexColor(r,g,b,a)
+    end
+    if self.InnerGlow then
+        self.InnerGlow:SetBackdropColor(r*0.25,g*0.25,b*0.25,0.5)
+    end
+    if self.Shadow then
+        local alpha = self.Shadow:GetAttribute("shadowAlpha") or 0.5
+        self.Shadow:SetBackdropBorderColor(r,g,b,alpha)
+    end
+end
+
+local HookBackdrop = function(self,...)
+    if(self.Panel) then
+        self.Panel:SetBackdrop(...)
+    end
+end
+
+local HookBackdropColor = function(self,r,g,b)
+    if(self.Panel) then
+        self.Panel:SetBackdropColor(r,g,b)
+    end
+end
+
+local HookBackdropBorderColor = function(self,...)
+    if(self.Panel) then
+        self.Panel:SetBackdropBorderColor(...)
+    end
+end
+
+local HookVertexColor = function(self,...)
+    if(self.Panel) then
+        self.Panel.Skin:SetVertexColor(...)
+    end
+end
+
+local HookCustomBackdrop_TypeA = function(self)
+    if(self.Panel) then
+        local bgid = self.Panel:GetAttribute("panelID")
+        local bdSet = SV.media.backdrop[bgid]
+        if(bdSet) then
+            if(not self.Panel:GetAttribute("panelLocked")) then
+                local edgeSize = bdSet.edgeSize;
+                if(edgeSize and type(edgeSize) == 'number') then
+                    local offset = ceil(edgeSize * 0.2);
+                    self.Panel:ClearAllPoints()
+                    self.Panel:SetPoint("TOPLEFT", self, "TOPLEFT", -offset, offset)
+                    self.Panel:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", offset, -offset)
+                end
+            end
+            self.Panel:SetBackdrop(bdSet)
+            self.Panel:SetBackdropBorderColor(0,0,0,1)
+        else
+            local newBgFile = SV.media.background[bgid]
+            local newBorderFile = SV.media.border[bgid]
+            if(newBgFile and newBorderFile) then
+                local w,h = self:GetSize()
+                local sizeMod = max(w,h)
+                local edgeSize = self.Panel:GetAttribute("panelPadding") or 1
+                local offset = ceil(edgeSize * 0.2)
+                local bdSet = {
+                    bgFile = newBgFile,
+                    edgeFile = newBorderFile,
+                    tile = true,
+                    tileSize = sizeMod,
+                    edgeSize = edgeSize,
+                    insets =
+                    {
+                        left = offset,
+                        right = offset,
+                        top = offset,
+                        bottom = offset,
+                    },
+                };
+                self.Panel:SetBackdrop(bdSet)
+                self.Panel:SetBackdropBorderColor(0,0,0,1)
+                if(not self.Panel:GetAttribute("panelLocked")) then
+                    self.Panel:ClearAllPoints()
+                    self.Panel:SetPoint("TOPLEFT", self, "TOPLEFT", -offset, offset)
+                    self.Panel:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", offset, -offset)
+                end
+            end
+        end
+
+        local colorID = self.Panel:GetAttribute("panelColor")
+        local panelColor = SV.media.color[colorID];
+        if(panelColor) then
+            self.Panel:SetBackdropColor(panelColor[1], panelColor[2], panelColor[3], panelColor[4] or 1)
+        end
+    end
+end
+
+local HookCustomBackdrop_TypeB = function(self)
+    if(self.Panel) then
+        local bgid = self.Panel:GetAttribute("panelID")
+        local bdSet = SV.media.backdrop[bgid]
+        if(bdSet) then
+            self:SetBackdrop(bdSet)
+            self:SetBackdropBorderColor(0,0,0,1)
+        else
+            local newBgFile = SV.media.background[bgid]
+            local newBorderFile = SV.media.border[bgid]
+            if(newBgFile and newBorderFile) then
+                local w,h = self:GetSize()
+                local sizeMod = max(w,h)
+                local edgeSize = self.Panel:GetAttribute("panelPadding") or 1
+                local offset = ceil(edgeSize * 0.2)
+                local bdSet = {
+                    bgFile = newBgFile,
+                    edgeFile = newBorderFile,
+                    tile = true,
+                    tileSize = sizeMod,
+                    edgeSize = edgeSize,
+                    insets =
+                    {
+                        left = offset,
+                        right = offset,
+                        top = offset,
+                        bottom = offset,
+                    },
+                };
+                self:SetBackdrop(bdSet)
+                self:SetBackdropBorderColor(0,0,0,1)
+            end
+        end
+
+        local colorID = self.Panel:GetAttribute("panelColor")
+        local panelColor = SV.media.color[colorID];
+        if(panelColor) then
+            self:SetBackdropColor(panelColor[1], panelColor[2], panelColor[3], panelColor[4] or 1)
+        end
+    end
+end
+
+local HookFrameLevel = function(self, level)
+    if(self.Panel) then
+        local adjustment = level - 1;
+        if(adjustment < 0) then adjustment = 0 end
+        self.Panel:SetFrameLevel(adjustment)
+    end
+end
+
+local Cooldown_ForceUpdate = function(self)
+    self.nextUpdate = 0;
+    self:Show()
+end
+
+local Cooldown_StopTimer = function(self)
+    self.enable = nil;
+    if(self.parent and self.parent.HideAfterCooldown) then
+        self.parent:Hide();
+    else
+        self:Hide();
+    end
+end
+
+local Cooldown_OnUpdate = function(self, elapsed)
+    if self.nextUpdate > 0 then
+        self.nextUpdate = self.nextUpdate - elapsed;
+        return
+    end
+    local now = GetTime();
+    local start = self.start;
+    local remaining = now - start;
+    local expires = (self.duration - remaining);
+    if expires > 0.05 then
+        if (self.fontScale * self:GetEffectiveScale() / UIParent:GetScale()) < 0.5 then
+            self.text:SetText('')
+            self.nextUpdate = 500
+        else
+            local timeLeft = 0;
+            local calc = 0;
+            if expires < 4 then
+                self.nextUpdate = 0.051
+                self.text:SetFormattedText("|cffff0000%.1f|r", expires)
+            elseif expires < 60 then
+                self.nextUpdate = 0.51
+                self.text:SetFormattedText("|cffffff00%d|r", floor(expires))
+            elseif expires < 3600 then
+                timeLeft = ceil(expires / 60);
+                calc = floor((expires / 60) + .5);
+                self.nextUpdate = calc > 1 and ((expires - calc) * 29.5) or (expires - 59.5);
+                self.text:SetFormattedText("|cffffffff%dm|r", timeLeft)
+            elseif expires < 86400 then
+                timeLeft = ceil(expires / 3600);
+                calc = floor((expires / 3600) + .5);
+                self.nextUpdate = calc > 1 and ((expires - calc) * 1799.5) or (expires - 3570);
+                self.text:SetFormattedText("|cff66ffff%dh|r", timeLeft)
+            else
+                timeLeft = ceil(expires / 86400);
+                calc = floor((expires / 86400) + .5);
+                self.nextUpdate = calc > 1 and ((expires - calc) * 43199.5) or (expires - 85680);
+                if(timeLeft > 7) then
+                    self.text:SetFormattedText("|cff6666ff%s|r", "long")
+                else
+                    self.text:SetFormattedText("|cff6666ff%dd|r", timeLeft)
+                end
+            end
+        end
+    else
+        Cooldown_StopTimer(self)
+    end
+end
+
+local Cooldown_OnSizeChanged = function(self, width, height)
+    local frame = self.timer
+    local override = self.SizeOverride
+    local newSize = floor(width + .5) / 36;
+    override = override or frame:GetParent():GetParent().SizeOverride;
+    if override then
+        newSize = override / 20
+    end
+    if newSize == frame.fontScale then
+        return
+    end
+    frame.fontScale = newSize;
+    if newSize < 0.5 and not override then
+        frame:Hide()
+    else
+        frame:Show()
+        frame.text:SetFont(SV.media.font.number, newSize * 15, 'OUTLINE')
+        if frame.enable then
+            Cooldown_ForceUpdate(frame)
+        end
+    end
+end
+
+local CreateCooldownTimer = function(self)
+    local timer = CreateFrame('Frame', nil, self)
+    timer.parent = self:GetParent()
+    timer:SetAllPoints()
+    timer:SetScript('OnUpdate', Cooldown_OnUpdate)
+
+    local timeText = timer:CreateFontString(nil,'OVERLAY')
+    timeText:SetPoint('CENTER',1,1)
+    timeText:SetJustifyH("CENTER")
+    timer.text = timeText;
+
+    timer:Hide()
+
+    self.timer = timer;
+
+    local width, height = self:GetSize()
+    Cooldown_OnSizeChanged(self, width, height)
+    self:SetScript('OnSizeChanged', Cooldown_OnSizeChanged)
+
+    return self.timer
+end
+
+local _hook_Cooldown_SetCooldown = function(self, start, duration, elapsed)
+    if start > 0 and duration > 2.5 then
+        local timer = self.timer or CreateCooldownTimer(self)
+        timer.start = start;
+        timer.duration = duration;
+        timer.enable = true;
+        timer.nextUpdate = 0;
+
+        if timer.fontScale >= 0.5 then
+            timer:Show()
+        end
+    else
+        local timer = self.timer;
+        if timer then
+            Cooldown_StopTimer(timer)
+        end
+    end
+    if self.timer then
+        if elapsed and elapsed > 0 then
+            self.timer:SetAlpha(0)
+        else
+            self.timer:SetAlpha(0.8)
+        end
+    end
+end
+
+local SetFrameBorderColor = function(self, r, g, b, setPrevious, reset)
+    if(setPrevious) then
+        self.Panel.__previous = setPrevious
+    elseif(reset) then
+        r,g,b = unpack(SV.media.color[self.Panel.__previous])
+    end
+    self.Panel.Shadow:SetBackdropBorderColor(r, g, b)
+end
+
+local ShowAlertFlash = function(self)
+    self:ColorBorder(1,0.9,0)
+    SV.Animate:Flash(self.Panel.Shadow, 0.75, true)
+end
+
+local HideAlertFlash = function(self)
+    SV.Animate:StopFlash(self.Panel.Shadow)
+    self:ColorBorder(1,0.9,0, nil, true)
+end
+--[[
+##########################################################
+TEMPLATE HELPERS
+##########################################################
+]]--
+local function SetCD(button, noSwipe)
+    local bn = button:GetName()
+    if(bn) then
+        local cooldown = _G[bn.."Cooldown"];
+        if(cooldown) then
+            if(not SV.db.general or (SV.db.general and (not SV.db.general.cooldown))) then return end
+            cooldown:ClearAllPoints()
+            cooldown:InsetPoints()
+            cooldown:SetDrawEdge(false)
+            cooldown:SetDrawBling(false)
+            cooldown:SetHideCountdownNumbers(true)
+            cooldown.SetHideCountdownNumbers = SV.fubar
+            if(not noSwipe) then
+                cooldown:SetSwipeColor(0, 0, 0, 1)
+            end
+
+            if(not cooldown.HookedCooldown) then
+                hooksecurefunc(cooldown, "SetCooldown", _hook_Cooldown_SetCooldown)
+                cooldown.HookedCooldown = true
+            end
+        end
+        return cooldown
+    end
+    return false
+end
+
+function MOD:FLASH(frame)
+    if(frame.Panel.Shadow) then
+        frame.Panel.__previous = 'darkest';
+        frame.ColorBorder = SetFrameBorderColor
+        frame.StartAlert = ShowAlertFlash
+        frame.StopAlert = HideAlertFlash
+    end
+end
+
+function MOD:CD(frame, noSwipe)
+    local cooldown = SetCD(frame, noSwipe)
+    if(not cooldown) then
+        cooldown = CreateFrame("Cooldown", nil, frame)
+        cooldown:ClearAllPoints()
+        cooldown:InsetPoints(frame, 1, 1)
+        cooldown:SetDrawEdge(false)
+        cooldown:SetDrawBling(false)
+        cooldown:SetHideCountdownNumbers(true)
+        cooldown.SetHideCountdownNumbers = SV.fubar
+        if(not noSwipe) then
+            cooldown:SetSwipeColor(0, 0, 0, 1)
+        end
+        if(not cooldown.HookedCooldown) then
+            hooksecurefunc(cooldown, "SetCooldown", _hook_Cooldown_SetCooldown)
+            cooldown.HookedCooldown = true
+        end
+    end
+    return cooldown
+end
+
+function MOD:APPLY(frame, templateName, underlay, padding, xOffset, yOffset, defaultColor)
+    local xmlTemplate = self.Templates[templateName] or self.Templates.Default;
+
+    local borderColor = {0,0,0,1}
+
+    local panel = CreateFrame('Frame', nil, frame, xmlTemplate)
+
+    local level = frame:GetFrameLevel()
+    if(level == 0 and not InCombatLockdown()) then
+        frame:SetFrameLevel(1)
+        level = 1
+    end
+
+    local adjustment = level - 1;
+
+    if(adjustment < 0) then adjustment = 0 end
+
+    panel:SetFrameLevel(adjustment)
+
+    hooksecurefunc(frame, "SetFrameLevel", HookFrameLevel)
+
+    if(defaultColor) then
+        panel:SetAttribute("panelColor", defaultColor)
+    end
+
+    local panelID       = panel:GetAttribute("panelID")
+    local colorName     = panel:GetAttribute("panelColor")
+    local gradientName  = panel:GetAttribute("panelGradient")
+    local forcedOffset  = panel:GetAttribute("panelOffset")
+
+    if(forcedOffset or xOffset or yOffset) then
+        panel:SetAttribute("panelLocked", true)
+    end
+
+    if(frame.noStyleUpdate) then
+        panel:SetAttribute("panelSkipUpdate", true)
+    end
+
+    padding = padding or panel:GetAttribute("panelPadding")
+    if(forcedOffset) then
+        xOffset = xOffset or forcedOffset
+        yOffset = yOffset or forcedOffset
+    else
+        xOffset = xOffset or padding
+        yOffset = yOffset or padding
+    end
+
+    --panel:WrapPoints(frame, xOffset, yOffset)
+    panel:SetPoint("TOPLEFT", frame, "TOPLEFT", -xOffset, yOffset)
+    panel:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", xOffset, -yOffset)
+
+    local bgColor = SV.media.color[colorName] or SV.media.color.default;
+    local borderColor = SV.media.bordercolor[panelID] or SV.media.bordercolor.default;
+
+    if(panel:GetBackdrop()) then
+        if(underlay) then
+            panel:SetBackdropColor(bgColor[1],bgColor[2],bgColor[3],bgColor[4] or 1)
+            panel:SetBackdropBorderColor(borderColor[1],borderColor[2],borderColor[3],borderColor[4] or 1)
+        else
+            local bd = panel:GetBackdrop()
+            frame:SetBackdrop(bd)
+            frame:SetBackdropColor(bgColor[1],bgColor[2],bgColor[3],bgColor[4] or 1)
+            frame:SetBackdropBorderColor(borderColor[1],borderColor[2],borderColor[3],borderColor[4] or 1)
+
+            panel:SetBackdrop(nil)
+        end
+
+        if(templateName ~= 'Transparent') then
+            hooksecurefunc(panel, "SetBackdropBorderColor", HookPanelBorderColor)
+            hooksecurefunc(frame, "SetBackdropBorderColor", HookBackdropBorderColor)
+            if(underlay) then
+                frame:SetBackdrop(nil)
+                frame.SetBackdrop = panel.SetBackdrop
+                --hooksecurefunc(frame, "SetBackdrop", HookBackdrop)
+                --hooksecurefunc(frame, "SetBackdropColor", HookBackdropColor)
+                frame.UpdateBackdrop = HookCustomBackdrop_TypeA
+            else
+                frame.UpdateBackdrop = HookCustomBackdrop_TypeB
+            end
+
+            frame.BackdropNeedsUpdate = true
+        end
+    end
+
+    if(padding and panel.BorderLeft) then
+        panel.BorderLeft:SetWidth(padding)
+        panel.BorderRight:SetWidth(padding)
+        panel.BorderTop:SetHeight(padding)
+        panel.BorderBottom:SetHeight(padding)
+    end
+
+    if(panel.Shadow) then
+        --panel.Shadow:SetAllPoints(panel)
+        panel.Shadow:SetPoint('TOPLEFT', panel, 'TOPLEFT', -2, 2)
+        panel.Shadow:SetPoint('BOTTOMRIGHT', panel, 'BOTTOMRIGHT', 2, -2)
+
+        local alpha = panel.Shadow:GetAttribute("shadowAlpha") or 0.5
+        panel.Shadow:SetBackdropBorderColor(0,0,0,alpha)
+
+        local level = panel.Shadow:GetFrameLevel() - 1
+        if(level >= 0) then
+            panel.Shadow:SetFrameLevel(level)
+        else
+            panel.Shadow:SetFrameLevel(0)
+        end
+    end
+
+    if(panel.Skin) then
+        panel.Skin:ClearAllPoints()
+        panel.Skin:SetAllPoints(panel)
+        if(not underlay) then
+            panel.Skin:SetParent(frame)
+        end
+        if(gradientName and SV.media.gradient[gradientName]) then
+            panel.Skin:SetGradient(unpack(SV.media.gradient[gradientName]))
+        else
+            panel.Skin:SetVertexColor(bgColor[1], bgColor[2], bgColor[3], bgColor[4] or 1)
+        end
+
+        if((not panel:GetAttribute("panelSkipUpdate")) and panel:GetAttribute("panelTexUpdate")) then
+            frame.TextureNeedsUpdate = true
+            if(panel:GetAttribute("panelHookVertex")) then
+                frame.UpdateColor = HookVertexColor
+                frame.NoColorUpdate = true
+            end
+        end
+    end
+
+    if(panel.TopLeft and (not underlay)) then
+        panel.TopLeft:SetParent(frame)
+        panel.TopRight:SetParent(frame)
+        panel.BottomLeft:SetParent(frame)
+        panel.BottomRight:SetParent(frame)
+    end
+
+    frame.Panel = panel;
+end
+--[[
+##########################################################
+UI ELEMENT METHODS
+##########################################################
+]]--
+local function CommonButtonSettings(frame, addChecked, noSwipe)
+    if(frame.Left) then
+        frame.Left:SetAlpha(0)
+    end
+
+    if(frame.Middle) then
+        frame.Middle:SetAlpha(0)
+    end
+
+    if(frame.Right) then
+        frame.Right:SetAlpha(0)
+    end
+
+    if(frame.SetNormalTexture) then
+        frame:SetNormalTexture("")
+    end
+
+    if(frame.SetDisabledTexture) then
+        frame:SetDisabledTexture("")
+    end
+
+    if(frame.SetCheckedTexture) then
+        frame:SetCheckedTexture("")
+    end
+
+    if(frame.SetHighlightTexture) then
+        if(not frame.hover) then
+            local hover = frame:CreateTexture(nil, "HIGHLIGHT")
+            hover:InsetPoints(frame.Panel)
+            frame.hover = hover;
+        end
+        frame.hover:SetColorTexture(0.1, 0.8, 0.8, 0.5)
+        frame:SetHighlightTexture(frame.hover)
+    end
+
+    if(frame.SetPushedTexture) then
+        if(not frame.pushed) then
+            local pushed = frame:CreateTexture(nil, "OVERLAY")
+            pushed:InsetPoints(frame.Panel)
+            frame.pushed = pushed;
+        end
+        frame.pushed:SetColorTexture(0.1, 0.8, 0.1, 0.3)
+        frame:SetPushedTexture(frame.pushed)
+    end
+
+    if(frame.SetCheckedTexture and addChecked) then
+        if(not frame.checked) then
+            local checked = frame:CreateTexture(nil, "OVERLAY")
+            checked:InsetPoints(frame.Panel)
+            frame.checked = checked
+        end
+        frame.checked:SetColorTexture(0, 0.5, 0, 0.2)
+        frame:SetCheckedTexture(frame.checked)
+    end
+
+    SetCD(frame, noSwipe)
+end
+
+MOD.Methods["Button"] = function(self, frame, inverse, xOffset, yOffset, defaultColor)
+    if(not frame or (frame and frame.Panel)) then return end
+
+    local x,y = -1,-1
+    if(xOffset or yOffset) then
+        x = xOffset or -1
+        y = yOffset or -1
+        inverse = true
+    end
+
+    self:APPLY(frame, "Button", inverse, 1, x, y, defaultColor)
+    CommonButtonSettings(frame, true)
+    if(defaultColor) then
+        frame.Panel:SetAttribute("panelID", "button"..defaultColor)
+        local count = #LIVE_UPDATE_FRAMES+1;
+        LIVE_UPDATE_FRAMES[count] = frame;
+    end
+end;
+
+MOD.Methods["LiteButton"] = function(self, frame, inverse, xOffset, yOffset, defaultColor)
+    if(not frame or (frame and frame.Panel)) then return end
+
+    local x,y = 1,1
+    if(xOffset or yOffset) then
+        x = xOffset or 1
+        y = yOffset or 1
+        inverse = true
+    end
+
+    self:APPLY(frame, "Lite", inverse, 1, x, y)
+    --frame:SetBackdropColor(0,0,0,0)
+    --frame:SetBackdropBorderColor(0,0,0,0)
+    CommonButtonSettings(frame, true)
+end;
+
+MOD.Methods["ActionSlot"] = function(self, frame, inverse, addChecked)
+    if(not frame or (frame and frame.Panel)) then return end
+
+    addChecked = addChecked or false;
+    local underlay = (not inverse)
+    self:APPLY(frame, "ActionSlot", underlay)
+
+    CommonButtonSettings(frame, addChecked, true)
+end;
+
+MOD.Methods["CheckButton"] = function(self, frame, inverse, x, y)
+    if(not frame or (frame and frame.Panel)) then return end
+
+    local width, height = frame:GetSize()
+    width = width * 0.7
+    height = height * 0.7
+    frame:SetSize(width, height)
+
+    local underlay = (not inverse)
+    self:APPLY(frame, "CheckButton", inverse, 1, 1, 1)
+
+    if(frame.SetNormalTexture) then
+        frame:SetNormalTexture("")
+    end
+
+    if(frame.SetPushedTexture) then
+        frame:SetPushedTexture("")
+    end
+
+    if(frame.SetHighlightTexture) then
+        if(not frame.hover) then
+            local hover = frame:CreateTexture(nil, "OVERLAY")
+            hover:InsetPoints(frame.Panel)
+            frame.hover = hover;
+        end
+        local color = SV.media.color.highlight
+        frame.hover:SetTexture(color[1], color[2], color[3], 0.5)
+        frame:SetHighlightTexture(frame.hover)
+    end
+
+    if(frame.SetCheckedTexture) then
+        frame:SetCheckedTexture(SV.media.button.check)
+        local ct = frame:GetCheckedTexture()
+        ct:SetTexCoord(0, 1, 0, 1)
+    end
+
+    if(frame.SetDisabledCheckedTexture) then
+        frame:SetDisabledCheckedTexture(SV.media.button.uncheck)
+        local ct = frame:GetDisabledCheckedTexture()
+        ct:SetTexCoord(0, 1, 0, 1)
+    end
+end;
+
+MOD.Methods["Editbox"] = function(self, frame, inverse, x, y)
+    if(not frame or (frame and frame.Panel)) then return end
+
+    if frame.TopLeftTex then frame.TopLeftTex:Die() end
+    if frame.TopRightTex then frame.TopRightTex:Die() end
+    if frame.TopTex then frame.TopTex:Die() end
+    if frame.BottomLeftTex then frame.BottomLeftTex:Die() end
+    if frame.BottomRightTex then frame.BottomRightTex:Die() end
+    if frame.BottomTex then frame.BottomTex:Die() end
+    if frame.LeftTex then frame.LeftTex:Die() end
+    if frame.RightTex then frame.RightTex:Die() end
+    if frame.MiddleTex then frame.MiddleTex:Die() end
+    if frame.Left then frame.Left:Die() end
+    if frame.Right then frame.Right:Die() end
+    if frame.Middle then frame.Middle:Die() end
+
+    local underlay = (not inverse)
+    self:APPLY(frame, "EditBox", underlay, 1, x, y)
+    if(frame.Panel.InnerGlow) then
+        frame.Panel.InnerGlow:SetFrameLevel(0)
+    end
+    local globalName = frame:GetName();
+    if globalName then
+        if _G[globalName.."Left"] then _G[globalName.."Left"]:Die() end
+        if _G[globalName.."Middle"] then _G[globalName.."Middle"]:Die() end
+        if _G[globalName.."Right"] then _G[globalName.."Right"]:Die() end
+        if _G[globalName.."Mid"] then _G[globalName.."Mid"]:Die() end
+
+        if globalName:find("Silver") or globalName:find("Copper") or globalName:find("Gold") then
+            frame.Panel:SetPoint("TOPLEFT", -3, 1)
+            if globalName:find("Silver") or globalName:find("Copper") then
+                frame.Panel:SetPoint("BOTTOMRIGHT", -12, -2)
+            else
+                frame.Panel:SetPoint("BOTTOMRIGHT", -2, -2)
+            end
+        end
+    end
+end;
+--[[
+##########################################################
+CUSTOM TEMPLATING METHODS
+##########################################################
+]]--
+MOD.Methods["Icon"] = function(self, frame, inverse, ...)
+    if(not frame or (frame and frame.Panel)) then return end
+    local underlay = (not inverse)
+    self:APPLY(frame, "Icon", underlay, ...)
+end;
+
+MOD.Methods["DockButton"] = function(self, frame, inverse, template)
+    if(not frame or (frame and frame.Panel)) then return end
+    template = template or "DockButton"
+    self:APPLY(frame, template, inverse)
+    self:FLASH(frame)
+
+    if(frame.Left) then
+        frame.Left:SetAlpha(0)
+    end
+
+    if(frame.Middle) then
+        frame.Middle:SetAlpha(0)
+    end
+
+    if(frame.Right) then
+        frame.Right:SetAlpha(0)
+    end
+
+    if(frame.SetNormalTexture) then
+        frame:SetNormalTexture("")
+    end
+
+    if(frame.SetDisabledTexture) then
+        frame:SetDisabledTexture("")
+    end
+
+    if(frame.SetCheckedTexture) then
+        frame:SetCheckedTexture("")
+    end
+
+    if(frame.SetHighlightTexture) then
+        if(not frame.hover) then
+            local hover = frame:CreateTexture(nil, "HIGHLIGHT")
+            hover:InsetPoints(frame.Panel)
+            frame.hover = hover;
+        end
+        frame.hover:SetColorTexture(0.1, 0.8, 0.8, 0.5)
+        frame:SetHighlightTexture(frame.hover)
+    end
+
+    if(not frame.Panel:GetAttribute("panelSkipUpdate")) then
+      local count = #LIVE_UPDATE_FRAMES+1;
+      LIVE_UPDATE_FRAMES[count] = frame;
+    end
+end;
+
+MOD.Methods["ShadowBox"] = function(self, frame, inverse, styleName, noupdate, overridePadding, xOffset, yOffset, defaultColor)
+    if(not frame or (frame and frame.Panel)) then return end
+    local padding = false;
+    if(overridePadding and type(overridePadding) == "number") then
+        padding = overridePadding
+    end
+    styleName = styleName or "Default";
+    local underlay = (not inverse)
+    if(noupdate) then
+        frame.noStyleUpdate = true
+    end
+    xOffset = xOffset or 2
+    yOffset = yOffset or 2
+    self:APPLY(frame, styleName, underlay, padding, xOffset, yOffset, defaultColor)
+    local shadowbox = CreateFrame('Frame', nil, frame, "SVUI_ShadowBoxTemplate")
+    shadowbox:SetPoint("TOPLEFT", frame, "TOPLEFT", -xOffset, yOffset)
+    shadowbox:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", xOffset, -yOffset)
+    if(not noupdate) then
+      local count = #LIVE_UPDATE_FRAMES+1;
+      LIVE_UPDATE_FRAMES[count] = frame;
+    end
+end;
+
+MOD.Methods["Frame"] = function(self, frame, inverse, styleName, noupdate, overridePadding, xOffset, yOffset, defaultColor)
+    if(not frame or (frame and frame.Panel)) then return end
+    local padding = false;
+    if(overridePadding and type(overridePadding) == "number") then
+        padding = overridePadding
+    end
+    styleName = styleName or "Default";
+    local underlay = (not inverse)
+    if(noupdate) then
+        frame.noStyleUpdate = true
+    end
+    self:APPLY(frame, styleName, underlay, padding, xOffset, yOffset, defaultColor)
+    if(not noupdate) then
+      local count = #LIVE_UPDATE_FRAMES+1;
+      LIVE_UPDATE_FRAMES[count] = frame;
+    end
+end;
+--[[
+##########################################################
+TEMPLATE API
+##########################################################
+]]--
+local SetPanelColor = function(self, ...)
+    local arg1,arg2,arg3,arg4,arg5,arg6,arg7 = select(1, ...)
+    if(not self.Panel or not arg1) then return; end
+    if(self.Panel.Skin and self.Panel:GetAttribute("panelGradient")) then
+        if(type(arg1) == "string") then
+            if(arg1 == "VERTICAL" or arg1 == "HORIZONTAL") then
+                self.Panel.Skin:SetGradient(...)
+            elseif(SV.media.gradient[arg1]) then
+                self.Panel:SetAttribute("panelColor", arg1)
+                self.Panel.Skin:SetGradient(unpack(SV.media.gradient[arg1]))
+                if(SV.media.color[arg1]) then
+                    local t = SV.media.color[arg1]
+                    self:SetBackdropColor(t[1], t[2], t[3], t[4])
+                end
+            end
+        end
+    elseif(type(arg1) == "string" and SV.media.color[arg1]) then
+        local t = SV.media.color[arg1]
+        self.Panel:SetAttribute("panelColor", arg1)
+        self:SetBackdropColor(t[1], t[2], t[3], t[4])
+    elseif(arg1 and type(arg1) == "number") then
+        self:SetBackdropColor(...)
+    end
+end
+
+local SetStyle = function(self, method, ...)
+    if(not self or (self and self.Panel)) then return end
+    method = method or "Frame";
+    local methodName, flags = method:gsub("!_", "");
+    local param = false;
+    if(flags and (flags > 0)) then
+        param = true;
+    end
+    local fn = MOD.Methods[methodName];
+    if(fn) then
+        local pass, catch = pcall(fn, MOD, self, param, ...)
+        if(catch) then
+            SV:HandleError("API", "SetStyle", catch);
+            return
+        end
+    end
+end
+--[[
+##########################################################
+HOOKED ATLAS HIJACKER
+##########################################################
+]]--
+local ATLAS_THIEF = {} -- Wasn't this the name of a movie?
+local ATLAS_HACKS = {} -- Couldn't think of anything clever honestly.
+ATLAS_HACKS["default"] = function(self)
+  self:SetTexture("")
+end
+
+local StealAtlas = function(self, atlas)
+    if(not self or not atlas) then return end
+    --print(atlas)
+    local hack = ATLAS_THIEF[atlas];
+    if(hack) then
+        local fn = ATLAS_HACKS[hack] or ATLAS_HACKS["default"]
+        local pass, catch = pcall(fn, self, atlas)
+        if(catch) then
+            SV:HandleError("API", "SetStyle", catch);
+            return
+        end
+    end
+end
+--[[
+##########################################################
+UPDATE CALLBACKS
+##########################################################
+]]--
+local function FrameTemplateUpdates()
+    for i=1, #LIVE_UPDATE_FRAMES do
+        local frame = LIVE_UPDATE_FRAMES[i]
+        if(frame) then
+            local panelID = frame.Panel:GetAttribute("panelID")
+            local colorID = frame.Panel:GetAttribute("panelColor")
+            local panelColor = SV.media.color[colorID];
+            if(frame.BackdropNeedsUpdate) then
+                if(frame.UpdateBackdrop) then
+                    frame:UpdateBackdrop()
+                end
+                if(panelColor) then
+                    frame:SetBackdropColor(panelColor[1], panelColor[2], panelColor[3], panelColor[4] or 1)
+                end
+                if(SV.media.bordercolor[panelID]) then
+                    local borderColor = SV.media.bordercolor[panelID]
+                    frame:SetBackdropBorderColor(borderColor[1], borderColor[2], borderColor[3], borderColor[4] or 1)
+                else
+                    frame:SetBackdropBorderColor(0,0,0,1)
+                end
+            end
+            if(frame.TextureNeedsUpdate and frame.Panel.Skin) then
+                local tex = SV.media.background[panelID]
+                if(tex) then
+                    frame.Panel.Skin:SetTexture(tex)
+                    --if(panelID == 'unitlarge') then print(frame.Panel.Skin:GetTexture()) end
+                end
+                if(not frame.NoColorUpdate) then
+                    local gradient = frame.Panel:GetAttribute("panelGradient")
+                    if(gradient and SV.media.gradient[gradient]) then
+                        local g = SV.media.gradient[gradient]
+                        frame.Panel.Skin:SetGradient(g[1], g[2], g[3], g[4], g[5], g[6], g[7])
+                    elseif(panelColor) then
+                        frame.Panel.Skin:SetVertexColor(panelColor[1], panelColor[2], panelColor[3], panelColor[4] or 1)
+                    end
+                end
+            end
+        end
+    end
+end
+
+SV.Events:On("SHARED_MEDIA_UPDATED", FrameTemplateUpdates, true);
+SV.Events:On("REQUEST_TEMPLATE_UPDATED", FrameTemplateUpdates, true);
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+function SV:SetAtlasFunc(atlas, fn)
+    ATLAS_HACKS[atlas] = fn
+end
+
+function SV:SetAtlasFilter(atlas, fn)
+    if(not fn) then
+        fn = "default"
+    end
+    ATLAS_THIEF[atlas] = fn
+end
+--[[
+##########################################################
+SCREEN HANDLER (IN DEVELOPMENT)
+##########################################################
+]]--
+function SV:UI_SCALE_CHANGED(event)
+    local managedScale = self.db.screen.autoScale;
+    local gxWidth, gxHeight, gxScale, customScale = ScreenUpdate();
+
+    if(managedScale) then
+        local needCalc = true;
+        if(self.db.screen.advanced) then
+            if(self.db.screen.forcedWidth ~= gxWidth) then
+                gxWidth = self.db.screen.forcedWidth
+                needCalc = false;
+            end
+            if(self.db.screen.forcedHeight ~= gxHeight) then
+                gxHeight = self.db.screen.forcedHeight
+                needCalc = false;
+            end
+        end
+        if(needCalc) then
+            if(gxWidth < 1600) then
+                self.LowRez = true;
+            elseif(gxWidth >= 3840) then
+                self.LowRez = nil
+                local evalwidth;
+                if(self.db.screen.multiMonitor) then
+                    if(gxWidth < 4080) then
+                        evalwidth = 1224;
+                    elseif(gxWidth < 4320) then
+                        evalwidth = 1360;
+                    elseif(gxWidth < 4680) then
+                        evalwidth = 1400;
+                    elseif(gxWidth < 4800) then
+                        evalwidth = 1440;
+                    elseif(gxWidth < 5760) then
+                        if(gxHeight == 900) then evalwidth = 1600 else evalwidth = 1680 end
+                    elseif(gxWidth < 7680) then
+                        evalwidth = 1920;
+                    elseif(gxWidth < 9840) then
+                        evalwidth = 2560;
+                    elseif(gxWidth > 9839) then
+                        evalwidth = 3280;
+                    end
+                else
+                    if(gxWidth < 4080) then
+                        evalwidth = 3840;
+                    elseif(gxWidth < 4320) then
+                        evalwidth = 4080;
+                    elseif(gxWidth < 4680) then
+                        evalwidth = 4320;
+                    elseif(gxWidth < 4800) then
+                        evalwidth = 4680;
+                    elseif(gxWidth < 5040) then
+                        evalwidth = 4800;
+                    elseif(gxWidth < 5760) then
+                        evalwidth = 5040;
+                    elseif(gxWidth < 7680) then
+                        evalwidth = 5760;
+                    elseif(gxWidth < 9840) then
+                        evalwidth = 7680;
+                    elseif(gxWidth > 9839) then
+                        evalwidth = 9840;
+                    end
+                end
+
+                gxWidth = evalwidth;
+            end
+        end
+    end
+    if(event == 'PLAYER_LOGIN' or event == 'UI_SCALE_CHANGED') then
+        self.Screen:ClearAllPoints()
+        self.Screen:SetPoint("CENTER")
+        local ignoreChange = false;
+
+        if(managedScale) then
+            local testScale1 = parsefloat(UIParent:GetScale(), 5);
+            local testScale2 = parsefloat(gxScale, 5);
+
+            if(event == "PLAYER_LOGIN" and (testScale1 ~= testScale2)) then
+                SetCVar("useUiScale", 1)
+                SetCVar("uiScale", gxScale)
+                WorldMapFrame.hasTaint = true;
+                ignoreChange = true;
+                _G.Advanced_UseUIScale:SetScale(0.0001)
+                _G.Advanced_UseUIScale:SetAlpha(0)
+                _G.Advanced_UIScaleSlider:SetScale(0.0001)
+                _G.Advanced_UIScaleSlider:SetAlpha(0)
+            end
+
+            if(gxWidth) then
+                local width = gxWidth
+                local height = gxHeight;
+                if(height > 1200) then
+                    height = UIParent:GetHeight();
+                    local ratio = gxHeight / height;
+                    width = gxWidth / ratio;
+                end
+                self.Screen:SetSize(width, height);
+            else
+                self.Screen:SetSize(UIParent:GetSize());
+            end
+        else
+            self.Screen:SetSize(UIParent:GetSize());
+        end
+
+        if((not customScale) and (not ignoreChange) and (event == 'UI_SCALE_CHANGED')) then
+            local change = abs((testScale1 * 100) - (testScale2 * 100))
+            if(change > 1) then
+                if(managedScale) then
+                    self:StaticPopup_Show('CHANGED_MANAGED_UISCALE')
+                elseif(BlizzardOptionsPanel_GetCVarSafe("useUiScale") ~= 0) then
+                    self:StaticPopup_Show('RELOAD_UI')
+                end
+            end
+        end
+    end
+end
+--[[
+##########################################################
+API INJECTION
+##########################################################
+]]--
+local MODIFIED_OBJECTS = {};
+local CURRENT_OBJECT = CreateFrame("Frame");
+
+local function AppendFrameMethods(OBJECT)
+    local objType = OBJECT:GetObjectType()
+    if(not MODIFIED_OBJECTS[objType]) then
+        local META = getmetatable(OBJECT).__index
+        if not OBJECT.SetStyle then META.SetStyle = SetStyle end
+        if not OBJECT.SetPanelColor then META.SetPanelColor = SetPanelColor end
+        if not OBJECT.ModSize then META.ModSize = ModSize end
+        if not OBJECT.SetSecurePoint then META.SetSecurePoint = SetSecurePoint end
+        if not OBJECT.SetAllSecurePoints then META.SetAllSecurePoints = SetAllSecurePoints end
+        if not OBJECT.WrapPoints then META.WrapPoints = WrapPoints end
+        if not OBJECT.InsetPoints then META.InsetPoints = InsetPoints end
+        if not OBJECT.Die then META.Die = Die end
+        if not OBJECT.RemoveTextures then META.RemoveTextures = RemoveTextures end
+        if not OBJECT.FadeIn then META.FadeIn = SecureFadeIn end
+        if not OBJECT.FadeOut then META.FadeOut = SecureFadeOut end
+        if not OBJECT.FadeCallback then META.FadeCallback = SecureFadeCallback end
+        MODIFIED_OBJECTS[objType] = true
+    end
+end
+
+local function AppendTextureMethods(OBJECT)
+    local META = getmetatable(OBJECT).__index
+    if not OBJECT.ModSize then META.ModSize = ModSize end
+    if not OBJECT.SetSecurePoint then META.SetSecurePoint = SetSecurePoint end
+    if not OBJECT.SetAllSecurePoints then META.SetAllSecurePoints = SetAllSecurePoints end
+    if not OBJECT.WrapPoints then META.WrapPoints = WrapPoints end
+    if not OBJECT.InsetPoints then META.InsetPoints = InsetPoints end
+    if not OBJECT.Die then META.Die = Die end
+    if(OBJECT.SetAtlas) then
+        hooksecurefunc(META, "SetAtlas", StealAtlas)
+    end
+end
+
+local function AppendFontStringMethods(OBJECT)
+    local META = getmetatable(OBJECT).__index
+    if not OBJECT.ModSize then META.ModSize = ModSize end
+    if not OBJECT.SetSecurePoint then META.SetSecurePoint = SetSecurePoint end
+    if not OBJECT.SetAllSecurePoints then META.SetAllSecurePoints = SetAllSecurePoints end
+    if not OBJECT.WrapPoints then META.WrapPoints = WrapPoints end
+    if not OBJECT.InsetPoints then META.InsetPoints = InsetPoints end
+end
+
+AppendFrameMethods(CURRENT_OBJECT)
+AppendTextureMethods(CURRENT_OBJECT:CreateTexture())
+AppendFontStringMethods(CURRENT_OBJECT:CreateFontString())
+
+CURRENT_OBJECT = EnumerateFrames()
+while CURRENT_OBJECT do
+    AppendFrameMethods(CURRENT_OBJECT)
+    CURRENT_OBJECT = EnumerateFrames(CURRENT_OBJECT)
+end
+--[[
+##########################################################
+STYLING CONCEPTS
+##########################################################
+]]--
+local Button_OnEnter = function(self)
+    self:SetBackdropColor(0.1, 0.8, 0.8)
+end
+
+local Button_OnLeave = function(self)
+    self:SetBackdropColor(unpack(SV.media.color.button))
+end
+
+local ConceptButton_OnEnter = function(self)
+    self:SetBackdropBorderColor(0.1, 0.8, 0.8)
+end
+
+local ConceptButton_OnLeave = function(self)
+    self:SetBackdropBorderColor(0,0,0,1)
+end
+
+local Tab_OnEnter = function(self)
+    self.backdrop:SetPanelColor("highlight")
+    self.backdrop:SetBackdropBorderColor(0.1, 0.8, 0.8)
+end
+
+local Tab_OnLeave = function(self)
+    self.backdrop:SetPanelColor("button")
+    self.backdrop:SetBackdropBorderColor(0,0,0,1)
+end
+
+local _hook_DropDownButton_SetPoint = function(self, _, _, _, _, _, breaker)
+    if not breaker then
+        self:SetPoint("RIGHT", self.AnchorParent, "RIGHT", -10, 3, true)
+    end
+end
+
+local _hook_Tooltip_OnShow = function(self)
+    self:SetBackdrop(SV.media.backdrop.tooltip)
+end
+
+MOD.Concepts["Frame"] = function(self, adjustable, frame, template, noStripping, padding, xOffset, yOffset)
+    if(not frame or (frame and frame.Panel)) then return end
+    template = template or "Transparent"
+    local baselevel = frame:GetFrameLevel()
+    if(baselevel < 1) then
+        frame:SetFrameLevel(1)
+    end
+    if(not noStripping) then
+        RemoveTextures(frame)
+    end
+    self.Methods["Frame"](self, frame, (not adjustable), template, true, padding, xOffset, yOffset)
+end
+
+MOD.Concepts["Window"] = function(self, adjustable, frame, altStyle, fullStrip, padding, xOffset, yOffset)
+    if(not frame or (frame and frame.Panel)) then return end
+    local template = altStyle and "Window2" or "Window"
+    local baselevel = frame:GetFrameLevel()
+    if(baselevel < 1) then
+        frame:SetFrameLevel(1)
+    end
+    RemoveTextures(frame, fullStrip)
+    local name = frame:GetName()
+    if(name and _G[name.."BtnCornerLeft"]) then
+      _G[name.."BtnCornerLeft"]:SetTexture("");
+		  _G[name.."BtnCornerRight"]:SetTexture("");
+		  _G[name.."ButtonBottomBorder"]:SetTexture("");
+    end
+    self.Methods["Frame"](self, frame, (not adjustable), template, false, padding, xOffset, yOffset)
+    if(frame.Inset) then
+      RemoveTextures(frame.Inset, fullStrip)
+      self.Methods["Frame"](self, frame.Inset, adjustable, "Inset", false, 3, 1, 1)
+    end
+    if(frame.portrait) then
+        frame.portrait:Hide()
+    end
+end
+
+MOD.Concepts["Button"] = function(self, adjustable, frame)
+    if(not frame or (frame and frame.Panel)) then return end
+    RemoveTextures(frame)
+    self.Methods["Button"](self, frame, adjustable)
+end
+
+MOD.Concepts["IconButton"] = function(self, adjustable, frame, texture)
+    if(not frame or (frame and frame.Panel)) then return end
+    iconTexture = texture or frame:GetNormalTexture()
+    RemoveTextures(frame)
+    self.Methods["Button"](self, frame, adjustable, -1, -1)
+    if not frame.icon then
+        frame.icon = frame:CreateTexture(nil,'ARTWORK')
+        InsetPoints(frame.icon, frame, 3, 3);
+        frame.icon:SetTexture(iconTexture)
+        frame.icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+    end
+end
+
+MOD.Concepts["CheckButton"] = function(self, adjustable, frame)
+    if(not frame or (frame and frame.Panel)) then return end
+    --RemoveTextures(frame)
+    self.Methods["CheckButton"](self, frame, adjustable)
+end
+
+MOD.Concepts["CloseButton"] = function(self, adjustable, frame, targetAnchor)
+    if(not frame or (frame and frame.Panel)) then return end
+
+    RemoveTextures(frame)
+
+    self.Methods["Button"](self, frame, adjustable, -6, -6, "red")
+    frame:SetFrameLevel(frame:GetFrameLevel() + 4)
+    frame:SetNormalTexture(SV.media.icon.close)
+    frame:HookScript("OnEnter", ConceptButton_OnEnter)
+    frame:HookScript("OnLeave", ConceptButton_OnLeave)
+
+    if(targetAnchor) then
+        frame:ClearAllPoints()
+        frame:SetPoint("TOPRIGHT", targetAnchor, "TOPRIGHT", 3, 3)
+    end
+end
+
+MOD.Concepts["InfoButton"] = function(self, adjustable, frame, targetAnchor, size)
+    if(not frame or (frame and frame.Panel)) then return end
+
+    RemoveTextures(frame)
+    size = size or 26
+    frame:SetSize(size, size)
+    --self.Methods["Button"](self, frame, false, -2, -2, "yellow")
+    frame:SetNormalTexture(SV.media.icon.info)
+    --frame:HookScript("OnEnter", ConceptButton_OnEnter)
+    --frame:HookScript("OnLeave", ConceptButton_OnLeave)
+
+    if(targetAnchor) then
+        frame:ClearAllPoints()
+        frame:SetPoint("TOPRIGHT", targetAnchor, "TOPRIGHT", 3, 3)
+    end
+end
+
+MOD.Concepts["ArrowButton"] = function(self, adjustable, frame, direction, targetAnchor)
+    if(not frame or (frame and frame.Panel)) then return end
+    local iconKey = "move_" .. direction:lower()
+
+    RemoveTextures(frame)
+
+    self.Methods["Button"](self, frame, adjustable, -7, -7, "green")
+    frame:SetFrameLevel(frame:GetFrameLevel() + 4)
+    frame:SetNormalTexture(SV.media.icon[iconKey])
+    frame:HookScript("OnEnter", ConceptButton_OnEnter)
+    frame:HookScript("OnLeave", ConceptButton_OnLeave)
+
+    if(targetAnchor) then
+        frame:ClearAllPoints()
+        frame:SetPoint("TOPRIGHT", targetAnchor, "TOPRIGHT", 0, 0)
+    end
+end
+
+MOD.Concepts["ItemButton"] = function(self, adjustable, frame, noScript)
+    if(not frame) then return end
+
+    RemoveTextures(frame)
+
+    if(not frame.Panel) then
+        if(not noScript) then
+            self.Methods["Frame"](self, frame, false, "Button", true, 1, -1, -1)
+            frame:HookScript("OnEnter", Button_OnEnter)
+            frame:HookScript("OnLeave", Button_OnLeave)
+        else
+            self.Methods["Frame"](self, frame, false, "Inset", true, 1, -1, -1)
+            -- frame:HookScript("OnEnter", ConceptButton_OnEnter)
+            -- frame:HookScript("OnLeave", ConceptButton_OnLeave)
+        end
+    end
+
+    local link = frame:GetName()
+
+    if(link) then
+        local nameObject = _G[("%sName"):format(link)]
+        local subNameObject = _G[("%sSubName"):format(link)]
+        local arrowObject = _G[("%sFlyoutArrow"):format(link)]
+        local levelObject = _G[("%sLevel"):format(link)]
+        local iconObject = _G[("%sIcon"):format(link)] or _G[("%sIconTexture"):format(link)] or frame.Icon or frame.icon
+        local countObject = _G[("%sCount"):format(link)]
+
+        if(not frame.Riser) then
+            local fg = CreateFrame("Frame", nil, frame)
+            fg:SetSize(120, 22)
+            fg:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", 0, -11)
+            fg:SetFrameLevel(frame:GetFrameLevel() + 1)
+            frame.Riser = fg
+        end
+
+        if(iconObject) then
+            iconObject:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+
+            if(not adjustable) then
+                iconObject:InsetPoints(frame, 2, 2)
+            end
+            if(not frame.IconShadow) then
+                frame.IconShadow = CreateFrame("Frame", nil, frame)
+                frame.IconShadow:WrapPoints(iconObject)
+                frame.IconShadow:SetStyle("Icon")
+            end
+
+            iconObject:SetParent(frame.Riser)
+            iconObject:SetDrawLayer("ARTWORK", -1)
+        end
+
+        if(countObject) then
+            countObject:SetParent(frame.Riser)
+            countObject:SetAllPoints(frame.Riser)
+            countObject:SetFontObject(SVUI_Font_Number)
+            countObject:SetDrawLayer("ARTWORK", 7)
+        end
+
+        if(nameObject) then nameObject:SetParent(frame.Riser) end
+        if(subNameObject) then subNameObject:SetParent(frame.Riser) end
+        if(arrowObject) then arrowObject:SetParent(frame.Riser) end
+
+        if(levelObject) then
+            levelObject:SetParent(frame.Riser)
+            levelObject:SetFontObject(SVUI_Font_Number)
+            levelObject:SetDrawLayer("ARTWORK", 7)
+        end
+    end
+end
+
+MOD.Concepts["PageButton"] = function(self, adjustable, frame, isVertical, isLeft)
+    if(not frame) then return end
+
+    local bName = frame:GetName()
+    local leftDown;
+    if(bName) then
+        local testName = bName:lower()
+        leftDown = ((bName and testName:find('left')) or testName:find('prev') or testName:find('decrement')) or false
+    else
+        leftDown = isLeft or false
+    end
+
+    frame:SetNormalTexture("")
+    frame:SetPushedTexture("")
+    frame:SetHighlightTexture("")
+    frame:SetDisabledTexture("")
+
+    if(not frame.Panel) then
+        RemoveTextures(frame)
+        frame:SetFrameLevel(frame:GetFrameLevel() + 2)
+        self.Methods["Button"](self, frame, adjustable, -4, -4)
+    end
+
+    if not frame.icon then
+        frame.icon = frame:CreateTexture(nil,'ARTWORK')
+        frame.icon:SetSize(13, 13)
+        frame.icon:SetPoint('CENTER')
+        frame.icon:SetTexture(SV.media.button.radio)
+        frame.icon:SetTexCoord(0.02, 0.2, 0.02, 0.2)
+
+        frame:HookScript('OnMouseDown',function(self)
+            if self:IsEnabled() then
+                self.icon:SetPoint("CENTER",-1,-1)
+            end
+        end)
+
+        frame:HookScript('OnMouseUp',function(self)
+            self.icon:SetPoint("CENTER",0,0)
+        end)
+
+        frame:SetScript('OnDisable',function(self)
+            SetDesaturation(self.icon, true)
+            self.icon:SetAlpha(0.5)
+        end)
+
+        frame:SetScript('OnEnable',function(self)
+            SetDesaturation(self.icon, false)
+            self.icon:SetAlpha(1.0)
+        end)
+
+        if not frame:IsEnabled() then
+            frame:GetScript('OnDisable')(frame)
+        end
+    end
+
+    if isVertical then
+        if leftDown then SquareButton_SetIcon(frame,'UP') else SquareButton_SetIcon(frame,'DOWN')end
+    else
+        if leftDown then SquareButton_SetIcon(frame,'LEFT') else SquareButton_SetIcon(frame,'RIGHT')end
+    end
+end
+
+MOD.Concepts["Tab"] = function(self, adjustable, frame, addBackground, xOffset, yOffset)
+    if(not frame or (frame and frame.Panel)) then return end
+
+    local tab = frame:GetName();
+
+    if _G[tab.."Left"] then _G[tab.."Left"]:SetTexture("") end
+    if _G[tab.."LeftDisabled"] then _G[tab.."LeftDisabled"]:SetTexture("") end
+    if _G[tab.."Right"] then _G[tab.."Right"]:SetTexture("") end
+    if _G[tab.."RightDisabled"] then _G[tab.."RightDisabled"]:SetTexture("") end
+    if _G[tab.."Middle"] then _G[tab.."Middle"]:SetTexture("") end
+    if _G[tab.."MiddleDisabled"] then _G[tab.."MiddleDisabled"]:SetTexture("") end
+
+    if(frame.GetHighlightTexture and frame:GetHighlightTexture()) then
+        frame:GetHighlightTexture():SetTexture("")
+    end
+
+    RemoveTextures(frame)
+
+    if(addBackground) then
+        local nTex = frame:GetNormalTexture()
+
+        if(nTex) then
+            nTex:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+            InsetPoints(nTex, frame)
+        end
+
+        xOffset = xOffset or 1
+        yOffset = yOffset or 1
+
+        frame.pushed = true;
+        frame.backdrop = CreateFrame("Frame", nil, frame)
+        WrapPoints(frame.backdrop, frame, xOffset, yOffset)
+        frame.backdrop:SetFrameLevel(0)
+        self.Methods["Frame"](self, frame.backdrop, (not adjustable), "Button", false)
+
+        local initialAnchor, anchorParent, relativeAnchor, xPosition, yPosition = frame:GetPoint()
+        frame:SetPoint(initialAnchor, anchorParent, relativeAnchor, 1, yPosition)
+    else
+        xOffset = xOffset or 10
+        yOffset = yOffset or 3
+        frame.backdrop = CreateFrame("Frame", nil, frame)
+        InsetPoints(frame.backdrop, frame, xOffset, yOffset);
+        if(frame:GetFrameLevel() > 0) then
+            frame.backdrop:SetFrameLevel(frame:GetFrameLevel() - 1)
+        end
+
+        self.Methods["Frame"](self, frame.backdrop, (not adjustable), "Button", false)
+    end
+
+    frame:HookScript("OnEnter", Tab_OnEnter)
+    frame:HookScript("OnLeave", Tab_OnLeave)
+    -- if(frame.backdrop.UpdateBackdrop) then
+    --     frame.backdrop:UpdateBackdrop()
+    -- end
+end
+
+MOD.Concepts["DropDown"] = function(self, adjustable, frame, width)
+    if(not frame or (frame and frame.Panel)) then return end
+
+    local ddName = frame:GetName();
+    local ddText = _G[("%sText"):format(ddName)]
+    local ddButton = _G[("%sButton"):format(ddName)]
+
+    if not width then width = max(frame:GetWidth(), 128) end
+
+    RemoveTextures(frame)
+    frame:SetWidth(width)
+
+    if(ddButton) then
+        if(ddText) then
+            ddText:SetPoint("RIGHT", ddButton, "LEFT", 2, 0)
+        end
+
+        ddButton:ClearAllPoints()
+        ddButton:SetPoint("RIGHT", frame, "RIGHT", -10, 3)
+        ddButton.AnchorParent = frame
+
+        hooksecurefunc(ddButton, "SetPoint", _hook_DropDownButton_SetPoint)
+
+        self.Concepts["PageButton"](self, false, ddButton, true)
+
+        local currentLevel = frame:GetFrameLevel()
+        if(currentLevel == 0) then
+            currentLevel = 1
+        end
+
+        if(not frame.BG) then
+            frame.BG = frame:CreateTexture(nil, "BACKGROUND")
+            frame.BG:SetPoint("TOPLEFT", frame, "TOPLEFT", 18, -2)
+            frame.BG:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -10, 6)
+            frame.BG:SetTexture(SV.media.background.transparent)
+
+            local fg = CreateFrame("Frame", nil, frame)
+            fg:SetPoint("TOPLEFT", frame, "TOPLEFT", 18, -2)
+            fg:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -10, 6)
+            fg:SetBackdrop(SV.media.backdrop.outline)
+            frame.Brdr = fg
+        end
+    end
+end
+
+MOD.Concepts["Tooltip"] = function(self, adjustable, frame, useHook)
+    if(not frame or (frame and frame.Panel)) then return end
+
+    if frame.Background then
+        frame.Background:SetTexture("")
+    end
+
+    if frame.Delimiter1 then
+        frame.Delimiter1:SetTexture("")
+        frame.Delimiter2:SetTexture("")
+    end
+
+    if frame.BorderTop then
+        frame.BorderTop:SetTexture("")
+    end
+
+    if frame.BorderTopLeft then
+        frame.BorderTopLeft:SetTexture("")
+    end
+
+    if frame.BorderTopRight then
+        frame.BorderTopRight:SetTexture("")
+    end
+
+    if frame.BorderLeft then
+        frame.BorderLeft:SetTexture("")
+    end
+
+    if frame.BorderRight then
+        frame.BorderRight:SetTexture("")
+    end
+
+    if frame.BorderBottom then
+        frame.BorderBottom:SetTexture("")
+    end
+
+    if frame.BorderBottomRight then
+        frame.BorderBottomRight:SetTexture("")
+    end
+
+    if frame.BorderBottomLeft then
+        frame.BorderBottomLeft:SetTexture("")
+    end
+
+    frame:SetBackdrop(SV.media.backdrop.tooltip)
+
+    if(useHook) then
+        frame:HookScript('OnShow', _hook_Tooltip_OnShow)
+    end
+end
+
+MOD.Concepts["EditBox"] = function(self, adjustable, frame, width, height, x, y)
+    if(not frame or (frame and frame.Panel)) then return end
+
+    RemoveTextures(frame, true)
+    self.Methods["Editbox"](self, frame, adjustable, x, y)
+
+    if width then frame:SetWidth(width) end
+    if height then frame:SetHeight(height) end
+end
+
+MOD.Concepts["QuestItem"] = function(self, adjustable, frame)
+    if(not frame or (frame and frame.Panel)) then return end
+
+    local icon, oldIcon;
+    local name = frame:GetName();
+    if(name and _G[name.."IconTexture"]) then
+        icon = _G[name.."IconTexture"];
+        oldIcon = _G[name.."IconTexture"]:GetTexture();
+    elseif(frame.Icon) then
+        icon = frame.Icon;
+        oldIcon = frame.Icon:GetTexture();
+    end
+
+    RemoveTextures(frame)
+    self.Methods["Icon"](self, frame, adjustable)
+
+    local width,height = frame:GetSize()
+    local fittedWidth = (width - height) + 4
+    local insetFrame = CreateFrame("Frame", nil, frame.Panel)
+    insetFrame:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT")
+    insetFrame:SetWidth(fittedWidth)
+    insetFrame:SetHeight(height)
+    self.Methods["Frame"](self, insetFrame, false, "Inset", 1, 0, -2)
+
+    if(icon) then
+        local size = height - 4
+        icon:ClearAllPoints()
+        icon:SetPoint("TOPLEFT", frame, "TOPLEFT", 2, -2)
+        icon:SetSize(size, size)
+
+        local iconFallback = frame.Panel:CreateTexture(nil, "BACKGROUND")
+        iconFallback:SetAllPoints(icon)
+        iconFallback:SetTexture([[Interface\ICONS\INV_Misc_Bag_10]])
+        iconFallback:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+
+        if(oldIcon) then
+            icon:SetTexture(oldIcon)
+        end
+        icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+    end
+end
+
+MOD.Concepts["Skin"] = function(self, style, frame, topX, topY, bottomX, bottomY)
+    if(not frame or (frame and frame.Panel)) then return end
+    if(not style) then style = "model" end
+    local artname = style:lower()
+    local texture = SV.media.background[artname] or SV.media.background.model
+    RemoveTextures(frame, true)
+
+    local borderFrame = CreateFrame("Frame", nil, frame)
+    borderFrame:SetPoint("TOPLEFT", frame, "TOPLEFT", topX, topY)
+    borderFrame:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", bottomX, bottomY)
+    borderFrame:SetBackdrop(SV.media.backdrop.outline)
+
+    local skin = frame:CreateTexture(nil, "BACKGROUND", nil, -1)
+    skin:SetAllPoints(borderFrame)
+    skin:SetTexture(texture)
+    skin:SetGradient(unpack(SV.media.gradient.special))
+end
+
+local ALERT_TEMPLATE = {
+    ["typeA"] = {
+        COLOR   = {0.8, 0.2, 0.2},
+        BG      = [[Interface\AddOns\SVUI_!Core\assets\textures\Alert\ALERT-BG]],
+        LEFT    = [[Interface\AddOns\SVUI_!Core\assets\textures\Alert\ALERT-LEFT]],
+        RIGHT   = [[Interface\AddOns\SVUI_!Core\assets\textures\Alert\ALERT-RIGHT]],
+        TOP     = [[Interface\AddOns\SVUI_!Core\assets\textures\Alert\ALERT-TOP]],
+        BOTTOM  = [[Interface\AddOns\SVUI_!Core\assets\textures\Alert\ALERT-BOTTOM]],
+    },
+    ["typeB"] = {
+        COLOR   = {0.08, 0.4, 0},
+        BG      = [[Interface\AddOns\SVUI_!Core\assets\textures\Alert\ALERT-BG-2]],
+        LEFT    = [[Interface\AddOns\SVUI_!Core\assets\textures\Alert\ALERT-LEFT-2]],
+        RIGHT   = [[Interface\AddOns\SVUI_!Core\assets\textures\Alert\ALERT-RIGHT-2]],
+        TOP     = [[Interface\AddOns\SVUI_!Core\assets\textures\Alert\ALERT-TOP]],
+        BOTTOM  = [[Interface\AddOns\SVUI_!Core\assets\textures\Alert\ALERT-BOTTOM]],
+    },
+};
+
+local SetIconAlertColor = function(self, r, g, b)
+    self.AlertPanel.icon:SetGradient('VERTICAL', (r*0.5), (g*0.5), (b*0.5), r, g, b)
+end;
+
+local SetAlertColor = function(self, r, g, b)
+    self.AlertPanel:SetBackdropColor(r,g,b)
+    self.AlertPanel.left:SetVertexColor(r,g,b)
+    self.AlertPanel.right:SetVertexColor(r,g,b)
+    self.AlertPanel.top:SetVertexColor(r,g,b)
+    self.AlertPanel.bottom:SetVertexColor(r,g,b)
+end;
+
+MOD.Concepts["Alert"] = function(self, defaultStyle, frame, arg)
+    if(not frame or (frame and frame.AlertPanel)) then return end
+
+    if(not defaultStyle) then
+        local size = frame:GetWidth() * 0.5;
+        local lvl = frame:GetFrameLevel();
+
+        if lvl < 1 then lvl = 1 end
+
+        local alertpanel = CreateFrame("Frame", nil, frame)
+        alertpanel:SetPoint("TOPLEFT", frame, "TOPLEFT", -25, 10)
+        alertpanel:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 10, 10)
+        alertpanel:SetHeight(size)
+        alertpanel:SetFrameLevel(lvl - 1)
+
+        --[[ FRAME BG ]]--
+        alertpanel.bg = alertpanel:CreateTexture(nil, "BACKGROUND", nil, -5)
+        alertpanel.bg:SetAllPoints()
+        alertpanel.bg:SetTexture([[Interface\AddOns\SVUI_!Core\assets\textures\Alert\ALERT-FULL]])
+        alertpanel.bg:SetGradient('VERTICAL', 0, 0, 0, .37, .32, .29)
+
+        --[[ ICON BG ]]--
+        alertpanel.icon = alertpanel:CreateTexture(nil, "BACKGROUND", nil, -2)
+        alertpanel.icon:SetTexture([[Interface\AddOns\SVUI_!Core\assets\textures\Alert\ALERT-ICON-BORDER]])
+        alertpanel.icon:SetGradient('VERTICAL', 1, 0.35, 0, 1, 1, 0)
+        alertpanel.icon:SetPoint("LEFT", alertpanel, "LEFT", -10, 30)
+        alertpanel.icon:SetSize(size, size)
+
+        frame.AlertPanel = alertpanel
+        frame.AlertColor = SetIconAlertColor
+    else
+        local alertType = arg and "typeB" or "typeA";
+
+        local TEMPLATE = ALERT_TEMPLATE[alertType];
+        local r,g,b = unpack(TEMPLATE.COLOR);
+        local size = frame:GetHeight();
+        local half = size * 0.5;
+        local offset = size * 0.1;
+        local lvl = frame:GetFrameLevel();
+
+        if lvl < 1 then lvl = 1 end
+
+        local alertpanel = CreateFrame("Frame", nil, frame)
+        alertpanel:SetPoint("TOPLEFT", frame, "TOPLEFT", offset, 0)
+        alertpanel:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -offset, 0)
+        alertpanel:SetFrameLevel(lvl - 1)
+        alertpanel:SetBackdrop({
+            bgFile = TEMPLATE.BG
+        })
+        alertpanel:SetBackdropColor(r,g,b)
+
+        --[[ LEFT ]]--
+        alertpanel.left = alertpanel:CreateTexture(nil, "BORDER")
+        alertpanel.left:SetTexture(TEMPLATE.LEFT)
+        alertpanel.left:SetVertexColor(r,g,b)
+        alertpanel.left:SetPoint("TOPRIGHT", alertpanel, "TOPLEFT", 0, 0)
+        alertpanel.left:SetPoint("BOTTOMRIGHT", alertpanel, "BOTTOMLEFT", 0, 0)
+        alertpanel.left:SetWidth(size)
+
+        --[[ RIGHT ]]--
+        alertpanel.right = alertpanel:CreateTexture(nil, "BORDER")
+        alertpanel.right:SetTexture(TEMPLATE.RIGHT)
+        alertpanel.right:SetVertexColor(r,g,b)
+        alertpanel.right:SetPoint("TOPLEFT", alertpanel, "TOPRIGHT", 0, 0)
+        alertpanel.right:SetPoint("BOTTOMLEFT", alertpanel, "BOTTOMRIGHT", 0, 0)
+        alertpanel.right:SetWidth(size * 2)
+
+        --[[ TOP ]]--
+        alertpanel.top = alertpanel:CreateTexture(nil, "BORDER")
+        alertpanel.top:SetTexture(TEMPLATE.TOP)
+        alertpanel.top:SetPoint("BOTTOMLEFT", alertpanel, "TOPLEFT", 0, 0)
+        alertpanel.top:SetPoint("BOTTOMRIGHT", alertpanel, "TOPRIGHT", 0, 0)
+        alertpanel.top:SetHeight(half)
+
+        --[[ BOTTOM ]]--
+        alertpanel.bottom = alertpanel:CreateTexture(nil, "BORDER")
+        alertpanel.bottom:SetTexture(TEMPLATE.BOTTOM)
+        alertpanel.bottom:SetPoint("TOPLEFT", alertpanel, "BOTTOMLEFT", 0, 0)
+        alertpanel.bottom:SetPoint("TOPRIGHT", alertpanel, "BOTTOMRIGHT", 0, 0)
+        alertpanel.bottom:SetWidth(half)
+
+        frame.AlertPanel = alertpanel
+        frame.AlertColor = SetAlertColor
+    end
+end
+
+--[[
+##########################################################
+SCROLL FRAME (COMPLEX) HANDLER
+##########################################################
+]]--
+local ModifyScrollType1 = function(self, adjustable, frame, scale, yOffset, upButton, downButton)
+    RemoveTextures(upButton)
+    if(not upButton.icon) then
+        local upW, upH = upButton:GetSize()
+        self.Concepts["PageButton"](self, false, upButton)
+        SquareButton_SetIcon(upButton, "UP")
+        upButton:SetSize(upW + scale, upH + scale)
+        if(yOffset) then
+            local anchor, parent, relative, xBase, yBase = upButton:GetPoint()
+            local yAdjust = (yOffset or 0) + yBase
+            upButton:ClearAllPoints()
+            upButton:SetPoint(anchor, parent, relative, xBase, yAdjust)
+        end
+    end
+    RemoveTextures(downButton)
+    if(not downButton.icon) then
+        local dnW, dnH = downButton:GetSize()
+        self.Concepts["PageButton"](self, false, downButton)
+        SquareButton_SetIcon(downButton, "DOWN")
+        downButton:SetSize(dnW + scale, dnH + scale)
+        if(yOffset) then
+            local anchor, parent, relative, xBase, yBase = downButton:GetPoint()
+            local yAdjust = ((yOffset or 0) * -1) + yBase
+            downButton:ClearAllPoints()
+            downButton:SetPoint(anchor, parent, relative, xBase, yAdjust)
+        end
+    end
+    if(not frame.BG) then
+        frame.BG = frame:CreateTexture(nil, "BACKGROUND")
+        frame.BG:SetPoint("TOPLEFT", upButton, "TOPLEFT", 1, -1)
+        frame.BG:SetPoint("BOTTOMRIGHT", downButton, "BOTTOMRIGHT", -1, 1)
+        frame.BG:SetTexture(SV.media.background.transparent)
+
+        -- local fg = CreateFrame("Frame", nil, frame)
+        -- fg:SetPoint("TOPLEFT", frame, "TOPLEFT", 18, -2)
+        -- fg:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -10, 6)
+        -- fg:SetBackdrop(SV.media.backdrop.outline)
+        -- frame.Brdr = fg
+    end
+    if(frame.SetThumbTexture) then
+        frame:SetThumbTexture(SV.media.button.knob)
+    end
+end
+
+local ModifyScrollType2 = function(self, adjustable, frame, scale)
+    if(frame:GetOrientation() == "VERTICAL") then
+        frame:SetWidth(12)
+    else
+        frame:SetHeight(12)
+        for i=1, frame:GetNumRegions() do
+            local child = select(i, frame:GetRegions())
+            if(child and child:GetObjectType() == "FontString") then
+                local anchor, parent, relative, x, y = child:GetPoint()
+                if relative:find("BOTTOM") then
+                    child:SetPoint(anchor, parent, relative, x, y - 4)
+                end
+            end
+        end
+    end
+
+    RemoveTextures(frame)
+    frame:SetBackdrop(nil)
+    self.Methods["Frame"](self, frame, (not adjustable), "Transparent", true)
+    frame:SetBackdropBorderColor(0.2,0.2,0.2)
+    frame:SetThumbTexture(SV.media.button.knob)
+    frame:DisableDrawLayer("BACKGROUND")
+end
+
+local ModifyBasicScroll = function(self, adjustable, frame, scale, yOffset, scrollName)
+    local bg, track, top, bottom, mid, upButton, downButton
+    bg = _G[("%sBG"):format(scrollName)] or frame.BG;
+    if(bg) then bg:SetTexture("") end
+    track = _G[("%sTrack"):format(scrollName)] or frame.Track;
+    if(track) then track:SetTexture("") end
+    top = _G[("%sTop"):format(scrollName)] or frame.Top;
+    if(top) then top:SetTexture("") end
+    bottom = _G[("%sBottom"):format(scrollName)] or frame.Bottom;
+    if(bottom) then bottom:SetTexture("") end
+    mid = _G[("%sMiddle"):format(scrollName)] or frame.Middle;
+    if(mid) then mid:SetTexture("") end
+    upButton = _G[("%sScrollUpButton"):format(scrollName)] or frame.ScrollUpButton;
+    downButton = _G[("%sScrollDownButton"):format(scrollName)] or frame.ScrollDownButton;
+
+    if(upButton and downButton) then
+        ModifyScrollType1(self, adjustable, frame, scale, yOffset, upButton, downButton)
+    elseif(frame.GetOrientation) then
+        ModifyScrollType2(self, adjustable, frame, scale)
+    end
+end
+
+local ModifyHybridScroll = function(self, adjustable, frame, scale, yOffset)
+    local bg, track, top, bottom, mid, upButton, downButton
+    bg = frame.BG;
+    if(bg) then bg:SetTexture("") end
+    track = frame.trackBG or frame.Track;
+    if(track) then track:SetTexture("") end
+    top = frame.ScrollBarTop or frame.Top;
+    if(top) then top:SetTexture("") end
+    bottom = frame.ScrollBarBottom or frame.Bottom;
+    if(bottom) then bottom:SetTexture("") end
+    mid = frame.ScrollBarMiddle or frame.Middle;
+    if(mid) then mid:SetTexture("") end
+    upButton = frame.GetParent().scrollUp or frame.ScrollUpButton;
+    downButton = frame.GetParent().scrollDown or frame.ScrollDownButton;
+
+    if(upButton and downButton) then
+        ModifyScrollType1(self, adjustable, frame, scale, yOffset, upButton, downButton)
+    elseif(frame.GetOrientation) then
+        ModifyScrollType2(self, adjustable, frame, scale)
+    end
+end
+
+MOD.Concepts["ScrollBar"] = function(self, adjustable, frame, scale, yOffset)
+    if(not frame or (frame and frame.Panel)) then return end
+    scale = scale or 5
+    local scrollName = frame:GetName()
+    if(scrollName) then
+        local testForBasic = _G[("%sScrollBar"):format(scrollName)];
+        if(testForBasic) then
+            RemoveTextures(frame)
+            scrollName = testForBasic:GetName()
+            frame = testForBasic
+            ModifyBasicScroll(self, adjustable, frame, scale, yOffset, scrollName)
+        else
+            local testForBar = frame.ScrollBar or frame.scrollBar;
+            if(testForBar) then
+                RemoveTextures(frame)
+                frame = testForBar
+                ModifyHybridScroll(self, adjustable, frame, scale, yOffset)
+            end
+        end
+    else
+        local testForBar = frame.ScrollBar or frame.scrollBar;
+        if(testForBar) then
+            RemoveTextures(frame)
+            frame = testForBar
+            ModifyHybridScroll(self, adjustable, frame, scale, yOffset)
+        end
+    end
+end
+
+--[[
+##########################################################
+SET METHOD
+##########################################################
+]]--
+function MOD:Set(concept, ...)
+    if(not concept) then return end
+
+    local fn;
+    local conceptString, flags = concept:gsub("!_", "");
+    local param = true;
+    if(flags and (flags > 0)) then
+        param = false;
+    end
+
+    local nameString, typeflags = conceptString:gsub("Skin", "");
+    if(typeflags and (typeflags > 0)) then
+        fn = self.Concepts["Skin"];
+        param = nameString
+    else
+        fn = self.Concepts[nameString];
+    end
+
+    if(fn) then
+        local pass, catch = pcall(fn, self, param, ...)
+        if(catch) then
+            SV:HandleError("API", "SetStyle", catch);
+            return
+        end
+    end
+end
+-- _G.Proxy_CreateFrame = CreateFrame;
+-- _G.CreateFrame = function(frameType, frameName, parentFrame, template)
+--     local f
+--     if(template and template == "UIPanelButtonTemplate") then
+--         f = Proxy_CreateFrame(frameType, frameName, parentFrame, template)
+--     else
+--         f = Proxy_CreateFrame(frameType, frameName, parentFrame, template)
+--     end
+--     return f
+-- end
+-- hooksecurefunc("CreateFrame", function(frameType, globalName, parent, template)
+--     if(template and template:find("UIPanelButtonTemplate")) then
+--         if(globalName) then
+--             print(globalName .. ' -> ' .. template)
+--         else
+--             print(template)
+--         end
+--     end
+-- end)
diff --git a/SVUI_!Core/system/automations.lua b/SVUI_!Core/system/automations.lua
new file mode 100644
index 0000000..c086bbf
--- /dev/null
+++ b/SVUI_!Core/system/automations.lua
@@ -0,0 +1,445 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pcall         = _G.pcall;
+local print         = _G.print;
+local ipairs        = _G.ipairs;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local rawset        = _G.rawset;
+local rawget        = _G.rawget;
+local tostring      = _G.tostring;
+local tonumber      = _G.tonumber;
+local getmetatable  = _G.getmetatable;
+local setmetatable  = _G.setmetatable;
+--STRING
+local string        = _G.string;
+local upper         = string.upper;
+local format        = string.format;
+local find          = string.find;
+local match         = string.match;
+local gsub          = string.gsub;
+--MATH
+local math          = _G.math;
+local floor         = math.floor;
+local random        = math.random;
+--TABLE
+local table         = _G.table;
+local tsort         = table.sort;
+local tconcat       = table.concat;
+local tremove       = _G.tremove;
+local twipe         = _G.wipe;
+--BLIZZARD API
+local ReloadUI              = _G.ReloadUI;
+local GetLocale             = _G.GetLocale;
+local CreateFrame           = _G.CreateFrame;
+local IsAddOnLoaded         = _G.IsAddOnLoaded;
+local InCombatLockdown      = _G.InCombatLockdown;
+local GetAddOnInfo          = _G.GetAddOnInfo;
+local LoadAddOn             = _G.LoadAddOn;
+local SendAddonMessage      = _G.SendAddonMessage;
+local LibStub               = _G.LibStub;
+local GetAddOnMetadata      = _G.GetAddOnMetadata;
+local GetCVarBool           = _G.GetCVarBool;
+local GameTooltip           = _G.GameTooltip;
+local StaticPopup_Hide      = _G.StaticPopup_Hide;
+local ERR_NOT_IN_COMBAT     = _G.ERR_NOT_IN_COMBAT;
+
+local SV = select(2, ...);
+local L = SV.L;
+--[[
+##########################################################
+LOCAL VARS
+##########################################################
+]]--
+local incpat 	  = gsub(gsub(FACTION_STANDING_INCREASED, "(%%s)", "(.+)"), "(%%d)", "(.+)");
+local changedpat  = gsub(gsub(FACTION_STANDING_CHANGED, "(%%s)", "(.+)"), "(%%d)", "(.+)");
+local decpat	  = gsub(gsub(FACTION_STANDING_DECREASED, "(%%s)", "(.+)"), "(%%d)", "(.+)");
+local standing    = ('%s:'):format(STANDING);
+local reputation  = ('%s:'):format(REPUTATION);
+local hideStatic = false;
+
+function SV:VendorGrays(destroy, silent, request)
+	if((not MerchantFrame or not MerchantFrame:IsShown()) and (not destroy) and (not request)) then
+		SV:AddonMessage(L["You must be at a vendor."])
+		return
+	end
+
+	local totalValue = 0;
+	local canDelete = 0;
+
+	for bagID = 0, 4 do
+		for slot = 1, GetContainerNumSlots(bagID) do
+			local itemLink = GetContainerItemLink(bagID, slot)
+			if(itemLink) then
+				local name, link, quality, iLevel, reqLevel, class, subclass, maxStack, equipSlot, texture, vendorPrice = GetItemInfo(itemLink)
+				if(vendorPrice) then
+					local itemCount = select(2, GetContainerItemInfo(bagID, slot))
+					local sellPrice = vendorPrice * itemCount
+					local itemID = GetContainerItemID(bagID, slot);
+					if(destroy) then
+						if(find(itemLink, "ff9d9d9d")) then
+							if(not request) then
+								PickupContainerItem(bagID, slot)
+								DeleteCursorItem()
+							end
+							totalValue = totalValue + sellPrice;
+							canDelete = canDelete + 1
+						elseif(SV.Inventory:VendorCheck(itemID, bagID, slot)) then
+							if(not request) then
+								PickupContainerItem(bagID, slot)
+								DeleteCursorItem()
+							end
+							totalValue = totalValue + sellPrice;
+							canDelete = canDelete + 1
+						end
+					elseif(sellPrice > 0) then
+						if(quality == 0) then
+							if(not request) then
+								UseContainerItem(bagID, slot)
+								PickupMerchantItem()
+							end
+							totalValue = totalValue + sellPrice
+						elseif(SV.Inventory and (not request) and SV.Inventory:VendorCheck(itemID, bagID, slot)) then
+							totalValue = totalValue + sellPrice
+						end
+					end
+				end
+			end
+		end
+	end
+
+	if request then return totalValue end
+
+	if(not silent) then
+		if(totalValue > 0) then
+			local prefix, strMsg
+			local gold, silver, copper = floor(totalValue / 10000) or 0, floor(totalValue%10000 / 100) or 0, totalValue%100;
+
+			if(not destroy) then
+				strMsg = ("%s |cffffffff%s%s%s%s%s%s|r"):format(L["Vendored gray items for:"], gold, L["goldabbrev"], silver, L["silverabbrev"], copper, L["copperabbrev"])
+				SV:AddonMessage(strMsg)
+			else
+				if(canDelete > 0) then
+					prefix = ("|cffffffff%s%s%s%s%s%s|r"):format(gold, L["goldabbrev"], silver, L["silverabbrev"], copper, L["copperabbrev"])
+					strMsg = (L["Deleted %d gray items. Total Worth: %s"]):format(canDelete, prefix)
+					SV:AddonMessage(strMsg)
+				else
+					SV:AddonMessage(L["No gray items to delete."])
+				end
+			end
+		elseif(destroy) then
+			SV:AddonMessage(L["No gray items to delete."])
+		end
+	end
+end
+--[[
+##########################################################
+INVITE AUTOMATONS
+##########################################################
+]]--
+function SV:PARTY_INVITE_REQUEST(event, invitedBy)
+	if(not self.db.Extras.autoAcceptInvite) then return; end
+
+	if(QueueStatusMinimapButton:IsShown() or IsInGroup()) then return end
+	if(GetNumFriends() > 0) then
+		ShowFriends()
+	end
+	if(IsInGuild()) then
+		GuildRoster()
+	end
+
+	hideStatic = true;
+	local invited = false;
+
+	for f = 1, GetNumFriends() do
+		local friend = gsub(GetFriendInfo(f), "-.*", "")
+		if(friend == invitedBy) then
+			AcceptGroup()
+			invited = true;
+			self:AddonMessage("Accepted an Invite From Your Friends!")
+			break;
+		end
+	end
+
+	if(not invited) then
+		for b = 1, BNGetNumFriends() do
+			local _, _, _, _, friend = BNGetFriendInfo(b)
+			invitedBy = invitedBy:match("(.+)%-.+") or invitedBy;
+			if(friend == invitedBy) then
+				AcceptGroup()
+				invited = true;
+				self:AddonMessage("Accepted an Invite From Your Friends!")
+				break;
+			end
+		end
+	end
+
+	if(not invited) then
+		for g = 1, GetNumGuildMembers(true) do
+			local guildMate = gsub(GetGuildRosterInfo(g), "-.*", "")
+			if(guildMate == invitedBy) then
+				AcceptGroup()
+				invited = true;
+				self:AddonMessage("Accepted an Invite From Your Guild!")
+				break;
+			end
+		end
+	end
+
+	if(invited) then
+		local popup = StaticPopup_FindVisible("PARTY_INVITE")
+		if(popup) then
+			popup.inviteAccepted = 1
+			StaticPopup_Hide("PARTY_INVITE")
+		else
+			popup = StaticPopup_FindVisible("PARTY_INVITE_XREALM")
+			if(popup) then
+				popup.inviteAccepted = 1
+				StaticPopup_Hide("PARTY_INVITE_XREALM")
+			end
+		end
+	end
+end
+--[[
+##########################################################
+REPAIR AUTOMATONS
+##########################################################
+]]--
+function SV:MERCHANT_SHOW()
+	if(self.db.Extras.vendorGrays) then
+		self:VendorGrays()
+	end
+	local autoRepair = self.db.Extras.autoRepair;
+	local guildRepair = (autoRepair == "GUILD");
+	if IsShiftKeyDown() or autoRepair == "NONE" or not CanMerchantRepair() then return end
+	local repairCost,canRepair = GetRepairAllCost()
+
+	if repairCost > 0 then
+		local loan = GetGuildBankWithdrawMoney()
+		if(guildRepair and ((not CanGuildBankRepair()) or (loan ~= -1 and (repairCost > loan)))) then
+			guildRepair = false
+		end
+		if canRepair then
+			RepairAllItems(guildRepair)
+			local x,y,z= repairCost % 100,floor((repairCost % 10000)/100), floor(repairCost / 10000)
+			if(guildRepair) then
+				self:AddonMessage("Repairs Complete! ...Using Guild Money!\n"..GetCoinTextureString(repairCost,12))
+			else
+				self:AddonMessage("Repairs Complete!\n"..GetCoinTextureString(repairCost,12))
+			end
+		else
+			self:AddonMessage("The Minions Say You Are Too Broke To Repair! They Are Laughing..")
+		end
+	end
+end
+--[[
+##########################################################
+REP AUTOMATONS
+##########################################################
+]]--
+function SV:CHAT_MSG_COMBAT_FACTION_CHANGE(event, msg)
+	if not self.db.Extras.autorepchange then return end
+	local _, _, faction, amount = msg:find(incpat)
+	if not faction then
+		_, _, faction, amount = msg:find(changedpat) or msg:find(decpat)
+	end
+	if faction and faction ~= GUILD_REPUTATION then
+		local active = GetWatchedFactionInfo()
+		for factionIndex = 1, GetNumFactions() do
+			local name = GetFactionInfo(factionIndex)
+			if name == faction and name ~= active then
+				SetWatchedFactionIndex(factionIndex)
+				local strMsg = ("Watching Faction: %s"):format(name)
+				self:AddonMessage(strMsg)
+				break
+			end
+		end
+	end
+end
+--[[
+##########################################################
+QUEST AUTOMATONS
+##########################################################
+]]--
+function SV:AutoQuestProxy()
+	if(IsShiftKeyDown()) then return false; end
+    if(((not QuestIsDaily()) or (not QuestIsWeekly())) and (self.db.Extras.autodailyquests)) then return false; end
+    if(QuestFlagsPVP() and (not self.db.Extras.autopvpquests)) then return false; end
+    return true
+end
+
+function SV:QUEST_GREETING()
+    if(self.db.Extras.autoquestaccept == true and self:AutoQuestProxy()) then
+        local active,available = GetNumActiveQuests(), GetNumAvailableQuests()
+        if(active + available == 0) then return end
+        if(available > 0) then
+        	for i = 1, available do
+            	SelectAvailableQuest(i)
+            end
+        end
+        if(active > 0) then
+            for i = 1, active do
+            	SelectActiveQuest(i)
+            end
+        end
+    end
+end
+
+do
+	local ACTIVE_QUESTS = {};
+
+	local function ParseGossipAvailableQuests(...)
+		local logCount = GetNumQuestLogEntries()
+		twipe(ACTIVE_QUESTS)
+		for i=1, logCount do
+			local title, level, suggestedGroup, isHeader, isCollapsed, isComplete = GetQuestLogTitle(i)
+			ACTIVE_QUESTS[title] = isComplete;
+		end
+		for i=1, select("#", ...), 6 do
+			local title = select(i, ...);
+			if(ACTIVE_QUESTS[title] == nil) then
+				SelectGossipAvailableQuest(i);
+			end
+		end
+	end
+
+	local function ParseGossipActiveQuests(...)
+		for i=1, select("#", ...), 6 do
+			local title = select(i, ...);
+			if(ACTIVE_QUESTS[title]) then
+				SelectGossipActiveQuest(i);
+			end
+		end
+	end
+
+	function SV:GOSSIP_SHOW()
+	    if(self.db.Extras.autoquestaccept == true and self:AutoQuestProxy()) then
+	    	local numOther = GetNumGossipOptions()
+	    	ParseGossipAvailableQuests(GetGossipAvailableQuests())
+	    	ParseGossipActiveQuests(GetGossipActiveQuests())
+	    end
+	end
+end
+
+function SV:QUEST_DETAIL()
+    if(self.db.Extras.autoquestaccept == true and self:AutoQuestProxy()) then
+        if(not QuestGetAutoAccept()) then
+			AcceptQuest()
+		else
+			CloseQuest()
+		end
+    end
+end
+
+function SV:QUEST_ACCEPT_CONFIRM()
+    if(self.db.Extras.autoquestaccept == true and self:AutoQuestProxy()) then
+        ConfirmAcceptQuest()
+        StaticPopup_Hide("QUEST_ACCEPT_CONFIRM")
+    end
+end
+
+function SV:QUEST_PROGRESS()
+	if(IsShiftKeyDown()) then return false; end
+  if(self.db.Extras.autoquestcomplete == true and IsQuestCompletable()) then
+      CompleteQuest()
+  end
+end
+
+function SV:QUEST_COMPLETE()
+	if(not self.db.Extras.autoquestcomplete and (not self.db.Extras.autoquestreward)) then return end
+	if(IsShiftKeyDown()) then return false; end
+	local rewards = GetNumQuestChoices()
+	local rewardsFrame = QuestInfoFrame.rewardsFrame;
+	if(rewards > 1) then
+		local auto_select = QuestFrameRewardPanel.itemChoice or QuestInfoFrame.itemChoice;
+		local selection, value = 1, 0;
+
+		for i = 1, rewards do
+			local iLink = GetQuestItemLink("choice", i)
+			if iLink then
+				local iValue = select(11,GetItemInfo(iLink))
+				if iValue and iValue > value then
+					value = iValue;
+					selection = i
+				end
+			end
+		end
+
+		local chosenItem = QuestInfo_GetRewardButton(rewardsFrame, selection)
+
+		if chosenItem.type == "choice" then
+			QuestInfoItemHighlight:ClearAllPoints()
+			QuestInfoItemHighlight:SetAllPoints(chosenItem)
+			QuestInfoItemHighlight:Show()
+			QuestInfoFrame.itemChoice = chosenItem:GetID()
+			self:AddonMessage("A Minion Has Chosen Your Reward!")
+		end
+
+		auto_select = selection
+
+		if self.db.Extras.autoquestreward == true then
+			GetQuestReward(auto_select)
+		end
+	else
+		if(self.db.Extras.autoquestcomplete == true) then
+			GetQuestReward(rewards)
+		end
+	end
+end
+
+local AutoRelease_OnEvent = function(self, event)
+	local isInstance, instanceType = IsInInstance()
+	if(isInstance and instanceType == "pvp") then
+		local spell = GetSpellInfo(20707)
+		if(SV.class ~= "SHAMAN" and not(spell and UnitBuff("player", spell))) then
+			RepopMe()
+		end
+	end
+	for i=1,GetNumWorldPVPAreas() do
+		local _,localizedName, isActive = GetWorldPVPAreaInfo(i)
+		if(GetRealZoneText() == localizedName and isActive) then RepopMe() end
+	end
+end
+--[[
+##########################################################
+BUILD FUNCTION / UPDATE
+##########################################################
+]]--
+local function InitializeAutomations()
+	--print("InitializeAutomations")
+	SV:RegisterEvent('PARTY_INVITE_REQUEST')
+	SV:RegisterEvent('CHAT_MSG_COMBAT_FACTION_CHANGE')
+	SV:RegisterEvent('MERCHANT_SHOW')
+	SV:RegisterEvent('QUEST_COMPLETE')
+	SV:RegisterEvent('QUEST_GREETING')
+	SV:RegisterEvent('GOSSIP_SHOW')
+	SV:RegisterEvent('QUEST_DETAIL')
+	SV:RegisterEvent('QUEST_ACCEPT_CONFIRM')
+	SV:RegisterEvent('QUEST_PROGRESS')
+
+	if SV.db.Extras.pvpautorelease then
+		local autoReleaseHandler = CreateFrame("frame")
+		autoReleaseHandler:RegisterEvent("PLAYER_DEAD")
+		autoReleaseHandler:SetScript("OnEvent", AutoRelease_OnEvent)
+	end
+
+	if(SV.db.Extras.skipcinematics) then
+		local skippy = CreateFrame("Frame")
+		skippy:RegisterEvent("CINEMATIC_START")
+		skippy:SetScript("OnEvent", CinematicFrame_CancelCinematic)
+		MovieFrame:SetScript("OnEvent", GameMovieFinished)
+	end
+end
+
+SV:NewScript(InitializeAutomations)
diff --git a/SVUI_!Core/system/core.lua b/SVUI_!Core/system/core.lua
new file mode 100644
index 0000000..00fdd41
--- /dev/null
+++ b/SVUI_!Core/system/core.lua
@@ -0,0 +1,910 @@
+--- SVUI is our global addon object.
+-- SuperVillain UI Core Module.
+-- @module SVUI_Core
+-- @author Steven Jackson (2014)
+-- @release 1.0.0
+-- @usage
+--    -- Every other file will set a reference to the addon using this variable. Here is how we set it.
+--
+--    -- METHOD 1 ----------------------------------------------------------------
+--    -- if we are setting this inside the core.lua file then use this method
+--    local global = "SVUI_Global"    -- reference to SavedVariables
+--    local errors = "SVUI_Errors"    -- reference to SavedVariables
+--    local private = "SVUI_Private"  -- reference to SavedVariables
+--    local media = "SVUI_Media"      -- reference to SavedVariables
+--    local shared = "SVUI_Shared"    -- reference to SavedVariables
+--
+--    local Registry = Librarian("Registry")  -- now pull down the Registry object
+--    -- finally we use the 'NewCore' function specifically for this
+--    local SV = Registry:NewCore(global, errors, private, media, shared)
+--
+--    -- METHOD 2 ----------------------------------------------------------------
+--    -- if we are setting the variable in any other file then use this method
+--    local SV = _G['SVUI']
+
+local _G = _G;
+---- LUA ----
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pcall         = _G.pcall;
+local print         = _G.print;
+local ipairs        = _G.ipairs;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local rawset        = _G.rawset;
+local rawget        = _G.rawget;
+local tostring      = _G.tostring;
+local tonumber      = _G.tonumber;
+local getmetatable  = _G.getmetatable;
+local setmetatable  = _G.setmetatable;
+---- STRING ----
+local string        = _G.string;
+local split         = string.split;
+local upper         = string.upper;
+local format        = string.format;
+local find          = string.find;
+local match         = string.match;
+local gsub          = string.gsub;
+---- MATH ----
+local math          = _G.math;
+local floor         = math.floor
+local random        = math.random;
+---- TABLE ----
+local table         = _G.table;
+local tsort         = table.sort;
+local tconcat       = table.concat;
+local tremove       = _G.tremove;
+local wipe          = _G.wipe;
+---- BLIZZARD API ----
+local collectgarbage        = _G.collectgarbage;
+local ERR_NOT_IN_COMBAT     = _G.ERR_NOT_IN_COMBAT;
+
+local RequestBattlefieldScoreData = _G.RequestBattlefieldScoreData;
+
+local SVUILib = Librarian("Registry");
+
+---- CONSTANTS ----
+
+_G.BINDING_HEADER_SVUI = "SuperVillain UI";
+_G.BINDING_NAME_SVUI_MARKERS = "Raid Markers";
+_G.BINDING_NAME_SVUI_DOCKS = "Toggle Both Docks";
+_G.BINDING_NAME_SVUI_DOCKS_LEFT = "Toggle Left Dock";
+_G.BINDING_NAME_SVUI_DOCKS_RIGHT = "Toggle Right Dock";
+_G.BINDING_NAME_SVUI_RIDE = "Let's Ride";
+_G.BINDING_NAME_SVUI_DRAENORZONE = "Draenor Zone Ability";
+_G.BINDING_NAME_SVUI_FRAMEDEBUGGER = "Supervillain UI: Frame Analyzer";
+
+_G.SlashCmdList.RELOADUI = ReloadUI
+_G.SLASH_RELOADUI1 = "/rl"
+_G.SLASH_RELOADUI2 = "/reloadui"
+
+_G.SVUI_ICON_COORDS = {0.1, 0.9, 0.1, 0.9};
+
+---- LOCALS ----
+
+local rez = GetCVar("gxFullscreenResolution");
+local baseHeight = tonumber(rez:match("%d+x(%d+)"))
+local baseWidth = tonumber(rez:match("(%d+)x%d+"))
+local defaultDockWidth = baseWidth * 0.66;
+local defaultCenterWidth = min(defaultDockWidth, 900);
+local callbacks = {};
+local numCallbacks = 0;
+local playerName = UnitName("player");
+local playerRealm = GetRealmName();
+local playerClass = select(2, UnitClass("player"));
+local errorPattern = "|cffff0000Error -- |r|cffff9900Required addon '|r|cffffff00%s|r|cffff9900' is %s.|r";
+
+---- COMMON CONSTANTS ----
+
+_G.SHOWORHIDE = SHOW .. "\\" .. HIDE;
+_G.MINIMIZEORMAXIMIZE = MINIMIZE .. "\\" .. WINDOWED_MAXIMIZED;
+
+---- BUILD CLASS COLOR GLOBAL, CAN BE OVERRIDDEN BY THE ADDON !ClassColors ----
+
+local CUSTOM_CLASS_COLORS = _G.CUSTOM_CLASS_COLORS;
+
+if(not CUSTOM_CLASS_COLORS) then
+    local env = getfenv(0)
+    env.CUSTOM_CLASS_COLORS = {}
+    CUSTOM_CLASS_COLORS = env.CUSTOM_CLASS_COLORS
+
+    local function RegisterCallback(self, m, h)
+        assert(type(m) == "string" or type(m) == "function", "Bad argument #1 to :RegisterCallback (string or function expected)")
+        if type(m) == "string" then
+            assert(type(h) == "table", "Bad argument #2 to :RegisterCallback (table expected)")
+            assert(type(h[m]) == "function", "Bad argument #1 to :RegisterCallback (m \"" .. m .. "\" not found)")
+            m = h[m]
+        end
+        callbacks[m] = h or true
+        numCallbacks = numCallbacks + 1
+    end
+
+    local function UnregisterCallback(self, m, h)
+        assert(type(m) == "string" or type(m) == "function", "Bad argument #1 to :UnregisterCallback (string or function expected)")
+        if type(m) == "string" then
+            assert(type(h) == "table", "Bad argument #2 to :UnregisterCallback (table expected)")
+            assert(type(h[m]) == "function", "Bad argument #1 to :UnregisterCallback (m \"" .. m .. "\" not found)")
+            m = h[m]
+        end
+        callbacks[m] = nil
+        numCallbacks = numCallbacks + 1
+    end
+
+    local function DispatchCallbacks()
+        if (numCallbacks < 1) then return end
+        for m, h in pairs(callbacks) do
+            local ok, err = pcall(m, h ~= true and h or nil)
+            if not ok then
+                print("ERROR:", err)
+            end
+        end
+    end
+
+    local classes = {};
+    local supercolors = {
+        ["HUNTER"]        = { r = 0.454, g = 0.698, b = 0 },
+        ["WARLOCK"]       = { r = 0.286, g = 0,     b = 0.788 },
+        ["PRIEST"]        = { r = 0.976, g = 1,     b = 0.839 },
+        ["PALADIN"]       = { r = 0.956, g = 0.207, b = 0.733 },
+        ["MAGE"]          = { r = 0,     g = 0.796, b = 1 },
+        ["ROGUE"]         = { r = 1,     g = 0.894, b = 0.117 },
+        ["DRUID"]         = { r = 1,     g = 0.513, b = 0 },
+        ["SHAMAN"]        = { r = 0,     g = 0.38,  b = 1 },
+        ["WARRIOR"]       = { r = 0.698, g = 0.36,  b = 0.152 },
+        ["DEATHKNIGHT"]   = { r = 0.847, g = 0.117, b = 0.074 },
+        ["MONK"]          = { r = 0.015, g = 0.886, b = 0.38 },
+        ["DEMONHUNTER"]   = { r = 0.454, g = 0.015, b = 0.894 },
+    };
+
+    ---- IF WE NEED TO FORCE DEFAULT COLORS, USE THIS INSTEAD ----
+
+    -- local supercolors = {
+    --     ["HUNTER"]        = { r = 0.67,  g = 0.83,  b = 0.45 },
+    --     ["WARLOCK"]       = { r = 0.58,  g = 0.51,  b = 0.79 },
+    --     ["PRIEST"]        = { r = 1,     g = 1,     b = 1 },
+    --     ["PALADIN"]       = { r = 0.96,  g = 0.55,  b = 0.73 },
+    --     ["MAGE"]          = { r = 0.41,  g = 0.80,  b = 0.94 },
+    --     ["ROGUE"]         = { r = 1,     g = 0.96,  b = 0.41 },
+    --     ["DRUID"]         = { r = 1,     g = 0.49,  b = 0.04 },
+    --     ["SHAMAN"]        = { r = 0,     g = 0.44,  b = 0.87 },
+    --     ["WARRIOR"]       = { r = 0.78,  g = 0.61,  b = 0.43 },
+    --     ["DEATHKNIGHT"]   = { r = 0.77,  g = 0.12,  b = 0.23 },
+    --     ["MONK"]          = { r = 0.33,  g = 0.54,  b = 0.52 },
+    -- };
+    local classCount = 1;
+    for class in pairs(RAID_CLASS_COLORS) do
+      classes[classCount] = class;
+      classCount=classCount+1;
+    end
+    tsort(classes)
+    setmetatable(CUSTOM_CLASS_COLORS,{
+        __index = function(t, k)
+            if k == "RegisterCallback" then return RegisterCallback end
+            if k == "UnregisterCallback" then return UnregisterCallback end
+            if k == "DispatchCallbacks" then return DispatchCallbacks end
+        end
+    });
+    for i, class in ipairs(classes) do
+        local color = supercolors[class]
+        local r, g, b = color.r, color.g, color.b
+        local hex = ("ff%02x%02x%02x"):format(r * 255, g * 255, b * 255)
+        if not CUSTOM_CLASS_COLORS[class] or not CUSTOM_CLASS_COLORS[class].r or not CUSTOM_CLASS_COLORS[class].g or not CUSTOM_CLASS_COLORS[class].b then
+            CUSTOM_CLASS_COLORS[class] = {
+                r = r,
+                g = g,
+                b = b,
+                colorStr = hex,
+            }
+        end
+    end
+    classes = nil
+end
+
+-- SQUARE_BUTTON_TEXCOORDS = {
+--     ["UP"] = {     0.45312500,    0.64062500,     0.01562500,     0.20312500};
+--     ["DOWN"] = {   0.45312500,    0.64062500,     0.20312500,     0.01562500};
+--     ["LEFT"] = {   0.23437500,    0.42187500,     0.01562500,     0.20312500};
+--     ["RIGHT"] = {  0.42187500,    0.23437500,     0.01562500,     0.20312500};
+--     ["DELETE"] = { 0.01562500,    0.20312500,     0.01562500,     0.20312500};
+-- };
+
+---- Global SVUI Object. We have to send the names ----
+---- of our three SavedVariables files since the ----
+---- WoW API has no method for parsing them in LUA. ----
+
+local SV = SVUILib:NewCore("SVUI_Global", "SVUI_Errors", "SVUI_Private", "SVUI_Media", "SVUI_Shared")
+
+SV.ConfigID           = "SVUI_!Options";
+SV.class              = playerClass;
+SV.GUID               = UnitGUID('player');
+SV.Allegiance         = UnitFactionGroup("player");
+SV.ClassRole          = "";
+SV.SpecificClassRole  = "NONE";
+
+SV.Screen = CreateFrame("Frame", "SVUIParent", UIParent);
+SV.Screen:SetFrameLevel(UIParent:GetFrameLevel());
+SV.Screen:SetPoint("CENTER", UIParent, "CENTER");
+SV.Screen:SetSize(UIParent:GetSize());
+
+SV.Hidden = CreateFrame("Frame", nil, UIParent);
+SV.Hidden:Hide();
+
+SV.RollFrames         = {};
+SV.SystemAlert        = {};
+
+SVUILib.CONSTRAINTS.IGNORED["LAYOUT"] = true;
+SVUILib.CONSTRAINTS.IGNORED["REPORT_SLOTS"] = true;
+
+SVUILib.CONSTRAINTS.PROTECTED["extended"] = true;
+SVUILib.CONSTRAINTS.PROTECTED["shared"] = true;
+SVUILib.CONSTRAINTS.PROTECTED["color"] = true;
+SVUILib.CONSTRAINTS.PROTECTED["bordercolor"] = true;
+SVUILib.CONSTRAINTS.PROTECTED["Filters"] = true;
+
+
+SV.mediadefaults      = {};
+SV.defaults           = {
+    LAYOUT = {},
+    Filters = {},
+    screen = {
+        autoScale = true,
+        multiMonitor = false,
+        advanced = false,
+        scaleAdjust = 0.64,
+        forcedWidth = baseWidth,
+        forcedHeight = baseHeight,
+    },
+    general = {
+        loginmessage = true,
+        logincredits = true,
+        cooldown = true,
+        useDraggable = true,
+        saveDraggable = false,
+        taintLog = false,
+        stickyFrames = true,
+        graphSize = 50,
+        loot = true,
+        lootRoll = true,
+        lootRollWidth = 328,
+        lootRollHeight = 28,
+        filterErrors = true,
+        hideErrorFrame = true,
+        customClassColor = false,
+        errorFilters = {
+            [INTERRUPTED] = false,
+            [ERR_ABILITY_COOLDOWN] = true,
+            [ERR_ATTACK_CHANNEL] = false,
+            [ERR_ATTACK_CHARMED] = false,
+            [ERR_ATTACK_CONFUSED] = false,
+            [ERR_ATTACK_DEAD] = false,
+            [ERR_ATTACK_FLEEING] = false,
+            [ERR_ATTACK_MOUNTED] = true,
+            [ERR_ATTACK_PACIFIED] = false,
+            [ERR_ATTACK_STUNNED] = false,
+            [ERR_ATTACK_NO_ACTIONS] = false,
+            [ERR_AUTOFOLLOW_TOO_FAR] = false,
+            [ERR_BADATTACKFACING] = false,
+            [ERR_BADATTACKPOS] = false,
+            [ERR_CLIENT_LOCKED_OUT] = false,
+            [ERR_GENERIC_NO_TARGET] = true,
+            [ERR_GENERIC_NO_VALID_TARGETS] = true,
+            [ERR_GENERIC_STUNNED] = false,
+            [ERR_INVALID_ATTACK_TARGET] = true,
+            [ERR_ITEM_COOLDOWN] = true,
+            [ERR_NOEMOTEWHILERUNNING] = false,
+            [ERR_NOT_IN_COMBAT] = false,
+            [ERR_NOT_WHILE_DISARMED] = false,
+            [ERR_NOT_WHILE_FALLING] = false,
+            [ERR_NOT_WHILE_MOUNTED] = false,
+            [ERR_NO_ATTACK_TARGET] = true,
+            [ERR_OUT_OF_ENERGY] = true,
+            [ERR_OUT_OF_FOCUS] = true,
+            [ERR_OUT_OF_MANA] = true,
+            [ERR_OUT_OF_RAGE] = true,
+            [ERR_OUT_OF_RANGE] = true,
+            [ERR_OUT_OF_RUNES] = true,
+            [ERR_OUT_OF_RUNIC_POWER] = true,
+            [ERR_SPELL_COOLDOWN] = true,
+            [ERR_SPELL_OUT_OF_RANGE] = false,
+            [ERR_TOO_FAR_TO_INTERACT] = false,
+            [ERR_USE_BAD_ANGLE] = false,
+            [ERR_USE_CANT_IMMUNE] = false,
+            [ERR_USE_TOO_FAR] = false,
+            [SPELL_FAILED_BAD_IMPLICIT_TARGETS] = true,
+            [SPELL_FAILED_BAD_TARGETS] = true,
+            [SPELL_FAILED_CASTER_AURASTATE] = true,
+            [SPELL_FAILED_NO_COMBO_POINTS] = true,
+            [SPELL_FAILED_SPELL_IN_PROGRESS] = true,
+            [SPELL_FAILED_TARGET_AURASTATE] = true,
+            [SPELL_FAILED_TOO_CLOSE] = false,
+            [SPELL_FAILED_UNIT_NOT_INFRONT] = false,
+        }
+    },
+    Extras = {
+        autoRoll = false,
+        autoRollDisenchant = false,
+        autoRollMaxLevel = false,
+        autoRollSoulbound = true,
+        autoRollQuality = '2',
+        vendorGrays = true,
+        autoAcceptInvite = false,
+        autorepchange = false,
+        pvpautorelease = false,
+        autoquestcomplete = false,
+        autoquestreward = false,
+        autoquestaccept = false,
+        autodailyquests = false,
+        autopvpquests = false,
+        skipcinematics = false,
+        mailOpener = true,
+        autoRepair = "PLAYER",
+        threatbar = false,
+        woot = true,
+        pvpinterrupt = true,
+        lookwhaticando = false,
+        reactionChat = false,
+        reactionEmote = false,
+        sharingiscaring = false,
+        arenadrink = true,
+        stupidhat = true,
+    },
+    Gear = {
+        durability = {
+            enable = true,
+            onlydamaged = true,
+        },
+        labels = {
+            characterItemLevel = true,
+            inventoryItemLevel = true,
+            characterGearSet = true,
+            inventoryGearSet = true,
+        },
+        specialization = {
+            enable = false,
+            primary = "none",
+            secondary = "none",
+        },
+        battleground = {
+            enable = false,
+            primary = "none",
+            secondary = "none",
+        },
+    },
+    FunStuff = {
+        drunk = true,
+        NPC = true,
+        comix = '1',
+        comixLastState = '1',
+        gamemenu = '1',
+        afk = '1',
+    },
+    Dock = {
+        dockWidth = 412,
+        dockHeight = 224,
+        dockOpacity = 1,
+        backdrop = true,
+        dockLeftWidth = 412,
+        dockLeftHeight = 224,
+        dockRightWidth = 412,
+        dockRightHeight = 224,
+        dockTopLeftWidth = 412,
+        dockTopLeftHeight = 224,
+        dockTopRightWidth = 412,
+        dockTopRightHeight = 224,
+        dockCenterWidth = defaultCenterWidth,
+        dockCenterHeight = 20,
+        buttonSize = 30,
+        buttonSpacing = 4,
+        topPanel = true,
+        bottomPanel = true,
+        dockTools = {
+            garrison = true,
+            firstAid = true,
+            cooking = true,
+            archaeology = true,
+            primary = true,
+            secondary = true,
+            hearth = true,
+            specswap = true,
+            leader = true,
+            breakstuff = true,
+            power = false
+        },
+        hearthOptions = {
+            left = 6948,
+            right = 110560
+        },
+    },
+    REPORT_SLOTS = {
+        ['1'] = { "Experience Bar", "Time", "System" },
+        ['2'] = { "Gold", "Friends", "Durability Bar" },
+        ['3'] = { "None", "None", "None" },
+        ['4'] = { "None", "None", "None" },
+    },
+    Reports = {
+        backdrop = false,
+        shortGold = true,
+        localtime = true,
+        time24 = false,
+        battleground = true,
+    },
+};
+
+---- EMBEDDED LIBS ----
+
+SV.Options = {
+    type = "group",
+    name = "|cff339fffUI Options|r",
+    args = {
+        SVUI_Header = {
+            order = 1,
+            type = "header",
+            name = ("Powered By |cffff9900SVUI|r - %s: |cff99ff33%s|r"):format(SV.L["Version"], SV.Version),
+            width = "full"
+        },
+        profiles = {
+            order = 9997,
+            type = "group",
+            name = SV.L["Profiles"],
+            childGroups = "tab",
+            args = {}
+        },
+        credits = {
+            type = "group",
+            name = SV.L["Credits"],
+            order = -1,
+            args = {
+                new = {
+                    order = 1,
+                    type = "description",
+                    name = function() return SV:PrintCredits() end
+                }
+            }
+        }
+    }
+};
+
+local function _tablecopy(d, s)
+    if(type(s) ~= "table") then return end
+    if(type(d) ~= "table") then return end
+    for k, v in pairs(s) do
+        local saved = d[k]
+        if type(v) == "table" then
+            if not saved then d[k] = {} end
+            _tablecopy(d[k], v)
+        elseif(saved == nil or (saved and type(saved) ~= type(v))) then
+            d[k] = v
+        end
+    end
+end
+
+local function _removedeprecated()
+    ---- BEGIN DEPRECATED ----
+    if(_G.SVUI_Filters and (not _G.SVUI_TRANSFER_WIZARD)) then
+        _tablecopy(SV.db.Filters, _G.SVUI_Filters)
+        _G.SVUI_Filters = nil
+    end
+    ---- END DEPRECATED ----
+end
+
+local function _needsupdate(value, lowMajor, lowMinor, lowPatch)
+    _removedeprecated();
+    lowMajor = lowMajor or 0;
+    lowMinor = lowMinor or 0;
+    lowPatch = lowPatch or 0;
+    local version = value or '0.0';
+    if(version and type(version) ~= string) then
+        version = tostring(version)
+    end
+    if(not version) then
+       ---- print('No Version Found') ----
+        return true
+    end
+    local vt = version:explode(".")
+    local MAJOR,MINOR,PATCH = unpack(vt)
+    ---- print(PATCH)print(type(lowPatch)) ----
+    if(PATCH and (lowPatch > 0)) then
+        if(type(PATCH) == "string") then
+            PATCH = tonumber(PATCH)
+        end
+        if(type(PATCH) == "number" and PATCH < lowPatch) then
+            SVUILib:CleanUpData(true);
+            SVUILib:SaveSafeData("install_version", SV.Version);
+        end
+    end
+    if(MINOR and (lowMinor > 0)) then
+        if(type(MINOR) == "string") then
+            MINOR = tonumber(MINOR)
+        end
+        if(type(MINOR) == "number" and MINOR < lowMinor) then
+            SVUILib:CleanUpData(true);
+            SVUILib:SaveSafeData("install_version", SV.Version);
+        end
+    end
+    if(MAJOR and (lowMajor > 0)) then
+        if(type(MAJOR) == "string") then
+            MAJOR = tonumber(MAJOR)
+        end
+        if(type(MAJOR) == "number" and MAJOR < lowMajor) then
+            return true
+        else
+            return false
+        end
+    else
+        return true
+    end
+end
+
+local SetLoginMessage;
+do
+  ---------------------------------------------------------------------
+  -- Messages
+  -- @section MESSAGES Addon Message Handlers
+  ---------------------------------------------------------------------
+    local commandments = {
+        {
+            "schemes diabolical",
+            "henchmen in-line",
+            "entrances grand",
+            "battles glorious",
+            "power absolute",
+        },
+        {
+            "traps inescapable",
+            "enemies overthrown",
+            "monologues short",
+            "victories infamous",
+            "identity a mystery",
+        }
+    };
+    local messagePattern = "|cffFF2F00%s:|r";
+    local debugPattern = "|cffFF2F00%s|r [|cff992FFF%s|r]|cffFF2F00:|r";
+    local testPattern = "Version |cffAA78FF%s|r, Build |cffAA78FF%s|r."
+
+    local function _send_message(msg, prefix)
+        if(type(msg) == "table") then
+             msg = tostring(msg)
+        end
+        if(not msg) then return end
+        if(prefix) then
+            local outbound = ("%s %s"):format(prefix, msg);
+            print(outbound)
+        else
+            print(msg)
+        end
+    end
+
+    SetLoginMessage = function(self)
+        if(not self.NameID) then return end
+        local prefix = (messagePattern):format(self.NameID)
+        local first = commandments[1][random(1,5)]
+        local second = commandments[2][random(1,5)]
+        local custom_msg = (self.L["LOGIN_MSG"]):format(first, second)
+        _send_message(custom_msg, prefix)
+        local login_msg = (self.L["LOGIN_MSG2"]):format(self.Version)
+        ---- local login_msg = (testPattern):format(self.Version, self.GameVersion) ----
+        _send_message(login_msg, prefix)
+    end
+
+    ---------------------------------------------------------------------
+    -- Send messages to the scrolling message frame (combat text).
+    -- @function SCTMessage
+    -- @tparam string message The dialog to be displayed.
+    -- @param red Text coloring, red value.
+    -- @param green Text coloring, green value.
+    -- @param blue Text coloring, blue value.
+    -- @param displayType Special animation type (STICKY, CRITICAL or nil).
+    -- @usage SV:SCTMessage('My message', 0.1, 0.2, 0.3, 'STICKY')
+    ---------------------------------------------------------------------
+
+    function SV:SCTMessage(message, red, green, blue, displayType)
+        ---- /script CombatText_AddMessage("TESTING", COMBAT_TEXT_SCROLL_FUNCTION, 1, 1, 0) ----
+        if not _G.CombatText_AddMessage then return end
+        _G.CombatText_AddMessage(message, COMBAT_TEXT_SCROLL_FUNCTION, red, green, blue, displayType)
+    end
+
+    ---------------------------------------------------------------------
+    -- Send messages to the chat frame prefixed with the addon branding.
+    -- @function AddonMessage
+    -- @tparam string message The dialog to be displayed.
+    ---------------------------------------------------------------------
+
+    function SV:AddonMessage(message)
+        local outbound = (messagePattern):format(self.NameID)
+        _send_message(message, outbound)
+    end
+
+    ---------------------------------------------------------------------
+    -- Send messages to the chat frame as if they came from your character.
+    -- @function CharacterMessage
+    -- @tparam string message The dialog to be displayed.
+    ---------------------------------------------------------------------
+
+    function SV:CharacterMessage(message)
+        local outbound = (messagePattern):format(playerName)
+        _send_message(message, outbound)
+    end
+end
+
+---------------------------------------------------------------------
+-- Utilities
+-- @section UTILITIES Utilities used and shared by the SVUI core.
+---------------------------------------------------------------------
+
+---------------------------------------------------------------------
+-- Dummy function used to override existing methods, effectively killing them.
+-- @function fubar
+-- @return nothing.
+-- @usage
+--   -- Kill a function
+--   SomeObject.some_function = SV.fubar
+---------------------------------------------------------------------
+
+function SV:fubar() return end
+
+---------------------------------------------------------------------
+-- Request specific 'Static Popup' windows.
+-- @function StaticPopup_Show
+-- @tparam string arg Name of the popup
+-- @usage
+--   -- Open the 'Reload UI' popup
+--   SV:StaticPopup_Show('RL_CLIENT')
+---------------------------------------------------------------------
+
+function SV:StaticPopup_Show(arg)
+    if arg == "ADDON_ACTION_FORBIDDEN" then
+        StaticPopup_Hide(arg)
+    end
+end
+
+---------------------------------------------------------------------
+-- Reset all SVUI created settings to defaults.
+-- @function ResetAllUI
+---------------------------------------------------------------------
+
+function SV:ResetAllUI(confirmed)
+    if InCombatLockdown()then
+        SV:AddonMessage(ERR_NOT_IN_COMBAT)
+        return
+    end
+    if(not confirmed) then
+        SV:StaticPopup_Show('RESET_UI_CHECK')
+        return
+    end
+    SV.Setup:Reset()
+    SV.Events:Trigger("FULL_UI_RESET");
+end
+
+---------------------------------------------------------------------
+-- Reset layout positions back to their default.
+-- @function ResetUI
+---------------------------------------------------------------------
+
+function SV:ResetUI(confirmed)
+    if InCombatLockdown()then
+        self:AddonMessage(ERR_NOT_IN_COMBAT)
+        return
+    end
+    if(not confirmed) then
+        self:StaticPopup_Show('RESETMOVERS_CHECK')
+        return
+    end
+    self:ResetAnchors()
+end
+
+---------------------------------------------------------------------
+-- Open the config menu ('/sv').
+-- @function ToggleConfig
+---------------------------------------------------------------------
+
+function SV:ToggleConfig()
+    if InCombatLockdown() then
+        self:AddonMessage(ERR_NOT_IN_COMBAT)
+        self:RegisterEvent('PLAYER_REGEN_ENABLED')
+        return
+    end
+    self.OptionsStandby = nil
+    if not IsAddOnLoaded(self.ConfigID) then
+        local _,_,_,_,_,state = GetAddOnInfo(self.ConfigID)
+        if state ~= "MISSING" and state ~= "DISABLED" then
+            LoadAddOn(self.ConfigID)
+        else
+            local errorMessage = (errorPattern):format(self.ConfigID, state)
+            self:AddonMessage(errorMessage)
+            return
+        end
+    end
+    local aceConfig = LibStub("AceConfigDialog-3.0", true)
+    if(aceConfig) then
+        local switch = not aceConfig.OpenFrames[self.NameID] and "Open" or "Close"
+        aceConfig[switch](aceConfig, self.NameID)
+        GameTooltip:Hide()
+    end
+end
+
+---------------------------------------------------------------------
+-- Checks to see which (if any) version of the core that the client has installed.
+-- @function VersionCheck
+---------------------------------------------------------------------
+
+function SV:VersionCheck()
+    local delayed;
+    if(_G.SVUI_TRANSFER_WIZARD) then
+        local copied = SVUILib:GetSafeData("transfer_wizard_used");
+        if(not copied) then
+            delayed = true;
+            _G.SVUI_TRANSFER_WIZARD()
+        end
+    end
+    if(not delayed) then
+        local version = SVUILib:GetSafeData("install_version");
+        if(not version or (version and _needsupdate(version, 1, 1, 0))) then
+            self.Setup:Install(true)
+        end
+    end
+end
+
+---------------------------------------------------------------------
+-- Reloads all current packages and modules.
+-- @function RefreshEverything
+---------------------------------------------------------------------
+
+function SV:RefreshEverything(bypass)
+    self:UpdateSharedMedia();
+    self:UpdateAnchors();
+    SVUILib:RefreshAll();
+    if not bypass then
+        self:VersionCheck()
+    end
+end
+
+---- EVENT HANDLERS ----
+
+function SV:PLAYER_ENTERING_WORLD()
+    self.GUID = UnitGUID('player');
+    if(not self.ClassRole or self.ClassRole == "") then
+        self:PlayerInfoUpdate()
+    else
+        self:GearSwap()
+    end
+    if(not self.MediaInitialized) then
+        self:RefreshAllMedia()
+    end
+    local _,instanceType = IsInInstance()
+    if(instanceType == "pvp") then
+        self.BGTimer = self.Timers:ExecuteLoop(RequestBattlefieldScoreData, 5)
+    elseif(self.BGTimer) then
+        self.Timers:RemoveLoop(self.BGTimer)
+        self.BGTimer = nil
+    end
+
+    if(not InCombatLockdown()) then
+        collectgarbage("collect")
+    end
+end
+
+function SV:PET_BATTLE_CLOSE()
+    self:AuditVisibility()
+    SVUILib:LiveUpdate()
+    ---- self.Events:Trigger("FONT_GROUP_UPDATED", "chatdialog", "chattab"); ----
+end
+
+function SV:PET_BATTLE_OPENING_START()
+    self:AuditVisibility(true);
+    ---- self.Events:Trigger("FONT_GROUP_UPDATED", "chatdialog", "chattab"); ----
+end
+
+function SV:PLAYER_REGEN_DISABLED()
+    local forceClosed = false;
+
+    if(self.OptionsLoaded) then
+        local aceConfig = LibStub("AceConfigDialog-3.0")
+        if aceConfig.OpenFrames[self.NameID] then
+            self:RegisterEvent("PLAYER_REGEN_ENABLED")
+            aceConfig:Close(self.NameID)
+            self.OptionsStandby = true
+            forceClosed = true
+        end
+    end
+
+    if(self:ForceAnchors(forceClosed) == true) then
+        self:AddonMessage(ERR_NOT_IN_COMBAT)
+    end
+
+    if(self.NeedsFrameAudit) then
+        self:AuditVisibility()
+    end
+end
+
+function SV:PLAYER_REGEN_ENABLED()
+    self:UnregisterEvent("PLAYER_REGEN_ENABLED")
+    if(self.OptionsStandby) then
+        self:ToggleConfig()
+    end
+end
+
+function SV:TaintHandler(event, taint, sourceName, sourceFunc)
+    if GetCVarBool('scriptErrors') ~= 1 then return end
+    local errorString = ("Error Captured: %s->%s->{%s}"):format(taint, sourceName or "Unknown", sourceFunc or "Unknown")
+    self:AddonMessage(errorString)
+end
+
+---- LOAD FUNCTIONS ----
+
+function SV:ReLoad()
+    self:RefreshAllMedia();
+    self:UpdateAnchors();
+    if(self.DebugMode) then
+        self:AddonMessage("User settings updated");
+    end
+end
+
+function SV:PreLoad()
+    self:RegisterEvent('PLAYER_REGEN_DISABLED');
+    self:RegisterEvent("PLAYER_ENTERING_WORLD");
+    self:RegisterEvent("UI_SCALE_CHANGED");
+    self:RegisterEvent("PET_BATTLE_CLOSE");
+    self:RegisterEvent("PET_BATTLE_OPENING_START");
+    self:RegisterEvent("ADDON_ACTION_BLOCKED", "TaintHandler");
+    self:RegisterEvent("ADDON_ACTION_FORBIDDEN", "TaintHandler");
+    self:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED", "PlayerInfoUpdate");
+    self:RegisterEvent("PLAYER_TALENT_UPDATE", "PlayerInfoUpdate");
+    self:RegisterEvent("CHARACTER_POINTS_CHANGED", "PlayerInfoUpdate");
+    self:RegisterEvent("UNIT_INVENTORY_CHANGED", "PlayerInfoUpdate");
+    self:RegisterEvent("UPDATE_BONUS_ACTIONBAR", "PlayerInfoUpdate");
+end
+
+function SV:Initialize()
+    self:UI_SCALE_CHANGED()
+    self.Events:TriggerOnce("LOAD_ALL_ESSENTIALS");
+    self.Events:TriggerOnce("LOAD_ALL_WIDGETS");
+
+    SVUILib:Launch();
+
+    self:UI_SCALE_CHANGED("PLAYER_LOGIN")
+    self:PlayerInfoUpdate();
+    self:VersionCheck();
+    self:RefreshAllMedia();
+
+    SVUILib:LoadScripts();
+    self.Events:TriggerOnce("CORE_INITIALIZED");
+
+    hooksecurefunc("StaticPopup_Show", self.StaticPopup_Show);
+    hooksecurefunc("CloseSpecialWindows", function() SV.OptionsStandby = nil; SV.Events:Trigger("SPECIAL_FRAMES_CLOSED") end)
+
+    if self.db.general.loginmessage then
+        SetLoginMessage(self);
+    end
+
+    if(self.DebugMode and self.HasErrors and self.ScriptError) then
+        self:ShowErrors();
+        wipe(self.ERRORLOG)
+    end
+
+    ---- print(p1 .. ", " .. p2:GetName() .. ", " .. p3 .. ", " .. p4 .. ", " .. p5) ----
+
+    collectgarbage("collect");
+
+    if self.db.general.logincredits then
+        self.Timers:ExecuteTimer(self.RollCredits, 10)
+    end
+end
+
+---- ################# ----
+---- THE CLEANING LADY ----
+---- ################# ----
+local LemonPledge = 0;
+local Consuela = CreateFrame("Frame")
+Consuela:RegisterAllEvents()
+Consuela:SetScript("OnEvent", function(self, event)
+    LemonPledge = LemonPledge  +  1
+    ---- print(event) ----
+    if(InCombatLockdown()) then return end;
+    if(LemonPledge > 10000) then
+        collectgarbage("collect");
+        LemonPledge = 0;
+    end
+end)
diff --git a/SVUI_!Core/system/credits.lua b/SVUI_!Core/system/credits.lua
new file mode 100644
index 0000000..1cde84b
--- /dev/null
+++ b/SVUI_!Core/system/credits.lua
@@ -0,0 +1,298 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+]]--
+
+--[[ GLOBALS ]]--
+
+local _G = _G;
+local table = _G.table;
+local math = _G.math;
+local concat = table.concat;
+local random = math.random;
+--[[ ADDON ]]--
+
+local SV = _G["SVUI"];
+local L = SV.L;
+
+local PRINTED_TEMPLATE = [[
+|cffff9900SUPERVILLAIN CREDITS:|r
+|cff4f4f4f---------------------------------------------|r
+|cffff9900CREATED BY:|r  Failcoder
+|cff4f4f4f---------------------------------------------|r
+|cffff9900CODE GRANTS BY:|r  Azilroka, Sortokk, Kkthnx
+|cff4f4f4f---------------------------------------------|r
+
+|cffff9900SPECIAL THANKS TO:
+|r|cfff81422Cairenn|r |cff2288cc(@WowInterface.com)|r  ..the most patient and accomodating person I know!
+|r|cfff81422Panser|r |cff2288cc(@TradeChat)|r  ..for all the re-tweets and favorites! |cff555555(now if I can get you to actually use this UI...)|r
+|r|cfff81422Synnistry|r and |cfff81422MetaGoblin|r  ..for giving this project life in your videos!
+|r|cfff81422Panda Co Live!|r and |cfff81422WoWProfitz|r ..for giving this project life in your streams!
+
+|cffff9900A VERY SPECIAL THANKS TO:  |r|cffffff00Movster|r  ..who inspired me to bring this project back to life!
+|cff4f4f4f---------------------------------------------|r
+
+|cffFFFF00THE HIGH COUNCIL  (aka EXECUTIVES):|r
+|cff33FF33SINNISTERR|r - (My wife, the MOST ruthless Warlock you will ever meet!)
+|cff33FF33PENGUINSANE|r - (The ace up my sleeve)
+|cff33FF33BLOODEAGLE|r - (The artisan tester)
+|cff33FF33HOTLUCK|r - (The profiler)
+|cff33FF33CROMAX|r - (The relentless)
+|cff33FF33DOONGA|r - (The man who keeps me busy)
+|cff33FF33DAIGAN|r - (Quality control with NO MERCY!)
+|cff33FF33FAOLANKING|r - (King of the bug report portal)
+|cff4f4f4f---------------------------------------------|r
+
+|cff99ff33KINGPINS  (aka INVESTORS):|r
+%s
+Other Silent Partners.. (Let me know if I have forgotten you)
+|cff4f4f4f---------------------------------------------|r
+
+|cff3399ffCODE MONKEYS  (aka CONTRIBUTORS):|r
+%s
+|cff4f4f4f---------------------------------------------|r
+
+|cffaa33ffMINIONS  (aka COMMUNITY TESTERS):|r
+%s
+The Wowinterface and Curse Community
+|cff4f4f4f---------------------------------------------|r
+
+|cff00ccffTheme Song By: Fingathing [taken from the song: SuperHero Music]|r
+]];
+
+local CreditFrame = _G["SVUI_CreditFrame"];
+CreditFrame.Title = _G["SVUI_CreditFrameTitle"];
+CreditFrame.List  = _G["SVUI_CreditFrameList"];
+local TitleFrame = _G["SVUI_SuperTitleFrame"];
+TitleFrame.Title = _G["SVUI_SuperTitleFrameTitle"];
+TitleFrame.List  = _G["SVUI_SuperTitleFrameList"];
+local playerName = UnitName("player");
+local playerClass = UnitClass("player");
+
+SV.Credits = {};
+
+SV.Credits["author"] = {
+  playerName,
+};
+
+SV.Credits["council"] = {
+  "Sinnisterr",
+  "Penguinsane",
+  "BloodEagle",
+  "Hotluck",
+  "Cromax",
+  "Doonga",
+  "Daigan",
+  "FaolanKing"
+};
+
+SV.Credits["investors"] = {
+  "Movster", "Meggalo", "Penguinsane", "FaolanKing", "Doonga",
+  "Cazart506", "Moondoggy", "Necroo", "Chief Pullin", "lkj61",
+  "BloodEagle", "Egbert", "Jerry Ferguson", "Hyti", "Elton",
+  "James Watson", "Lathron", "Adam Vargas", "Daphne", "Dave (Naméra)",
+  "Soulkrusher-Shu-Halo", "Talirrine", "Gaeline", "Malinche", "StealthyMangos",
+  "Monger", "JoeyMagz",
+  "Cherep2267", "Ravensongs", "Huggiedabear", "Titatotemaar", "Mahga"
+};
+
+SV.Credits["contributors"] = {
+  "Azilroka", "Sortokk", "Kkthnx", "Vyntrox", "Mydraal", "Profitz",
+  "AlleyKat", "Quokka", "Duugu", "Zork", "Haleth", "P3lim",
+  "Haste", "Totalpackage", "Kryso", "Thepilli", "Phanx"
+};
+
+SV.Credits["community"] = {
+  "Movster", "Judicate", "Cazart506", "MuffinMonster", "Joelsoul",
+  "Trendkill09", "Luamar", "Zharooz", "Lyn3x5", "Madh4tt3r",
+  "Xarioth", "AtomicKiller", "Meljen", "Moondoggy", "Stormblade",
+  "Schreibstift", "Anj", "Risien", "Cromax", "Nitro_Turtle",
+  "Shinzou", "Autolykus", "Taotao", "ColorsGaming", "Necroo", "Panser (TradeChat)",
+  "Synnistry", "MetaGoblin", "Panda Co Live!"
+};
+
+local LIST_PATTERN = "    %s\n        %s\n            %s\n                %s";
+local EPISODE_TEXT;
+local ROLLED_CREDITS = 0;
+local DELAY = 0;
+local CREDITS_DATA = {
+  {"Produced By: ", "council"},
+  {"Sponsored In Part By: ", "investors"},
+  {"Contributions Provided By: ", "contributors"},
+  {"Community Support From: ", "community"},
+  {"Written and Directed By: ", "author"},
+};
+
+local FLAVOR_TITLES = {
+  "The Adventures Of...", "The Legend Of...", "They Call Me...", "The Amazing...", "Tales Of..."
+};
+
+local FLAVOR_TEXTS = {
+  {"%s Of Legend", "The Notorious %s", "Do The %s Dance", "%s: 1, Everyone else: 0", "Chronicles of the %s"},
+  {"Chronicles of the %s %s", "Super %s %s", "The Notorious %s %s"}
+};
+
+local function RollCredits()
+  ROLLED_CREDITS = 1;
+  CreditFrame:CallBack()
+end
+
+local function ShowIssueString()
+  local WEEKDAY, MONTHNUM, DAYNUM, YEARNUM = CalendarGetDate();
+  local ISSUE_TEXT = ("Issue: #%d, Volume: #%d"):format(DAYNUM, MONTHNUM);
+  local flavorKey = random(1,2);
+  local flavorList = FLAVOR_TEXTS[flavorKey];
+  local flavorPattern = flavorList[random(1, #flavorList)]
+  if(flavorKey == 1) then
+    EPISODE_TEXT = flavorPattern:format(playerClass)
+  else
+    local currentGroup = GetActiveSpecGroup()
+    local currentSpec = GetSpecialization(false, false, currentGroup);
+    local specText = currentSpec and select(2, GetSpecializationInfo(currentSpec)) or nil
+    if(not specText) then
+      EPISODE_TEXT = "A Day In The Life..."
+    else
+      EPISODE_TEXT = flavorPattern:format(specText, playerClass)
+    end
+  end
+  CreditFrame:SetAlpha(0);
+  CreditFrame:Show();
+  CreditFrame.Title:SetText(ISSUE_TEXT);
+  CreditFrame.List:SetText(EPISODE_TEXT);
+  CreditFrame:FadeIn(1);
+end
+
+local function KillCredits()
+  TitleFrame:SetScript("OnUpdate", nil)
+  TitleFrame:Hide()
+  CreditFrame:SetScript("OnUpdate", nil)
+  CreditFrame:Hide()
+end
+
+local function TitleFrame_OnUpdate(self, elapsed)
+  DELAY = DELAY + elapsed
+  if(DELAY < 3) then return end
+  if(DELAY <= 3.5) then
+    self:FadeOut(1);
+  elseif(DELAY >= 7) then
+    DELAY = 0
+    self:SetScript("OnUpdate", nil)
+  end
+end
+
+local function InitTitleFrame_OnUpdate(self, elapsed)
+  DELAY = DELAY + elapsed
+  if(DELAY < 3) then return end
+  if(DELAY <= 3.5) then
+    self:FadeOut(1);
+  elseif(DELAY > 6 and DELAY <= 7) then
+    DELAY = 7.1
+    ShowIssueString()
+  elseif(DELAY > 9.5 and DELAY <= 10.5) then
+    CreditFrame:FadeOut(1);
+  elseif(DELAY > 14) then
+    DELAY = 0
+    self:SetScript("OnUpdate", nil)
+    RollCredits()
+  end
+end
+
+local function CreditFrame_OnUpdate(self, elapsed)
+  DELAY = DELAY + elapsed
+  if(DELAY < 3) then return end
+  if(DELAY <= 3.5) then
+    self:FadeOut(1);
+  elseif(DELAY >= 7) then
+    DELAY = 0
+    self:SetScript("OnUpdate", nil)
+    self:CallBack()
+  end
+end
+
+function TitleFrame:ShowTitle(title, text)
+  self:SetAlpha(0);
+  self:Show();
+  self.Title:SetText(title);
+  self.List:SetText(text);
+  self:FadeIn(1);
+  DELAY = 0;
+  self:SetScript("OnUpdate", TitleFrame_OnUpdate)
+end
+
+function CreditFrame:ShowCredit(title, text)
+  self:SetAlpha(0);
+  self:Show();
+  self.Title:SetText(title);
+  self.List:SetText(text);
+  self:FadeIn(1);
+  DELAY = 0;
+  self:SetScript("OnUpdate", CreditFrame_OnUpdate)
+end
+
+local All_Credits = function(self)
+  local title, list = "", "";
+  if(ROLLED_CREDITS < 5) then
+    title = "Thank You"
+    local council = SV.Credits['council'][random(1, #SV.Credits['council'])]
+    local investors = SV.Credits['investors'][random(1, #SV.Credits['investors'])]
+    local contributors = SV.Credits['contributors'][random(1, #SV.Credits['contributors'])]
+    local community = SV.Credits['community'][random(1, #SV.Credits['community'])]
+    list = LIST_PATTERN:format(council, investors, contributors, community);
+    ROLLED_CREDITS = ROLLED_CREDITS + 1;
+    self:ShowCredit(title, list);
+  else
+    KillCredits()
+  end
+end
+
+local Intro_Credits = function(self)
+  local title, list = "", "";
+  if(ROLLED_CREDITS == 1) then
+    title = "Produced By"
+    local council = SV.Credits['council'][random(1, #SV.Credits['council'])]
+    local investors = SV.Credits['investors'][random(1, #SV.Credits['investors'])]
+    local contributors = SV.Credits['contributors'][random(1, #SV.Credits['contributors'])]
+    local community = SV.Credits['community'][random(1, #SV.Credits['community'])]
+    list = LIST_PATTERN:format(council, investors, contributors, community);
+    ROLLED_CREDITS = 2;
+    self:ShowCredit(title, list);
+  elseif(ROLLED_CREDITS == 2) then
+    title = "Written and Directed By"
+    list = playerName
+    ROLLED_CREDITS = 0;
+    self:ShowCredit(title, list);
+  else
+    KillCredits()
+  end
+end
+
+function SV:PrintCredits()
+  local investors, contributors, community;
+  investors = concat(self.Credits["investors"], ", ");
+  contributors = concat(self.Credits["contributors"], ", ");
+  community = concat(self.Credits["community"], ", ");
+  return PRINTED_TEMPLATE:format(investors, contributors, community)
+end
+
+function SV:RollCredits()
+  CreditFrame.CallBack = Intro_Credits
+  CreditFrame:SetScript("OnMouseDown", KillCredits);
+  TitleFrame:SetScript("OnMouseDown", KillCredits);
+  DELAY = 0;
+  SV.Events:On("SPECIAL_FRAMES_CLOSED", KillCredits, true);
+  TitleFrame:SetAlpha(0);
+  TitleFrame:Show();
+  local titleKey = random(1,#FLAVOR_TITLES)
+  local titlePattern = FLAVOR_TITLES[titleKey]
+  TitleFrame:ShowTitle(titlePattern, playerName);
+  TitleFrame.List:SetText(playerName);
+  TitleFrame:FadeIn(1);
+  TitleFrame:SetScript("OnUpdate", InitTitleFrame_OnUpdate);
+end
+
+function SV:FlashTitle(text1, text2)
+  TitleFrame:ShowTitle(text1, text2);
+end
+
+SV:AddSlashCommand("credits", "Display some randomly selected SVUI credits", function() CreditFrame.CallBack = All_Credits; RollCredits() end);
diff --git a/SVUI_!Core/system/damage_text.lua b/SVUI_!Core/system/damage_text.lua
new file mode 100644
index 0000000..c8b4392
--- /dev/null
+++ b/SVUI_!Core/system/damage_text.lua
@@ -0,0 +1,34 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G 	= _G;
+local type 	= type;
+--[[
+##########################################################
+FORCIBLY CHANGE THE GAME WORLD COMBAT TEXT FONT
+##########################################################
+]]--
+local FONT_NAME = "DAMAGE_TEXT_FONT";
+
+local MAIN_DIR = "Fonts\\%s.ttf";
+local BASE_DIR = "Interface\\AddOns\\SVUI_!Core\\%s.ttf";
+local FONT_DIR = "Interface\\AddOns\\SVUI_!Core\\assets\\fonts\\%s.ttf";
+
+--local FONTSIZE = 32;
+--local USER_FONT1 = BASE_DIR:format(FONT_NAME);
+--local USER_FONT2 = MAIN_DIR:format(FONT_NAME);
+
+local NEW_DAMAGE_FONT  = FONT_DIR:format(FONT_NAME);
+
+local function ForceDamageFont()
+	_G.DAMAGE_TEXT_FONT = NEW_DAMAGE_FONT
+	_G.COMBAT_TEXT_CRIT_SCALE_TIME = 0.7;
+	_G.COMBAT_TEXT_SPACING = 15;
+end
+
+ForceDamageFont();
diff --git a/SVUI_!Core/system/debug.lua b/SVUI_!Core/system/debug.lua
new file mode 100644
index 0000000..9f151cd
--- /dev/null
+++ b/SVUI_!Core/system/debug.lua
@@ -0,0 +1,455 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+############################################################################## ]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack            = _G.unpack;
+local select            = _G.select;
+local assert            = _G.assert;
+local type              = _G.type;
+local error             = _G.error;
+local pcall             = _G.pcall;
+local print             = _G.print;
+local ipairs            = _G.ipairs;
+local pairs             = _G.pairs;
+local next              = _G.next;
+local rawset            = _G.rawset;
+local rawget            = _G.rawget;
+local tostring          = _G.tostring;
+local tonumber          = _G.tonumber;
+local getmetatable      = _G.getmetatable;
+local setmetatable      = _G.setmetatable;
+local collectgarbage    = _G.collectgarbage;
+local tinsert   = _G.tinsert;
+local string    = _G.string;
+local math      = _G.math;
+local table     = _G.table;
+local wipe      = _G.wipe;
+--[[ STRING METHODS ]]--
+local format, find, lower, match, gsub = string.format, string.find, string.lower, string.match, string.gsub;
+--[[ MATH METHODS ]]--
+local floor, abs, min, max = math.floor, math.abs, math.min, math.max;
+--[[ TABLE METHODS ]]--
+local tremove, tcopy, twipe, tsort, tconcat = table.remove, table.copy, table.wipe, table.sort, table.concat;
+local tprint = table.tostring;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G["SVUI"];
+local L = SV.L;
+SV.ScriptError = _G["SVUI_ScriptError"];
+local ScriptErrorDialog = _G["SVUI_ScriptErrorDialog"];
+local ScriptErrorScrollBar = _G["SVUI_ScriptErrorDialogScrollBar"];
+
+local DevTools_Dump = _G.DevTools_Dump;
+local DevTools_RunDump = _G.DevTools_RunDump;
+--[[
+##########################################################
+CUSTOM MESSAGE WINDOW
+##########################################################
+]]--
+local ScriptError_OnShow = function(self)
+    if self.Source then
+        local txt = self.Source;
+        self.Title:SetText(txt);
+    end
+end
+
+local ScriptError_OnTextChanged = function(self, userInput)
+    if userInput then return end
+    local _, max = ScriptErrorScrollBar:GetMinMaxValues()
+    for i = 1, max do
+      ScrollFrameTemplate_OnMouseWheel(ScriptErrorDialog, -1)
+    end
+end
+
+local function getOriginalContext()
+    UIParentLoadAddOn("Blizzard_DebugTools")
+    local orig_DevTools_RunDump = DevTools_RunDump
+    local originalContext
+    DevTools_RunDump = function(value, context)
+        originalContext = context
+    end
+    DevTools_Dump("")
+    DevTools_RunDump = orig_DevTools_RunDump
+    return originalContext
+end
+
+local function formatValueString(value)
+    if "string" == type(value) then
+        value = gsub(value,"\n","\\n")
+        if match(gsub(value,"[^'\"]",""),'^"+$') then
+            return "'"..value.."'";
+        else
+            return '"'..gsub(value,'"','\\"')..'"';
+        end
+    else
+        return tprint(value, true);
+    end
+end
+
+local function formatKeyString(text)
+    if("string" == type(text) and match(text,"^[_%a][_%a%d]*$")) then
+        return text;
+    else
+        return "["..formatValueString(text).."]";
+    end
+end
+
+local DUMPTABLE = {};
+local CHECKTABLE = {};
+
+local function loadDumpTable(arg)
+    for key,data in pairs(arg) do
+        if(type(data) == "table") then
+            loadDumpTable(data);
+        else
+            tinsert(DUMPTABLE, "\n        "..formatKeyString(key).." = "..formatValueString(data));
+        end
+    end
+end
+
+local function DebugDump(arg)
+    if(arg == nil) then
+        return "No Result"
+    elseif(type(arg) == "string") then
+        return arg
+    elseif(type(arg) == "table") then
+        loadDumpTable(arg)
+        return table.concat(DUMPTABLE);
+        -- local context = getOriginalContext()
+        -- if(context) then
+        --     local buffer = ""
+        --     context.Write = function(self, msg)
+        --         buffer = buffer.."\n"..msg
+        --     end
+
+        --     DevTools_RunDump(arg, context)
+        --     return buffer .. "\n" .. tableOutput(arg)
+        -- else
+        --     return tableOutput(arg)
+        -- end
+    elseif(type(arg) == "number") then
+        return tostring(arg)
+    end
+    return arg
+end
+
+function SV.ScriptError:DebugOutput(msg)
+    if not self:IsShown() then
+        self:Show()
+    end
+    ScriptErrorDialog.Input:SetText(msg)
+end
+
+function SV.ScriptError:TableDump(t)
+    self:DebugOutput(tprint(t))
+end
+
+function SV.ScriptError:ShowDebug(header, ...)
+    wipe(DUMPTABLE);
+    wipe(CHECKTABLE);
+    local value = (header and format("Debug %s: ", header)) or "Debug: "
+    value = format("|cff11ff11 %s|r = {\n", value)
+    for i = 1, select('#', ...) do
+        local data = select(i, ...)
+        local var;
+        if(data.GetRegions) then
+            var = DebugDump(data:GetRegions())
+        else
+            var = DebugDump(data)
+        end
+        value = format("%s    [%d] = { %s\n    }\n", value, i, var)
+    end
+    value = format("%s}", value)
+    self.Source = header;
+    self:DebugOutput(value)
+end
+
+_G.DebugThisFrame = function(arg)
+    local outputString = " ";
+    if arg then
+        arg = _G[arg] or GetMouseFocus()
+    else
+        arg = GetMouseFocus()
+    end
+    if arg and (arg.GetName and arg:GetName()) then
+        local point, relativeTo, relativePoint, xOfs, yOfs = arg:GetPoint()
+        outputString = outputString.."|cffCC0000----------------------------".."\n"
+        outputString = outputString.."|cffCC00FF--Mouseover Frame".."|r".."\n"
+        outputString = outputString.."|cffCC0000----------------------------|r".."\n"
+        outputString = outputString.."|cff00D1FF".."Name: |cffFFD100"..arg:GetName().."\n"
+        if arg:GetParent() and arg:GetParent():GetName() then
+            outputString = outputString.."|cff00D1FF".."Parent: |cffFFD100"..arg:GetParent():GetName().."\n"
+        end
+        outputString = outputString.."|cff00D1FF".."Width: |cffFFD100"..format("%.2f",arg:GetWidth()).."\n"
+        outputString = outputString.."|cff00D1FF".."Height: |cffFFD100"..format("%.2f",arg:GetHeight()).."\n"
+
+        if(arg.GetFrameStrata) then
+            outputString = outputString.."|cff00D1FF".."Strata: |cffFFD100"..arg:GetFrameStrata().."\n"
+        end
+
+        if(arg.GetFrameLevel) then
+            outputString = outputString.."|cff00D1FF".."Level: |cffFFD100"..arg:GetFrameLevel().."\n"
+        end
+
+        if(arg.GetDrawLayer) then
+            outputString = outputString.."|cff00D1FF".."DrawLayer: |cffFFD100"..arg:GetDrawLayer().."\n"
+        end
+
+        outputString = outputString.."|cff00D1FF".."IsShown: |cffFFD100"..tostring(arg:IsShown()).."\n"
+
+        if(arg.GetAlpha) then
+            outputString = outputString.."|cff00D1FF".."Alpha: |cffFFD100"..arg:GetAlpha().."\n"
+        end
+
+        if(arg.GetText and arg:GetText() and arg.GetTextColor) then
+            outputString = outputString.."|cff00D1FF".."Text: |cffFFD100"..arg:GetText().."\n"
+            local tr, tg, tb = arg:GetTextColor();
+            outputString = outputString.."|cff00D1FF".."Text Color: \n"
+            outputString = outputString.."|cffFF0000".."        Red: |cffFFFFFF "..tr.."\n"
+            outputString = outputString.."|cff00FF00".."        Green: |cffFFFFFF "..tg.."\n"
+            outputString = outputString.."|cff0000FF".."        Blue: |cffFFFFFF "..tb.."\n"
+        end
+
+        if arg.Panel and arg.Panel:GetAttribute("panelPadding") then
+            outputString = outputString.."|cff00D1FF".."Padding: |cffFFD100"..arg.Panel:GetAttribute("panelPadding").."\n"
+        end
+        if arg.Panel and arg.Panel:GetAttribute("panelOffset") then
+            outputString = outputString.."|cff00D1FF".."Offset: |cffFFD100"..arg.Panel:GetAttribute("panelOffset").."\n"
+        end
+        if arg.Panel and arg.Panel:GetAttribute("panelID") then
+            outputString = outputString.."|cff00D1FF".."StyleName: |cffFFD100"..arg.Panel:GetAttribute("panelID").."\n"
+        end
+        if xOfs then
+            outputString = outputString.."|cff00D1FF".."X: |cffFFD100"..format("%.2f",xOfs).."\n"
+        end
+        if yOfs then
+            outputString = outputString.."|cff00D1FF".."Y: |cffFFD100"..format("%.2f",yOfs).."\n"
+        end
+        if relativeTo and relativeTo:GetName() then
+            outputString = outputString.."|cff00D1FF".."Point: |cffFFD100"..point.."|r anchored to "..relativeTo:GetName().."'s |cffFFD100"..relativePoint.."\n"
+        end
+        if(arg.GetBackdrop) then
+            local bg = arg:GetBackdrop()
+            if type(bg) == "table" then
+                outputString = outputString.."|cffFF9900>> BACKDROP --------------------------|r".."\n"
+                outputString = outputString..tprint(bg, true).."\n"
+            end
+            if arg._template then
+                outputString = outputString.."Template Name: |cff00FF55"..arg._template.."\n"
+            end
+            if arg.Panel then
+                local cpt, crt, crp, cxo, cyo = arg.Panel:GetPoint()
+                outputString = outputString.."|cffFF8800>> backdropFrame --------------------------|r".."\n"
+                outputString = outputString.."|cff00D1FF".."Width: |cffFFD100"..format("%.2f",arg.Panel:GetWidth()).."\n"
+                outputString = outputString.."|cff00D1FF".."Height: |cffFFD100"..format("%.2f",arg.Panel:GetHeight()).."\n"
+                outputString = outputString.."|cff00D1FF".."Strata: |cffFFD100"..arg.Panel:GetFrameStrata().."\n"
+                outputString = outputString.."|cff00D1FF".."Level: |cffFFD100"..arg.Panel:GetFrameLevel().."\n"
+                if cxo then
+                    outputString = outputString.."|cff00D1FF".."X: |cffFFD100"..format("%.2f",cxo).."\n"
+                end
+                if cyo then
+                    outputString = outputString.."|cff00D1FF".."Y: |cffFFD100"..format("%.2f",cyo).."\n"
+                end
+                if crt and crt:GetName() then
+                    outputString = outputString.."|cff00D1FF".."Point: |cffFFD100"..cpt.."|r anchored to "..crt:GetName().."'s |cffFFD100"..crp.."\n"
+                end
+                bg = arg.Panel:GetBackdrop()
+                if type(bg) == "table" then
+                    outputString = outputString.."|cffFF9900>> BACKDROP --------------------------|r".."\n"
+                    outputString = outputString..tprint(bg, true).."\n"
+                end
+                if arg.Panel.Skin then
+                    local cpt, crt, crp, cxo, cyo = arg.Panel.Skin:GetPoint()
+                    outputString = outputString.."|cffFF7700>> backdropTexture --------------------------|r".."\n"
+                    outputString = outputString.."|cff00D1FF".."Width: |cffFFD100"..format("%.2f",arg.Panel.Skin:GetWidth()).."\n"
+                    outputString = outputString.."|cff00D1FF".."Height: |cffFFD100"..format("%.2f",arg.Panel.Skin:GetHeight()).."\n"
+                    if cxo then
+                        outputString = outputString.."|cff00D1FF".."X: |cffFFD100"..format("%.2f",cxo).."\n"
+                    end
+                    if cyo then
+                        outputString = outputString.."|cff00D1FF".."Y: |cffFFD100"..format("%.2f",cyo).."\n"
+                    end
+                    if crt and crt:GetName() then
+                        outputString = outputString.."|cff00D1FF".."Point: |cffFFD100"..cpt.."|r anchored to "..crt:GetName().."'s |cffFFD100"..crp.."\n"
+                    end
+                    bg = arg.Panel.Skin:GetTexture()
+                    if bg then
+                        outputString = outputString.."|cff00D1FF".."Texture: |cffFFD100"..bg.."\n"
+                    end
+                end
+            end
+            local childFrames = { arg:GetChildren() }
+            if #childFrames > 0 then
+                outputString = outputString.."|cffCC00FF>>>> Child Frames----------------------------".."|r".."\n".."\n"
+                for _, child in ipairs(childFrames) do
+                    local cpt, crt, crp, cxo, cyo = child:GetPoint()
+                    if child:GetName() then
+                        outputString = outputString.."\n\n|cff00FF55++"..child:GetName().."|r".."\n"
+                    else
+                        outputString = outputString.."\n\n|cff99FF55+!!+".."Anonymous Frame".."|r".."\n"
+                    end
+                    outputString = outputString.."|cffCC00FF----------------------------|r".."\n"
+                    outputString = outputString.."|cff00D1FF".."Width: |cffFFD100"..format("%.2f",child:GetWidth()).."\n"
+                    outputString = outputString.."|cff00D1FF".."Height: |cffFFD100"..format("%.2f",child:GetHeight()).."\n"
+                    outputString = outputString.."|cff00D1FF".."Strata: |cffFFD100"..child:GetFrameStrata().."\n"
+                    outputString = outputString.."|cff00D1FF".."Level: |cffFFD100"..child:GetFrameLevel().."\n"
+                    if child.Panel and child.Panel:GetAttribute("panelID") then
+                        outputString = outputString.."|cff00D1FF".."StyleName: |cffFFD100"..child.Panel:GetAttribute("panelID").."\n"
+                    end
+                    if child.Panel and child.Panel:GetAttribute("panelPadding") then
+                        outputString = outputString.."|cff00D1FF".."Padding: |cffFFD100"..child.Panel:GetAttribute("panelPadding").."\n"
+                    end
+                    if child.Panel and child.Panel:GetAttribute("panelOffset") then
+                        outputString = outputString.."|cff00D1FF".."Offset: |cffFFD100"..child.Panel:GetAttribute("panelOffset").."\n"
+                    end
+                    if cxo then
+                        outputString = outputString.."|cff00D1FF".."X: |cffFFD100"..format("%.2f",cxo).."\n"
+                    end
+                    if cyo then
+                        outputString = outputString.."|cff00D1FF".."Y: |cffFFD100"..format("%.2f",cyo).."\n"
+                    end
+                    if crt and crt:GetName() then
+                        outputString = outputString.."|cff00D1FF".."Point: |cffFFD100"..cpt.."|r anchored to "..crt:GetName().."'s |cffFFD100"..crp.."\n"
+                    end
+                    bg = child:GetBackdrop()
+                    if type(bg) == "table" then
+                        outputString = outputString.."|cffFF9900>> BACKDROP --------------------------|r".."\n"
+                        outputString = outputString..tprint(bg, true).."\n"
+                    end
+                    if child._template then
+                        outputString = outputString.."Template Name: |cff00FF55"..child._template.."\n"
+                    end
+                    if child.Panel then
+                        local cpt, crt, crp, cxo, cyo = child.Panel:GetPoint()
+                        outputString = outputString.."|cffFF8800>> backdropFrame --------------------------|r".."\n"
+                        outputString = outputString.."|cff00D1FF".."Width: |cffFFD100"..format("%.2f",child.Panel:GetWidth()).."\n"
+                        outputString = outputString.."|cff00D1FF".."Height: |cffFFD100"..format("%.2f",child.Panel:GetHeight()).."\n"
+                        outputString = outputString.."|cff00D1FF".."Strata: |cffFFD100"..child.Panel:GetFrameStrata().."\n"
+                        outputString = outputString.."|cff00D1FF".."Level: |cffFFD100"..child.Panel:GetFrameLevel().."\n"
+                        if cxo then
+                            outputString = outputString.."|cff00D1FF".."X: |cffFFD100"..format("%.2f",cxo).."\n"
+                        end
+                        if cyo then
+                            outputString = outputString.."|cff00D1FF".."Y: |cffFFD100"..format("%.2f",cyo).."\n"
+                        end
+                        if crt and crt:GetName() then
+                            outputString = outputString.."|cff00D1FF".."Point: |cffFFD100"..cpt.."|r anchored to "..crt:GetName().."'s |cffFFD100"..crp.."\n"
+                        end
+                        bg = child.Panel:GetBackdrop()
+                        if type(bg) == "table" then
+                            outputString = outputString.."|cffFF9900>> BACKDROP --------------------------|r".."\n"
+                            outputString = outputString..tprint(bg, true).."\n"
+                        end
+                        if child._skin then
+                            local cpt, crt, crp, cxo, cyo = child._skin:GetPoint()
+                            outputString = outputString.."|cffFF7700>> backdropTexture --------------------------|r".."\n"
+                            outputString = outputString.."|cff00D1FF".."Width: |cffFFD100"..format("%.2f",child._skin:GetWidth()).."\n"
+                            outputString = outputString.."|cff00D1FF".."Height: |cffFFD100"..format("%.2f",child._skin:GetHeight()).."\n"
+                            if cxo then
+                                outputString = outputString.."|cff00D1FF".."X: |cffFFD100"..format("%.2f",cxo).."\n"
+                            end
+                            if cyo then
+                                outputString = outputString.."|cff00D1FF".."Y: |cffFFD100"..format("%.2f",cyo).."\n"
+                            end
+                            if crt and crt:GetName() then
+                                outputString = outputString.."|cff00D1FF".."Point: |cffFFD100"..cpt.."|r anchored to "..crt:GetName().."'s |cffFFD100"..crp.."\n"
+                            end
+                            bg = child._skin:GetTexture()
+                            if bg then
+                                outputString = outputString.."|cffFF9900----------------------------|r".."\n"
+                                outputString = outputString..bg.."\n"
+                            end
+                            outputString = outputString.."|cffCC0000----------------------------|r".."\n"
+                        end
+                    end
+                end
+                outputString = outputString.."\n\n"
+            end
+        end
+    elseif arg == nil or arg == "" then
+        outputString = outputString.."Invalid frame name".."\n"
+    else
+        outputString = outputString.."Could not find frame info".."\n"
+    end
+    SV.ScriptError:DebugOutput(outputString)
+    --ScriptErrorDialog:SetVerticalScroll(1)
+end
+
+_G.SlashCmdList["SVUI_FRAME_DEBUG"] = DebugThisFrame;
+_G.SLASH_SVUI_FRAME_DEBUG1 = "/svdf"
+
+--SetCVar('scriptProfile',1)
+
+local function InitializeScriptError()
+    SV.ScriptError:SetParent(SV.Screen)
+    SV.ScriptError.Source = "";
+    SV.ScriptError:SetStyle("!_Frame", "Transparent")
+    SV.ScriptError.Clear:SetStyle("Button")
+    SV.ScriptError:SetScript("OnShow", ScriptError_OnShow)
+    SV.API:Set("ScrollBar", SVUI_ScriptErrorDialogScrollBar)
+    ScriptErrorDialog:SetStyle("!_Frame", "Transparent")
+    ScriptErrorDialog.Input:SetScript("OnTextChanged", ScriptError_OnTextChanged)
+    SV.ScriptError:RegisterForDrag("LeftButton");
+end
+
+SV.Events:On("LOAD_ALL_ESSENTIALS", InitializeScriptError);
+--[[
+##########################################################
+REVEAL INTERNAL ERRORS
+##########################################################
+]]--
+local function _showErrors(msg)
+    if msg then
+        if(msg == "off") then
+            SV.DebugMode = false
+            SV:AddonMessage("Debug Mode |cffFF0000DISABLED|r")
+        elseif(msg == "on") then
+            SV.DebugMode = true
+            SV:AddonMessage("Debug Mode |cff00FF00ENABLED|r")
+        end
+    end
+
+    if(SV.DebugMode) then
+        local ERRORSTRING = table.concat(SV.ERRORLOG, "\n\n");
+        SV.ScriptError:DebugOutput(ERRORSTRING)
+        wipe(SV.ERRORLOG)
+    else
+        SV:AddonMessage("Debug Mode Not Enabled! Try using |cff00FF00/showerrors on|r")
+    end
+end
+
+function SV:ShowErrors()
+    _showErrors()
+end
+
+function SV:ResetErrors()
+    wipe(SV.ERRORLOG)
+end
+
+_G.SlashCmdList["SVUI_SHOW_ERRORS"] = _showErrors;
+_G.SLASH_SVUI_SHOW_ERRORS1 = "/showerrors"
+
+--[[
+##########################################################
+FIX BAD INTERACTION WITH FSTACK
+##########################################################
+]]--
+_G.FrameStackTooltip_Toggle = function(showHidden, showRegions)
+	local tooltip = _G["FrameStackTooltip"];
+	if ( tooltip:IsVisible() ) then
+		tooltip:Hide();
+		FrameStackHighlight:Hide();
+	else
+		tooltip:SetOwner(UIParent, "ANCHOR_NONE");
+		tooltip:SetPoint("BOTTOMRIGHT", UIParent, "BOTTOMRIGHT", -CONTAINER_OFFSET_X - 13, CONTAINER_OFFSET_Y);
+		tooltip.default = 1;
+		tooltip.showRegions = showRegions;
+		tooltip.showHidden = showHidden;
+        local pass, catch = pcall(tooltip.SetFrameStack, tooltip, showHidden, showRegions)
+	end
+end
diff --git a/SVUI_!Core/system/dock.lua b/SVUI_!Core/system/dock.lua
new file mode 100644
index 0000000..6d26e7d
--- /dev/null
+++ b/SVUI_!Core/system/dock.lua
@@ -0,0 +1,2154 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+############################################################################## ]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pcall         = _G.pcall;
+local print         = _G.print;
+local ipairs        = _G.ipairs;
+local pairs         = _G.pairs;
+local tostring      = _G.tostring;
+local tonumber      = _G.tonumber;
+
+--STRING
+local string        = _G.string;
+local upper         = string.upper;
+local format        = string.format;
+local find          = string.find;
+local match         = string.match;
+local gsub          = string.gsub;
+local split 		= string.split;
+--TABLE
+local table 		= _G.table;
+local tinsert       = _G.tinsert;
+local tremove       = _G.tremove;
+local wipe 			= _G.wipe;
+local tsort 		= table.sort;
+--MATH
+local math      	= _G.math;
+local random 		= math.random;
+local min 			= math.min;
+local floor         = math.floor;
+local ceil          = math.ceil;
+local parsefloat 	= math.parsefloat;
+--BLIZZARD API
+local InCombatLockdown     	= _G.InCombatLockdown;
+local CreateFrame          	= _G.CreateFrame;
+--[[
+##########################################################
+ADDON
+##########################################################
+]]--
+local SV = select(2, ...);
+local L = SV.L;
+local MOD = SV:NewPackage("Dock", L["Docks"]);
+MOD.Border = {};
+--[[
+##########################################################
+LOCALS
+##########################################################
+]]--
+-- SV.SpecialFX:Register("dragging_highlight", [[Spells\Warlock_bodyofflames_medium_state_shoulder_right_purple.m2]], -20, 50, 20, -50, 0.35, 0, 0.5)
+SV.SpecialFX:Register("dragging_highlight_top", [[Spells\Creature_spellportal_blue_clickable.m2]], 0, 0, 0, -80, 0.8, 0, 2.5)
+SV.SpecialFX:Register("dragging_highlight_bottom", [[Spells\Creature_spellportal_blue_clickable.m2]], 0, 80, 0, 0, 0.9, 0, -0.25)
+
+local ToggleDraggingMode;
+local DOCK_CHECK, DRAG_LASTINDEX, DRAG_ORDERINDEX, DRAG_TARGETBAR, DRAG_BUTTONWIDTH, DRAG_ENABLED;
+local ORDER_TEMP, DOCK_REGISTRY, DOCK_DROPDOWN_OPTIONS = {}, {}, {};
+local DOCK_LOCATIONS = {
+	["BottomLeft"] = {1, "LEFT", true, "ANCHOR_TOPLEFT"},
+	["BottomRight"] = {-1, "RIGHT", true, "ANCHOR_TOPLEFT"},
+	["TopLeft"] = {1, "LEFT", false, "ANCHOR_BOTTOMLEFT"},
+	["TopRight"] = {-1, "RIGHT", false, "ANCHOR_BOTTOMLEFT"},
+};
+--[[
+	Quick explaination of what Im doing with all of these locals...
+	Unlike many of the other modules, Chat has to continuously
+	reference config settings which can start to get sluggish. What
+	I have done is set local variables for every database value
+	that the module can read efficiently. The function "UpdateLocals"
+	is used to refresh these any time a change is made to configs
+	and once when the mod is loaded.
+]]--
+-- local DOCK_WIDTH = 412;
+-- local DOCK_HEIGHT = 224;
+-- local DOCK_ALPHA = 1;
+--[[
+##########################################################
+THEMEABLE ITEMS
+##########################################################
+]]--
+MOD.ButtonSound = SV.Sounds:Blend("DockButton", "Buttons", "Levers");
+MOD.ErrorSound = SV.Sounds:Blend("Malfunction", "Sparks", "Wired");
+
+local function copyTable(tab)
+	local copy = {};
+	for k, v in pairs(tab) do
+		if ( type(v) == "table" ) then
+			copy[k] = copyTable(v);
+		else
+			copy[k] = v;
+		end
+	end
+	return copy;
+end
+
+local function GetDockDimensions(location)
+	local width, height;
+	local isTop = location:find("Top")
+	local isLeft = location:find("Left")
+	if(isTop) then
+		if(isLeft) then
+			width = SV.db.Dock.dockTopLeftWidth;
+			height = SV.db.Dock.dockTopLeftHeight;
+		else
+			width = SV.db.Dock.dockTopRightWidth;
+			height = SV.db.Dock.dockTopRightHeight;
+		end
+	else
+		if(isLeft) then
+			width = SV.db.Dock.dockLeftWidth;
+			height = SV.db.Dock.dockLeftHeight;
+			if(MOD.private.LeftExpanded) then
+				height = height + 300
+			end
+		else
+			width = SV.db.Dock.dockRightWidth;
+			height = SV.db.Dock.dockRightHeight;
+			if(MOD.private.RightExpanded) then
+				height = height + 300
+			end
+		end
+	end
+
+	return width, height;
+end
+
+local function SetDockDimensions(location, width, height, buttonSize)
+	local isTop = location:find("Top")
+	local isLeft = location:find("Left")
+	if(isTop) then
+		if(isLeft) then
+			SV.db.Dock.dockTopLeftWidth = width;
+			if(not buttonSize) then
+				SV.db.Dock.dockTopLeftHeight = height;
+			end
+		else
+			SV.db.Dock.dockTopRightWidth = width;
+			if(not buttonSize) then
+				SV.db.Dock.dockTopRightHeight = height;
+			end
+		end
+	else
+		if(isLeft) then
+			SV.db.Dock.dockLeftWidth = width;
+			if(not buttonSize) then
+				SV.db.Dock.dockLeftHeight = height;
+			end
+		else
+			SV.db.Dock.dockRightWidth = width;
+			if(not buttonSize) then
+				SV.db.Dock.dockRightHeight = height;
+			end
+		end
+	end
+
+	if(buttonSize) then
+		SV.db.Dock.buttonSize = height;
+	end
+end
+
+local dockPostSizeFunc = function(self, width, height)
+	local name = self:GetName()
+	SetDockDimensions(name, width, height)
+	MOD:Refresh()
+end
+
+local dockBarPostSizeFunc = function(self, width, height)
+	local name = self:GetName()
+	SetDockDimensions(name, width, height, true)
+	MOD:Refresh()
+end
+
+local function SaveCurrentPosition(button)
+	if((not button) or (not MOD.private.Dimensions)) then return end
+
+	local anchor1, parent, anchor2, x, y = button:GetPoint();
+
+	if(anchor1 and anchor2 and x and y) then
+		local parentName;
+		if(not parent or (not parent.GetName) or (not parent:GetName())) then
+			parentName = "UIParent"
+		else
+			parentName = parent:GetName()
+		end
+
+		local name = button:GetName();
+		local width, height = 0,0;
+		if(button.FrameLink) then
+			local frame = button.FrameLink;
+			frame:ClearAllPoints();
+			frame:SetPoint("BOTTOMLEFT", button, "TOPLEFT", -3, 6);
+			if(frame.UpdateBackdrop) then frame:UpdateBackdrop() end
+			local saved = MOD.private.Dimensions[name];
+			local currentWidth, currentHeight = frame:GetSize();
+			if(saved) then
+				local _, _, _, _, _, w, h = split("|", saved);
+				width, height = w, h
+				if((currentWidth ~= w) or (currentHeight ~= h)) then
+					frame:SetSize(w, h)
+				end
+			else
+				width, height = currentWidth, currentHeight;
+			end
+			if((not width) or (not height)) then
+				width, height = 0,0;
+			end
+		end
+		local result = ("%s|%s|%s|%d|%d|%d|%d"):format(anchor1, parentName, anchor2, parsefloat(x), parsefloat(y), parsefloat(width), parsefloat(height))
+		MOD.private.Dimensions[name] = result;
+	end
+end
+
+local function SaveCurrentDimensions(button)
+	if((not button) or (not MOD.private.Dimensions)) then return end
+
+	if(button.FrameLink) then
+		local name = button:GetName();
+		local saved = MOD.private.Dimensions[name];
+		local anchor1, parent, anchor2, x, y, width, height;
+		if(saved) then
+			anchor1, parent, anchor2, x, y = split("|", saved);
+		else
+			anchor1, parent, anchor2, x, y = button:GetPoint();
+		end
+		local frame = button.FrameLink;
+		width, height = frame:GetSize()
+		if((not width) or (not height)) then
+			-- print(frame:GetSize())
+			width, height = 0, 0
+		end
+		local parentName;
+		if(not parent or (not parent.GetName) or (not parent:GetName())) then
+			parentName = "UIParent"
+		else
+			parentName = parent:GetName()
+		end
+		local result = ("%s|%s|%s|%d|%d|%d|%d"):format(anchor1, parentName, anchor2, parsefloat(x), parsefloat(y), parsefloat(width), parsefloat(height))
+		frame:ClearAllPoints();
+		frame:SetPoint("BOTTOMLEFT", button, "TOPLEFT", -3, 6);
+		if(frame.UpdateBackdrop) then
+			frame:UpdateBackdrop()
+		end
+		MOD.private.Dimensions[name] = result;
+	end
+end
+
+local function LoadSavedDimensions(button)
+	local saved = MOD.private.Dimensions[button:GetName()];
+	if(saved and (type(saved) == "string") and (saved ~= 'TBD')) then
+		local anchor1, anchorParent, anchor2, xPos, yPos, width, height = split("|", saved)
+		button:ClearAllPoints()
+		button:SetPoint(anchor1, anchorParent, anchor2, xPos, yPos)
+
+		local frame = button.FrameLink;
+		if(frame) then
+			frame:ClearAllPoints();
+			frame:SetPoint("BOTTOMLEFT", button, "TOPLEFT", -3, 6);
+			if((not width) or (not height)) then
+				width, height = frame:GetSize()
+			end
+			frame:SetSize(width, height)
+			if(frame.UpdateBackdrop) then frame:UpdateBackdrop() end
+		end
+	end
+end
+
+local function ScreenBorderVisibility()
+	if SV.db.Dock.bottomPanel then
+		SVUIDock_BottomBorder:Show()
+	else
+		SVUIDock_BottomBorder:Hide()
+	end
+
+	if SV.db.Dock.topPanel then
+		SVUIDock_TopBorder:Show()
+	else
+		SVUIDock_TopBorder:Hide()
+	end
+end
+
+local function SetBasicBackdrop(frame)
+	local backdrop = CreateFrame("Frame", nil, frame)
+	backdrop:InsetPoints(frame,4,4)
+	backdrop:SetFrameStrata("BACKGROUND")
+
+	local underlay = backdrop:CreateTexture(nil, "BORDER")
+	underlay:InsetPoints(backdrop)
+	underlay:SetColorTexture(0, 0, 0, 0.5)
+
+	local left = backdrop:CreateTexture(nil, "OVERLAY")
+	left:SetColorTexture(0, 0, 0, 1)
+	left:SetPoint("TOPLEFT", 1, -1)
+	left:SetPoint("BOTTOMLEFT", -1, -1)
+	left:SetWidth(2)
+
+	local right = backdrop:CreateTexture(nil, "OVERLAY")
+	right:SetColorTexture(0, 0, 0, 1)
+	right:SetPoint("TOPRIGHT", -1, -1)
+	right:SetPoint("BOTTOMRIGHT", -1, -1)
+	right:SetWidth(2)
+
+	local bottom = backdrop:CreateTexture(nil, "OVERLAY")
+	bottom:SetColorTexture(0, 0, 0, 1)
+	bottom:SetPoint("BOTTOMLEFT", 1, -1)
+	bottom:SetPoint("BOTTOMRIGHT", -1, -1)
+	bottom:SetHeight(2)
+
+	local top = backdrop:CreateTexture(nil, "OVERLAY")
+	top:SetColorTexture(0, 0, 0, 1)
+	top:SetPoint("TOPLEFT", 1, -1)
+	top:SetPoint("TOPRIGHT", -1, 1)
+	top:SetHeight(2)
+
+	return backdrop
+end
+
+local UpdateBackdrop = function(self)
+	local centerX, centerY = self:GetCenter()
+	local screenHeight = GetScreenHeight()
+	local heightTop = screenHeight  *  0.75;
+	local current = MOD.private.Opacity[self:GetName()];
+
+	if(SV.db.Dock.backdrop and (not MOD.private.Disabled[self:GetName() .. 'Button'])) then
+		if(self.backdrop.forceTop or (centerY and (centerY > heightTop))) then
+			self.backdrop.underlay:SetGradientAlpha("VERTICAL", 0, 0, 0, 0, 0, 0, 0, 0.8)
+			self.backdrop.left:SetGradientAlpha("VERTICAL", 0, 0, 0, 0, 0, 0, 0, 1)
+			self.backdrop.right:SetGradientAlpha("VERTICAL", 0, 0, 0, 0, 0, 0, 0, 1)
+			--self.backdrop.bottom:SetColorTexture(0, 0, 0, 0)
+			self.backdrop.bottom:SetAlpha(0)
+			self.backdrop.bottom:SetHeight(1)
+			--self.backdrop.top:SetColorTexture(0, 0, 0, 1)
+			self.backdrop.top:SetAlpha(1)
+			self.backdrop.top:SetHeight(2)
+		else
+			self.backdrop.underlay:SetGradientAlpha("VERTICAL", 0, 0, 0, 0.8, 0, 0, 0, 0)
+			self.backdrop.left:SetGradientAlpha("VERTICAL", 0, 0, 0, 1, 0, 0, 0, 0)
+			self.backdrop.right:SetGradientAlpha("VERTICAL", 0, 0, 0, 1, 0, 0, 0, 0)
+			--self.backdrop.bottom:SetColorTexture(0, 0, 0, 1)
+			self.backdrop.bottom:SetAlpha(1)
+			self.backdrop.bottom:SetHeight(2)
+			--self.backdrop.top:SetColorTexture(0, 0, 0, 0)
+			self.backdrop.top:SetAlpha(0)
+			self.backdrop.top:SetHeight(1)
+		end
+		self.backdrop:SetAlpha(1);
+	else
+		self.backdrop:SetAlpha(0);
+	end
+	self.backdrop:SetFrameLevel(0)
+	self:SetAlpha(current or 1);
+end
+
+function MOD.SetThemedBackdrop(frame, forceTop)
+	local frameLevel = frame:GetFrameLevel()
+	local backdrop = CreateFrame("Frame", nil, frame)
+	backdrop:SetAllPoints(frame)
+	backdrop:SetFrameStrata("BACKGROUND")
+	backdrop.forceTop = forceTop
+
+	backdrop:SetFrameLevel(0)
+
+	local underlay = backdrop:CreateTexture(nil, "BACKGROUND")
+	underlay:InsetPoints(backdrop)
+	underlay:SetColorTexture(1, 1, 1, 1)
+
+	backdrop.underlay = underlay;
+
+	local left = backdrop:CreateTexture(nil, "BORDER")
+	left:SetColorTexture(1, 1, 1, 1)
+	left:SetPoint("TOPLEFT", -1, 1)
+	left:SetPoint("BOTTOMLEFT", -1, -1)
+	left:SetWidth(2)
+
+	backdrop.left = left;
+
+	local right = backdrop:CreateTexture(nil, "BORDER")
+	right:SetColorTexture(1, 1, 1, 1)
+	right:SetPoint("TOPRIGHT", 1, 1)
+	right:SetPoint("BOTTOMRIGHT", 1, -1)
+	right:SetWidth(2)
+
+	backdrop.right = right;
+
+	local bottom = backdrop:CreateTexture(nil, "BORDER")
+	bottom:SetColorTexture(0, 0, 0, 1)
+	bottom:SetPoint("BOTTOMLEFT", -1, -1)
+	bottom:SetPoint("BOTTOMRIGHT", 1, -1)
+	bottom:SetHeight(2)
+
+	backdrop.bottom = bottom;
+
+	local top = backdrop:CreateTexture(nil, "BORDER")
+	top:SetColorTexture(0, 0, 0, 1)
+	top:SetPoint("TOPLEFT", -1, 1)
+	top:SetPoint("TOPRIGHT", 1, 1)
+	top:SetHeight(2)
+
+	backdrop.top = top;
+
+	frame.backdrop = backdrop
+
+	UpdateBackdrop(frame);
+	frame.UpdateBackdrop = UpdateBackdrop;
+end
+
+function MOD:SetBorderTheme()
+	self.Border.Top:SetPoint("TOPLEFT", SV.Screen, "TOPLEFT", -1, 1)
+	self.Border.Top:SetPoint("TOPRIGHT", SV.Screen, "TOPRIGHT", 1, 1)
+	self.Border.Top:SetHeight(10)
+	self.Border.Top:SetBackdrop({
+		bgFile = SV.media.background.button,
+		edgeFile = [[Interface\BUTTONS\WHITE8X8]],
+		tile = false,
+		tileSize = 0,
+		edgeSize = 1,
+		insets = {left = 0, right = 0, top = 0, bottom = 0}
+	})
+	self.Border.Top:SetBackdropColor(unpack(SV.media.color.dark))
+	self.Border.Top:SetBackdropBorderColor(0,0,0,1)
+	self.Border.Top:SetFrameLevel(0)
+	self.Border.Top:SetFrameStrata('BACKGROUND')
+	self.Border.Top:SetScript("OnShow", function(self)
+		self:SetFrameLevel(0)
+		self:SetFrameStrata('BACKGROUND')
+	end)
+
+	self.Border.Bottom:SetPoint("BOTTOMLEFT", SV.Screen, "BOTTOMLEFT", -1, -1)
+	self.Border.Bottom:SetPoint("BOTTOMRIGHT", SV.Screen, "BOTTOMRIGHT", 1, -1)
+	self.Border.Bottom:SetHeight(10)
+	self.Border.Bottom:SetBackdrop({
+		bgFile = SV.media.background.button,
+		edgeFile = [[Interface\BUTTONS\WHITE8X8]],
+		tile = false,
+		tileSize = 0,
+		edgeSize = 1,
+		insets = {left = 0, right = 0, top = 0, bottom = 0}
+	})
+	self.Border.Bottom:SetBackdropColor(unpack(SV.media.color.dark))
+	self.Border.Bottom:SetBackdropBorderColor(0,0,0,1)
+	self.Border.Bottom:SetFrameLevel(0)
+	self.Border.Bottom:SetFrameStrata('BACKGROUND')
+	self.Border.Bottom:SetScript("OnShow", function(self)
+		self:SetFrameLevel(0)
+		self:SetFrameStrata('BACKGROUND')
+	end)
+end
+
+function MOD:SetButtonTheme(button, size)
+	local sparkSize = size * 5;
+    local sparkOffset = size * 0.5;
+
+    button:SetStyle("DockButton")
+
+	local sparks = button:CreateTexture(nil, "OVERLAY", nil, 2)
+	sparks:SetSize(sparkSize, sparkSize)
+	sparks:SetPoint("CENTER", button, "BOTTOMRIGHT", -sparkOffset, 4)
+	sparks:SetTexture(SV.media.dock.sparks[1])
+	sparks:SetVertexColor(0.7, 0.6, 0.5)
+	sparks:SetBlendMode("ADD")
+	sparks:SetAlpha(0)
+
+	SV.Animate:Sprite8(sparks, 0.08, 2, false, true)
+
+	button.Sparks = sparks;
+
+	button.ClickTheme = function(self)
+		self.Sparks:SetTexture(SV.media.dock.sparks[random(1,3)])
+		self.Sparks.anim:Play()
+	end
+end
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+_G.ToggleSuperDockLeft = function(self, button)
+	GameTooltip:Hide()
+	local activeDock = MOD.private.Active.BottomLeft
+	if(button and IsAltKeyDown()) then
+		SV:StaticPopup_Show('RESETDOCKS_CHECK')
+	elseif(button and button == 'RightButton') then
+		if(InCombatLockdown()) then
+			MOD.ErrorSound()
+			SV:AddonMessage(ERR_NOT_IN_COMBAT)
+			return
+		end
+		MOD.ButtonSound()
+		local userSize = SV.db.Dock.dockLeftHeight
+		if(not MOD.private.LeftExpanded) then
+			MOD.private.LeftExpanded = true
+			MOD.BottomLeft.Window:SetHeight(userSize + 300)
+		else
+			MOD.private.LeftExpanded = nil
+			MOD.BottomLeft.Window:SetHeight(userSize)
+		end
+		MOD.BottomLeft.Bar:Update()
+		MOD:UpdateDockBackdrops()
+		SV.Events:Trigger("DOCK_EXPANDED", "BottomLeft", activeDock);
+	else
+		if MOD.private.LeftFaded then
+			MOD.private.LeftFaded = nil;
+			MOD.BottomLeft:FadeIn(0.2, MOD.BottomLeft:GetAlpha(), 1)
+			MOD.BottomLeft.Bar:FadeIn(0.2, MOD.BottomLeft.Bar:GetAlpha(), 1)
+			SV.Events:Trigger("DOCK_FADE_IN", "BottomLeft", activeDock);
+			PlaySoundFile([[sound\doodad\be_scryingorb_explode.ogg]])
+		else
+			MOD.private.LeftFaded = true;
+			MOD.BottomLeft:FadeOut(0.2, MOD.BottomLeft:GetAlpha(), 0)
+			MOD.BottomLeft.Bar:FadeOut(0.2, MOD.BottomLeft.Bar:GetAlpha(), 0)
+			SV.Events:Trigger("DOCK_FADE_OUT", "BottomLeft", activeDock);
+			PlaySoundFile([[sound\doodad\be_scryingorb_explode.ogg]])
+		end
+	end
+end
+
+_G.ToggleSuperDockRight = function(self, button)
+	GameTooltip:Hide()
+	local activeDock = MOD.private.Active.BottomRight
+	if(button and IsAltKeyDown()) then
+		SV:StaticPopup_Show('RESETDOCKS_CHECK')
+	elseif(button and button == 'RightButton') then
+		if(InCombatLockdown()) then
+			MOD.ErrorSound()
+			SV:AddonMessage(ERR_NOT_IN_COMBAT)
+			return
+		end
+		MOD.ButtonSound()
+		local userSize = SV.db.Dock.dockRightHeight
+		if(not MOD.private.RightExpanded) then
+			MOD.private.RightExpanded = true
+			MOD.BottomRight.Window:SetHeight(userSize + 300)
+		else
+			MOD.private.RightExpanded = nil
+			MOD.BottomRight.Window:SetHeight(userSize)
+		end
+		MOD.BottomRight.Bar:Update()
+		MOD:UpdateDockBackdrops()
+		SV.Events:Trigger("DOCK_EXPANDED", "BottomRight", activeDock);
+	else
+		if MOD.private.RightFaded then
+			MOD.private.RightFaded = nil;
+			MOD.BottomRight:FadeIn(0.2, MOD.BottomRight:GetAlpha(), 1)
+			MOD.BottomRight.Bar:FadeIn(0.2, MOD.BottomRight.Bar:GetAlpha(), 1)
+			SV.Events:Trigger("DOCK_FADE_IN", "BottomRight", activeDock);
+			PlaySoundFile([[sound\doodad\be_scryingorb_explode.ogg]])
+		else
+			MOD.private.RightFaded = true;
+			MOD.BottomRight:FadeOut(0.2, MOD.BottomRight:GetAlpha(), 0)
+			MOD.BottomRight.Bar:FadeOut(0.2, MOD.BottomRight.Bar:GetAlpha(), 0)
+			SV.Events:Trigger("DOCK_FADE_OUT", "BottomRight", activeDock);
+			PlaySoundFile([[sound\doodad\be_scryingorb_explode.ogg]])
+		end
+	end
+end
+
+_G.ToggleSuperDocks = function()
+	if(MOD.private.AllFaded) then
+		MOD.private.AllFaded = nil;
+		MOD.private.LeftFaded = nil;
+		MOD.private.RightFaded = nil;
+		MOD.BottomLeft:FadeIn(0.2, MOD.BottomLeft:GetAlpha(), 1)
+		MOD.BottomLeft.Bar:FadeIn(0.2, MOD.BottomLeft.Bar:GetAlpha(), 1)
+		SV.Events:Trigger("DOCK_FADE_IN", "BottomLeft", MOD.private.Active.BottomLeft);
+		MOD.BottomRight:FadeIn(0.2, MOD.BottomRight:GetAlpha(), 1)
+		MOD.BottomRight.Bar:FadeIn(0.2, MOD.BottomRight.Bar:GetAlpha(), 1)
+		SV.Events:Trigger("DOCK_FADE_IN", "BottomRight", MOD.private.Active.BottomRight);
+		PlaySoundFile([[sound\doodad\be_scryingorb_explode.ogg]])
+	else
+		MOD.private.AllFaded = true;
+		MOD.private.LeftFaded = true;
+		MOD.private.RightFaded = true;
+		MOD.BottomLeft:FadeOut(0.2, MOD.BottomLeft:GetAlpha(), 0)
+		MOD.BottomLeft.Bar:FadeOut(0.2, MOD.BottomLeft.Bar:GetAlpha(), 0)
+		SV.Events:Trigger("DOCK_FADE_OUT", "BottomLeft");
+		MOD.BottomRight:FadeOut(0.2, MOD.BottomRight:GetAlpha(), 0)
+		MOD.BottomRight.Bar:FadeOut(0.2, MOD.BottomRight.Bar:GetAlpha(), 0)
+		SV.Events:Trigger("DOCK_FADE_OUT", "BottomRight");
+		PlaySoundFile([[sound\doodad\be_scryingorb_explode.ogg]])
+	end
+end
+
+function MOD:EnterFade()
+	if MOD.private.LeftFaded then
+		self.BottomLeft:FadeIn(0.2, self.BottomLeft:GetAlpha(), 1)
+		self.BottomLeft.Bar:FadeIn(0.2, self.BottomLeft.Bar:GetAlpha(), 1)
+		SV.Events:Trigger("DOCK_FADE_IN", "BottomLeft", MOD.private.Active.BottomLeft);
+	end
+	if MOD.private.RightFaded then
+		self.BottomRight:FadeIn(0.2, self.BottomRight:GetAlpha(), 1)
+		self.BottomRight.Bar:FadeIn(0.2, self.BottomRight.Bar:GetAlpha(), 1)
+		SV.Events:Trigger("DOCK_FADE_IN", "BottomRight", MOD.private.Active.BottomRight);
+	end
+end
+
+function MOD:ExitFade()
+	if MOD.private.LeftFaded then
+		self.BottomLeft:FadeOut(2, self.BottomLeft:GetAlpha(), 0)
+		self.BottomLeft.Bar:FadeOut(2, self.BottomLeft.Bar:GetAlpha(), 0)
+		SV.Events:Trigger("DOCK_FADE_OUT", "BottomLeft");
+	end
+	if MOD.private.RightFaded then
+		self.BottomRight:FadeOut(2, self.BottomRight:GetAlpha(), 0)
+		self.BottomRight.Bar:FadeOut(2, self.BottomRight.Bar:GetAlpha(), 0)
+		SV.Events:Trigger("DOCK_FADE_OUT", "BottomRight");
+	end
+end
+--[[
+##########################################################
+DRAGGING HIGHLIGHT FUNCTIONS
+##########################################################
+]]--
+do
+	local function UpdateDividers(self)
+		local anchorParent = self.ToolBar;
+		local offsetMod = self.Data.Modifier;
+		local orderList = self.Data.Order;
+		local buttonList = self.Data.Buttons;
+		local dividerList = self.Data.Dividers;
+		local location = self.Data.Location;
+		local anchor = upper(location);
+		local count = #orderList;
+		local offset = 2;
+
+		if(count > 0) then
+			for i = 1, count do
+				local nextButton = buttonList[orderList[i]];
+				local divider = dividerList[i];
+				if(nextButton and (not nextButton:IsDragging())) then
+					local buttonWidth = nextButton:GetWidth();
+					local dividerWidth = divider:GetWidth();
+					if(not nextButton:IsDragging()) then
+						divider:ClearAllPoints();
+						divider:SetPoint(anchor, anchorParent, anchor, (offset * offsetMod), 0);
+						offset = offset + (dividerWidth + 2);
+
+						nextButton:ClearAllPoints();
+						nextButton:SetPoint(anchor, anchorParent, anchor, (offset * offsetMod), 0);
+						offset = offset + (buttonWidth + 2);
+					end
+				end
+			end
+		end
+	end
+
+	local HighLight_OnUpdate = function(self)
+		local highlight = self.Highlight;
+
+		if(not highlight) then
+			self:SetScript("OnUpdate", nil)
+			return
+		end
+
+		if(highlight:IsMouseOver(50, -50, -50, 50)) then
+			highlight:SetAlpha(1)
+			local orderList = self.Data.Order;
+			local dividerList = self.Data.Dividers;
+			local hovering = false;
+			for i = 1, #orderList do
+				local divider = dividerList[i]
+				if(divider) then
+					if(divider:IsMouseOver(25, 0, -25, 0) and (not hovering)) then
+						hovering = true;
+						highlight:SetAlpha(0.5)
+						divider:SetAlpha(1)
+						divider:SetWidth(DRAG_BUTTONWIDTH)
+					else
+						divider:SetAlpha(0)
+						divider:SetWidth(1)
+					end
+				end
+			end
+		else
+			highlight:SetAlpha(0.2)
+		end
+
+		UpdateDividers(self)
+	end
+
+	ToggleDraggingMode = function(enabled)
+		DRAG_TARGETBAR = nil;
+		DRAG_ORDERINDEX = nil;
+		if(enabled) then
+			for location, settings in pairs(DOCK_LOCATIONS) do
+				local dock = MOD[location];
+				if(dock and dock.Bar) then
+					local dockbar = dock.Bar;
+					local orderList = dockbar.Data.Order;
+					local dividerList = dockbar.Data.Dividers;
+					dockbar.Highlight:Show()
+					dockbar.Highlight:SetAlpha(0.2)
+					dockbar:SetScript("OnUpdate", HighLight_OnUpdate)
+					for i = 1, #orderList do
+						if(dividerList[i]) then
+							dividerList[i]:SetAlpha(0)
+							dividerList[i]:SetWidth(1)
+							dividerList[i]:SetBackdropColor(0, 0.5, 1, 1)
+							dividerList[i]:SetBackdropBorderColor(0, 1, 1, 1)
+						end
+					end
+				end
+			end
+		else
+			local hovering = false;
+			for location, settings in pairs(DOCK_LOCATIONS) do
+				local dock = MOD[location];
+				local dockbar = dock.Bar;
+				local dock = MOD[location];
+				if(dock and dock.Bar) then
+					local dockbar = dock.Bar;
+					local orderList = dockbar.Data.Order;
+					local dividerList = dockbar.Data.Dividers;
+					if(dockbar.Highlight:IsMouseOver(50, -50, -50, 50)) then
+						DRAG_TARGETBAR = dockbar;
+					end
+					dockbar.Highlight:Hide()
+					dockbar.Highlight:SetAlpha(0)
+					dockbar:SetScript("OnUpdate", nil)
+					for i = 1, #orderList do
+						local divider = dividerList[i];
+						if(divider) then
+							if(divider:IsMouseOver(25, 0, -25, 0) and (divider:GetAlpha() > 0) and (not hovering)) then
+								DRAG_ORDERINDEX = i;
+								hovering = true;
+							end
+							divider:SetAlpha(0)
+							divider:SetWidth(1)
+							divider:SetBackdropColor(0, 0.5, 1, 1)
+							divider:SetBackdropBorderColor(0, 1, 1, 1)
+						end
+					end
+				end
+			end
+		end
+	end
+end
+--[[
+##########################################################
+DOCKBAR FUNCTIONS
+##########################################################
+]]--
+local function DeactivateDockletButton(button)
+	button.ActiveDocklet = false;
+	button:SetPanelColor("default")
+	if(button.Icon) then
+		button.Icon:SetGradient(unpack(SV.media.gradient.icon));
+	end
+end
+
+local function DeactivateAllDockletButtons(dockbar)
+	local location = dockbar.Data.Location;
+	local buttonList = dockbar.Data.Buttons;
+	for nextName,nextButton in pairs(buttonList) do
+		DeactivateDockletButton(nextButton)
+	end
+end
+
+local function ActivateDockletButton(button)
+	DeactivateAllDockletButtons(button.Parent);
+	button.ActiveDocklet = true;
+	button:SetPanelColor("default");
+	if(button.Icon) then
+		button.Icon:SetGradient(unpack(SV.media.gradient.checked));
+	end
+end
+
+local function ShowDockletWindow(button, location)
+	if((not button) or (not button.FrameLink)) then return end
+	--print(button:GetName())
+	local window = button.FrameLink
+	window:FadeIn(0.1, 0, 1)
+	if(not InCombatLockdown()) then	window:SetFrameLevel(5) end
+	if(window.PostShowCallback) then
+		window:PostShowCallback()
+	else
+		SV.Events:Trigger("DOCKLET_SHOWN", location, button.LinkKey);
+	end
+	return true;
+end
+
+local function HideDockletWindow(button, location)
+	if((not button) or (not button.FrameLink)) then return end
+	local window = button.FrameLink
+	window:FadeOut(0.1, 1, 0, true)
+	if(not InCombatLockdown()) then	window:SetFrameLevel(0) end
+	if(window.PostHideCallback) then
+		window:PostHideCallback()
+	else
+		SV.Events:Trigger("DOCKLET_HIDDEN", location, button.LinkKey);
+	end
+	return true;
+end
+
+local function ResetAllDockletWindows(dockbar, button)
+	local location = dockbar.Data.Location;
+	local buttonList = dockbar.Data.Buttons;
+	local currentButton = "";
+	if(button and button.GetName) then
+		currentButton = button:GetName()
+	end
+	--print('ResetAllDockletWindows: ' .. currentButton)
+	for nextName,nextButton in pairs(buttonList) do
+		if(nextName ~= currentButton) then
+			if(nextButton.FrameLink) then
+				HideDockletWindow(nextButton, location)
+			end
+		end
+	end
+	SV.Events:Trigger("DOCKLET_RESET", location);
+end
+
+local DockBar_ResetAll = function(self)
+	ResetAllDockletWindows(self);
+	DeactivateAllDockletButtons(self);
+end
+
+local DockBar_SetDefault = function(self, button)
+	local location = self.Data.Location;
+	self.Parent.Alert:Deactivate()
+	if(button) then
+		local name = button:GetName()
+		local lookup = MOD.private.Locations[name];
+		if(button.isFloating or (lookup and (lookup == "Floating"))) then
+			button.OrderIndex = 0;
+			SaveCurrentPosition(button);
+			if(ShowDockletWindow(button, lookup)) then
+				ActivateDockletButton(button);
+			end
+			return true;
+		elseif(button.FrameLink) then
+			MOD.private.Active[location] = name;
+		end
+	end
+
+	if((not button) or (not button.FrameLink)) then
+		local defaultButton = MOD.private.Active[location];
+		button = _G[defaultButton];
+	end
+
+	if(button and button.FrameLink) then
+		ResetAllDockletWindows(self, button);
+		self.Parent.Window.FrameLink = button.FrameLink;
+		if(not InCombatLockdown()) then
+			self.Parent.Window:Show();
+		end
+		self.Parent.Window:FadeIn();
+		if(ShowDockletWindow(button, location)) then
+			ActivateDockletButton(button);
+			return true;
+		end
+	end
+
+	return false
+end
+
+local DockBar_NextDefault = function(self)
+	local location = self.Data.Location;
+	local buttonList = self.Data.Buttons;
+	for name,button in pairs(buttonList) do
+		if(button.FrameLink) then
+			MOD.private.Active[location] = name;
+			ResetAllDockletWindows(self, button);
+			self.Parent.Window.FrameLink = button.FrameLink;
+			if(not InCombatLockdown()) then
+				self.Parent.Window:Show();
+			end
+			self.Parent.Window:FadeIn();
+			if(ShowDockletWindow(button, location)) then
+				ActivateDockletButton(button);
+				return;
+			end
+		end
+	end
+	SV.Events:Trigger("DOCKLET_LIST_EMPTY", location);
+end
+
+local DockBar_UpdateOrder = function(self)
+	local ORDER_TEMP = {};
+	local location = self.Data.Location;
+	local buttonList = self.Data.Buttons;
+	local orderList = self.Data.Order;
+	local internalCount = #orderList;
+
+	for i=1, internalCount do
+		orderList[i] = nil;
+	end
+
+	local saved = MOD.private.Order[location];
+	local savedCount = #saved;
+	local safeIndex = 1;
+	for i=1, savedCount do
+		local nextName = saved[i];
+		local nextButton = buttonList[nextName];
+		if(nextButton) then
+			if(not ORDER_TEMP[nextName]) then
+				ORDER_TEMP[nextName] = true;
+				nextButton.OrderIndex = safeIndex;
+				orderList[safeIndex] = nextName;
+				safeIndex = safeIndex + 1;
+			end
+		end
+	end
+end
+
+local DockBar_ChangeOrder = function(self, button, targetIndex)
+	local ORDER_TEMP = {};
+	local location = self.Data.Location;
+	local targetName = button:GetName();
+	local currentIndex = button.OrderIndex;
+	local saved = MOD.private.Order[location];
+	local maxCount = #saved;
+	local count = 1;
+	for i=1, maxCount do
+		local nextName = saved[i];
+		if(i == targetIndex) then
+			if(currentIndex > targetIndex) then
+				ORDER_TEMP[count] = targetName;
+				count=count+1;
+				ORDER_TEMP[count] = nextName;
+				count=count+1;
+			else
+				ORDER_TEMP[count] = nextName;
+				count=count+1;
+				ORDER_TEMP[count] = targetName;
+				count=count+1;
+			end
+		elseif(targetName ~= nextName) then
+			ORDER_TEMP[count] = nextName;
+			count=count+1;
+		end
+	end
+
+	for i=1, maxCount do
+		MOD.private.Order[location][i] = ORDER_TEMP[i];
+	end
+
+	DockBar_UpdateOrder(self);
+end
+
+local DockBar_CheckOrder = function(self, targetName)
+	local masterOrder = MOD.private.Order;
+	local masterLocation = MOD.private.Locations;
+	for otherLoc,otherData in pairs(masterOrder) do
+		for x = 1, #otherData do
+			local otherName = otherData[x];
+			local registeredLocation = masterLocation[otherName];
+			if(registeredLocation ~= otherLoc) then
+				masterOrder[otherLoc][x] = nil;
+			end
+		end
+	end
+
+	local found = false;
+	local location = self.Data.Location;
+	local saved = masterOrder[location];
+	if(not saved) then return end
+	local maxCount = #saved;
+	for i = 1, maxCount do
+		if(saved[i] == targetName) then
+			found = true;
+		end
+	end
+	if(not found) then
+		saved[maxCount+1] = targetName;
+	end
+
+	DockBar_UpdateOrder(self);
+end
+
+local function CreateDivider(parent)
+	local size = parent.ToolBar:GetHeight();
+	local frame = CreateFrame("Frame", nil, parent);
+	frame:SetSize(1,size);
+	frame:SetStyle("!_Frame", "Transparent")
+	frame:SetBackdropColor(0, 0.5, 1)
+	frame:SetBackdropBorderColor(0, 1, 1)
+	frame:SetAlpha(0)
+	return frame;
+end
+
+local DockBar_UpdateLayout = function(self)
+	local anchorParent = self.ToolBar;
+	local offsetMod = self.Data.Modifier;
+	local orderList = self.Data.Order;
+	local buttonList = self.Data.Buttons;
+	local dividerList = self.Data.Dividers;
+	local location = self.Data.Location;
+
+	local anchor = upper(location);
+	local size = anchorParent:GetHeight();
+	local count = #orderList;
+	local offset = 2;
+
+	for i = 1, #dividerList do
+		local divider = dividerList[i];
+		divider:Hide()
+	end
+
+	local safeIndex = 1;
+	for i = 1, #orderList do
+		local nextName = orderList[i];
+		local nextButton = buttonList[nextName];
+
+		if(nextButton and (not nextButton.isFloating)) then
+			nextButton.OrderIndex = safeIndex;
+
+			local calcWidth = size * (nextButton.widthMultiplier or 1);
+
+			local divider = dividerList[safeIndex];
+			if(not divider) then
+				divider = CreateDivider(self);
+				dividerList[safeIndex] = divider;
+			end
+
+			divider:Show();
+			divider:SetAlpha(0);
+			divider:ClearAllPoints();
+			divider:SetSize(1, size);
+			divider:SetPoint(anchor, anchorParent, anchor, (offset * offsetMod), 0);
+			offset = offset + 3;
+
+			if(not InCombatLockdown() or (not nextButton:IsProtected())) then
+				nextButton:Show();
+				nextButton:ClearAllPoints();
+				nextButton:SetSize(calcWidth, size);
+				nextButton:SetPoint(anchor, anchorParent, anchor, (offset * offsetMod), 0);
+			end
+			offset = offset + (calcWidth + 2);
+
+			safeIndex = safeIndex + 1;
+		end
+	end
+
+	local defaultButton = MOD.private.Active[location];
+	if(not buttonList[defaultButton]) then
+		MOD.private.Active[location] = nil
+	end
+
+	anchorParent:SetWidth(offset + size);
+end
+
+local DockBar_AddButton = function(self, button, order)
+	if not button then return end
+	local name = button:GetName();
+	local currentLocation = self.Data.Location
+	order = order or 0;
+	--if(self.Data.Buttons[name] and (order == 0)) then return end
+	local registeredLocation = MOD.private.Locations[name];
+
+	if(registeredLocation) then
+		if(registeredLocation == 'Floating') then
+			return
+		elseif(registeredLocation ~= currentLocation) then
+			if(MOD[registeredLocation].Bar.Data.Buttons[name]) then
+				MOD[registeredLocation].Bar:Remove(button, true);
+			else
+				--MOD[registeredLocation].Bar:Add(button);
+				return
+			end
+		end
+	end
+	if(MOD.private.Disabled[name]) then return end
+
+	MOD.private.Dimensions[name] = nil;
+
+	button:Show()
+	self.Data.Buttons[name] = button;
+
+	DockBar_CheckOrder(self, name);
+	if(order > 0) then
+		DockBar_ChangeOrder(self, button, order)
+	end
+
+	MOD.private.Locations[name] = currentLocation;
+	button.Parent = self;
+	button:SetParent(self.ToolBar);
+
+	if(button.FrameLink) then
+		local frame = button.FrameLink
+		local frameName = frame:GetName()
+		self.Data.Windows[frameName] = frame;
+		MOD.private.Windows[frameName] = currentLocation;
+		frame:Show()
+		frame:ClearAllPoints()
+		frame:SetParent(self.Parent.Window)
+		frame:InsetPoints(self.Parent.Window)
+		frame.Parent = self.Parent
+		if(frame.UpdateBackdrop) then
+			frame:UpdateBackdrop();
+		end
+		frame:FadeIn()
+		if(not MOD.private.Active[currentLocation]) then
+			DockBar_SetDefault(self, button)
+		end
+	end
+
+	self:SetDefault()
+	self:Update()
+end
+
+local DockBar_RemoveButton = function(self, button, isMoving)
+	if not button then return end
+	local name = button:GetName();
+	local registeredLocation = MOD.private.Locations[name];
+	local currentLocation = self.Data.Location
+
+	if(registeredLocation and (registeredLocation == currentLocation)) then
+		MOD.private.Locations[name] = nil;
+	end
+
+	for i = 1, #self.Data.Order do
+		local nextName = self.Data.Order[i];
+		if(nextName == name) then
+			--print('Removing #' .. i .. ' = ' .. nextName)
+			tremove(self.Data.Order, i);
+			break;
+		end
+	end
+
+	if(self.Data.Buttons[name]) then
+		button.OrderIndex = 0;
+		button:Hide()
+		MOD.private.Disabled[name] = currentLocation;
+		if(button.FrameLink) then
+			button.FrameLink:SetParent(UIParent)
+			local frameName = button.FrameLink:GetName()
+			MOD.private.Windows[frameName] = nil;
+			if(button.FrameLink.UpdateBackdrop) then
+				button.FrameLink:UpdateBackdrop();
+			end
+			button.FrameLink:FadeOut(0.2, 1, 0, true);
+			self.Data.Windows[frameName] = nil;
+		end
+
+		if(#self.Data.Order == 0) then
+			MOD.private.Active[currentLocation] = nil;
+		end
+
+		self.Data.Buttons[name] = nil;
+		DockBar_UpdateOrder(self);
+		if(MOD.private.Active[currentLocation] == name or (not MOD.private.Active[currentLocation]) or (MOD.private.Active[currentLocation] == "")) then
+			self:NextDefault()
+		else
+			self:SetDefault()
+		end
+	end
+	self:Update()
+end
+--[[
+##########################################################
+DOCKBUTTON FUNCTIONS
+##########################################################
+]]--
+local function UpdateAllLayouts()
+	for location, settings in pairs(DOCK_LOCATIONS) do
+		local dock = MOD[location];
+		local dockbar = dock.Bar;
+		if(dockbar) then
+			dockbar:Update()
+		end
+	end
+end
+
+local function SetFloatingDock(dock)
+	local name = dock:GetName();
+	dock:SetDocked(false);
+	MOD.private.Disabled[name] = nil;
+	dock:Show();
+	dock.isFloating = true;
+	SaveCurrentPosition(dock);
+
+	if(dock.FrameLink) then
+		dock.FrameLink:ClearAllPoints();
+		dock.FrameLink:SetPoint("BOTTOMLEFT", dock, "TOPLEFT", -3, 6);
+		dock.FrameLink:SetResizable(true);
+		dock.FrameLink:Show();
+		dock.FrameLink.resize:Show();
+	end
+	LoadSavedDimensions(dock);
+	if(ShowDockletWindow(dock, "Floating")) then
+		ActivateDockletButton(dock);
+	end
+	if(MOD.private.Locations[name] == 'Floating') then return end
+	MOD.private.Locations[name] = "Floating";
+	UpdateAllLayouts()
+end
+
+local DockButton_OnDragStart = function(self)
+	if(IsShiftKeyDown() and (not InCombatLockdown())) then
+		GameTooltip:Hide();
+
+		self:SetMovable(true);
+		self:StartMoving();
+		local name = self:GetName();
+		MOD.private.Disabled[name] = nil;
+		DRAG_TARGETBAR = nil;
+		DRAG_LASTINDEX = self.OrderIndex;
+		DRAG_BUTTONWIDTH = self:GetWidth()
+		ToggleDraggingMode(true);
+		DRAG_ENABLED = true;
+	end
+end
+
+local DockButton_OnDragStop = function(self)
+	if(DRAG_ENABLED) then
+		self:StopMovingOrSizing();
+		ToggleDraggingMode(false);
+		local name = self:GetName();
+		local previous = MOD.private.Locations[name];
+		self.OrderIndex = 0;
+		if(not DRAG_TARGETBAR) then
+			SetFloatingDock(self)
+		else
+			local target = DRAG_TARGETBAR;
+			if(not target) then
+				target = MOD[previous];
+			end
+			self:SetMovable(false);
+			self.isFloating = nil;
+			MOD.private.Locations[name] = nil;
+			if(self.FrameLink) then
+				self.FrameLink:SetResizable(false);
+				self.FrameLink.resize:Hide();
+			end
+
+			target:Add(self, DRAG_ORDERINDEX);
+
+			if(self.FrameLink and self.FrameLink.UpdateBackdrop) then
+				self.FrameLink:UpdateBackdrop()
+			end
+
+			SV.Events:Trigger("DOCKLET_MOVED", self.LocationKey);
+		end
+
+		DRAG_ENABLED = false;
+	end
+end
+
+local DockButton_DefaultTip = function(self, ...)
+	local tipText = self:GetAttribute("tipText")
+	if(tipText) then
+		GameTooltip:AddDoubleLine("[Left-Click]", tipText, 0, 1, 0, 1, 1, 1)
+	end
+end
+
+local DockButton_OnEnter = function(self, ...)
+	if(self:IsDragging()) then return end
+	MOD:EnterFade()
+	self:SetPanelColor("highlight")
+	self.Icon:SetGradient(unpack(SV.media.gradient.highlight))
+	local tipAnchor = self:GetAttribute("tipAnchor")
+	GameTooltip:SetOwner(self, tipAnchor, 0, 4)
+	GameTooltip:ClearLines()
+	if(self.GeneralTip) then
+		self:GeneralTip()
+		GameTooltip:AddLine(" ", 1, 1, 1)
+	end
+	if(self.ShowDockOptions) then
+		GameTooltip:AddDoubleLine("Right-Click", "Options", 0, 1, 0, 0.5, 1, 0.5)
+	end
+	GameTooltip:AddDoubleLine("|cff0099FFSHIFT|r + Drag", "Relocate", 0, 1, 0, 0.5, 1, 0.5)
+	GameTooltip:AddDoubleLine("|cff0099FFALT|r + Right-Click", "Hide", 0, 1, 0, 0.5, 1, 0.5)
+	GameTooltip:Show()
+end
+
+local DockButton_OnLeave = function(self, ...)
+	MOD:ExitFade()
+	self:SetPanelColor("default")
+	if(self.ActiveDocklet) then
+		self.Icon:SetGradient(unpack(SV.media.gradient.checked))
+	else
+		self.Icon:SetGradient(unpack(SV.media.gradient.icon))
+	end
+	GameTooltip:Hide()
+end
+
+local DockButton_OnClick = function(self, button)
+	if(self.ClickTheme) then
+		self:ClickTheme()
+	end
+	MOD.ButtonSound()
+	if(button and (button == "RightButton")) then
+		if(IsAltKeyDown()) then
+			self.ActiveDocklet = false;
+			self:SetPanelColor("default")
+			if(self.Icon) then
+				self.Icon:SetGradient(unpack(SV.media.gradient.icon));
+			end
+			if(self.FrameLink) then
+				local registeredLocation = MOD.private.Locations[self.LocationKey];
+				HideDockletWindow(self, registeredLocation)
+			end
+		elseif(self.RightClickCallback) then
+			self:RightClickCallback();
+		elseif((not InCombatLockdown()) and self.ShowDockOptions) then
+			self:ShowDockOptions();
+		end
+	else
+		local clickAllowed = false;
+		if(self.FrameLink) then
+			clickAllowed = DockBar_SetDefault(self.Parent, self)
+		else
+			clickAllowed = true;
+		end
+		if(self.LeftClickCallback and clickAllowed) then
+			self:LeftClickCallback(button)
+		end
+	end
+end
+
+local DockButton_OnPostClick = function(self, button)
+	if InCombatLockdown() then
+		MOD.ErrorSound()
+		return
+	end
+	if(self.ClickTheme) then self:ClickTheme() end
+	if(button and (button == "RightButton")) then
+		if(self.RightClickCallback) then
+			self:RightClickCallback()
+		end
+	elseif(self.LeftClickCallback) then
+		self:LeftClickCallback()
+	end
+	MOD.ButtonSound()
+end
+
+local DockButton_SetEnabled = function(self, isEnabled)
+	local name = self:GetName()
+	if(isEnabled) then
+		MOD.private.Disabled[name] = nil
+	elseif(self.Parent) then
+		MOD.private.Disabled[name] = self.Parent.Data.Location
+	else
+		MOD.private.Disabled[name] = "Floating"
+	end
+end
+
+local DockButton_IsEnabled = function(self)
+	return (not MOD.private.Disabled[self:GetName()]);
+end
+
+local DockButton_SetDocked = function(self, attach)
+	local name = self:GetName()
+	local lastKnownLocation = MOD.private.Disabled[name];
+	if((not self.Parent) and (not lastKnownLocation)) then return end
+	local lookup = MOD.private.Locations[name] or MOD.private.Windows[name];
+	local parent = self.Parent;
+	if(attach) then
+		if(lastKnownLocation and MOD[lastKnownLocation]) then
+			parent = MOD[lastKnownLocation].Bar;
+		end
+		MOD.private.Disabled[name] = nil;
+		if(not parent.Add) then return end
+		parent:Add(self)
+		if(lookup and (lookup == "Floating")) then
+			SetFloatingDock(self);
+		end
+	elseif(parent and parent.Remove) then
+		parent:Remove(self)
+	end
+end
+
+local DockButton_SetClickCallbacks = function(self, onleftclick, onrightclick, extendedoptions)
+	if(onleftclick and (type(onleftclick) == 'function')) then
+		self.LeftClickCallback = onleftclick;
+	end
+	if((onrightclick and (type(onrightclick) == 'function'))) then
+		self.RightClickCallback = onrightclick;
+	end
+	if((extendedoptions and (type(extendedoptions) == 'function'))) then
+		self.ExtendedOptions = extendedoptions;
+	end
+end
+--[[
+##########################################################
+DROPDOWN OPTION BUILDERS
+##########################################################
+]]--
+local OptionMenu_ButtonFunc = function(self)
+ --DO STUFF
+end
+
+local OptionMenu_SliderFunc = function(self, value)
+	local frame = self.FrameLink;
+	if(frame) then
+		local name = frame:GetName();
+		MOD.private.Opacity[name] = value;
+		if(frame.UpdateBackdrop) then
+			frame:UpdateBackdrop()
+		end
+	end
+end
+
+local DockButton_ShowDockOptions = function(self)
+	local button = self;
+	local frame = button.FrameLink;
+	local list;
+
+	if(self.ExtendedOptions) then
+		list = self:ExtendedOptions();
+	else
+		list = {};
+	end
+
+	if(frame) then
+		local name = frame:GetName();
+		local current = MOD.private.Opacity[name] or 1;
+		tinsert(list, { title = "Backdrop Alpha", divider = true });
+		tinsert(list, { range = {0,1}, value = current, func = OptionMenu_SliderFunc });
+	end
+
+	local menuTitle = self:GetAttribute("tipText") or "Dock";
+	SV.Dropdown:Open(self, list, menuTitle);
+end
+--[[
+##########################################################
+REMAINING DOCKBAR FUNCTIONS
+##########################################################
+]]--
+local DockBar_CreateButton = function(self, displayName, globalName, texture, tipFunction, primaryTemplate, frameLink)
+	local dockIcon = texture or [[Interface\AddOns\SVUI_!Core\assets\textures\Dock\DOCK-ICON-ADDON]];
+	local size = self.ToolBar:GetHeight();
+	local template = "SVUI_DockletButtonTemplate"
+	local isAction = false;
+
+	if(primaryTemplate) then
+		template = primaryTemplate .. ", SVUI_DockletButtonTemplate";
+		isAction = true;
+	end
+
+	local button = _G[globalName .. "DockletButton"] or CreateFrame("Button", globalName, self.ToolBar, template)
+
+	button:ClearAllPoints()
+	button:SetSize(size, size)
+	MOD:SetButtonTheme(button, size)
+	button:SetPanelColor("default")
+	button.Icon:SetTexture(dockIcon)
+	button.Icon:SetGradient(unpack(SV.media.gradient.icon))
+
+	button:SetAttribute("tipText", displayName)
+	button:SetAttribute("tipAnchor", self.Data.TipAnchor)
+	button:SetScript("OnEnter", DockButton_OnEnter)
+	button:SetScript("OnLeave", DockButton_OnLeave)
+	button:RegisterForDrag("LeftButton");
+	button:SetScript("OnDragStart", DockButton_OnDragStart);
+	button:SetScript("OnDragStop", DockButton_OnDragStop);
+	if(not isAction) then
+		button:SetScript("OnClick", DockButton_OnClick)
+	else
+		button:SetScript("PostClick", DockButton_OnPostClick)
+	end
+
+	button.Parent 				= self;
+	button.OrderIndex 			= 0;
+	button.LocationKey  		= globalName;
+	button.SetDocked 			= DockButton_SetDocked;
+	button.SetClickCallbacks 	= DockButton_SetClickCallbacks;
+	button.SetEnabled 			= DockButton_SetEnabled;
+	button.IsEnabled 			= DockButton_IsEnabled;
+
+	if(tipFunction and type(tipFunction) == "function") then
+		button.GeneralTip = tipFunction
+	else
+		button.GeneralTip = DockButton_DefaultTip
+	end
+
+	if(frameLink) then
+		button.FrameLink 				= frameLink;
+		button.LinkKey   				= frameLink:GetName();
+		button.ShowDockOptions 	= DockButton_ShowDockOptions;
+	end
+
+	self:Add(button)
+
+	return button
+end
+
+function MOD:SetDockButton(location, displayName, globalName, texture, tipFunction, primaryTemplate)
+	if(not self.private) then return end
+	if(self.private.Locations[globalName]) then
+		location = self.private.Locations[globalName];
+	else
+		self.private.Locations[globalName] = location;
+	end
+	local parent = self[location]
+	return DockBar_CreateButton(parent.Bar, displayName, globalName, texture, tipFunction, primaryTemplate)
+end
+--[[
+##########################################################
+DOCKS
+##########################################################
+]]--
+MOD.TopCenter = _G["SVUI_DockTopCenter"];
+MOD.BottomCenter = _G["SVUI_DockBottomCenter"];
+
+local DockAlert_OnEvent = function(self, event)
+    if(event == 'PLAYER_REGEN_ENABLED') then
+        self:SetHeight(self.activeHeight)
+        self:UnregisterEvent(event)
+    end
+end
+
+local DockAlert_Activate = function(self, child, newHeight)
+	local fallbackHeight = SV.db.Dock.buttonSize or 22;
+	local size = newHeight or fallbackHeight;
+	self:SetHeight(size);
+	if(child) then
+		child:SetAllSecurePoints(self)
+	end
+end
+
+local DockAlert_Deactivate = function(self)
+	self:SetHeight(1)
+end
+
+local DockProxy_ResetAll = function(self, ...)
+	if(self.Bar and self.Bar.Reset) then
+		self.Bar:Reset(...)
+	end
+end
+
+local DockProxy_UpdateLayout = function(self, ...)
+	if(self.Bar and self.Bar.Update) then
+		self.Bar:Update(...)
+	end
+end
+
+local DockProxy_AddButton = function(self, ...)
+	if(self.Bar and self.Bar.Add) then
+		self.Bar:Add(...)
+	end
+end
+
+local DockProxy_RemoveButton = function(self, ...)
+	if(self.Bar and self.Bar.Remove) then
+		self.Bar:Remove(...)
+	end
+end
+
+local DockProxy_CreateButton = function(self, ...)
+	if(self.Bar and self.Bar.Create) then
+		self.Bar:Create(...)
+	end
+end
+
+for location, settings in pairs(DOCK_LOCATIONS) do
+	MOD[location] = _G["SVUI_Dock" .. location];
+	MOD[location].Bar = _G["SVUI_DockBar" .. location];
+
+	MOD[location].Alert.Activate 	= DockAlert_Activate;
+	MOD[location].Alert.Deactivate 	= DockAlert_Deactivate;
+	--MOD[location].Alert:SetScript("OnEvent", DockAlert_OnEvent);
+
+	MOD[location].Bar.Parent 		= MOD[location];
+	MOD[location].Bar.SetDefault 	= DockBar_SetDefault;
+	MOD[location].Bar.NextDefault 	= DockBar_NextDefault;
+	MOD[location].Bar.Reset 		= DockBar_ResetAll;
+	MOD[location].Bar.Update 		= DockBar_UpdateLayout;
+	MOD[location].Bar.Add 			= DockBar_AddButton;
+	MOD[location].Bar.Remove 		= DockBar_RemoveButton;
+	MOD[location].Bar.Create 		= DockBar_CreateButton;
+	MOD[location].Bar.Data = {
+		Location = location,
+		Anchor = settings[2],
+		Modifier = settings[1],
+		TipAnchor = settings[4],
+		Buttons = {},
+		Windows = {},
+		Order = {},
+		Dividers = {}
+	};
+
+	-- PROXY METHODS
+	MOD[location].Reset 		= DockProxy_ResetAll;
+	MOD[location].Update 		= DockProxy_UpdateLayout;
+	MOD[location].Add 			= DockProxy_AddButton;
+	MOD[location].Remove 		= DockProxy_RemoveButton;
+	MOD[location].Create 		= DockProxy_CreateButton;
+	--MOD[location].Bar:SetScript("OnEvent", DockBar_OnEvent)
+end
+--[[
+##########################################################
+DOCKLETS (DOCK BUTTONS WITH ASSOCIATED WINDOWS)
+##########################################################
+]]--
+local Docklet_Enable = function(self)
+	local dock = self.Parent;
+	if(self.Button) then dock.Bar:Add(self.Button) end
+end
+
+local Docklet_Disable = function(self)
+	local dock = self.Parent;
+	if(self.Button) then dock.Bar:Remove(self.Button) end
+end
+
+local Docklet_ButtonSize = function(self)
+	local size = self.Bar.ToolBar:GetHeight() or 30;
+	return size;
+end
+
+local Docklet_Relocate = function(self, location)
+	local newParent = MOD[location];
+
+	if(not newParent) then return end
+
+	if(self.Button) then
+		newParent.Bar:Add(self.Button)
+	end
+
+	if(self.Bar) then
+		local height = newParent.Bar.ToolBar:GetHeight();
+		local mod = newParent.Bar.Data[1];
+		local barAnchor = newParent.Bar.Data[2];
+		local barReverse = SV:GetReversePoint(barAnchor);
+		local spacing = SV.db.Dock.buttonSpacing;
+
+		self.Bar:ClearAllPoints();
+		self.Bar:SetPoint(barAnchor, newParent.Bar.ToolBar, barReverse, (spacing * mod), 0)
+	end
+end
+
+local DockletResize_OnMouseDown = function(self)
+	local centerX, centerY = self.parent:GetCenter();
+	self.parent:ClearAllPoints()
+	self.parent:SetPoint("CENTER", UIParent, "BOTTOMLEFT", centerX, centerY)
+	self.parent.Button:ClearAllPoints()
+	self.parent.Button:SetPoint("TOPLEFT", self.parent, "BOTTOMLEFT", 3, -6)
+	self.parent:StartSizing("BOTTOMRIGHT");
+end
+
+local DockletResize_OnMouseUp = function(self)
+	local centerX, centerY = self.parent.Button:GetCenter();
+	self.parent:StopMovingOrSizing();
+	self.parent.Button:ClearAllPoints()
+	self.parent.Button:SetPoint("CENTER", UIParent, "BOTTOMLEFT", centerX, centerY)
+	self.parent:ClearAllPoints()
+	self.parent:SetPoint("BOTTOMLEFT", self.parent.Button, "TOPLEFT", -3, 6)
+	SaveCurrentDimensions(self.parent.Button);
+	if(self.parent.PostResizeCallback) then
+		self.parent.PostResizeCallback(self.parent);
+	end
+end
+
+local Docklet_SetClickCallbacks = function(self, ...)
+	if(not self.Button) then return end
+	self.Button:SetClickCallbacks(...)
+end
+
+local Docklet_SetDocked = function(self, ...)
+	if(not self.Button) then return end
+	self.Button:SetDocked(...)
+end
+
+local Docklet_SetEnabled = function(self)
+	if(not self.Button) then return end
+	local result = self.Button:SetEnabled()
+	return result;
+end
+
+local Docklet_IsEnabled = function(self)
+	if(not self.Button) then return end
+	local result = self.Button:IsEnabled()
+	return result;
+end
+
+local Docklet_SetVisibilityCallbacks = function(self, onshow, onhide, onsize)
+	if(onshow and (type(onshow) == 'function')) then
+		self.PostShowCallback = onshow;
+	end
+	if(onhide and (type(onhide) == 'function')) then
+		self.PostHideCallback = onhide;
+	end
+	if(onsize and (type(onsize) == 'function')) then
+		self.PostResizeCallback = onsize;
+	end
+end
+
+function MOD:NewDocklet(location, globalName, readableName, texture, onenter)
+	if(DOCK_REGISTRY[globalName]) then return end;
+
+	if(self.private.Windows[globalName]) then
+		location = self.private.Windows[globalName];
+	else
+		self.private.Windows[globalName] = location;
+	end
+	self.private.Locations[globalName] = nil;
+
+	local newParent = self[location];
+	if(not newParent) then return end
+
+	local frame = _G[globalName] or CreateFrame("Frame", globalName, UIParent);
+
+	if(not self.private.Opacity[globalName]) then
+		self.private.Opacity[globalName] = 1;
+	end
+
+	local parentWidth, parentHeight = newParent.Window:GetSize();
+
+	frame:SetParent(newParent.Window);
+	frame:SetSize(parentWidth, parentHeight);
+	frame:SetPoint("TOPLEFT", newParent.Window, "TOPLEFT", 0, 0);
+	frame:SetPoint("BOTTOMRIGHT", newParent.Window, "BOTTOMRIGHT", 0, 0);
+	frame:SetFrameStrata("BACKGROUND");
+
+	frame.Parent = newParent;
+	frame.Bar = newParent.Bar;
+	frame.Disable = Docklet_Disable;
+	frame.Enable = Docklet_Enable;
+	frame.SetDocked = Docklet_SetDocked;
+	frame.Relocate = Docklet_Relocate;
+	frame.GetButtonSize = Docklet_ButtonSize;
+	frame.SetEnabled = Docklet_SetEnabled;
+	frame.IsEnabled = Docklet_IsEnabled;
+	frame.SetClickCallbacks = Docklet_SetClickCallbacks;
+	frame.SetVisibilityCallbacks = Docklet_SetVisibilityCallbacks;
+
+	self.SetThemedBackdrop(frame)
+	frame.resize = CreateFrame("Button", nil, frame);
+	frame.resize:SetSize(16,16)
+	frame.resize:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", 0, 0)
+	frame.resize:SetNormalTexture([[Interface\ChatFrame\UI-ChatIM-SizeGrabber-Up]])
+	frame.resize:Hide()
+
+	newParent.Bar.Data.Windows[globalName] = frame;
+
+	local buttonName = ("%sButton"):format(globalName)
+	frame.Button = newParent.Bar:Create(readableName, buttonName, texture, onenter, false, frame);
+	DOCK_REGISTRY[globalName] = frame;
+	frame:SetAlpha(0);
+	DOCK_CHECK = true;
+
+	frame.resize.parent = frame;
+	frame.resize:SetScript("OnMouseDown", DockletResize_OnMouseDown);
+	frame.resize:SetScript("OnMouseUp", DockletResize_OnMouseUp);
+
+	LoadSavedDimensions(frame.Button);
+
+	return frame
+end
+--[[
+##########################################################
+BUILD/UPDATE
+##########################################################
+]]--
+local CornerButton_OnEnter = function(self, ...)
+	MOD:EnterFade()
+
+	self:SetPanelColor("highlight")
+	self.Icon:SetGradient(unpack(SV.media.gradient.highlight))
+
+	GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT", 0, 4)
+	GameTooltip:ClearLines()
+	local tipText = self:GetAttribute("tipText")
+	GameTooltip:AddDoubleLine("Left-Click", tipText, 0, 1, 0, 1, 1, 1)
+	local tipExtraText = self:GetAttribute("tipExtraText")
+	GameTooltip:AddDoubleLine("Right-Click", tipExtraText, 0, 1, 0, 1, 1, 1)
+	GameTooltip:Show()
+end
+
+local CornerButton_OnLeave = function(self, ...)
+	MOD:ExitFade()
+	self:SetPanelColor("default")
+	if(self.ActiveDocklet) then
+		self.Icon:SetGradient(unpack(SV.media.gradient.checked))
+	else
+		self.Icon:SetGradient(unpack(SV.media.gradient.icon))
+	end
+	GameTooltip:Hide()
+end
+
+local CornerButton_OnClick = function(self, button)
+	if(button and IsAltKeyDown() and button == 'RightButton') then
+		SV:StaticPopup_Show('RESETDOCKS_CHECK')
+	else
+		self:ToggleFunc(button)
+	end
+end
+
+local CornerButton2_OnEnter = function(self, ...)
+	MOD:EnterFade()
+
+	self:SetPanelColor("highlight")
+	self.Icon:SetGradient(unpack(SV.media.gradient.highlight))
+
+	GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT", 0, 4)
+	GameTooltip:ClearLines()
+	GameTooltip:AddDoubleLine("Left-Click", "Enable Docklets", 0, 1, 0, 1, 1, 1)
+	GameTooltip:AddDoubleLine("Right-Click", "Disable Docklets", 0, 1, 0, 1, 1, 1)
+	GameTooltip:AddDoubleLine("|cff0099FFAlt|r + Right-Click", "Reset All Docklets", 0, 1, 0, 1, 1, 1)
+	GameTooltip:Show()
+end
+
+local sort_menu_fn = function(a,b) return a.text < b.text end;
+
+local CornerButton2_OnClick = function(self, button)
+	if(IsAltKeyDown() and button and button == 'RightButton') then
+		SV:StaticPopup_Show('RESETDOCKS_CHECK')
+	else
+		if(InCombatLockdown()) then return end
+		local menu = {};
+		local titleText = "Disabled";
+		if(button and button == 'RightButton') then
+			titleText = "Enabled";
+			for name,parent in pairs(MOD.private.Locations) do
+				if((not MOD.private.Disabled[name]) and _G[name]) then
+					local b = _G[name];
+					local tipText = b:GetAttribute("tipText")
+					if(tipText) then
+						tinsert(menu, { text = tipText, func = function() b:SetDocked(false); end });
+					end
+				end
+			end
+		else
+			for name,parent in pairs(MOD.private.Disabled) do
+				local b = _G[name];
+				if(b) then
+					local tipText = b:GetAttribute("tipText")
+					if(tipText) then
+						tinsert(menu, { text = tipText, func = function() b:SetDocked(true); end });
+					end
+				end
+			end
+		end
+
+		tsort(menu, sort_menu_fn)
+
+		SV.Dropdown:Open(self, menu, titleText);
+	end
+end
+
+function MOD:UpdateDockBackdrops()
+	for name,frame in pairs(DOCK_REGISTRY) do
+		if(frame.backdrop and frame.UpdateBackdrop) then
+			frame:UpdateBackdrop()
+		end
+	end
+end
+
+function MOD:ResetAllButtons()
+	wipe(MOD.private.Order)
+	wipe(MOD.private.Locations)
+	wipe(MOD.private.Windows)
+	wipe(MOD.private.Dimensions)
+	wipe(MOD.private.Opacity)
+	wipe(MOD.private.Disabled)
+	SV.Events:Trigger("DOCKLETS_RESET", location);
+	ReloadUI()
+end
+
+local function LoadAllDocklets()
+	for name, location in pairs(MOD.private.Locations) do
+		local button = _G[name];
+		local disabled = MOD.private.Disabled[name];
+		if(button and (location == 'Floating') and (not disabled)) then
+			button:Show();
+
+			if(MOD.private.Dimensions) then
+				LoadSavedDimensions(button);
+			end
+
+			if(ShowDockletWindow(button, location)) then
+				ActivateDockletButton(button);
+			end
+		elseif(button) then
+			button:StopMovingOrSizing();
+			button:SetMovable(false)
+			if(disabled) then
+				button:Hide();
+				local frame = button.FrameLink;
+				if(frame) then
+					frame:FadeOut(0.2, 1, 0, true);
+				end
+			end
+		end
+	end
+
+	for location, settings in pairs(DOCK_LOCATIONS) do
+		local dock = MOD[location];
+		DockBar_SetDefault(dock.Bar);
+		DockBar_UpdateOrder(dock.Bar);
+	end
+
+	MOD:UpdateDockBackdrops()
+end
+
+function MOD:Refresh()
+	local buttonsize = SV.db.Dock.buttonSize;
+	local spacing = SV.db.Dock.buttonSpacing;
+
+	for location, settings in pairs(DOCK_LOCATIONS) do
+		local width, height = GetDockDimensions(location);
+		local dock = self[location];
+
+		dock.Bar:SetSize(width, buttonsize)
+	    dock.Bar.ToolBar:SetHeight(buttonsize)
+	    dock:SetSize(width, height)
+	    dock.Alert:SetSize(width, 1)
+	    dock.Window:SetSize(width, height)
+
+	    if(dock.Bar.Button) then
+	    	dock.Bar.Button:SetSize(buttonsize, buttonsize)
+	    end
+
+	    dock.Bar:Update()
+	end
+
+	local centerWidth = SV.db.Dock.dockCenterWidth;
+	local dockWidth = centerWidth * 0.5;
+	local dockHeight = SV.db.Dock.dockCenterHeight;
+
+	self.BottomCenter:SetSize(centerWidth, dockHeight);
+	self.TopCenter:SetSize(centerWidth, dockHeight);
+
+	ScreenBorderVisibility();
+
+	self:UpdateDockBackdrops();
+	self:UpdateProfessionTools();
+	self:UpdateMiscTools();
+	self:UpdateGarrisonTool();
+	self:UpdateRaidLeader();
+
+	LoadAllDocklets()
+
+	SV.Events:Trigger("DOCKS_UPDATED");
+end
+
+function MOD:PLAYER_REGEN_ENABLED()
+	self:UnregisterEvent('PLAYER_REGEN_ENABLED')
+
+	if(self.ProfessionNeedsUpdate) then
+		self.ProfessionNeedsUpdate = nil;
+		self:UpdateProfessionTools()
+	end
+
+	if(self.MiscNeedsUpdate) then
+		self.MiscNeedsUpdate = nil;
+		self:UpdateMiscTools()
+	end
+
+	if(self.GarrisonNeedsUpdate) then
+		self.GarrisonNeedsUpdate = nil;
+		self:UpdateGarrisonTool()
+	end
+
+	if(self.RaidLeaderNeedsUpdate) then
+		self.RaidLeaderNeedsUpdate = nil;
+		self:UpdateRaidLeader()
+	end
+end
+
+function MOD:Load()
+	if(not SV.private.Docks) then
+		SV.private.Docks = {}
+	end
+
+	self.private = SV.private.Docks;
+
+	if(not self.private.AllFaded) then self.private.AllFaded = false; end
+	if(not self.private.LeftFaded) then self.private.LeftFaded = false; end
+	if(not self.private.RightFaded) then self.private.RightFaded = false; end
+	if(not self.private.LeftExpanded) then self.private.LeftExpanded = false; end
+	if(not self.private.RightExpanded) then self.private.RightExpanded = false; end
+
+	if(not self.private.Order) then self.private.Order = {} end
+	if(not self.private.Locations) then self.private.Locations = {} end
+	if(not self.private.Windows) then self.private.Windows = {} end
+	if(not self.private.Dimensions) then self.private.Dimensions = {} end
+	if(not self.private.Opacity) then self.private.Opacity = {} end
+	if(not self.private.Disabled) then self.private.Disabled = {} end
+
+	if(self.private.DefaultDocklets) then
+		self.private.Active = copyTable(self.private.DefaultDocklets);
+		self.private.DefaultDocklets = nil;
+	elseif(not self.private.Active) then
+		self.private.Active = {}
+	end
+
+	self:MakeSharable();
+	self:IgnoreSharedKeys('AllFaded','LeftFaded','RightFaded','LeftExpanded','RightExpanded','Embed1','Embed2');
+
+	local buttonsize = SV.db.Dock.buttonSize;
+	local spacing = SV.db.Dock.buttonSpacing;
+
+	-- [[ TOP AND BOTTOM BORDERS ]] --
+
+	self.Border.Top = CreateFrame("Frame", "SVUIDock_TopBorder", SV.Screen);
+	self.Border.Bottom = CreateFrame("Frame", "SVUIDock_BottomBorder", SV.Screen);
+	self:SetBorderTheme();
+	ScreenBorderVisibility();
+
+	for location, settings in pairs(DOCK_LOCATIONS) do
+		local width, height = GetDockDimensions(location);
+		local dock = self[location];
+		local mod = settings[1];
+		local anchor = upper(location);
+		local reverse = SV:GetReversePoint(anchor);
+		local barAnchor = settings[2];
+		local barReverse = SV:GetReversePoint(barAnchor);
+		local isBottom = settings[3];
+		local vertMod = isBottom and 1 or -1
+
+		dock.Bar:SetParent(SV.Screen)
+		dock.Bar:ClearAllPoints()
+		dock.Bar:SetSize(width, buttonsize)
+		dock.Bar:SetPoint(anchor, SV.Screen, anchor, (2 * mod), (2 * vertMod))
+
+		local highlight = CreateFrame("Frame", nil, dock.Bar)
+		highlight:SetFrameStrata("BACKGROUND")
+		highlight:SetFrameLevel(1)
+		if(location:find('Top')) then
+			highlight:SetPoint("TOPLEFT", dock.Bar, "TOPLEFT", 0, 0)
+			highlight:SetPoint("TOPRIGHT", dock.Bar, "TOPRIGHT", 0, 0)
+			highlight:SetHeight(buttonsize * 2)
+			SV.SpecialFX:SetFXFrame(highlight, "dragging_highlight_top")
+			highlight.texture = highlight:CreateTexture(nil, "BACKGROUND")
+			highlight.texture:SetAllPoints()
+			highlight.texture:SetTexture(SV.media.statusbar.default);
+			highlight.texture:SetGradientAlpha("VERTICAL",0,0,1,0,0,0.8,1,0.8)
+		else
+			highlight:SetPoint("BOTTOMLEFT", dock.Bar, "BOTTOMLEFT", 0, 0)
+			highlight:SetPoint("BOTTOMRIGHT", dock.Bar, "BOTTOMRIGHT", 0, 0)
+			highlight:SetHeight(buttonsize * 2)
+			SV.SpecialFX:SetFXFrame(highlight, "dragging_highlight_bottom")
+			highlight.texture = highlight:CreateTexture(nil, "BACKGROUND")
+			highlight.texture:SetAllPoints()
+			highlight.texture:SetTexture(SV.media.statusbar.default);
+			highlight.texture:SetGradientAlpha("VERTICAL",0,0.8,1,0.8,0,0,1,0)
+		end
+		highlight:Hide()
+
+		dock.Bar.Highlight = highlight
+
+		if(not MOD.private.Order[location]) then
+			MOD.private.Order[location] = {}
+		end
+
+		dock.Bar.ToolBar:ClearAllPoints()
+
+		if(dock.Bar.Button) then
+			dock.Bar.Button:SetSize(buttonsize, buttonsize)
+			self:SetButtonTheme(dock.Bar.Button, buttonsize)
+			dock.Bar.Button.Icon:SetTexture(SV.media.dock.sizeIcon)
+			dock.Bar.ToolBar:SetSize(1, buttonsize)
+			dock.Bar.ToolBar:SetPoint(barAnchor, dock.Bar.Button, barReverse, (spacing * mod), 0)
+			dock.Bar.Button:SetPanelColor("default")
+			dock.Bar.Button.Icon:SetGradient(unpack(SV.media.gradient.icon))
+			if(location:find('Left')) then
+				dock.Bar.Button:SetAttribute("tipText", SHOWORHIDE .. " Left Dock")
+				dock.Bar.Button:SetAttribute("tipExtraText", MINIMIZEORMAXIMIZE .. " Left Dock")
+			else
+				dock.Bar.Button:SetAttribute("tipText", SHOWORHIDE .. " Right Dock")
+				dock.Bar.Button:SetAttribute("tipExtraText", MINIMIZEORMAXIMIZE .. " Right Dock")
+			end
+			dock.Bar.Button:SetScript("OnEnter", CornerButton_OnEnter)
+			dock.Bar.Button:SetScript("OnLeave", CornerButton_OnLeave)
+
+			if(location == "BottomLeft") then
+				dock.Bar.Button.ToggleFunc = ToggleSuperDockLeft;
+			else
+				dock.Bar.Button.ToggleFunc = ToggleSuperDockRight;
+			end
+			dock.Bar.Button:SetScript("OnClick", CornerButton_OnClick)
+
+			if(dock.Bar.Button2) then
+				dock.Bar.Button2:SetSize(buttonsize, buttonsize)
+				self:SetButtonTheme(dock.Bar.Button2, buttonsize)
+				dock.Bar.Button2.Icon:SetTexture(SV.media.dock.optionsIcon)
+				dock.Bar.ToolBar:SetSize(1, buttonsize)
+				dock.Bar.ToolBar:SetPoint(barAnchor, dock.Bar.Button2, barReverse, (spacing * mod), 0)
+				dock.Bar.Button2:SetPanelColor("default")
+				dock.Bar.Button2.Icon:SetGradient(unpack(SV.media.gradient.icon))
+				if(location:find('Left')) then
+					dock.Bar.Button2:SetAttribute("tipText", SHOWORHIDE .. " Left Dock")
+					dock.Bar.Button2:SetAttribute("tipExtraText", MINIMIZEORMAXIMIZE .. " Left Dock")
+				else
+					dock.Bar.Button2:SetAttribute("tipText", SHOWORHIDE .. " Right Dock")
+					dock.Bar.Button2:SetAttribute("tipExtraText", MINIMIZEORMAXIMIZE .. " Right Dock")
+				end
+				dock.Bar.Button2:SetScript("OnEnter", CornerButton2_OnEnter)
+				dock.Bar.Button2:SetScript("OnLeave", CornerButton_OnLeave)
+				dock.Bar.Button2.ShowDockOptions = CornerButton2_OnClick
+
+				dock.Bar.Button2.ToggleFunc = CornerButton2_OnClick;
+				dock.Bar.Button2:SetScript("OnClick", CornerButton_OnClick)
+			end
+		else
+			dock.Bar.ToolBar:SetSize(1, buttonsize)
+			dock.Bar.ToolBar:SetPoint(barAnchor, dock.Bar, barAnchor, 0, 0)
+		end
+
+		dock:SetParent(SV.Screen)
+		dock:ClearAllPoints()
+		dock:SetPoint(anchor, dock.Bar, reverse, 0, (12 * vertMod))
+		dock:SetSize(width, height)
+		dock:SetAttribute("buttonSize", buttonsize)
+		dock:SetAttribute("spacingSize", spacing)
+
+		dock.Alert:ClearAllPoints()
+		dock.Alert:SetSize(width, 1)
+		dock.Alert:SetPoint(anchor, dock, anchor, 0, 0)
+		dock.Alert:SetParent(UIParent)
+
+		dock.Window:ClearAllPoints()
+		dock.Window:SetSize(width, height)
+		dock.Window:SetPoint(anchor, dock.Alert, reverse, 0, 4)
+
+		SV:NewAnchor(dock.Bar, location .. " Dock ToolBar");
+		SV:SetAnchorResizing(dock.Bar, dockBarPostSizeFunc, 10, 500, 10, 80);
+		SV:NewAnchor(dock, location .. " Dock Window");
+		SV:SetAnchorResizing(dock, dockPostSizeFunc, 10, 500);
+
+		dock.Alert:SetParent(UIParent)
+	end
+
+	if MOD.private.LeftFaded then MOD.BottomLeft:Hide() end
+	if MOD.private.RightFaded then MOD.BottomRight:Hide() end
+
+	SV:ManageVisibility(self.BottomRight.Window)
+	SV:ManageVisibility(self.TopLeft)
+	SV:ManageVisibility(self.TopRight)
+	--SV:ManageVisibility(self.BottomCenter)
+	SV:ManageVisibility(self.TopCenter)
+
+	local centerWidth = SV.db.Dock.dockCenterWidth;
+	local dockHeight = SV.db.Dock.dockCenterHeight;
+
+	self.TopCenter:SetParent(SV.Screen)
+	self.TopCenter:ClearAllPoints()
+	self.TopCenter:SetSize(centerWidth, dockHeight)
+	self.TopCenter:SetPoint("TOP", SV.Screen, "TOP", 0, 0)
+
+	self.BottomCenter:SetParent(SV.Screen)
+	self.BottomCenter:ClearAllPoints()
+	self.BottomCenter:SetSize(centerWidth, dockHeight)
+	self.BottomCenter:SetPoint("BOTTOM", SV.Screen, "BOTTOM", 0, 0)
+
+	DockBar_SetDefault(self.BottomLeft.Bar)
+	DockBar_SetDefault(self.BottomRight.Bar)
+	DockBar_SetDefault(self.TopLeft.Bar)
+	DockBar_SetDefault(self.TopRight.Bar)
+
+	self:LoadProfessionTools();
+	self:LoadAllMiscTools();
+	self:LoadGarrisonTool();
+	self:LoadRaidLeaderTools();
+	self:LoadBreakStuff();
+end
+
+SV:NewScript(LoadAllDocklets)
diff --git a/SVUI_!Core/system/dropdown.lua b/SVUI_!Core/system/dropdown.lua
new file mode 100644
index 0000000..27f0b96
--- /dev/null
+++ b/SVUI_!Core/system/dropdown.lua
@@ -0,0 +1,293 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pcall         = _G.pcall;
+local print         = _G.print;
+local ipairs        = _G.ipairs;
+local pairs         = _G.pairs;
+local tostring      = _G.tostring;
+local tonumber      = _G.tonumber;
+
+--STRING
+local string        = _G.string;
+local upper         = string.upper;
+local format        = string.format;
+local find          = string.find;
+local match         = string.match;
+local gsub          = string.gsub;
+--TABLE
+local table 		= _G.table;
+local tremove       = _G.tremove;
+local twipe 		= _G.wipe;
+--MATH
+local math      	= _G.math;
+local min 			= math.min;
+local floor         = math.floor;
+local ceil          = math.ceil;
+local parsefloat 	= math.parsefloat;
+--BLIZZARD API
+local InCombatLockdown     	= _G.InCombatLockdown;
+local CreateFrame          	= _G.CreateFrame;
+--[[
+##########################################################
+ADDON
+##########################################################
+]]--
+local SV = select(2, ...)
+local L = SV.L
+
+SV.Dropdown = _G["SVUI_DropdownFrame"];
+
+local DropdownButton_OnClick = function(self)
+	self.func(self.target);
+	ToggleFrame(SV.Dropdown);
+end
+
+local DropdownSlider_OnValueChanged = function(self, value)
+	local result = parsefloat(value, 2)
+	self.Text:SetText(result);
+	self.func(self.target, result);
+end
+
+local DropdownButton_OnEnter = function(self)
+	self.hoverTex:Show();
+end
+
+local DropdownButton_OnLeave = function(self)
+	self.hoverTex:Hide();
+end
+
+local function GetScreenPosition(frame)
+	local parent = frame:GetParent()
+	local centerX, centerY = parent:GetCenter()
+	local screenWidth = GetScreenWidth()
+	local screenHeight = GetScreenHeight()
+	local result;
+	if not centerX or not centerY then
+		return "CENTER"
+	end
+	local heightTop = screenHeight * 0.75;
+	local heightBottom = screenHeight * 0.25;
+	local widthLeft = screenWidth * 0.25;
+	local widthRight = screenWidth * 0.75;
+	if(((centerX > widthLeft) and (centerX < widthRight)) and (centerY > heightTop)) then
+		result = "TOP"
+	elseif((centerX < widthLeft) and (centerY > heightTop)) then
+		result = "TOPLEFT"
+	elseif((centerX > widthRight) and (centerY > heightTop)) then
+		result = "TOPRIGHT"
+	elseif(((centerX > widthLeft) and (centerX < widthRight)) and centerY < heightBottom) then
+		result = "BOTTOM"
+	elseif((centerX < widthLeft) and (centerY < heightBottom)) then
+		result = "BOTTOMLEFT"
+	elseif((centerX > widthRight) and (centerY < heightBottom)) then
+		result = "BOTTOMRIGHT"
+	elseif((centerX < widthLeft) and (centerY > heightBottom) and (centerY < heightTop)) then
+		result = "LEFT"
+	elseif((centerX > widthRight) and (centerY < heightTop) and (centerY > heightBottom)) then
+		result = "RIGHT"
+	else
+		result = "CENTER"
+	end
+	return result
+end
+
+function SV.Dropdown:Open(target, list, titleText, colWidth)
+	if(InCombatLockdown() or (not list)) then return end
+
+	if(not self.option) then
+		self.option = {};
+	end
+
+	local maxPerColumn = 25;
+	local cols = 1;
+
+	if(titleText) then
+		self.Title:SetText(titleText)
+	else
+		self.Title:SetText("Menu")
+	end
+
+	for i=1, #self.option do
+		self.option[i].button:Hide();
+		self.option[i].divider:Hide();
+		self.option[i].header:Hide();
+		self.option[i].slider:Hide();
+		self.option[i]:Hide();
+	end
+
+	local heightOffset = 50;
+	local heightPadded = false;
+	colWidth = colWidth or 135;
+
+	for i=1, #list do
+		if(not self.option[i]) then
+			-- HOLDER
+			self.option[i] = CreateFrame("Frame", nil, self);
+			self.option[i]:SetHeight(16);
+			self.option[i]:SetWidth(colWidth);
+
+			-- DIVIDER
+			self.option[i].divider = self.option[i]:CreateTexture(nil, 'BORDER');
+			self.option[i].divider:SetAllPoints();
+			self.option[i].divider:SetTexture([[Interface\AddOns\SVUI_!Core\assets\textures\DROPDOWN-DIVIDER]]);
+			self.option[i].divider:Hide();
+
+			self.option[i].header = self.option[i]:CreateFontString(nil, 'OVERLAY');
+			self.option[i].header:SetAllPoints();
+			self.option[i].header:SetFont(SV.media.font.default, 10, "OUTLINE");
+			self.option[i].header:SetTextColor(1, 0.8, 0)
+			self.option[i].header:SetJustifyH("CENTER");
+			self.option[i].header:SetJustifyV("MIDDLE");
+
+			-- BUTTON
+			self.option[i].button = CreateFrame("Button", nil, self.option[i]);
+			self.option[i].button:SetAllPoints();
+
+			self.option[i].button.hoverTex = self.option[i].button:CreateTexture(nil, 'OVERLAY');
+			self.option[i].button.hoverTex:SetAllPoints();
+			self.option[i].button.hoverTex:SetTexture([[Interface\AddOns\SVUI_!Core\assets\textures\TITLE-HIGHLIGHT]]);
+			self.option[i].button.hoverTex:SetBlendMode("ADD");
+			self.option[i].button.hoverTex:Hide();
+
+			self.option[i].button.text = self.option[i].button:CreateFontString(nil, 'BORDER');
+			self.option[i].button.text:SetAllPoints();
+			self.option[i].button.text:SetFont(SV.media.font.default, 12, "OUTLINE");
+			self.option[i].button.text:SetJustifyH("LEFT");
+
+			self.option[i].button:SetScript("OnEnter", DropdownButton_OnEnter);
+			self.option[i].button:SetScript("OnLeave", DropdownButton_OnLeave);
+
+			--SVUI_DDSliderTemplate
+			-- SLIDER
+			self.option[i].slider = CreateFrame("Slider", nil, self.option[i], "SVUI_TinySliderTemplate");
+			self.option[i].slider:SetPoint("TOPLEFT", self.option[i], "TOPLEFT", 0, -3);
+			self.option[i].slider:SetPoint("BOTTOMRIGHT", self.option[i], "BOTTOMRIGHT", 0, 3);
+			self.option[i].slider.Text:SetJustifyH("CENTER");
+			self.option[i].slider.Low:SetJustifyH("LEFT");
+			self.option[i].slider.High:SetJustifyH("RIGHT");
+		else
+			self.option[i]:SetWidth(colWidth);
+		end
+
+		self.option[i]:Show();
+
+		self.option[i].button:SetScript("OnClick", nil);
+		self.option[i].slider:SetScript("OnValueChanged", nil);
+
+		local yOffset = heightPadded and 12 or 0;
+		if(list[i].range) then
+			yOffset = 12;
+			local minRange, maxRange = list[i].range[1], list[i].range[2];
+			local saved = list[i].value or 0;
+			local value = parsefloat(saved, 2)
+			self.option[i].button:Hide();
+			self.option[i].header:Hide();
+			self.option[i].slider:Show();
+			self.option[i].slider.target = target;
+			self.option[i].slider:SetMinMaxValues(minRange, maxRange);
+			self.option[i].slider:SetValue(value);
+			self.option[i].slider.Low:SetText(minRange);
+			self.option[i].slider.High:SetText(maxRange);
+			self.option[i].slider.Text:SetText(value);
+			self.option[i].slider.func = list[i].func;
+			self.option[i].slider:SetScript("OnValueChanged", DropdownSlider_OnValueChanged);
+			heightPadded = true;
+		else
+			if(list[i].title) then
+				self.option[i].button:Hide();
+				self.option[i].slider:Hide();
+				self.option[i].header:Show();
+				self.option[i].header:SetText(list[i].title);
+				if(list[i].divider) then self.option[i].divider:Show(); end
+			elseif(list[i].text) then
+				local lineText = list[i].text;
+				if(list[i].icon) then
+					lineText = list[i].icon .. list[i].text
+				end
+				self.option[i].header:Hide();
+				self.option[i].slider:Hide();
+				self.option[i].button:Show();
+				self.option[i].button.target = target;
+				self.option[i].button.text:SetText(lineText);
+				self.option[i].button.func = list[i].func;
+				self.option[i].button:SetScript("OnClick", DropdownButton_OnClick);
+			end
+			heightPadded = false;
+		end
+
+		heightOffset = heightOffset + yOffset;
+
+		if(i == 1) then
+			self.option[i]:SetPoint("TOPLEFT", self, "TOPLEFT", 10, -30)
+		elseif((i - 1) % maxPerColumn == 0) then
+			self.option[i]:SetPoint("TOPLEFT", self.option[i - maxPerColumn], "TOPRIGHT", 10, 0)
+			cols = cols + 1
+		else
+			self.option[i]:SetPoint("TOPLEFT", self.option[i - 1], "BOTTOMLEFT", 0, -yOffset)
+		end
+	end
+
+	local maxHeight = (min(maxPerColumn, #list) * 16) + heightOffset;
+	local maxWidth = (colWidth * cols) + (10 * cols) + 10;
+	local point = GetScreenPosition(target);
+
+	self:ClearAllPoints();
+	self:SetSize(maxWidth, maxHeight);
+
+	if(point:find("BOTTOM")) then
+		self:SetPoint("BOTTOMLEFT", target, "TOPLEFT", 10, 10);
+	else
+		self:SetPoint("TOPLEFT", target, "BOTTOMLEFT", 10, -10);
+	end
+
+	if(GameTooltip:IsShown()) then
+		GameTooltip:Hide();
+	end
+
+	ToggleFrame(self);
+end
+
+local function InitializeDropdown()
+	SV.Dropdown:SetParent(SV.Screen)
+	SV.Dropdown:SetFrameStrata("FULLSCREEN_DIALOG")
+	SV.Dropdown:SetFrameLevel(99)
+	SV.Dropdown:SetStyle("Frame", "Default")
+	SV.Dropdown.option = {};
+	SV.Dropdown.close = CreateFrame("Button", nil, SV.Dropdown, "UIPanelCloseButton")
+	SV.Dropdown.close:SetPoint("TOPRIGHT", SV.Dropdown, "TOPRIGHT")
+	SV.Dropdown.close:SetScript("OnClick", function() ToggleFrame(SV.Dropdown) end)
+	SV.API:Set("CloseButton", SV.Dropdown.close)
+	SV.Dropdown.Title = SV.Dropdown:CreateFontString(nil, "OVERLAY")
+	SV.Dropdown.Title:SetFont(SV.media.font.zone, 16, "OUTLINE")
+	SV.Dropdown.Title:SetPoint("TOPLEFT", SV.Dropdown, "TOPLEFT", 7, -7)
+	SV.Dropdown.Title:SetText("Menu")
+	SV.Dropdown.Title:SetTextColor(1, 0.5, 0)
+	SV.Dropdown:SetClampedToScreen(true);
+	SV.Dropdown:SetSize(155, 94)
+
+	local uisfCount = #UISpecialFrames + 1;
+	UISpecialFrames[uisfCount] = SV.Dropdown:GetName();
+	SV.Dropdown:Hide();
+
+	-- WorldFrame:HookScript("OnMouseDown", function()
+	-- 	if(SV.Dropdown:IsShown()) then
+	-- 		ToggleFrame(SV.Dropdown)
+	-- 	end
+	-- end)
+
+	SV:ManageVisibility(SV.Dropdown)
+end
+
+SV.Events:On("LOAD_ALL_WIDGETS", InitializeDropdown);
diff --git a/SVUI_!Core/system/errors.lua b/SVUI_!Core/system/errors.lua
new file mode 100644
index 0000000..250b141
--- /dev/null
+++ b/SVUI_!Core/system/errors.lua
@@ -0,0 +1,88 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack        = _G.unpack;
+local select        = _G.select;
+local pairs         = _G.pairs;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...)
+local SVUILib = Librarian("Registry");
+local L = SV.L;
+--[[
+##########################################################
+LOCAL VARS
+##########################################################
+]]--
+local UIErrorsFrame = _G.UIErrorsFrame;
+local SVUI_ErrorsFrame = CreateFrame("Frame", nil);
+local ERR_FILTERS = {};
+--[[
+##########################################################
+EVENTS
+##########################################################
+]]--
+local ErrorFrameHandler = function(self, event, msgType, msg)
+	if(event == 'PLAYER_REGEN_DISABLED') then
+		self:UnregisterEvent('UI_ERROR_MESSAGE')
+	elseif(event == 'PLAYER_REGEN_ENABLED') then
+		self:RegisterEvent('UI_ERROR_MESSAGE')
+	elseif(msg and (not ERR_FILTERS[msg])) then
+		UIErrorsFrame:AddMessage(msg, 1.0, 0.1, 0.1, 1.0);
+	end
+end
+
+local function CacheFilters()
+	for k, v in pairs(SV.db.general.errorFilters) do
+		ERR_FILTERS[k] = v
+	end
+	if(ERR_FILTERS[INTERRUPTED]) then
+		ERR_FILTERS[SPELL_FAILED_INTERRUPTED] = true
+		ERR_FILTERS[SPELL_FAILED_INTERRUPTED_COMBAT] = true
+	end
+end
+
+function SV:UpdateErrorFilters()
+	if(SV.db.general.filterErrors) then
+		CacheFilters()
+		UIErrorsFrame:UnregisterEvent('UI_ERROR_MESSAGE')
+		SVUI_ErrorsFrame:RegisterEvent('UI_ERROR_MESSAGE')
+		if(SV.db.general.hideErrorFrame) then
+			SVUI_ErrorsFrame:RegisterEvent('PLAYER_REGEN_DISABLED')
+			SVUI_ErrorsFrame:RegisterEvent('PLAYER_REGEN_ENABLED')
+		end
+	else
+		UIErrorsFrame:RegisterEvent('UI_ERROR_MESSAGE')
+		SVUI_ErrorsFrame:UnregisterEvent('UI_ERROR_MESSAGE')
+		SVUI_ErrorsFrame:UnregisterEvent('PLAYER_REGEN_DISABLED')
+		SVUI_ErrorsFrame:UnregisterEvent('PLAYER_REGEN_ENABLED')
+	end
+end
+--[[
+##########################################################
+LOAD
+##########################################################
+]]--
+local function SetErrorFilters()
+	if(SV.db.general.filterErrors) then
+		CacheFilters()
+		UIErrorsFrame:UnregisterEvent('UI_ERROR_MESSAGE')
+		SVUI_ErrorsFrame:RegisterEvent('UI_ERROR_MESSAGE')
+		if(SV.db.general.hideErrorFrame) then
+			SVUI_ErrorsFrame:RegisterEvent('PLAYER_REGEN_DISABLED')
+			SVUI_ErrorsFrame:RegisterEvent('PLAYER_REGEN_ENABLED')
+		end
+		SVUI_ErrorsFrame:SetScript("OnEvent", ErrorFrameHandler)
+	end
+end
+
+SV:NewScript(SetErrorFilters)
\ No newline at end of file
diff --git a/SVUI_!Core/system/funstuff.lua b/SVUI_!Core/system/funstuff.lua
new file mode 100644
index 0000000..e3e5b2c
--- /dev/null
+++ b/SVUI_!Core/system/funstuff.lua
@@ -0,0 +1,778 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+--LUA
+
+local unpack            = _G.unpack;
+local select            = _G.select;
+local assert            = _G.assert;
+local type              = _G.type;
+local error             = _G.error;
+local pcall             = _G.pcall;
+local print             = _G.print;
+local ipairs            = _G.ipairs;
+local pairs             = _G.pairs;
+local next              = _G.next;
+local rawset            = _G.rawset;
+local rawget            = _G.rawget;
+local tostring          = _G.tostring;
+local tonumber          = _G.tonumber;
+--STRING
+local string        = _G.string;
+local format        = string.format;
+local find          = string.find;
+--MATH
+local math          = _G.math;
+local min 			= math.min;
+local max 			= math.max;
+local random 		= math.random;
+--BLIZZARD API
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+local GameTooltip           = _G.GameTooltip;
+local hooksecurefunc        = _G.hooksecurefunc;
+local PlaySound             = _G.PlaySound;
+local PlaySoundFile         = _G.PlaySoundFile;
+local PlayMusic             = _G.PlayMusic;
+local StopMusic             = _G.StopMusic;
+local SetCVar               = _G.SetCVar;
+local GetCVar               = _G.GetCVar;
+local UnitName              = _G.UnitName;
+local ToggleFrame           = _G.ToggleFrame;
+local ERR_NOT_IN_COMBAT     = _G.ERR_NOT_IN_COMBAT;
+local RAID_CLASS_COLORS     = _G.RAID_CLASS_COLORS;
+local CUSTOM_CLASS_COLORS   = _G.CUSTOM_CLASS_COLORS;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...)
+local SVUILib = Librarian("Registry");
+local L = SV.L;
+--[[
+##########################################################
+NPC
+##########################################################
+]]--
+SV.NPC = _G["SVUI_NPCFrame"];
+
+local talkAnims = {60,64,65,67};
+
+local function NPCTalking()
+	local timer = 0;
+	local sequence = random(1, #talkAnims);
+	SV.NPC.Model:ClearModel()
+	SV.NPC.Model:SetUnit('target')
+	SV.NPC.Model:SetCamDistanceScale(1)
+	SV.NPC.Model:SetPortraitZoom(0.95)
+	SV.NPC.Model:SetPosition(0,0,0)
+	SV.NPC.Model:SetAnimation(talkAnims[sequence],0)
+	SV.NPC.Model:SetScript("OnUpdate",function(self,e)
+		if(timer < 2000) then
+			timer = (timer + (e*1000))
+		else
+			timer = 0;
+			self:ClearModel()
+			self:SetUnit('player')
+			self:SetCamDistanceScale(1)
+			self:SetPortraitZoom(0.95)
+			self:SetPosition(0.15,0,0)
+			self:SetRotation(-1)
+			self:SetAnimation(0)
+			self:SetScript("OnUpdate", nil)
+		end
+	end)
+end
+
+local function PlayerTalking()
+	local timer = 0;
+	local sequence = random(1, #talkAnims);
+	SV.NPC.Model:ClearModel()
+	SV.NPC.Model:SetUnit('player')
+	SV.NPC.Model:SetCamDistanceScale(1)
+	SV.NPC.Model:SetPortraitZoom(0.95)
+	SV.NPC.Model:SetPosition(0.15,0,0)
+	SV.NPC.Model:SetRotation(-1)
+	SV.NPC.Model:SetAnimation(talkAnims[sequence],0)
+	SV.NPC.Model:SetScript("OnUpdate",function(self,e)
+		if(timer < 2000) then
+			timer = (timer + (e*1000))
+		else
+			timer = 0;
+			if(UnitExists("target")) then
+				self:ClearModel()
+				self:SetUnit('target')
+				self:SetCamDistanceScale(1)
+				self:SetPortraitZoom(0.95)
+				self:SetPosition(0,0,0)
+				self:SetRotation(0)
+			end
+			self:SetAnimation(0)
+			self:SetScript("OnUpdate", nil)
+		end
+	end)
+end
+
+function SV.NPC:NPCTalksFirst()
+	if(InCombatLockdown() or (not SV.db.FunStuff.NPC) or (not UnitExists("target"))) then return end
+	local timer = 0;
+	self.Model:ClearModel()
+	self.Model:SetUnit('target')
+	self.Model:SetCamDistanceScale(1)
+	self.Model:SetPortraitZoom(0.95)
+	self.Model:SetPosition(0,0,0)
+	self.Model:SetRotation(0)
+	self.Model:SetAnimation(67)
+	self.Model:SetScript("OnUpdate",function(self,e)
+		if(timer < 2000) then
+			timer = (timer + (e*1000))
+		else
+			timer = 0;
+			self:SetAnimation(0)
+			self:SetScript("OnUpdate", nil)
+			PlayerTalking()
+		end
+	end)
+end
+
+function SV.NPC:PlayerTalksFirst()
+	if(InCombatLockdown() or (not SV.db.FunStuff.NPC) or (not UnitExists("target"))) then return end
+	local timer = 0;
+	self.Model:ClearModel()
+	self.Model:SetUnit('player')
+	self.Model:SetCamDistanceScale(1)
+	self.Model:SetPortraitZoom(0.95)
+	self.Model:SetPosition(0.15,0,0)
+	self.Model:SetRotation(-1)
+	self.Model:SetAnimation(67)
+	self.Model:SetScript("OnUpdate",function(self,e)
+		if(timer < 2000) then
+			timer = (timer + (e*1000))
+		else
+			timer = 0;
+			self:SetAnimation(0)
+			self:SetScript("OnUpdate", nil)
+			NPCTalking()
+		end
+	end)
+end
+
+local SetNPCText = function(self, text)
+	self:Hide()
+	SV.NPC.InfoTop.Text:SetText(text)
+	SV.NPC.InfoTop:Show()
+end
+
+function SV.NPC:Toggle(parentFrame, textFrame)
+	if(InCombatLockdown() or (not SV.db.FunStuff.NPC) or (not UnitExists("target"))) then return end
+	local timer = 0;
+	if(parentFrame) then
+		self:SetParent(parentFrame)
+		self:ClearAllPoints();
+		self:SetAllPoints(parentFrame)
+		self:Show();
+		self:SetAlpha(1);
+
+		self.Model:ClearModel()
+		self.Model:SetUnit('target')
+		self.Model:SetCamDistanceScale(1)
+		self.Model:SetPortraitZoom(0.95)
+		self.Model:SetPosition(0,0,0)
+
+		if(textFrame and textFrame.GetText) then
+			local text = textFrame:GetText()
+			textFrame:Hide()
+			self.InfoTop.Text:SetText(text)
+			self.InfoTop:Show()
+		else
+			self.InfoTop:Hide()
+		end
+
+		SV.NPC:NPCTalksFirst()
+	else
+		self.Model:SetScript("OnUpdate", nil)
+		self:SetAlpha(0);
+		self.InfoTop:Hide();
+		self:Hide();
+	end
+end
+
+function SV.NPC:Register(parentFrame, textFrame)
+	if(not SV.db.FunStuff.NPC) then return end
+	parentFrame:HookScript('OnShow', function() SV.NPC:Toggle(parentFrame, textFrame) end)
+	parentFrame:HookScript('OnHide', function() SV.NPC:Toggle() end)
+	if(textFrame and textFrame.SetText) then
+		hooksecurefunc(textFrame, "SetText", SetNPCText)
+	end
+end
+--[[
+##########################################################
+AFK
+##########################################################
+]]--
+SV.AFK = _G["SVUI_AFKFrame"];
+local AFK_SEQUENCES = {
+	[1] = 120,
+	[2] = 141,
+	[3] = 119,
+	[4] = 5,
+};
+
+local Kill_AFK_Widget = function()
+	if(InCombatLockdown()) then return end
+	SV.AFK:SetScript("OnMouseDown", nil)
+	for i,name in pairs(CHAT_FRAMES) do
+		if(_G[name]) then
+			SetChatWindowUninteractable(i, false)
+		end
+	end
+	UIParent:Show();
+	SV.AFK:SetAlpha(0);
+	SV.AFK:Hide();
+	if(SV.db.FunStuff.afk == '1') then
+		MoveViewLeftStop();
+	end
+end
+
+local Start_AFK_Widget = function()
+	if(InCombatLockdown()) then return end
+	local sequence = random(1, 4);
+	if(SV.db.FunStuff.afk == '1') then
+		MoveViewLeftStart(0.05);
+	end
+	SV.AFK:SetScript("OnMouseDown", Kill_AFK_Widget)
+	SV.AFK:Show();
+	UIParent:Hide();
+	SV.AFK:SetAlpha(1);
+	SV.AFK.Model:SetAnimation(AFK_SEQUENCES[sequence])
+	DoEmote("READ")
+end
+
+local AFK_OnEvent = function(self, event)
+	if(event == "PLAYER_FLAGS_CHANGED") then
+		if(IsChatAFK() or UnitIsAFK("player")) then
+			Start_AFK_Widget()
+		else
+			Kill_AFK_Widget()
+		end
+	else
+		Kill_AFK_Widget()
+	end
+end
+
+function SV.AFK:Toggle()
+	if(SV.db.FunStuff.afk ~= 'NONE') then
+		self:RegisterEvent("PLAYER_FLAGS_CHANGED")
+		self:RegisterEvent("PLAYER_REGEN_DISABLED")
+		self:RegisterEvent("PLAYER_ENTERING_WORLD")
+		self:RegisterEvent("PET_BATTLE_OPENING_START")
+		self:RegisterEvent("PLAYER_DEAD")
+		self:SetScript("OnEvent", AFK_OnEvent)
+	else
+		self:UnregisterEvent("PLAYER_FLAGS_CHANGED")
+		self:UnregisterEvent("PLAYER_REGEN_DISABLED")
+		self:UnregisterEvent("PLAYER_ENTERING_WORLD")
+		self:UnregisterEvent("PET_BATTLE_OPENING_START")
+		self:UnregisterEvent("PLAYER_DEAD")
+		self:SetScript("OnEvent", nil)
+	end
+end
+--[[
+##########################################################
+COMIX
+##########################################################
+]]--
+SV.Comix = _G["SVUI_ComixFrame"];
+local COMIX_DATA = {
+	{
+		{0,0.25,0,0.25},
+		{0.25,0.5,0,0.25},
+		{0.5,0.75,0,0.25},
+		{0.75,1,0,0.25},
+		{0,0.25,0.25,0.5},
+		{0.25,0.5,0.25,0.5},
+		{0.5,0.75,0.25,0.5},
+		{0.75,1,0.25,0.5},
+		{0,0.25,0.5,0.75},
+		{0.25,0.5,0.5,0.75},
+		{0.5,0.75,0.5,0.75},
+		{0.75,1,0.5,0.75},
+		{0,0.25,0.75,1},
+		{0.25,0.5,0.75,1},
+		{0.5,0.75,0.75,1},
+		{0.75,1,0.75,1}
+	},
+	{
+		{220, 210, 20, -20, 220, 210, -1, 5},
+	    {230, 210, 20, 5, 280, 210, -5, 1},
+	    {280, 160, 1, 20, 280, 210, -1, 5},
+	    {220, 210, 20, -20, 220, 210, -1, 5},
+	    {210, 190, 20, 20, 220, 210, -1, 5},
+	    {220, 210, 20, -20, 220, 210, -1, 5},
+	    {230, 210, 20, 5, 280, 210, -5, 1},
+	    {280, 160, 1, 20, 280, 210, -1, 5},
+	    {220, 210, 20, -20, 220, 210, -1, 5},
+	    {210, 190, 20, 20, 220, 210, -1, 5},
+	    {220, 210, 20, -20, 220, 210, -1, 5},
+	    {230, 210, 20, 5, 280, 210, -5, 1},
+	    {280, 160, 1, 20, 280, 210, -1, 5},
+	    {220, 210, 20, -20, 220, 210, -1, 5},
+	    {210, 190, 20, 20, 220, 210, -1, 5},
+	    {210, 190, 20, 20, 220, 210, -1, 5}
+	}
+};
+
+SV.Comix.Ready = true;
+
+--/script SVUI.Comix:LaunchPremium()
+function SV.Comix:LaunchPremium()
+	self.Ready = false
+	local coords, step1_x, step1_y, step2_x, step2_y, size, offsets;
+	local key = random(1, 16);
+	coords = COMIX_DATA[1][key];
+	if(not coords) then return end
+	offsets = COMIX_DATA[2][key]
+	step1_x = offsets[1] * 0.1;
+	step1_y = offsets[2] * 0.1;
+	step2_x = (offsets[5] * 0.1) + offsets[3];
+	step2_y = (offsets[6] * 0.1) + offsets[4];
+	self.Premium.tex:SetTexCoord(coords[1],coords[2],coords[3],coords[4])
+	self.Premium.bg.tex:SetTexCoord(coords[1],coords[2],coords[3],coords[4])
+	-- self.Premium.anim[1]:SetOffset(offsets[1],offsets[2])
+	-- self.Premium.anim[2]:SetOffset(offsets[3],offsets[4])
+	self.Premium.anim[1]:SetOffset(step1_x, step1_y);
+	self.Premium.anim[2]:SetOffset(offsets[3],offsets[4]);
+	self.Premium.anim[3]:SetOffset(0,0)
+	-- self.Premium.bg.anim[1]:SetOffset(offsets[5],offsets[6])
+	-- self.Premium.bg.anim[2]:SetOffset(offsets[7],offsets[8])
+	self.Premium.bg.anim[1]:SetOffset(step2_x, step2_y);
+	self.Premium.bg.anim[2]:SetOffset(offsets[7],offsets[8]);
+	self.Premium.bg.anim[3]:SetOffset(0,0)
+
+	self.Premium.anim:Play()
+	self.Premium.bg.anim:Play()
+end
+
+--/script SVUI.Comix:LaunchPopup()
+function SV.Comix:LaunchPopup()
+	self.Ready = false
+	local coords, step1_x, step1_y, step2_x, step2_y, size, offsets;
+	local rng = random(0, 32);
+	local key = random(1, 16);
+	coords = COMIX_DATA[1][key];
+	if(not coords) then return end
+	if((rng == 32) and (SV.db.FunStuff.comix == '1')) then
+		ComixToastyPanelBG.anim[2]:SetOffset(256, -256)
+		ComixToastyPanelBG.anim[2]:SetOffset(0, 0)
+		ComixToastyPanelBG.anim:Play()
+		PlaySoundFile([[Interface\AddOns\SVUI_!Core\assets\sounds\toasty.mp3]])
+	elseif(rng < 24) then
+		step1_x = random(-150, 150);
+		if(step1_x > -20 and step1_x < 20) then step1_x = step1_x * 3 end
+		step1_y = random(50, 150);
+		step2_x = step1_x * 0.5;
+		step2_y = step1_y * 0.75;
+		self.Deluxe.tex:SetTexCoord(coords[1],coords[2],coords[3],coords[4]);
+		self.Deluxe.anim[1]:SetOffset(step1_x, step1_y);
+		self.Deluxe.anim[2]:SetOffset(step2_x, step2_y);
+		self.Deluxe.anim[3]:SetOffset(0,0);
+		self.Deluxe.anim:Play();
+	elseif(rng < 12) then
+		step1_x = random(-100, 100);
+		step1_y = random(-50, 1);
+		size = random(96,128);
+		self.Basic:SetSize(size,size);
+		self.Basic.tex:SetTexCoord(coords[1],coords[2],coords[3],coords[4]);
+		self.Basic:ClearAllPoints();
+		self.Basic:SetPoint("CENTER", SV.Screen, "CENTER", step1_x, step1_y);
+		self.Basic.anim:Play();
+	end
+end
+
+function SV:ToastyKombat()
+	ComixToastyPanelBG.anim[2]:SetOffset(256, -256)
+	ComixToastyPanelBG.anim[2]:SetOffset(0, 0)
+	ComixToastyPanelBG.anim:Play()
+	PlaySoundFile([[Interface\AddOns\SVUI_!Core\assets\sounds\toasty.mp3]])
+end
+
+_G.SlashCmdList["KOMBAT"] = function(msg)
+	SV:ToastyKombat()
+end
+_G.SLASH_KOMBAT1 = "/kombat"
+
+local Comix_OnEvent = function(self, event, ...)
+	if(not self.Ready) then return end
+	local _, subEvent, _, guid = ...;
+	if((subEvent == "PARTY_KILL") and (guid == UnitGUID('player'))) then
+		self:LaunchPopup()
+	end
+end
+
+local Comix_OnUpdate = function() SV.Comix.Ready = true; end
+
+local Toasty_OnUpdate = function(self) SV.Comix.Ready = true; self.parent:SetAlpha(0) end
+
+function SV.Comix:Toggle()
+	if(SV.db.FunStuff.comix == 'NONE') then
+		self:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
+		self:SetScript("OnEvent", nil)
+	else
+		self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
+		self:SetScript("OnEvent", Comix_OnEvent)
+	end
+end
+--[[
+##########################################################
+DRUNK MODE
+##########################################################
+]]--
+SV.Drunk = _G["SVUI_BoozedUpFrame"];
+local WORN_ITEMS = {};
+local DRUNK_EFFECT = [[Spells\Largebluegreenradiationfog.m2]];
+local DRUNK_EFFECT2 = [[Spells\Monk_drunkenhaze_impact.m2]];
+local TIPSY_FILTERS = {
+	[DRUNK_MESSAGE_ITEM_SELF1] = true,
+	[DRUNK_MESSAGE_ITEM_SELF2] = true,
+	[DRUNK_MESSAGE_SELF1] = true,
+	[DRUNK_MESSAGE_SELF2] = true,
+};
+local DRUNK_FILTERS = {
+	[DRUNK_MESSAGE_ITEM_SELF3] = true,
+	[DRUNK_MESSAGE_ITEM_SELF4] = true,
+	[DRUNK_MESSAGE_SELF3] = true,
+	[DRUNK_MESSAGE_SELF4] = true,
+};
+
+local function GetNekkid()
+	for c = 1, 19 do
+		if CursorHasItem() then
+			ClearCursor()
+		end
+		local item = GetInventoryItemID("player", c);
+		WORN_ITEMS[c] = item;
+		PickupInventoryItem(c);
+		for b = 1, 4 do
+			if CursorHasItem() then
+				PutItemInBag(b)
+			end
+		end
+	end
+end
+
+local function GetDressed()
+	for c, item in pairs(WORN_ITEMS) do
+		if(item) then
+			EquipItemByName(item)
+			WORN_ITEMS[c] = false
+		end
+	end
+end
+
+function SV.Drunk:PartysOver()
+	SetCVar("Sound_MusicVolume", 0)
+	SetCVar("Sound_EnableMusic", 0)
+	StopMusic()
+	SV.Drunk:Hide()
+	SV.Drunk.PartyMode = nil
+	SV:AddonMessage("Party's Over...")
+	--GetDressed()
+end
+
+function SV.Drunk:LetsParty()
+	if(not SV.db.FunStuff.drunk) then return end
+	--GetNekkid()
+	self.PartyMode = true
+	SetCVar("Sound_MusicVolume", 100)
+	SetCVar("Sound_EnableMusic", 1)
+	StopMusic()
+	PlayMusic([[Interface\AddOns\SVUI_!Core\assets\sounds\beer30.mp3]])
+	self:Show()
+	self.ScreenEffect1:ClearModel()
+	self.ScreenEffect1:SetModel(DRUNK_EFFECT)
+	self.ScreenEffect2:ClearModel()
+	self.ScreenEffect2:SetModel(DRUNK_EFFECT2)
+	self.ScreenEffect3:ClearModel()
+	self.ScreenEffect3:SetModel(DRUNK_EFFECT2)
+	SV:AddonMessage("YEEEEEEEEE-HAW!!!")
+	DoEmote("dance")
+	-- SV.Timers:ExecuteTimer(PartysOver, 60)
+end
+
+local DrunkAgain_OnEvent = function(self, event, message, ...)
+	if(self.PartyMode) then
+		for pattern,_ in pairs(TIPSY_FILTERS) do
+			if(message:find(pattern)) then
+				self:PartysOver()
+				break
+			end
+		end
+	else
+		for pattern,_ in pairs(DRUNK_FILTERS) do
+			if(message:find(pattern)) then
+				self:LetsParty()
+				break
+			end
+		end
+	end
+end
+
+_G.SLASH_PARTYSOVER1 = "/sobriety"
+_G.SlashCmdList["PARTYSOVER"] = function(msg)
+	if(SV.Drunk.PartyMode) then
+		SV.Drunk:PartysOver()
+	end
+end
+
+function SV.Drunk:Toggle()
+	if(not SV.db.FunStuff.drunk) then
+		self:UnregisterEvent("CHAT_MSG_SYSTEM")
+		self:SetScript("OnEvent", nil)
+	else
+		self:RegisterEvent("CHAT_MSG_SYSTEM")
+		self:SetScript("OnEvent", DrunkAgain_OnEvent)
+	end
+end
+--[[
+##########################################################
+GAMEMENU
+##########################################################
+]]--
+SV.GameMenu = _G["SVUI_GameMenuFrame"];
+--[[
+4    - walk
+5    - run
+26   - attack stance
+40   - falling loop
+52   - casting loop
+55   - roar pose (paused)
+60   - chat normal
+64   - chat exclaimation
+65   - chat shrug
+69   - dance
+74   - roar
+111  - attack ready
+119  - stealth walk
+120  - stealth standing loop
+125  - spell2
+138  - craft loop
+141  - kneel loop
+203  - cannibalize
+225  - cower loop
+]]--
+local Sequences = {26, 52, 111, 69};
+
+local GameMenu_Activate = function(self)
+	if(SV.db.FunStuff.gamemenu == 'NONE') then
+		self:Toggle()
+		return
+	end
+	local key = random(1, 4)
+	local emote = Sequences[key]
+	self:SetAlpha(1)
+	self.ModelLeft:SetAnimation(emote)
+	local models = SV.YOUR_HENCHMEN
+	local mod = random(1, #models)
+	self.ModelRight:ClearModel()
+	self.ModelRight:SetDisplayInfo(models[mod][1])
+	self.ModelRight:SetAnimation(emote)
+end
+
+function SV.GameMenu:Toggle()
+	if(SV.db.FunStuff.gamemenu ~= 'NONE') then
+		self:Show()
+		self:SetScript("OnShow", GameMenu_Activate)
+	else
+		self:Hide()
+		self:SetScript("OnShow", nil)
+	end
+end
+--[[
+##########################################################
+LOAD BY TRIGGER
+##########################################################
+]]--
+local function InitializeFunStuff()
+	--[[ AFK SCREEN ]]--
+	local afk = SV.AFK;
+	local classToken = select(2,UnitClass("player"))
+	local color = CUSTOM_CLASS_COLORS[classToken]
+	if(not SV.db.general.customClassColor) then
+		color = RAID_CLASS_COLORS[classToken]
+	end
+
+	afk.BG:SetVertexColor(color.r, color.g, color.b)
+	afk.BG:ClearAllPoints()
+	afk.BG:SetSize(500,600)
+	afk.BG:SetPoint("BOTTOMRIGHT", afk, "BOTTOMRIGHT", 0, 0)
+
+	afk:SetFrameLevel(0)
+	afk:SetAllPoints(SV.Screen)
+
+	local narr = afk.Model:CreateTexture(nil, "OVERLAY")
+	narr:SetSize(300, 150)
+	narr:SetTexture([[Interface\AddOns\SVUI_!Core\assets\textures\Doodads\AFK-NARRATIVE]])
+	narr:SetPoint("TOPLEFT", SV.Screen, "TOPLEFT", 15, -15)
+
+	afk.Model:ClearAllPoints()
+	afk.Model:SetSize(600,600)
+	afk.Model:SetPoint("BOTTOMRIGHT", afk, "BOTTOMRIGHT", 64, -64)
+	afk.Model:SetUnit("player")
+	afk.Model:SetCamDistanceScale(1.15)
+	afk.Model:SetFacing(6)
+
+	local splash = afk.Model:CreateTexture(nil, "OVERLAY")
+	splash:SetSize(350, 175)
+	splash:SetTexture([[Interface\AddOns\SVUI_!Core\assets\textures\Doodads\PLAYER-AFK]])
+	splash:SetPoint("BOTTOMRIGHT", afk.Model, "CENTER", -75, 75)
+
+	afk:Hide()
+	if(SV.db.FunStuff.afk ~= 'NONE') then
+		afk:RegisterEvent("PLAYER_FLAGS_CHANGED")
+		afk:RegisterEvent("PLAYER_REGEN_DISABLED")
+		afk:RegisterEvent("PLAYER_ENTERING_WORLD")
+		afk:RegisterEvent("PET_BATTLE_OPENING_START")
+		afk:SetScript("OnEvent", AFK_OnEvent)
+		UIParent:HookScript("OnShow", Kill_AFK_Widget)
+		SV.Events:On("SPECIAL_FRAMES_CLOSED", Kill_AFK_Widget, true);
+	end
+
+	--[[ COMIX POPUPS ]]--
+	local comix = SV.Comix
+	comix.Basic = _G["SVUI_ComixPopup1"]
+	comix.Deluxe = _G["SVUI_ComixPopup2"]
+	comix.Premium = _G["SVUI_ComixPopup3"]
+
+	comix.Basic:SetParent(SV.Screen)
+	comix.Basic:SetSize(100,100)
+	comix.Basic.tex:SetTexCoord(0,0.25,0,0.25)
+	SV.Animate:Kapow(comix.Basic, true, true)
+	comix.Basic:SetAlpha(0)
+	comix.Basic:Show()
+	comix.Basic.anim[2]:SetScript("OnFinished", Comix_OnUpdate)
+
+	comix.Deluxe:SetParent(SV.Screen)
+	comix.Deluxe:SetSize(100,100)
+	comix.Deluxe.tex:SetTexCoord(0,0.25,0,0.25)
+	SV.Animate:RandomSlide(comix.Deluxe, true)
+	comix.Deluxe:SetAlpha(0)
+	comix.Deluxe:Show()
+	comix.Deluxe.anim[3]:SetScript("OnFinished", Comix_OnUpdate)
+
+	comix.Premium:SetParent(SV.Screen)
+	comix.Premium:SetSize(96,96);
+	comix.Premium.tex:SetTexCoord(0,0.25,0,0.25)
+	--comix.Premium.tex:SetBlendMode('ADD')
+	SV.Animate:RandomSlide(comix.Premium, true)
+	comix.Premium:SetAlpha(0)
+	comix.Premium:Show()
+	comix.Premium.anim[3]:SetScript("OnFinished", Comix_OnUpdate)
+
+	comix.Premium.bg:SetSize(96,96);
+	comix.Premium.bg.tex:SetTexCoord(0,0.25,0,0.25)
+	comix.Premium.bg.tex:SetBlendMode('ADD')
+	SV.Animate:RandomSlide(comix.Premium.bg, false)
+	comix.Premium.bg:SetAlpha(0)
+	comix.Premium.bg.anim[3]:SetScript("OnFinished", Comix_OnUpdate)
+
+	local toasty = CreateFrame("Frame", "ComixToastyPanelBG", SV.Screen)
+	toasty:SetSize(256, 256)
+	toasty:SetFrameStrata("DIALOG")
+	toasty:SetPoint("BOTTOMRIGHT", SV.Screen, "BOTTOMRIGHT", 0, 0)
+	toasty.tex = toasty:CreateTexture(nil, "ARTWORK")
+	toasty.tex:InsetPoints(toasty)
+	toasty.tex:SetTexture([[Interface\AddOns\SVUI_!Core\assets\textures\Doodads\TOASTY]])
+	SV.Animate:Slide(toasty, 256, -256, true)
+	toasty:SetAlpha(0)
+	toasty.anim[4]:SetScript("OnFinished", Toasty_OnUpdate)
+
+	comix.Ready = true;
+	comix:Toggle()
+
+	--[[ DRUNK MODE ]]--
+	local drunk = SV.Drunk;
+	drunk:SetParent(SV.Screen)
+	drunk:ClearAllPoints()
+	drunk:SetAllPoints(SV.Screen)
+
+	drunk.ScreenEffect1:SetParent(drunk)
+	drunk.ScreenEffect1:SetAllPoints(SV.Screen)
+	drunk.ScreenEffect1:SetModel(DRUNK_EFFECT)
+	drunk.ScreenEffect1:SetCamDistanceScale(1)
+
+	drunk.ScreenEffect2:SetParent(drunk)
+	drunk.ScreenEffect2:SetPoint("BOTTOMLEFT", SV.Screen, "BOTTOMLEFT", 0, 0)
+	drunk.ScreenEffect2:SetPoint("TOPRIGHT", SV.Screen, "TOP", 0, 0)
+	drunk.ScreenEffect2:SetModel(DRUNK_EFFECT2)
+	drunk.ScreenEffect2:SetCamDistanceScale(0.25)
+
+	drunk.ScreenEffect3:SetParent(drunk)
+	drunk.ScreenEffect3:SetPoint("BOTTOMRIGHT", SV.Screen, "BOTTOMRIGHT", 0, 0)
+	drunk.ScreenEffect3:SetPoint("TOPLEFT", SV.Screen, "TOP", 0, 0)
+	drunk.ScreenEffect3:SetModel(DRUNK_EFFECT2)
+	drunk.ScreenEffect3:SetCamDistanceScale(0.25)
+
+	drunk.YeeHaw:SetSize(512,350);
+	drunk:Hide()
+	drunk:Toggle()
+
+	--[[ GAME MENU ]]--
+	local gamemenu = SV.GameMenu;
+	gamemenu:SetAllPoints(SV.Screen)
+
+	gamemenu.ModelLeft:SetUnit("player")
+	gamemenu.ModelLeft:SetRotation(1)
+	gamemenu.ModelLeft:SetPortraitZoom(0.05)
+	gamemenu.ModelLeft:SetPosition(0,0,-0.25)
+
+	if(SV.db.FunStuff.gamemenu == '1') then
+		gamemenu.ModelRight:SetDisplayInfo(49084)
+		gamemenu.ModelRight:SetRotation(-1)
+		gamemenu.ModelRight:SetCamDistanceScale(1.9)
+		gamemenu.ModelRight:SetFacing(6)
+		gamemenu.ModelRight:SetPosition(0,0,-0.3)
+	elseif(SV.db.FunStuff.gamemenu == '2') then
+		gamemenu.ModelRight:SetUnit("player")
+		gamemenu.ModelRight:SetRotation(-1)
+		gamemenu.ModelRight:SetCamDistanceScale(1.9)
+		gamemenu.ModelRight:SetFacing(6)
+		gamemenu.ModelRight:SetPosition(0,0,-0.3)
+	end
+
+	gamemenu:SetScript("OnShow", GameMenu_Activate)
+
+	local npc = SV.NPC;
+	npc.Model:SetStyle("Frame", "Model", false, 5, 3, 3)
+	npc.InfoTop = CreateFrame("Frame", nil, npc)
+	npc.InfoTop:SetPoint("BOTTOMLEFT", npc.Model, "BOTTOMRIGHT", 2, 22)
+	npc.InfoTop:SetSize(196, 98)
+	npc.InfoTop:SetBackdrop({
+		bgFile = [[Interface\AddOns\SVUI_!Core\assets\textures\NPC-NAMETAG]],
+	    tile = false,
+	    tileSize = 0,
+	    edgeFile = [[Interface\AddOns\SVUI_!Core\assets\textures\EMPTY]],
+	    edgeSize = 1,
+	    insets =
+	    {
+	        left = 0,
+	        right = 0,
+	        top = 0,
+	        bottom = 0,
+	    },
+	});
+  	npc.InfoTop:SetBackdropColor(1, 1, 0, 1)
+	npc.InfoTop:SetFrameLevel(npc:GetFrameLevel() + 1)
+
+	npc.InfoTop.Text = npc.InfoTop:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
+	npc.InfoTop.Text:SetPoint("TOPLEFT", npc.InfoTop, "TOPLEFT", 0, -33)
+	npc.InfoTop.Text:SetPoint("BOTTOMRIGHT", npc.InfoTop, "BOTTOMRIGHT", 0, 0)
+end
+
+SV.Events:On("CORE_INITIALIZED", InitializeFunStuff);
diff --git a/SVUI_!Core/system/gear.lua b/SVUI_!Core/system/gear.lua
new file mode 100644
index 0000000..20e9e25
--- /dev/null
+++ b/SVUI_!Core/system/gear.lua
@@ -0,0 +1,523 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local string 	= _G.string;
+local math 		= _G.math;
+--[[ STRING METHODS ]]--
+local find, format, match, split, join = string.find, string.format, string.match, string.split, string.join;
+local sub, byte = string.sub, string.byte;
+--[[ MATH METHODS ]]--
+local ceil, floor, round = math.ceil, math.floor, math.round;
+--[[ TABLE METHODS ]]--
+local tremove, tcopy, twipe, tsort, tcat = table.remove, table.copy, table.wipe, table.sort, table.concat;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...)
+local L = SV.L
+--[[
+##########################################################
+LOCAL VARS
+##########################################################
+]]--
+local NewHook = hooksecurefunc;
+local ParseItemLevel, ParseGearSlots;
+local GEAR_CACHE, GEARSET_LISTING = {}, {};
+local EquipmentSlots = {
+    ["HeadSlot"] = {true,true},
+    ["NeckSlot"] = {true,false},
+    ["ShoulderSlot"] = {true,true},
+    ["BackSlot"] = {true,false},
+    ["ChestSlot"] = {true,true},
+    ["WristSlot"] = {true,true},
+    ["MainHandSlot"] = {true,true,true},
+    ["SecondaryHandSlot"] = {true,true},
+    ["HandsSlot"] = {true,true,true},
+    ["WaistSlot"] = {true,true,true},
+    ["LegsSlot"] = {true,true,true},
+    ["FeetSlot"] = {true,true,true},
+    ["Finger0Slot"] = {true,false,true},
+    ["Finger1Slot"] = {true,false,true},
+    ["Trinket0Slot"] = {true,false,true},
+    ["Trinket1Slot"] = {true,false,true}
+}
+--[[
+	Quick explaination of what Im doing with all of these locals...
+	Unlike many of the other modules, Inventory has to continuously
+	reference config settings which can start to get sluggish. What
+	I have done is set local variables for every database value
+	that the module can read efficiently. The function "UpdateLocals"
+	is used to refresh these any time a change is made to configs
+	and once when the mod is loaded.
+]]--
+local COLOR_KEYS = { [0] = "|cffff0000", [1] = "|cff00ff00", [2] = "|cffffff88" };
+local LIVESET, LASTSET, BG_SET, SPEC_SET, SHOW_DURABILITY, ONLY_DAMAGED, AVG_LEVEL, MAX_LEVEL;
+local SPEC_SWAP, BG_SWAP;
+local SHOW_CHAR_LEVEL, SHOW_BAG_LEVEL, SHOW_CHAR_SET, SHOW_BAG_SET;
+local iLevelFilter = ITEM_LEVEL:gsub( "%%d", "(%%d+)" )
+--[[
+##########################################################
+LOCAL FUNCTIONS
+##########################################################
+]]--
+local GearHandler = CreateFrame("Frame", nil);
+
+local function encodeSub(i, j, k)
+	local l = j;
+	while((k > 0) and (l <= #i)) do
+		local m = byte(i, l)
+		if(m > 240) then
+			l = l + 4;
+		elseif(m > 225) then
+			l = l + 3;
+		elseif(m > 192) then
+			l = l + 2;
+		else
+			l = l + 1;
+		end
+		k = k - 1;
+	end
+	return i:sub(j, (l - 1))
+end
+
+do
+    local _heirlooms80 = {
+      44102,42944,44096,42943,42950,48677,42946,42948,42947,42992,
+      50255,44103,44107,44095,44098,44097,44105,42951,48683,48685,
+      42949,48687,42984,44100,44101,44092,48718,44091,42952,48689,
+      44099,42991,42985,48691,44094,44093,42945,48716
+    }
+    local _heirlooms90h = {105689,105683,105686,105687,105688,105685,105690,105691,105684,105692,105693}
+    local _heirlooms90n = {104399,104400,104401,104402,104403,104404,104405,104406,104407,104408,104409}
+    local _heirlooms90f = {105675,105670,105672,105671,105674,105673,105676,105677,105678,105679,105680}
+
+    -- DEPRECATED
+    -- local _heirloom_regex = "|?c?f?f?(%x*)|?H?([^:]*):?(%d+):?(%d*):?(%d*):?(%d*):?(%d*):?(%d*):?(%-?%d*):?(%-?%d*):?(%d*):?(%d*)|?h?%[?([^%[%]]*)%]?|?h?|?r?";
+
+    local _slots = {
+        ["HeadSlot"] = {true, true},            ["NeckSlot"] = {true, false},
+        ["ShoulderSlot"] = {true, true},        ["BackSlot"] = {true, false},
+        ["ChestSlot"] = {true, true},           ["WristSlot"] = {true, true},
+        ["MainHandSlot"] = {true, true, true},  ["SecondaryHandSlot"] = {true, true},
+        ["HandsSlot"] = {true, true, true},     ["WaistSlot"] = {true, true, true},
+        ["LegsSlot"] = {true, true, true},      ["FeetSlot"] = {true, true, true},
+        ["Finger0Slot"] = {true, false, true},  ["Finger1Slot"] = {true, false, true},
+        ["Trinket0Slot"] = {true, false, true}, ["Trinket1Slot"] = {true, false, true}
+    }
+
+    local function _justthetip()
+        for i=1, #GameTooltip.shoppingTooltips do
+            if(not GameTooltip.shoppingTooltips[i]:IsShown()) then
+                return GameTooltip.shoppingTooltips[i]
+            end
+        end
+    end
+
+    local function _getHeirloomLevel(unit, itemId)
+        if(not itemId) then return; end
+
+        local baseLevel = UnitLevel(unit)
+        if baseLevel > 85 then
+            for i=1, #_heirlooms90h do
+              if(_heirlooms90h[i] == itemId) then
+                baseLevel = 582
+                break
+              end
+            end
+
+            for i=1, #_heirlooms90n do
+              if(_heirlooms90n[i] == itemId) then
+                baseLevel = 569
+                break
+              end
+            end
+
+            for i=1, #_heirlooms90f do
+              if(_heirlooms90f[i] == itemId) then
+                baseLevel = 548
+                break
+              end
+            end
+
+            return baseLevel
+        elseif baseLevel > 80 then
+            for i=1, #_heirlooms80 do
+                if(_heirlooms80[i] == itemId) then
+                    baseLevel = 80;
+                    break
+                end
+            end
+        end
+
+        if(baseLevel > 80) then
+            return (((baseLevel - 81) * 12.2) + 272)
+        elseif(baseLevel > 67) then
+            return (((baseLevel - 68) * 6) + 130)
+        elseif(baseLevel > 59) then
+            return (((baseLevel - 60) * 3) + 85)
+        end
+        return baseLevel
+    end
+
+    function ParseItemLevel(unit, itemLink)
+        local name, link, quality;
+        local iLevel = 0;
+        if(itemLink and type(itemLink) == "string") then
+          name, link, quality, iLevel = GetItemInfo(itemLink)
+          local itemId = tonumber(itemLink:match("item:%d+:%d+:%d+:%d+:%d+:%d+:%-?%d+:%-?%d+:%d+:%d+:(%d+)"))
+          if iLevel and itemId then
+              if(quality == 7) then
+                  iLevel = _getHeirloomLevel(unit, itemId)
+              end
+          end
+        end
+        return iLevel or 0
+    end
+
+    local function _getEquippedItemLevel(unit, itemLink)
+        local tooltip = _justthetip();
+        if(not tooltip) then return ParseItemLevel(unit, itemLink) end
+        tooltip:SetOwner(UIParent, "ANCHOR_NONE");
+        tooltip:SetHyperlink(itemLink);
+        tooltip:Show();
+
+        local iLevel = 0;
+        local tname = tooltip:GetName().."TextLeft%s";
+        for i = 2, tooltip:NumLines() do
+            local text = _G[tname:format(i)]:GetText();
+            if(text and text ~= "") then
+                local value = tonumber(text:match(iLevelFilter));
+                if(value) then
+                    iLevel = value;
+                end
+            end
+        end
+
+        tooltip:Hide();
+        return iLevel
+    end
+
+    local function _setLevelDisplay(frame, iLevel)
+      if(not frame or (not frame.ItemLevel)) then return; end
+      frame.ItemLevel:SetText('')
+      if(SHOW_CHAR_LEVEL and iLevel) then
+        local key = (iLevel < (AVG_LEVEL - 10)) and 0 or (iLevel > (AVG_LEVEL + 10)) and 1 or 2;
+        frame.ItemLevel:SetFormattedText("%s%d|r", COLOR_KEYS[key], iLevel)
+      end
+    end
+
+    local function _setDurabilityDisplay(frame, slotId)
+      if(not frame or (not frame.DurabilityInfo)) then return; end
+      if(SHOW_DURABILITY) then
+        local current,total,actual,perc,r,g,b;
+        current,total = GetInventoryItemDurability(slotId)
+        if(current and total) then
+          frame.DurabilityInfo.bar:SetMinMaxValues(0, 100)
+          if(current == total and ONLY_DAMAGED) then
+            frame.DurabilityInfo:Hide()
+          else
+            if(current ~= total) then
+              actual = current / total;
+              perc = actual * 100;
+              r,g,b = SV:ColorGradient(actual,1,0,0,1,1,0,0,1,0)
+              frame.DurabilityInfo.bar:SetValue(perc)
+              frame.DurabilityInfo.bar:SetStatusBarColor(r,g,b)
+              if not frame.DurabilityInfo:IsShown() then
+                frame.DurabilityInfo:Show()
+              end
+            else
+              frame.DurabilityInfo.bar:SetValue(100)
+              frame.DurabilityInfo.bar:SetStatusBarColor(0, 1, 0)
+            end
+          end
+        else
+          frame.DurabilityInfo:Hide()
+        end
+      else
+        frame.DurabilityInfo:Hide()
+      end
+    end
+
+    function ParseGearSlots(unit, category, setLevel, setDurability)
+        local averageLevel,totalSlots = 0,0;
+
+        for slotName, flags in pairs(_slots) do
+            local slotId = GetInventorySlotInfo(slotName);
+            local iLink = GetInventoryItemLink(unit, slotId)
+            local iLevel;
+            if(iLink and type(iLink) == "string") then
+                iLevel = _getEquippedItemLevel(unit, iLink)
+                if(iLevel and iLevel > 0) then
+                    totalSlots = totalSlots + 1;
+                    averageLevel = averageLevel + iLevel
+                end
+            end
+
+            if(setLevel and flags[1]) then
+              _setLevelDisplay(_G[category .. slotName], iLevel)
+            end
+            if(setDurability and (slotId ~= nil) and (not inspecting) and flags[2]) then
+              _setDurabilityDisplay(_G[category .. slotName], slotId)
+            end
+        end
+        return averageLevel,totalSlots
+    end
+end
+
+function SV:ParseGearSlots(unit, inspecting, setLevel, setDurability)
+    local category = (inspecting) and "Inspect" or "Character";
+    local averageLevel,totalSlots = ParseGearSlots(unit, category, setLevel, setDurability);
+    if(averageLevel < 1 or totalSlots < 15) then return end
+    return floor(averageLevel / totalSlots)
+end
+
+function SV:SetGearLabels(frame, bagID, slotID, itemLink, quality, equipSlot)
+  quality = quality or 0;
+  equipSlot = equipSlot or '';
+
+  if(frame.GearInfo) then
+    local loc = format("%d_%d", bagID, slotID);
+    if((not SHOW_BAG_SET) or (not GEARSET_LISTING[loc])) then
+      frame.GearInfo:SetText('')
+  	else
+      local setNumber = #GEARSET_LISTING[loc] < 4 and #GEARSET_LISTING[loc] or 3;
+  		if(setNumber == 1) then
+        frame.GearInfo:SetFormattedText("|cffffffaa%s|r", encodeSub(GEARSET_LISTING[loc][1], 1, 4))
+  		elseif(setNumber == 2) then
+        frame.GearInfo:SetFormattedText("|cffffffaa%s %s|r", encodeSub(GEARSET_LISTING[loc][1], 1, 4), encodeSub(GEARSET_LISTING[loc][2], 1, 4))
+  		elseif(setNumber == 3) then
+        frame.GearInfo:SetFormattedText("|cffffffaa%s %s %s|r", encodeSub(GEARSET_LISTING[loc][1], 1, 4), encodeSub(GEARSET_LISTING[loc][2], 1, 4), encodeSub(GEARSET_LISTING[loc][3], 1, 4))
+  		else
+        frame.GearInfo:SetText('')
+  		end
+  	end
+  end
+
+  if(frame.ItemLevel) then
+    local iLevel = ParseItemLevel('player', itemLink)
+  	if((not SHOW_BAG_LEVEL) or (iLevel <= 1) or (quality == 7) or (not equipSlot:find('INVTYPE'))) then
+      frame.ItemLevel:SetText('')
+  	else
+  		local key = (iLevel < (AVG_LEVEL - 10)) and 0 or (iLevel > (AVG_LEVEL + 10)) and 1 or 2;
+      frame.ItemLevel:SetFormattedText("%s%d|r", COLOR_KEYS[key], iLevel)
+  	end
+  end
+end
+
+local function GetActiveGear()
+	local count = GetNumEquipmentSets()
+	local resultSpec = GetActiveSpecGroup()
+	local resultSet
+  BG_SET = "none"
+	SPEC_SET = "none"
+	if(resultSpec and GetSpecializationInfo(resultSpec) and (resultSpec ~= 1)) then
+    SPEC_SET = SV.db.Gear.specialization.secondary
+    BG_SET = SV.db.Gear.battleground.secondary
+  else
+    SPEC_SET = SV.db.Gear.specialization.primary
+    BG_SET = SV.db.Gear.battleground.primary
+	end
+	if(count == 0) then
+		return resultSpec,false
+	end
+	for i=1, count do
+		local setName,_,_,setUsed = GetEquipmentSetInfo(i)
+		if setUsed then
+			resultSet = setName
+			break
+		end
+	end
+	return resultSpec,resultSet
+end
+
+local function SetDisplayStats(arg)
+	for slotName, flags in pairs(EquipmentSlots) do
+		local globalName = format("%s%s", arg, slotName)
+		local frame = _G[globalName]
+
+		if(flags[1]) then
+			frame.ItemLevel = frame:CreateFontString(nil, "OVERLAY")
+			frame.ItemLevel:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", 2, 1)
+			frame.ItemLevel:SetFontObject(SVUI_Font_Default)
+		end
+
+		if(arg == "Character" and flags[2]) then
+			frame.DurabilityInfo = CreateFrame("Frame", nil, frame)
+			frame.DurabilityInfo:SetWidth(7)
+			if flags[3] then
+				frame.DurabilityInfo:SetPoint("TOPRIGHT", frame, "TOPLEFT", -1, 1)
+				frame.DurabilityInfo:SetPoint("BOTTOMRIGHT", frame, "BOTTOMLEFT", -1, -1)
+			else
+				frame.DurabilityInfo:SetPoint("TOPLEFT", frame, "TOPRIGHT", 1, 1)
+				frame.DurabilityInfo:SetPoint("BOTTOMLEFT", frame, "BOTTOMRIGHT", 1, -1)
+			end
+			frame.DurabilityInfo:SetFrameLevel(frame:GetFrameLevel()-1)
+			frame.DurabilityInfo:SetBackdrop(SV.media.backdrop.glow)
+			frame.DurabilityInfo:SetBackdropColor(0, 0, 0, 0.5)
+			frame.DurabilityInfo:SetBackdropBorderColor(0, 0, 0, 0.8)
+			frame.DurabilityInfo.bar = CreateFrame("StatusBar", nil, frame.DurabilityInfo)
+			frame.DurabilityInfo.bar:InsetPoints(frame.DurabilityInfo, 2, 2)
+			frame.DurabilityInfo.bar:SetStatusBarTexture(SV.media.statusbar.default)
+			frame.DurabilityInfo.bar:SetOrientation("VERTICAL")
+			frame.DurabilityInfo.bg = frame.DurabilityInfo:CreateTexture(nil, "BORDER")
+			frame.DurabilityInfo.bg:InsetPoints(frame.DurabilityInfo, 2, 2)
+			frame.DurabilityInfo.bg:SetTexture([[Interface\BUTTONS\WHITE8X8]])
+			frame.DurabilityInfo.bg:SetVertexColor("VERTICAL", 0.5, 0.53, 0.55, 0.8, 0.8, 1)
+		end
+	end
+end
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+local function RefreshInspectedGear()
+	if(not SV.GearBuildComplete) then return end
+	if(InCombatLockdown()) then
+		GearHandler:RegisterEvent("PLAYER_REGEN_ENABLED", RefreshInspectedGear)
+		return
+	else
+		GearHandler.WaitingOnInspect = nil
+	end
+
+	local unit = InspectFrame and InspectFrame.unit or "player";
+	if(not unit or (unit and not CanInspect(unit,false))) then return end
+
+  SV:ParseGearSlots(unit, true, true)
+end
+
+local function UpdateLocals()
+  SPEC_SWAP = SV.db.Gear.specialization.enable
+  BG_SWAP = SV.db.Gear.battleground.enable
+	SHOW_CHAR_LEVEL = SV.db.Gear.labels.characterItemLevel
+  SHOW_BAG_LEVEL = SV.db.Gear.labels.inventoryItemLevel
+  SHOW_CHAR_SET = SV.db.Gear.labels.characterGearSet
+  SHOW_BAG_SET = SV.db.Gear.labels.inventoryGearSet
+	SHOW_DURABILITY = SV.db.Gear.durability.enable
+	ONLY_DAMAGED = SV.db.Gear.durability.onlydamaged
+	MAX_LEVEL, AVG_LEVEL = GetAverageItemLevel()
+end
+
+function SV:BuildEquipmentMap()
+  UpdateLocals()
+	for key, gearData in pairs(GEARSET_LISTING) do
+		twipe(gearData);
+	end
+	local set, player, bank, bags, slotIndex, bagIndex, loc, _;
+	for i = 1, GetNumEquipmentSets() do
+		set = GetEquipmentSetInfo(i);
+		GEAR_CACHE = GetEquipmentSetLocations(set);
+		if(GEAR_CACHE) then
+			for key, location in pairs(GEAR_CACHE) do
+				if(type(location) ~= "string") then
+					player, bank, bags, _, slotIndex, bagIndex = EquipmentManager_UnpackLocation(location);
+					if((bank or bags) and (slotIndex and bagIndex)) then
+						loc = format("%d_%d", bagIndex, slotIndex);
+						GEARSET_LISTING[loc] = GEARSET_LISTING[loc] or {};
+            local gslCount = #GEARSET_LISTING[loc] + 1
+						GEARSET_LISTING[loc][gslCount] = set;
+					end
+				end
+			end
+		end
+	end
+end
+
+function SV:UpdateGearInfo()
+	if(not SV.GearBuildComplete) then return end
+	if(InCombatLockdown()) then
+		GearHandler:RegisterEvent("PLAYER_REGEN_ENABLED")
+		return
+	end
+	UpdateLocals()
+  SV:ParseGearSlots("player", false, true, true)
+end
+
+local Gear_UpdateTabs = function()
+	GearHandler.WaitingOnInspect = true
+	SV.Timers:ExecuteTimer(RefreshInspectedGear, 0.2)
+end
+
+function SV:GearSwap()
+	if(InCombatLockdown()) then return; end
+	local gearSpec, gearSet = GetActiveGear()
+	if(not gearSet) then return; end
+
+	if(BG_SWAP and (BG_SET ~= "none" and BG_SET ~= gearSet)) then
+		local inDungeon,dungeonType = IsInInstance()
+		if(inDungeon and dungeonType == "pvp" or dungeonType == "arena") then
+			if BG_SET ~= "none" and BG_SET ~= gearSet then
+				LIVESET = BG_SET;
+				UseEquipmentSet(BG_SET)
+			end
+			return
+		end
+	end
+
+	if(SPEC_SWAP and (SPEC_SET ~= "none" and SPEC_SET ~= gearSet)) then
+		LIVESET = SPEC_SET;
+		UseEquipmentSet(SPEC_SET)
+	end
+end
+
+local MSG_PREFIX = "You have equipped equipment set: "
+
+local GearHandler_OnEvent = function(self, event, ...)
+	if(event == "PLAYER_REGEN_ENABLED") then
+		self:UnregisterEvent("PLAYER_REGEN_ENABLED")
+		if(self.WaitingOnInspect) then
+			SV.Timers:ExecuteTimer(RefreshInspectedGear, 0.2)
+		else
+			SV:UpdateGearInfo()
+		end
+	elseif(event == "EQUIPMENT_SWAP_FINISHED") then
+		if LIVESET then
+			local strMsg = ("%s%s"):format(MSG_PREFIX, LIVESET)
+			SV:AddonMessage(strMsg)
+			LIVESET = nil
+		end
+	else
+		SV:UpdateGearInfo()
+	end
+end
+
+local function InitializeGearInfo()
+	MSG_PREFIX = L["You have equipped equipment set: "]
+  SHOW_CHAR_LEVEL = SV.db.Gear.labels.characterItemLevel
+  SHOW_BAG_LEVEL = SV.db.Gear.labels.inventoryItemLevel
+  SHOW_CHAR_SET = SV.db.Gear.labels.characterGearSet
+  SHOW_BAG_SET = SV.db.Gear.labels.inventoryGearSet
+	SHOW_DURABILITY = SV.db.Gear.durability.enable
+	ONLY_DAMAGED = SV.db.Gear.durability.onlydamaged
+	MAX_LEVEL, AVG_LEVEL = GetAverageItemLevel()
+
+  GearHandler:RegisterEvent("PLAYER_ENTERING_WORLD")
+	GearHandler:RegisterEvent("UPDATE_INVENTORY_DURABILITY")
+	GearHandler:RegisterEvent("PLAYER_EQUIPMENT_CHANGED")
+	GearHandler:RegisterEvent("SOCKET_INFO_UPDATE")
+	GearHandler:RegisterEvent("COMBAT_RATING_UPDATE")
+	GearHandler:RegisterEvent("MASTERY_UPDATE")
+	GearHandler:RegisterEvent("EQUIPMENT_SWAP_FINISHED")
+	GearHandler:SetScript("OnEvent", GearHandler_OnEvent)
+
+	LoadAddOn("Blizzard_InspectUI")
+	SetDisplayStats("Character")
+	SetDisplayStats("Inspect")
+	NewHook('InspectFrame_UpdateTabs', Gear_UpdateTabs)
+	SV.Timers:ExecuteTimer(SV.UpdateGearInfo, 10)
+	SV:GearSwap()
+	SV.GearBuildComplete = true
+end
+
+SV:NewScript(InitializeGearInfo)
diff --git a/SVUI_!Core/system/henchmen.lua b/SVUI_!Core/system/henchmen.lua
new file mode 100644
index 0000000..843c919
--- /dev/null
+++ b/SVUI_!Core/system/henchmen.lua
@@ -0,0 +1,639 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pcall         = _G.pcall;
+local print         = _G.print;
+local ipairs        = _G.ipairs;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local rawset        = _G.rawset;
+local rawget        = _G.rawget;
+local tostring      = _G.tostring;
+local tonumber      = _G.tonumber;
+local getmetatable  = _G.getmetatable;
+local setmetatable  = _G.setmetatable;
+--STRING
+local string        = _G.string;
+local upper         = string.upper;
+local format        = string.format;
+local find          = string.find;
+local match         = string.match;
+local gsub          = string.gsub;
+--MATH
+local math          = _G.math;
+local floor         = math.floor;
+local random        = math.random;
+--TABLE
+local table         = _G.table;
+local tsort         = table.sort;
+local tconcat       = table.concat;
+local tremove       = _G.tremove;
+local twipe         = _G.wipe;
+--BLIZZARD API
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+local GameTooltip           = _G.GameTooltip;
+
+local SV = select(2, ...)
+local L = SV.L
+--[[
+##########################################################
+LOCAL VARS
+##########################################################
+]]--
+local HenchmenFrame = CreateFrame("Frame", "HenchmenFrame", UIParent);
+local STANDARD_TEXT_FONT = _G.STANDARD_TEXT_FONT
+local OPTION_LEFT = [[Interface\Addons\SVUI_!Core\assets\textures\Doodads\HENCHMEN-OPTION-LEFT]];
+local OPTION_RIGHT = [[Interface\Addons\SVUI_!Core\assets\textures\Doodads\HENCHMEN-OPTION-RIGHT]];
+local OPTION_SUB = [[Interface\Addons\SVUI_!Core\assets\textures\Doodads\HENCHMEN-SUBOPTION]];
+local SWITCH = [[Interface\Addons\SVUI_!Core\assets\textures\Doodads\HENCHMEN-MINION-SWITCH]];
+local BUBBLE = [[Interface\Addons\SVUI_!Core\assets\textures\Doodads\HENCHMEN-SPEECH]];
+local SUBOPTIONS = {};
+local HENCHMEN_DATA = {
+	{
+		{40,"Adjust My Colors!","Color Themes","Click here to change your current color theme to one of the default sets."},
+		{40,"Adjust My Frames!","Frame Styles","Click here to change your current frame styles to one of the default sets."},
+		{0,"Adjust My Bars!","Bar Layouts","Click here to change your current actionbar layout to one of the default sets."},
+		{-40,"Adjust My Auras!","Aura Layouts","Click here to change your buff/debuff layout to one of the default sets."},
+		{-40,"Show Me All Options!","Config Screen","Click here to access the entire SVUI configuration."}
+	},
+	{
+		{-40,"Accept Quests","Your minions will automatically accept quests for you", "autoquestaccept"},
+		{-40,"Complete Quests","Your minions will automatically complete quests for you", "autoquestcomplete"},
+		{0,"Select Rewards","Your minions will automatically select quest rewards for you", "autoquestreward"},
+		{40,"Greed Roll","Your minions will automatically roll greed (or disenchant if available) on green quality items for you", "autoRoll"},
+		{40,"Watch Factions","Your minions will automatically change your tracked reputation to the last faction you were awarded points for", "autorepchange"}
+	}
+}
+
+local CALLOUTICON = {
+	[[Interface\Addons\SVUI_!Core\assets\textures\Doodads\HENCHMEN-CALLOUT]],
+	[[Interface\Addons\SVUI_!Core\assets\textures\Doodads\HENCHMEN-WTF]],
+	[[Interface\Addons\SVUI_!Core\assets\textures\Doodads\HENCHMEN-WTF]],
+	[[Interface\Addons\SVUI_!Core\assets\textures\Doodads\HENCHMEN-SRSLY]],
+	[[Interface\Addons\SVUI_!Core\assets\textures\Doodads\HENCHMEN-SRSLY]],
+	[[Interface\Addons\SVUI_!Core\assets\textures\Doodads\HENCHMEN-CALLOUT]],
+	[[Interface\Addons\SVUI_!Core\assets\textures\Doodads\HENCHMEN-CALLOUT]]
+};
+SV.YOUR_HENCHMEN = {
+	{49084,67,113,69,70,73,75}, --Rascal Bot
+	{29404,67,113,69,70,73,75}, --Macabre Marionette
+	{45613,0,5,10,69,10,69}, 	--Bishibosh
+	{34770,70,82,70,82,70,82}, 	--Gilgoblin
+	{45562,69,69,69,69,69,69}, 	--Burgle
+	{37339,60,60,60,60,60,60}, 	--Augh
+	{2323,67,113,69,70,73,75}, 	--Defias Henchman
+}
+--[[
+##########################################################
+SCRIPT HANDLERS
+##########################################################
+]]--
+local ColorFunc = function(self) SV.Setup:ColorTheme(self.value, true); SV:ToggleHenchman() end
+local UnitFunc = function(self) SV.Setup:UnitframeLayout(self.value, true); SV:ToggleHenchman() end
+local BarFunc = function(self) SV.Setup:BarLayout(self.value, true); SV:ToggleHenchman() end
+local AuraFunc = function(self) SV.Setup:Auralayout(self.value, true); SV:ToggleHenchman() end
+local ConfigFunc = function() SV:ToggleConfig(); SV:ToggleHenchman() end
+local speechTimer;
+
+local Tooltip_Show = function(self)
+	GameTooltip:SetOwner(HenchmenFrame,"ANCHOR_TOP",0,12)
+	GameTooltip:ClearLines()
+	GameTooltip:AddLine(self.ttText)
+	GameTooltip:Show()
+end
+
+local Tooltip_Hide = function(self)
+	GameTooltip:Hide()
+end
+
+local Minion_OnMouseUp = function(self)
+	local current = self.getval()
+	if(not current) then
+		self.indicator:SetTexCoord(0,1,0.5,1)
+		self.setval(true)
+	else
+		self.indicator:SetTexCoord(0,1,0,0.5)
+		self.setval(false)
+	end
+end
+
+local Option_OnMouseUp = function(self)
+	--print('Option_OnMouseUp Fired')
+	if(type(self.callback) == "function") then
+		self:callback()
+	--else
+		--print('Option_OnMouseUp No Callbacks')
+	end
+end
+
+local SubOption_OnMouseUp = function(self)
+	if not InCombatLockdown()then
+		local name=self:GetName()
+		for _,frame in pairs(SUBOPTIONS) do
+			frame.anim:Finish()
+			frame:Hide()
+		end
+		if not self.isopen then
+			for i=1, self.suboptions do
+				_G[name.."Sub"..i]:Show()
+				_G[name.."Sub"..i].anim:Play()
+				_G[name.."Sub"..i].anim:Finish()
+			end
+			self.isopen=true
+		else
+			self.isopen=false
+		end
+	end
+end
+
+local function UpdateHenchmanModel(hide)
+	if(not hide and not HenchmenFrameModel:IsShown()) then
+		local models = SV.YOUR_HENCHMEN
+		local mod = random(1,#models)
+		local emod = random(2,7)
+		local id = models[mod][1]
+		local emote = models[mod][emod]
+		HenchmenCalloutFramePic:SetTexture(CALLOUTICON[mod])
+		HenchmenFrameModel:ClearModel()
+		HenchmenFrameModel:SetDisplayInfo(id)
+		HenchmenFrameModel:SetAnimation(emote)
+		HenchmenFrameModel:Show()
+	else
+		HenchmenFrameModel:Hide()
+	end
+end
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+local function CreateMinionOptions(i)
+	local lastIndex = i - 1;
+	local options = HENCHMEN_DATA[2][i]
+	local offsetX = options[1]
+	local option = CreateFrame("Frame", "MinionOptionButton"..i, HenchmenFrame)
+	option:SetSize(148,50)
+
+	if i==1 then
+		option:SetPoint("TOP",_G["MinionOptionButton0"],"BOTTOM",offsetX,-32)
+	else
+		option:SetPoint("TOP",_G["MinionOptionButton"..lastIndex],"BOTTOM",offsetX,-32)
+	end
+
+	local setting = options[4];
+	local dbSet = SV.db.Extras[setting];
+
+	option.getval = function()
+		return SV.db.Extras[setting]
+	end
+	option.setval = function(toggle)
+		SV.db.Extras[setting] = toggle;
+	end
+	SV.Animate:Slide(option,-500,-500)
+	option:SetFrameStrata("DIALOG")
+	option:SetFrameLevel(24)
+	option:EnableMouse(true)
+	option.bg = option:CreateTexture(nil,"BORDER")
+	option.bg:SetPoint("TOPLEFT",option,"TOPLEFT",-4,4)
+	option.bg:SetPoint("BOTTOMRIGHT",option,"BOTTOMRIGHT",4,-24)
+	option.bg:SetTexture(OPTION_LEFT)
+	option.bg:SetVertexColor(1,1,1,0.6)
+	option.txt = option:CreateFontString(nil,"DIALOG")
+	option.txt:InsetPoints(option)
+	option.txt:SetFont(SV.media.font.narrator,12,"NONE")
+	option.txt:SetJustifyH("CENTER")
+	option.txt:SetJustifyV("MIDDLE")
+	option.txt:SetText(options[2])
+	option.txt:SetTextColor(0,0,0)
+	option.txthigh = option:CreateFontString(nil,"HIGHLIGHT")
+	option.txthigh:InsetPoints(option)
+	option.txthigh:SetFont(SV.media.font.narrator,12,"OUTLINE")
+	option.txthigh:SetJustifyH("CENTER")
+	option.txthigh:SetJustifyV("MIDDLE")
+	option.txthigh:SetText(options[2])
+	option.txthigh:SetTextColor(0,1,1)
+	option.ttText = options[3]
+	option.indicator = option:CreateTexture(nil,"OVERLAY")
+	option.indicator:SetSize(100,32)
+	option.indicator:SetPoint("RIGHT", option , "LEFT", -5, 0)
+	option.indicator:SetTexture(SWITCH)
+	if(not dbSet) then
+		option.indicator:SetTexCoord(0,1,0,0.5)
+	else
+		option.indicator:SetTexCoord(0,1,0.5,1)
+	end
+
+	option:SetScript("OnEnter", Tooltip_Show)
+	option:SetScript("OnLeave", Tooltip_Hide)
+	option:SetScript("OnMouseUp", Minion_OnMouseUp)
+end
+
+local function CreateHenchmenOptions(i)
+	local lastIndex = i - 1;
+	local options = HENCHMEN_DATA[1][i]
+	local offsetX = options[1]
+	local option = CreateFrame("Frame", "HenchmenOptionButton"..i, HenchmenFrame)
+	option:SetSize(148,50)
+	if i==1 then
+		option:SetPoint("TOP",_G["HenchmenOptionButton0"],"BOTTOM",offsetX,-32)
+	else
+		option:SetPoint("TOP",_G["HenchmenOptionButton"..lastIndex],"BOTTOM",offsetX,-32)
+	end
+	SV.Animate:Slide(option,500,-500)
+	option:SetFrameStrata("DIALOG")
+	option:SetFrameLevel(24)
+	option:EnableMouse(true)
+	option.bg = option:CreateTexture(nil,"BORDER")
+	option.bg:SetPoint("TOPLEFT",option,"TOPLEFT",-4,4)
+	option.bg:SetPoint("BOTTOMRIGHT",option,"BOTTOMRIGHT",4,-24)
+	option.bg:SetTexture(OPTION_RIGHT)
+	option.bg:SetVertexColor(1,1,1,0.6)
+	option.txt = option:CreateFontString(nil,"DIALOG")
+	option.txt:InsetPoints(option)
+	option.txt:SetFont(SV.media.font.narrator,12,"NONE")
+	option.txt:SetJustifyH("CENTER")
+	option.txt:SetJustifyV("MIDDLE")
+	option.txt:SetText(options[2])
+	option.txt:SetTextColor(0,0,0)
+	option.txthigh = option:CreateFontString(nil,"HIGHLIGHT")
+	option.txthigh:InsetPoints(option)
+	option.txthigh:SetFont(SV.media.font.narrator,12,"OUTLINE")
+	option.txthigh:SetJustifyH("CENTER")
+	option.txthigh:SetJustifyV("MIDDLE")
+	option.txthigh:SetText(options[2])
+	option.txthigh:SetTextColor(0,1,1)
+	option.ttText = options[3]
+	option:SetScript("OnEnter", Tooltip_Show)
+	option:SetScript("OnLeave", Tooltip_Hide)
+end
+
+local function CreateHenchmenSubOptions(buttonIndex,optionIndex)
+	local parent = _G["HenchmenOptionButton"..buttonIndex]
+	local name = format("HenchmenOptionButton%dSub%d", buttonIndex, optionIndex);
+	local calc = 90 * optionIndex;
+	local yOffset = 180 - calc;
+	local frame = CreateFrame("Frame",name,HenchmenFrame)
+	frame:SetSize(122,50)
+	frame:SetPoint("BOTTOMLEFT", parent, "TOPRIGHT", 75, yOffset)
+	frame:SetFrameStrata("DIALOG")
+	frame:SetFrameLevel(24)
+	frame:EnableMouse(true)
+	frame.bg = frame:CreateTexture(nil,"BORDER")
+	frame.bg:SetPoint("TOPLEFT",frame,"TOPLEFT",-12,12)
+	frame.bg:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",12,-18)
+	frame.bg:SetTexture(OPTION_SUB)
+	frame.bg:SetVertexColor(1,1,1,0.6)
+	frame.txt = frame:CreateFontString(nil,"DIALOG")
+	frame.txt:InsetPoints(frame)
+	frame.txt:SetFontObject(SVUI_Font_Default)
+	frame.txt:SetTextColor(1,1,1)
+	frame.txthigh = frame:CreateFontString(nil,"HIGHLIGHT")
+	frame.txthigh:InsetPoints(frame)
+	frame.txthigh:SetFontObject(SVUI_Font_Default)
+	frame.txthigh:SetTextColor(1,1,0)
+	SV.Animate:Slide(frame,500,0)
+	local soCount = #SUBOPTIONS + 1;
+	SUBOPTIONS[soCount] = frame;
+end
+
+local function CreateHenchmenFrame()
+	HenchmenFrame:SetParent(UIParent)
+	HenchmenFrame:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
+	HenchmenFrame:SetWidth(500)
+	HenchmenFrame:SetHeight(500)
+	HenchmenFrame:SetFrameStrata("DIALOG")
+	HenchmenFrame:SetFrameLevel(24)
+	SV.Animate:Slide(HenchmenFrame,0,-500)
+
+	local model = CreateFrame("PlayerModel", "HenchmenFrameModel", HenchmenFrame)
+	model:SetPoint("TOPLEFT",HenchmenFrame,25,-25)
+	model:SetPoint("BOTTOMRIGHT",HenchmenFrame,-25,25)
+	model:SetFrameStrata("DIALOG")
+	model:SetPosition(0,0,0)
+	model:Hide()
+
+	HenchmenFrame:Hide()
+
+	local HenchmenCalloutFrame = CreateFrame("Frame", "HenchmenCalloutFrame", UIParent)
+	HenchmenCalloutFrame:SetPoint("BOTTOM",UIParent,"BOTTOM",100,150)
+	HenchmenCalloutFrame:SetWidth(256)
+	HenchmenCalloutFrame:SetHeight(128)
+	HenchmenCalloutFrame:SetFrameStrata("DIALOG")
+	HenchmenCalloutFrame:SetFrameLevel(24)
+	SV.Animate:Slide(HenchmenCalloutFrame,-356,-278)
+	local HenchmenCalloutFramePic = HenchmenCalloutFrame:CreateTexture("HenchmenCalloutFramePic","ARTWORK")
+	HenchmenCalloutFramePic:SetTexture([[Interface\Addons\SVUI_!Core\assets\textures\Doodads\HENCHMEN-CALLOUT]])
+	HenchmenCalloutFramePic:SetAllPoints(HenchmenCalloutFrame)
+	HenchmenCalloutFrame:Hide()
+
+	local HenchmenFrameBG = CreateFrame("Frame", "HenchmenFrameBG", UIParent)
+	HenchmenFrameBG:SetAllPoints(WorldFrame)
+	HenchmenFrameBG:SetBackdrop({bgFile = [[Interface\BUTTONS\WHITE8X8]]})
+	HenchmenFrameBG:SetBackdropColor(0,0,0,0.9)
+	HenchmenFrameBG:SetFrameStrata("DIALOG")
+	HenchmenFrameBG:SetFrameLevel(22)
+	HenchmenFrameBG:Hide()
+	HenchmenFrameBG:SetScript("OnMouseUp", SV.ToggleHenchman)
+
+	local h_option = CreateFrame("Frame", "HenchmenOptionButton0", HenchmenFrame)
+	h_option:SetSize(148,50)
+	h_option:SetPoint("TOPLEFT",HenchmenFrame,"TOPRIGHT",32,0)
+	SV.Animate:Slide(h_option,500,-500)
+	h_option:SetFrameStrata("DIALOG")
+	h_option:SetFrameLevel(24)
+	h_option:EnableMouse(true)
+	h_option.bg = h_option:CreateTexture(nil,"BORDER")
+	h_option.bg:SetPoint("TOPLEFT",h_option,"TOPLEFT",-4,4)
+	h_option.bg:SetPoint("BOTTOMRIGHT",h_option,"BOTTOMRIGHT",4,-24)
+	h_option.bg:SetTexture(OPTION_RIGHT)
+	h_option.bg:SetVertexColor(1,1,1,0.6)
+	h_option.txt = h_option:CreateFontString(nil,"DIALOG")
+	h_option.txt:InsetPoints(h_option)
+	h_option.txt:SetFont(SV.media.font.narrator,12,"NONE")
+	h_option.txt:SetJustifyH("CENTER")
+	h_option.txt:SetJustifyV("MIDDLE")
+	h_option.txt:SetText("Random Backdrops!")
+	h_option.txt:SetTextColor(0,0,0)
+	h_option.txthigh = h_option:CreateFontString(nil,"HIGHLIGHT")
+	h_option.txthigh:InsetPoints(h_option)
+	h_option.txthigh:SetFont(SV.media.font.narrator,12,"OUTLINE")
+	h_option.txthigh:SetJustifyH("CENTER")
+	h_option.txthigh:SetJustifyV("MIDDLE")
+	h_option.txthigh:SetText("Random Backdrops!")
+	h_option.txthigh:SetTextColor(0,1,1)
+	h_option.ttText = "Set a random texture for all unit frame backdrops!"
+	h_option:SetScript("OnEnter", Tooltip_Show)
+	h_option:SetScript("OnLeave", Tooltip_Hide)
+	h_option:SetScript("OnMouseUp", function() SV.Setup:RandomBackdrops() end)
+
+	local m_option = CreateFrame("Frame", "MinionOptionButton0", HenchmenFrame)
+	m_option:SetSize(148,50)
+	m_option:SetPoint("TOPRIGHT",HenchmenFrame,"TOPLEFT",-32,0)
+	SV.Animate:Slide(m_option,-500,-500)
+	m_option:SetFrameStrata("DIALOG")
+	m_option:SetFrameLevel(24)
+	m_option:EnableMouse(true)
+	m_option.bg = m_option:CreateTexture(nil,"BORDER")
+	m_option.bg:SetPoint("TOPLEFT",m_option,"TOPLEFT",-4,4)
+	m_option.bg:SetPoint("BOTTOMRIGHT",m_option,"BOTTOMRIGHT",4,-24)
+	m_option.bg:SetTexture(OPTION_LEFT)
+	m_option.bg:SetVertexColor(1,1,1,0.6)
+	m_option.txt = m_option:CreateFontString(nil,"DIALOG")
+	m_option.txt:InsetPoints(m_option)
+	m_option.txt:SetFont(SV.media.font.narrator,12,"NONE")
+	m_option.txt:SetJustifyH("CENTER")
+	m_option.txt:SetJustifyV("MIDDLE")
+	m_option.txt:SetText("Comic Popups")
+	m_option.txt:SetTextColor(0,0,0)
+	m_option.txthigh = m_option:CreateFontString(nil,"HIGHLIGHT")
+	m_option.txthigh:InsetPoints(m_option)
+	m_option.txthigh:SetFont(SV.media.font.narrator,12,"OUTLINE")
+	m_option.txthigh:SetJustifyH("CENTER")
+	m_option.txthigh:SetJustifyV("MIDDLE")
+	m_option.txthigh:SetText("Comic Popups")
+	m_option.txthigh:SetTextColor(0,1,1)
+	m_option.ttText = "Toggle the use of comic style popups in combat.";
+	m_option.indicator = m_option:CreateTexture(nil,"OVERLAY")
+	m_option.indicator:SetSize(100,32)
+	m_option.indicator:SetPoint("RIGHT", m_option , "LEFT", -5, 0)
+	m_option.indicator:SetTexture(SWITCH)
+	m_option:SetScript("OnEnter", Tooltip_Show)
+	m_option:SetScript("OnLeave", Tooltip_Hide)
+	m_option:SetScript("OnMouseUp", Minion_OnMouseUp)
+	m_option.getval = function()
+		if(SV.db.FunStuff.comix == 'NONE') then
+			return false
+		else
+			return SV.db.FunStuff.comix
+		end
+	end
+	m_option.setval = function(toggle)
+		local savedToggle = SV.db.FunStuff.comixLastState;
+		if(toggle == true) then
+			SV.db.FunStuff.comix = savedToggle;
+		else
+			SV.db.FunStuff.comix = 'NONE';
+		end
+	end
+
+	if(SV.db.FunStuff.comix == 'NONE') then
+		m_option.indicator:SetTexCoord(0,1,0,0.5)
+	else
+		m_option.indicator:SetTexCoord(0,1,0.5,1)
+	end
+
+	for i=1, 5 do
+		CreateHenchmenOptions(i)
+		CreateMinionOptions(i)
+	end
+	------------------------------------------------------------------------
+	CreateHenchmenSubOptions(1,1)
+	HenchmenOptionButton1Sub1.txt:SetText("KABOOM!")
+	HenchmenOptionButton1Sub1.txthigh:SetText("KABOOM!")
+	HenchmenOptionButton1Sub1.value = "kaboom"
+	HenchmenOptionButton1Sub1.callback = ColorFunc
+	HenchmenOptionButton1Sub1:SetScript("OnMouseUp", Option_OnMouseUp)
+
+	CreateHenchmenSubOptions(1,2)
+	HenchmenOptionButton1Sub2.txt:SetText("Darkness")
+	HenchmenOptionButton1Sub2.txthigh:SetText("Darkness")
+	HenchmenOptionButton1Sub2.value = "dark"
+	HenchmenOptionButton1Sub2.callback = ColorFunc
+	HenchmenOptionButton1Sub2:SetScript("OnMouseUp", Option_OnMouseUp)
+
+	CreateHenchmenSubOptions(1,3)
+	HenchmenOptionButton1Sub3.txt:SetText("Classy")
+	HenchmenOptionButton1Sub3.txthigh:SetText("Classy")
+	HenchmenOptionButton1Sub3.value = "classy"
+	HenchmenOptionButton1Sub3.callback = ColorFunc
+	HenchmenOptionButton1Sub3:SetScript("OnMouseUp", Option_OnMouseUp)
+
+	CreateHenchmenSubOptions(1,4)
+	HenchmenOptionButton1Sub4.txt:SetText("Vintage")
+	HenchmenOptionButton1Sub4.txthigh:SetText("Vintage")
+	HenchmenOptionButton1Sub4.value = "default"
+	HenchmenOptionButton1Sub4.callback = ColorFunc
+	HenchmenOptionButton1Sub4:SetScript("OnMouseUp", Option_OnMouseUp)
+
+	HenchmenOptionButton1.suboptions = 4;
+	HenchmenOptionButton1.isopen = false;
+	HenchmenOptionButton1:SetScript("OnMouseUp",SubOption_OnMouseUp)
+	------------------------------------------------------------------------
+	CreateHenchmenSubOptions(2,1)
+	HenchmenOptionButton2Sub1.txt:SetText("SUPER: Elaborate Frames")
+	HenchmenOptionButton2Sub1.txthigh:SetText("SUPER: Elaborate Frames")
+	HenchmenOptionButton2Sub1.value = "super"
+	HenchmenOptionButton2Sub1.callback = UnitFunc
+	HenchmenOptionButton2Sub1:SetScript("OnMouseUp", Option_OnMouseUp)
+
+	CreateHenchmenSubOptions(2,2)
+	HenchmenOptionButton2Sub2.txt:SetText("Simple: Basic Frames")
+	HenchmenOptionButton2Sub2.txthigh:SetText("Simple: Basic Frames")
+	HenchmenOptionButton2Sub2.value = "simple"
+	HenchmenOptionButton2Sub2.callback = UnitFunc
+	HenchmenOptionButton2Sub2:SetScript("OnMouseUp", Option_OnMouseUp)
+
+	CreateHenchmenSubOptions(2,3)
+	HenchmenOptionButton2Sub3.txt:SetText("Compact: Minimal Frames")
+	HenchmenOptionButton2Sub3.txthigh:SetText("Compact: Minimal Frames")
+	HenchmenOptionButton2Sub3.value = "compact"
+	HenchmenOptionButton2Sub3.callback = UnitFunc
+	HenchmenOptionButton2Sub3:SetScript("OnMouseUp", Option_OnMouseUp)
+
+	HenchmenOptionButton2.suboptions = 3;
+	HenchmenOptionButton2.isopen = false;
+	HenchmenOptionButton2:SetScript("OnMouseUp",SubOption_OnMouseUp)
+	------------------------------------------------------------------------
+	CreateHenchmenSubOptions(3,1)
+	HenchmenOptionButton3Sub1.txt:SetText("One Row: Small Buttons")
+	HenchmenOptionButton3Sub1.txthigh:SetText("One Row: Small Buttons")
+	HenchmenOptionButton3Sub1.value = "default"
+	HenchmenOptionButton3Sub1.callback = BarFunc
+	HenchmenOptionButton3Sub1:SetScript("OnMouseUp", Option_OnMouseUp)
+
+	CreateHenchmenSubOptions(3,2)
+	HenchmenOptionButton3Sub2.txt:SetText("Two Rows: Small Buttons")
+	HenchmenOptionButton3Sub2.txthigh:SetText("Two Rows: Small Buttons")
+	HenchmenOptionButton3Sub2.value = "twosmall"
+	HenchmenOptionButton3Sub2.callback = BarFunc
+	HenchmenOptionButton3Sub2:SetScript("OnMouseUp", Option_OnMouseUp)
+
+	CreateHenchmenSubOptions(3,3)
+	HenchmenOptionButton3Sub3.txt:SetText("One Row: Large Buttons")
+	HenchmenOptionButton3Sub3.txthigh:SetText("One Row: Large Buttons")
+	HenchmenOptionButton3Sub3.value = "onebig"
+	HenchmenOptionButton3Sub3.callback = BarFunc
+	HenchmenOptionButton3Sub3:SetScript("OnMouseUp", Option_OnMouseUp)
+
+	CreateHenchmenSubOptions(3,4)
+	HenchmenOptionButton3Sub4.txt:SetText("Two Rows: Large Buttons")
+	HenchmenOptionButton3Sub4.txthigh:SetText("Two Rows: Large Buttons")
+	HenchmenOptionButton3Sub4.value = "twobig"
+	HenchmenOptionButton3Sub4.callback = BarFunc
+	HenchmenOptionButton3Sub4:SetScript("OnMouseUp", Option_OnMouseUp)
+
+	HenchmenOptionButton3.suboptions = 4;
+	HenchmenOptionButton3.isopen = false;
+	HenchmenOptionButton3:SetScript("OnMouseUp",SubOption_OnMouseUp)
+	------------------------------------------------------------------------
+	CreateHenchmenSubOptions(4,1)
+	HenchmenOptionButton4Sub1.txt:SetText("Icons")
+	HenchmenOptionButton4Sub1.txthigh:SetText("Icons")
+	HenchmenOptionButton4Sub1.value = "default"
+	HenchmenOptionButton4Sub1.callback = AuraFunc
+	HenchmenOptionButton4Sub1:SetScript("OnMouseUp", Option_OnMouseUp)
+
+	CreateHenchmenSubOptions(4,2)
+	HenchmenOptionButton4Sub2.txt:SetText("Bars")
+	HenchmenOptionButton4Sub2.txthigh:SetText("Bars")
+	HenchmenOptionButton4Sub2.value = "bars"
+	HenchmenOptionButton4Sub2.callback = AuraFunc
+	HenchmenOptionButton4Sub2:SetScript("OnMouseUp", Option_OnMouseUp)
+
+	HenchmenOptionButton4.suboptions = 2;
+	HenchmenOptionButton4.isopen = false;
+	HenchmenOptionButton4:SetScript("OnMouseUp",SubOption_OnMouseUp)
+	------------------------------------------------------------------------
+	HenchmenOptionButton5:SetScript("OnMouseUp", ConfigFunc)
+	------------------------------------------------------------------------
+	for _,frame in pairs(SUBOPTIONS) do
+		frame.anim:Finish()
+		frame:Hide()
+	end
+
+	SV.PostLoaded = true
+end
+
+
+function SV:ToggleHenchman()
+	if(InCombatLockdown() or (not SV.HenchmenButton)) then return end
+	if(not SV.PostLoaded) then
+		CreateHenchmenFrame()
+	end
+	if not HenchmenFrame:IsShown()then
+		HenchmenFrameBG:Show()
+
+		UpdateHenchmanModel()
+
+		HenchmenFrame.anim:Finish()
+		HenchmenFrame:Show()
+		HenchmenFrame.anim:Play()
+		HenchmenCalloutFrame.anim:Finish()
+		HenchmenCalloutFrame:Show()
+		HenchmenCalloutFrame:SetAlpha(1)
+		HenchmenCalloutFrame.anim:Play()
+		UIFrameFadeOut(HenchmenCalloutFrame,5)
+		for i=0,5 do
+			local option=_G["HenchmenOptionButton"..i]
+			option.anim:Finish()
+			option:Show()
+			option.anim:Play()
+
+			local minion=_G["MinionOptionButton"..i]
+			minion.anim:Finish()
+			minion:Show()
+			minion.anim:Play()
+			local current = minion.getval()
+			if(not current) then
+				minion.indicator:SetTexCoord(0,1,0,0.5)
+			else
+				minion.indicator:SetTexCoord(0,1,0.5,1)
+			end
+		end
+		SV.HenchmenButton.Icon:SetGradient(unpack(SV.media.gradient.green))
+	else
+		UpdateHenchmanModel(true)
+		for _,frame in pairs(SUBOPTIONS)do
+			frame.anim:Finish()
+			frame:Hide()
+		end
+		HenchmenOptionButton1.isopen=false;
+		HenchmenOptionButton2.isopen=false;
+		HenchmenOptionButton3.isopen=false;
+		HenchmenCalloutFrame.anim:Finish()
+		HenchmenCalloutFrame:Hide()
+		HenchmenFrame.anim:Finish()
+		HenchmenFrame:Hide()
+		HenchmenFrameBG:Hide()
+		for i=0,5 do
+			local option=_G["HenchmenOptionButton"..i]
+			option.anim:Finish()
+			option:Hide()
+
+			local minion=_G["MinionOptionButton"..i]
+			minion.anim:Finish()
+			minion:Hide()
+		end
+		SV.HenchmenButton.Icon:SetGradient("VERTICAL", 0.5, 0.53, 0.55, 0.8, 0.8, 1)
+	end
+end
+--[[
+##########################################################
+BUILD FUNCTION / UPDATE
+##########################################################
+]]--
+local function LockdownCallback()
+	if(HenchmenFrameModel and HenchmenFrame and HenchmenFrame:IsShown()) then
+        HenchmenFrame:Hide()
+        HenchmenFrameBG:Hide()
+    end
+end
+
+local function InitializeHenchmen()
+	SV.HenchmenButton = SV.Dock:SetDockButton("BottomRight", "Call Henchman!", "SVUI_Henchmen", [[Interface\AddOns\SVUI_!Core\assets\textures\Dock\DOCK-ICON-HENCHMAN]])
+	SV.HenchmenButton:SetClickCallbacks(SV.ToggleHenchman, false);
+	SV.Events:OnLock(LockdownCallback);
+end
+
+SV:NewScript(InitializeHenchmen)
diff --git a/SVUI_!Core/system/layout.lua b/SVUI_!Core/system/layout.lua
new file mode 100644
index 0000000..54e9ec7
--- /dev/null
+++ b/SVUI_!Core/system/layout.lua
@@ -0,0 +1,1466 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack    = _G.unpack;
+local select    = _G.select;
+local pairs     = _G.pairs;
+local ipairs    = _G.ipairs;
+local type      = _G.type;
+local error     = _G.error;
+local pcall     = _G.pcall;
+local tostring  = _G.tostring;
+local tonumber  = _G.tonumber;
+local string 	= _G.string;
+local math 		= _G.math;
+--[[ STRING METHODS ]]--
+local format, split, upper, lower = string.format, string.split, string.upper, string.lower;
+--[[ MATH METHODS ]]--
+local min, floor, ceil = math.min, math.floor, math.ceil;
+local parsefloat = math.parsefloat;
+--BLIZZARD API
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+local GameTooltip           = _G.GameTooltip;
+local ReloadUI              = _G.ReloadUI;
+local hooksecurefunc        = _G.hooksecurefunc;
+local IsAltKeyDown          = _G.IsAltKeyDown;
+local IsShiftKeyDown        = _G.IsShiftKeyDown;
+local IsControlKeyDown      = _G.IsControlKeyDown;
+local IsModifiedClick       = _G.IsModifiedClick;
+local PlaySound             = _G.PlaySound;
+local PlaySoundFile         = _G.PlaySoundFile;
+local PlayMusic             = _G.PlayMusic;
+local StopMusic             = _G.StopMusic;
+local UnitName              = _G.UnitName;
+local ToggleFrame           = _G.ToggleFrame;
+local ERR_NOT_IN_COMBAT     = _G.ERR_NOT_IN_COMBAT;
+local RAID_CLASS_COLORS     = _G.RAID_CLASS_COLORS;
+local CUSTOM_CLASS_COLORS   = _G.CUSTOM_CLASS_COLORS;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...);
+local L = SV.L;
+local SVUILib = Librarian("Registry");
+
+local Layout = _G["SVUI_Layout"];
+Layout.Frames = {};
+Layout.Sections = {
+	['ALL'] = {},
+	['GENERAL'] = {}
+};
+
+local CLOAKED_BG = CreateFrame('Frame', nil, UIParent)
+
+local UIPanels = {};
+UIPanels["AchievementFrame"] 				= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["AuctionFrame"] 					= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["ArchaeologyFrame"] 				= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["BattlefieldMinimap"] 				= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = true };
+UIPanels["BarberShopFrame"] 				= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["BlackMarketFrame"] 				= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["CalendarFrame"] 					= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = true };
+UIPanels["CharacterFrame"] 					= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["ClassTrainerFrame"] 				= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["CollectionsJournal"] 				= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["DressUpFrame"] 					= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+--UIPanels["DraenorZoneAbilityFrame"] 		= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["EncounterJournal"] 				= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["FriendsFrame"] 					= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["GMSurveyFrame"] 					= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = true };
+UIPanels["GossipFrame"] 					= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["GuildFrame"] 						= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["GuildBankFrame"] 					= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["GuildRegistrarFrame"] 			= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["GarrisonLandingPage"] 			= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = true };
+UIPanels["GarrisonMissionFrame"] 			= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = true };
+UIPanels["GarrisonBuildingFrame"] 			= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = true };
+UIPanels["GarrisonShipyardFrame"] 			= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = true };
+UIPanels["GarrisonCapacitiveDisplayFrame"]  = { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["HelpFrame"] 						= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = true };
+UIPanels["InterfaceOptionsFrame"] 			= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = true };
+UIPanels["ItemUpgradeFrame"]				= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["KeyBindingFrame"] 				= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = true };
+UIPanels["LFGDungeonReadyPopup"] 			= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = true };
+UIPanels["MacOptionsFrame"] 				= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = true };
+UIPanels["MacroFrame"] 						= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["MailFrame"] 						= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["MerchantFrame"] 					= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["ObjectiveTrackerFrame"] 			= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["PlayerTalentFrame"] 				= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["PetJournalParent"] 				= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["PetStableFrame"] 					= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["PVEFrame"] 						= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["PVPFrame"] 						= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["QuestFrame"] 						= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["QuestLogFrame"] 					= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["RaidBrowserFrame"] 				= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["ReadyCheckFrame"] 				= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = true };
+UIPanels["ReforgingFrame"] 					= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["ReportCheatingDialog"] 			= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["ReportPlayerNameDialog"] 			= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["RolePollPopup"] 					= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = true };
+UIPanels["SpellBookFrame"] 					= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["TabardFrame"] 					= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["TaxiFrame"] 						= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["TimeManagerFrame"] 				= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["TradeSkillFrame"] 				= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["TradeFrame"] 						= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["TransmogrifyFrame"] 				= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["TutorialFrame"] 					= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = true };
+UIPanels["VideoOptionsFrame"] 				= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = true };
+UIPanels["VoidStorageFrame"] 				= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["ScrollOfResurrectionSelectionFrame"] = { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+
+local Sticky = {};
+Sticky.Frames = {};
+Sticky.Frames[1] = SV.Screen;
+Sticky.scripts = Sticky.scripts or {}
+Sticky.rangeX = 15
+Sticky.rangeY = 15
+Sticky.StuckTo = Sticky.StuckTo or {}
+
+local function SnapStickyFrame(frameA, frameB, left, top, right, bottom)
+	local sA, sB = frameA:GetEffectiveScale(), frameB:GetEffectiveScale()
+	local xA, yA = frameA:GetCenter()
+	local xB, yB = frameB:GetCenter()
+	local hA, hB = frameA:GetHeight()  /  2, ((frameB:GetHeight()  *  sB)  /  sA)  /  2
+	local wA, wB = frameA:GetWidth()  /  2, ((frameB:GetWidth()  *  sB)  /  sA)  /  2
+	local newX, newY = xA, yA
+	if not left then left = 0 end
+	if not top then top = 0 end
+	if not right then right = 0 end
+	if not bottom then bottom = 0 end
+	if not xB or not yB or not sB or not sA or not sB then return end
+	xB, yB = (xB * sB)  /  sA, (yB * sB)  /  sA
+	local stickyAx, stickyAy = wA  *  0.75, hA  *  0.75
+	local stickyBx, stickyBy = wB  *  0.75, hB  *  0.75
+	local lA, tA, rA, bA = frameA:GetLeft(), frameA:GetTop(), frameA:GetRight(), frameA:GetBottom()
+	local lB, tB, rB, bB = frameB:GetLeft(), frameB:GetTop(), frameB:GetRight(), frameB:GetBottom()
+	local snap = nil
+	lB, tB, rB, bB = (lB  *  sB)  /  sA, (tB  *  sB)  /  sA, (rB  *  sB)  /  sA, (bB  *  sB)  /  sA
+	if (bA  <= tB and bB  <= tA) then
+		if xA  <= (xB  +  Sticky.rangeX) and xA  >= (xB - Sticky.rangeX) then
+			newX = xB
+			snap = true
+		end
+		if lA  <= (lB  +  Sticky.rangeX) and lA  >= (lB - Sticky.rangeX) then
+			newX = lB  +  wA
+			if frameB == UIParent or frameB == WorldFrame or frameB == SVUIParent then
+				newX = newX  +  4
+			end
+			snap = true
+		end
+		if rA  <= (rB  +  Sticky.rangeX) and rA  >= (rB - Sticky.rangeX) then
+			newX = rB - wA
+			if frameB == UIParent or frameB == WorldFrame or frameB == SVUIParent then
+				newX = newX - 4
+			end
+			snap = true
+		end
+		if lA  <= (rB  +  Sticky.rangeX) and lA  >= (rB - Sticky.rangeX) then
+			newX = rB  +  (wA - left)
+			snap = true
+		end
+		if rA  <= (lB  +  Sticky.rangeX) and rA  >= (lB - Sticky.rangeX) then
+			newX = lB - (wA - right)
+			snap = true
+		end
+	end
+	if (lA  <= rB and lB  <= rA) then
+		if yA  <= (yB  +  Sticky.rangeY) and yA  >= (yB - Sticky.rangeY) then
+			newY = yB
+			snap = true
+		end
+		if tA  <= (tB  +  Sticky.rangeY) and tA  >= (tB - Sticky.rangeY) then
+			newY = tB - hA
+			if frameB == UIParent or frameB == WorldFrame or frameB == SVUIParent then
+				newY = newY - 4
+			end
+			snap = true
+		end
+		if bA  <= (bB  +  Sticky.rangeY) and bA  >= (bB - Sticky.rangeY) then
+			newY = bB  +  hA
+			if frameB == UIParent or frameB == WorldFrame or frameB == SVUIParent then
+				newY = newY  +  4
+			end
+			snap = true
+		end
+		if tA  <= (bB  +  Sticky.rangeY  +  bottom) and tA  >= (bB - Sticky.rangeY  +  bottom) then
+			newY = bB - (hA - top)
+			snap = true
+		end
+		if bA  <= (tB  +  Sticky.rangeY - top) and bA  >= (tB - Sticky.rangeY - top) then
+			newY = tB  +  (hA - bottom)
+			snap = true
+		end
+	end
+	if snap then
+		frameA:ClearAllPoints()
+		frameA:SetPoint("CENTER", UIParent, "BOTTOMLEFT", newX, newY)
+		return true
+	end
+end
+
+local function GetStickyUpdate(frame, xoffset, yoffset, left, top, right, bottom)
+	return function()
+		local x, y = GetCursorPosition()
+		local s = frame:GetEffectiveScale()
+		x, y = x / s, y / s
+		frame:ClearAllPoints()
+		frame:SetPoint("CENTER", UIParent, "BOTTOMLEFT", x + xoffset, y + yoffset)
+		Sticky.StuckTo[frame] = nil
+		for i = 1, #Sticky.Frames do
+			local v = Sticky.Frames[i]
+			if(frame ~= v and frame ~= v:GetParent() and IsShiftKeyDown() and v:IsVisible()) then
+				if SnapStickyFrame(frame, v, left, top, right, bottom) then
+					Sticky.StuckTo[frame] = v
+					break
+				end
+			end
+		end
+	end
+end
+
+local function StickyStartMoving(frame, left, top, right, bottom)
+	local x, y = GetCursorPosition()
+	local aX, aY = frame:GetCenter()
+	local aS = frame:GetEffectiveScale()
+	aX, aY = aX * aS, aY * aS
+	local xoffset, yoffset = (aX - x), (aY - y)
+	Sticky.scripts[frame] = frame:GetScript("OnUpdate")
+	frame:SetScript("OnUpdate", GetStickyUpdate(frame, xoffset, yoffset, left, top, right, bottom))
+end
+
+local function StickyStopMoving(frame)
+	frame:SetScript("OnUpdate", Sticky.scripts[frame])
+	Sticky.scripts[frame] = nil
+	if Sticky.StuckTo[frame] then
+		local frame2 = Sticky.StuckTo[frame]
+		Sticky.StuckTo[frame] = nil
+		return true, frame2
+	else
+		return false, nil
+	end
+end
+local CurrentFrameTarget, UpdateFrameTarget;
+--[[
+##########################################################
+LOCAL FUNCTIONS
+##########################################################
+]]--
+local function Pinpoint(parent)
+    local centerX, centerY = parent:GetCenter()
+    local screenWidth = GetScreenWidth()
+    local screenHeight = GetScreenHeight()
+    local result;
+    if not centerX or not centerY then
+        return "CENTER"
+    end
+    local heightTop = screenHeight  *  0.75;
+    local heightBottom = screenHeight  *  0.25;
+    local widthLeft = screenWidth  *  0.25;
+    local widthRight = screenWidth  *  0.75;
+    if(((centerX > widthLeft) and (centerX < widthRight)) and (centerY > heightTop)) then
+        result = "TOP"
+    elseif((centerX < widthLeft) and (centerY > heightTop)) then
+        result = "TOPLEFT"
+    elseif((centerX > widthRight) and (centerY > heightTop)) then
+        result = "TOPRIGHT"
+    elseif(((centerX > widthLeft) and (centerX < widthRight)) and centerY < heightBottom) then
+        result = "BOTTOM"
+    elseif((centerX < widthLeft) and (centerY < heightBottom)) then
+        result = "BOTTOMLEFT"
+    elseif((centerX > widthRight) and (centerY < heightBottom)) then
+        result = "BOTTOMRIGHT"
+    elseif((centerX < widthLeft) and (centerY > heightBottom) and (centerY < heightTop)) then
+        result = "LEFT"
+    elseif((centerX > widthRight) and (centerY < heightTop) and (centerY > heightBottom)) then
+        result = "RIGHT"
+    else
+        result = "CENTER"
+    end
+    return result
+end
+
+local function CurrentPosition(frame)
+	if not frame then return end
+	local parentName
+	local anchor1, parent, anchor2, x, y = frame:GetPoint()
+	if((not anchor1) or (not anchor2) or (not x) or (not y)) then
+		anchor1, anchor2, x, y = "TOPLEFT", "TOPLEFT", 160, -80
+	end
+	if(not parent or (parent and (not parent:GetName()))) then
+		parentName = "UIParent"
+	else
+		parentName = parent:GetName()
+	end
+	local width, height = frame:GetSize()
+	if((not width) or (not height)) then
+		width, height = 0, 0
+	end
+	return ("%s|%s|%s|%d|%d|%d|%d"):format(anchor1, parentName, anchor2, parsefloat(x), parsefloat(y), parsefloat(width), parsefloat(height))
+end
+
+local function SaveAnchor(frameName)
+	if((not _G[frameName]) or (not Layout.Anchors)) then return end
+	Layout.Anchors[frameName] = CurrentPosition(_G[frameName])
+end
+
+local function LayoutParser(str, frameName)
+	if not str then return end
+	if(str:find("\031")) then
+		if(frameName and _G[frameName] and Layout.Anchors[frameName]) then
+			str = str:gsub("\031", "|")
+			Layout.Anchors[frameName] = str
+		else
+			return split("\031", str)
+		end
+	end
+
+	return split("|", str)
+end
+
+local function GrabUsableRegions(frame)
+	local parent = frame or SV.Screen
+	local right = parent:GetRight()
+	local top = parent:GetTop()
+	local center = parent:GetCenter()
+	return right, top, center
+end
+
+local function CalculateOffsets(frame)
+	if(not CurrentFrameTarget) then return end
+	local right, top, center = GrabUsableRegions()
+	local xOffset, yOffset = CurrentFrameTarget:GetCenter()
+	local screenLeft = (right * 0.33);
+	local screenRight = (right * 0.66);
+	local topMedian = (top * 0.5);
+	local anchor, a1, a2;
+
+	xOffset = xOffset or 0
+	yOffset = yOffset or 0
+
+	if(yOffset >= (top * 0.5)) then
+		a1 = "TOP"
+		yOffset = -(top - CurrentFrameTarget:GetTop())
+	else
+		a1 = "BOTTOM"
+		yOffset = CurrentFrameTarget:GetBottom()
+	end
+
+	if xOffset >= screenRight then
+		a2 = "RIGHT"
+		xOffset = (CurrentFrameTarget:GetRight() - right)
+	elseif xOffset <= screenLeft then
+		a2 = "LEFT"
+		xOffset = CurrentFrameTarget:GetLeft()
+	else
+		a2 = ""
+		xOffset = (xOffset - center)
+	end
+
+	xOffset = parsefloat(xOffset, 0)
+	yOffset = parsefloat(yOffset, 0)
+	anchor = ("%s%s"):format(a1,a2)
+
+	return xOffset, yOffset, anchor
+end
+
+local function ResetAllAlphas()
+	for entry,_ in pairs(Layout.Frames) do
+		local frame = _G[entry]
+		if(frame) then
+			frame:SetAlpha(0.4)
+		end
+	end
+end
+--[[
+##########################################################
+MOVING ANIMATION WIDGET
+##########################################################
+]]--
+local TheHand = CreateFrame("Frame", nil, UIParent)
+TheHand:SetFrameStrata("DIALOG")
+TheHand:SetFrameLevel(99)
+TheHand:SetClampedToScreen(true)
+TheHand:SetSize(128,128)
+TheHand:SetPoint("CENTER")
+TheHand.bg = TheHand:CreateTexture(nil, "OVERLAY")
+TheHand.bg:SetAllPoints(TheHand)
+TheHand.bg:SetTexture([[Interface\AddOns\SVUI_!Core\assets\textures\Doodads\MENTALO-HAND-OFF]])
+TheHand.energy = TheHand:CreateTexture(nil, "OVERLAY")
+TheHand.energy:SetAllPoints(TheHand)
+TheHand.energy:SetTexture([[Interface\AddOns\SVUI_!Core\assets\textures\Doodads\MENTALO-ENERGY]])
+SV.Animate:Orbit(TheHand.energy, 10)
+TheHand.flash = TheHand.energy.anim;
+TheHand.energy:Hide()
+TheHand.elapsedTime = 0;
+TheHand.flash:Stop()
+TheHand:Hide()
+TheHand.UserHeld = false;
+
+local TheHand_OnUpdate = function(self, elapsed)
+	self.elapsedTime = self.elapsedTime  +  elapsed
+	if self.elapsedTime > 0.1 then
+		self.elapsedTime = 0
+		local x, y = GetCursorPosition()
+		local scale = SV.Screen:GetEffectiveScale()
+		self:SetPoint("CENTER", SV.Screen, "BOTTOMLEFT", (x  /  scale)  +  50, (y  /  scale)  +  50)
+	end
+end
+
+function TheHand:Enable()
+	self:Show()
+	self.bg:SetTexture([[Interface\AddOns\SVUI_!Core\assets\textures\Doodads\MENTALO-HAND-ON]])
+	self.energy:Show()
+	self.flash:Play()
+	self:SetScript("OnUpdate", TheHand_OnUpdate)
+end
+
+function TheHand:Disable()
+	self.flash:Stop()
+	self.energy:Hide()
+	self.bg:SetTexture([[Interface\AddOns\SVUI_!Core\assets\textures\Doodads\MENTALO-HAND-OFF]])
+	self:SetScript("OnUpdate", nil)
+	self.elapsedTime = 0
+	self:Hide()
+end
+--[[
+##########################################################
+HANDLERS
+##########################################################
+]]--
+local LayoutUpdateHandler = CreateFrame("Frame", nil)
+
+local function SetPrecisionSizes()
+	if(not CurrentFrameTarget) then return end
+	if(not CurrentFrameTarget.postsize) then
+		SVUI_LayoutPrecision:SetHeight(70)
+		SVUI_LayoutPrecisionWidthAdjust:Hide()
+		SVUI_LayoutPrecisionHeightAdjust:Hide()
+	else
+		local x,y = SVUI_LayoutPrecision:GetCenter()
+		SVUI_LayoutPrecision:ClearAllPoints()
+		SVUI_LayoutPrecision:SetPoint("BOTTOMLEFT", SVUIParent, "BOTTOMLEFT", x,y)
+
+		SVUI_LayoutPrecision:SetHeight(144)
+		local minRange = CurrentFrameTarget.minRange or 0;
+		local maxRange = CurrentFrameTarget.maxRange or 500;
+		local min2Range = CurrentFrameTarget.min2Range or minRange;
+		local max2Range = CurrentFrameTarget.max2Range or maxRange;
+
+		local curWidth = floor(CurrentFrameTarget:GetWidth())
+		local curHeight = floor(CurrentFrameTarget:GetHeight())
+
+		SVUI_LayoutPrecisionWidthAdjust.rangeLow:SetText(minRange);
+		SVUI_LayoutPrecisionWidthAdjust.rangeHigh:SetText(maxRange);
+		SVUI_LayoutPrecisionWidthAdjust:SetMinMaxValues(minRange, maxRange);
+		SVUI_LayoutPrecisionWidthAdjust:SetValue(curWidth);
+		SVUI_LayoutPrecisionWidthAdjust.rangeValue:SetText(curWidth);
+		SVUI_LayoutPrecisionWidthAdjust:Show()
+		SVUI_LayoutPrecisionHeightAdjust.rangeLow:SetText(min2Range);
+		SVUI_LayoutPrecisionHeightAdjust.rangeHigh:SetText(max2Range);
+		SVUI_LayoutPrecisionHeightAdjust:SetMinMaxValues(minRange, maxRange);
+		SVUI_LayoutPrecisionHeightAdjust:SetValue(curHeight);
+		SVUI_LayoutPrecisionHeightAdjust.rangeValue:SetText(curHeight);
+		SVUI_LayoutPrecisionHeightAdjust:Show()
+	end
+end
+
+function Layout:Movable_OnMouseUp()
+	if(not SVUI_LayoutPrecision) then return end;
+	CurrentFrameTarget = self;
+	local xOffset, yOffset, anchor = CalculateOffsets()
+
+	SVUI_LayoutPrecisionSetX.CurrentValue = xOffset;
+	SVUI_LayoutPrecisionSetX:SetText(xOffset)
+
+	SVUI_LayoutPrecisionSetY.CurrentValue = yOffset;
+	SVUI_LayoutPrecisionSetY:SetText(yOffset)
+
+	SVUI_LayoutPrecision.Title:SetText(self.textString)
+end
+
+function Layout:Movable_OnUpdate()
+	local frame = UpdateFrameTarget;
+	if not frame then return end
+	local rightPos, topPos, centerPos = GrabUsableRegions()
+	local centerX, centerY = frame:GetCenter()
+	local calc1 = rightPos * 0.33;
+	local calc2 = rightPos * 0.66;
+	local calc3 = topPos * 0.5;
+	local anchor1, anchor2;
+	local xOffset,yOffset = 0,0;
+	if centerY >= calc3 then
+		anchor1 = "TOP"
+		anchor2 = "BOTTOM"
+		yOffset = -25
+	else
+		anchor1 = "BOTTOM"
+		anchor2 = "TOP"
+		yOffset = 25
+	end
+	if centerX >= calc2 then
+		anchor1 = "RIGHT"
+		anchor2 = "LEFT"
+		xOffset = -25
+	elseif centerX <= calc1 then
+		anchor1 = "LEFT"
+		anchor2 = "RIGHT"
+		xOffset = 25
+	end
+	if(not SVUI_LayoutPrecision) then return end;
+	if CurrentFrameTarget ~= frame then
+		SVUI_LayoutPrecision:Hide()
+		frame:GetScript("OnMouseUp")(frame)
+	else
+		SVUI_LayoutPrecision:ClearAllPoints()
+		SVUI_LayoutPrecision:SetPoint(anchor1, frame, anchor2, xOffset, yOffset)
+		SetPrecisionSizes()
+	end
+	Layout.Movable_OnMouseUp(frame)
+end
+
+function Layout:Movable_OnSizeChanged()
+	if InCombatLockdown()then return end
+	if self.dirtyWidth and self.dirtyHeight then
+		self.Grip:SetSize(self.dirtyWidth, self.dirtyHeight)
+	else
+		self.Grip:SetSize(self:GetSize())
+	end
+end
+
+function Layout:Movable_OnDragStart()
+	if InCombatLockdown() then SV:AddonMessage(ERR_NOT_IN_COMBAT)return end
+	if SV.db.general.stickyFrames then
+		StickyStartMoving(self, self.snapOffset, -2)
+	else
+		self:StartMoving()
+	end
+	UpdateFrameTarget = self;
+	LayoutUpdateHandler:Show()
+	LayoutUpdateHandler:SetScript("OnUpdate", Layout.Movable_OnUpdate)
+	TheHand:Enable()
+	TheHand.UserHeld = true
+end
+
+function Layout:Movable_OnDragStop()
+	if InCombatLockdown()then SV:AddonMessage(ERR_NOT_IN_COMBAT)return end
+	if SV.db.general.stickyFrames then
+		StickyStopMoving(self)
+	else
+		self:StopMovingOrSizing()
+	end
+	local pR, pT, pC = GrabUsableRegions()
+	local cX, cY = self:GetCenter()
+	local newAnchor;
+	if cY >= (pT * 0.5) then
+		newAnchor = "TOP";
+		cY = (-(pT - self:GetTop()))
+	else
+		newAnchor = "BOTTOM"
+		cY = self:GetBottom()
+	end
+	if cX >= (pR * 0.66) then
+		newAnchor = newAnchor.."RIGHT"
+		cX = self:GetRight() - pR
+	elseif cX <= (pR * 0.33) then
+		newAnchor = newAnchor.."LEFT"
+		cX = self:GetLeft()
+	else
+		cX = cX - pC
+	end
+	if self.positionOverride then
+		self.parent:ClearAllPoints()
+		self.parent:SetPoint(self.positionOverride, self, self.positionOverride)
+	end
+
+	self:ClearAllPoints()
+	self:SetPoint(newAnchor, SV.Screen, newAnchor, cX, cY)
+
+	SaveAnchor(self.name)
+
+	if SVUI_LayoutPrecision then
+		Layout.Movable_OnMouseUp(self)
+	end
+
+	UpdateFrameTarget = nil;
+
+	LayoutUpdateHandler:SetScript("OnUpdate", nil)
+	LayoutUpdateHandler:Hide()
+
+	if(self.postdrag ~= nil and type(self.postdrag) == "function") then
+		self:postdrag(Pinpoint(self))
+	end
+	self:SetUserPlaced(false)
+	TheHand.UserHeld = false;
+	TheHand:Disable()
+end
+
+function Layout:Movable_OnShow()
+	self:SetBackdropBorderColor(0, 0.25, 1, 0.5)
+end
+
+function Layout:Movable_OnEnter()
+	if TheHand.UserHeld then return end
+	ResetAllAlphas()
+	self:SetAlpha(1)
+	if(CurrentFrameTarget ~= self) then
+		self.text:SetTextColor(0, 1, 1)
+		self:SetBackdropBorderColor(0, 0.7, 1, 1)
+	end
+	UpdateFrameTarget = self;
+	Layout.Portrait:SetTexture([[Interface\AddOns\SVUI_!Core\assets\textures\Doodads\MENTALO-ON]])
+	TheHand:SetPoint("CENTER", self, "TOP", 0, 0)
+	TheHand:Show()
+end
+
+function Layout:Movable_OnLeave()
+	if TheHand.UserHeld then return end
+	if(CurrentFrameTarget ~= self) then
+		self.text:SetTextColor(1, 1, 1)
+		self:SetBackdropBorderColor(0, 0.25, 1, 0.5)
+	end
+	Layout.Portrait:SetTexture([[Interface\AddOns\SVUI_!Core\assets\textures\Doodads\MENTALO-OFF]])
+	TheHand:Hide()
+	if(not SVUI_LayoutPrecision) then return end;
+	if(CurrentFrameTarget ~= self and not SVUI_LayoutPrecision:IsShown()) then
+		self:SetAlpha(0.4)
+	end
+end
+
+function Layout:Movable_OnMouseDown(button)
+	if button == "RightButton" then
+		TheHand.UserHeld = false;
+		if(SV.db.general.stickyFrames) then
+			StickyStopMoving(self)
+		else
+			self:StopMovingOrSizing()
+		end
+		if(not SVUI_LayoutPrecision) then return end;
+		CurrentFrameTarget = self
+		self.text:SetTextColor(0.2, 1, 0)
+		self:SetBackdropBorderColor(0, 1, 0, 1)
+		Layout:Movable_OnUpdate()
+		SVUI_LayoutPrecision:Show()
+	end
+end
+
+function Layout:Movable_HasMoved()
+	if(Layout.Anchors and Layout.Anchors[self.name]) then
+		return true
+	else
+		return false
+	end
+end
+--[[
+##########################################################
+CONSTRUCTS
+##########################################################
+]]--
+local function SetNewAnchor(frame, moveName, title, postDragFunc)
+	if((not frame) or (not moveName) or (Layout.Frames[moveName] ~= nil)) then return end
+
+	Layout.Frames[moveName] = {
+		text = title,
+		postdrag = postDragFunc,
+		layoutString = CurrentPosition(frame),
+	}
+	Layout.Sections.ALL[moveName] = true;
+	local currentCategory = SVUILib.CURRENT_SCHEMA;
+	if(currentCategory) then
+		currentCategory = upper(currentCategory)
+		if(not Layout.Sections[currentCategory]) then
+			Layout.Sections[currentCategory] = {}
+		end
+		Layout.Sections[currentCategory][moveName] = true;
+	end
+
+	local grip = CreateFrame("Button", moveName, SV.Screen)
+	grip:SetFrameLevel(frame:GetFrameLevel() + 1)
+	grip:SetClampedToScreen(true)
+	grip:SetFrameStrata("DIALOG")
+
+	grip.parent = frame;
+	grip.name = moveName;
+	grip.textString = title;
+	grip.postdrag = postDragFunc;
+	grip.HasMoved = Layout.Movable_HasMoved
+	grip.snapOffset = frame.snapOffset or -2;
+
+	local anchor1, anchorParent, anchor2, xPos, yPos
+	if(Layout.Anchors and Layout.Anchors[moveName] and (type(Layout.Anchors[moveName]) == "string")) then
+		anchor1, anchorParent, anchor2, xPos, yPos = LayoutParser(Layout.Anchors[moveName])
+	else
+		anchor1, anchorParent, anchor2, xPos, yPos = LayoutParser(CurrentPosition(frame))
+	end
+
+	local width, height = frame:GetSize()
+	grip:SetPoint(anchor1, anchorParent, anchor2, xPos, yPos)
+	grip:SetSize(width, height)
+	grip:SetStyle("!_Frame", "Transparent")
+	grip:SetAlpha(0.4)
+
+	frame:SetScript("OnSizeChanged", Layout.Movable_OnSizeChanged)
+	frame.Grip = grip;
+	frame:ClearAllPoints()
+	frame:SetPoint(anchor1, grip, anchor1, 0, 0)
+
+	local mtext = grip:CreateFontString(nil, "OVERLAY")
+	mtext:SetFontObject(SVUI_Font_Default)
+	mtext:SetJustifyH("CENTER")
+	mtext:SetPoint("CENTER")
+	mtext:SetText(title or moveName)
+	mtext:SetTextColor(1, 1, 1)
+
+	grip:SetFontString(mtext)
+	grip.text = mtext;
+
+	grip:RegisterForDrag("LeftButton", "RightButton")
+
+	grip:SetScript("OnMouseUp", Layout.Movable_OnMouseUp)
+	grip:SetScript("OnDragStart", Layout.Movable_OnDragStart)
+	grip:SetScript("OnDragStop", Layout.Movable_OnDragStop)
+	grip:SetScript("OnShow", Layout.Movable_OnShow)
+	grip:SetScript("OnEnter", Layout.Movable_OnEnter)
+	grip:SetScript("OnMouseDown", Layout.Movable_OnMouseDown)
+	grip:SetScript("OnLeave", Layout.Movable_OnLeave)
+
+	grip:SetMovable(true)
+	grip:Hide()
+
+	Sticky.Frames[#Sticky.Frames + 1] = grip;
+end
+
+function Layout:Reset(request, bypass)
+	if(request == "" or request == nil) then
+		for frameName, frameData in pairs(self.Frames) do
+			local frame = _G[frameName];
+			if(frameData.layoutString) then
+				local anchor1, anchorParent, anchor2, xPos, yPos, width, height = LayoutParser(frameData.layoutString)
+				frame:ClearAllPoints()
+				frame:SetPoint(anchor1, anchorParent, anchor2, xPos, yPos)
+				if(not bypass) then
+					if(frameData.postdrag and (type(frameData.postdrag) == "function")) then
+						frameData.postdrag(frame, Pinpoint(frame))
+					end
+				end
+			end
+			if(self.Anchors and self.Anchors[frameName]) then
+				self.Anchors[frameName] = nil
+			end
+		end
+	else
+		for frameName, frameData in pairs(self.Frames) do
+			if(frameData.layoutString and (request == frameName or request == frameData.text)) then
+				local frame = _G[frameName]
+				local anchor1, anchorParent, anchor2, xPos, yPos, width, height = LayoutParser(frameData.layoutString)
+				frame:ClearAllPoints()
+				frame:SetPoint(anchor1, anchorParent, anchor2, xPos, yPos)
+				if(not bypass) then
+					if(frameData.postdrag and (type(frameData.postdrag) == "function")) then
+						frameData.postdrag(frame, Pinpoint(frame))
+					end
+				end
+				if(self.Anchors and self.Anchors[frameName]) then
+					self.Anchors[frameName] = nil
+				end
+				break
+			end
+		end
+	end
+end
+
+function Layout:Update()
+	self.Anchors = SV.db.LAYOUT or {}
+	for frameName, frameData in pairs(self.Frames) do
+		--print('Layout:Update(' .. frameName .. ')')
+		local frame = _G[frameName];
+		local anchor1, parent, anchor2, x, y, width, height;
+		if frame then
+			if (self.Anchors and self.Anchors[frameName] and (type(self.Anchors[frameName]) == "string")) then
+				anchor1, parent, anchor2, x, y, width, height = LayoutParser(self.Anchors[frameName], frameName)
+				frame:ClearAllPoints()
+				frame:SetPoint(anchor1, parent, anchor2, x, y)
+			elseif(frameData.layoutString) then
+				anchor1, parent, anchor2, x, y, width, height = LayoutParser(frameData.layoutString, frameName)
+				frame:ClearAllPoints()
+				frame:SetPoint(anchor1, parent, anchor2, x, y)
+			end
+		end
+	end
+end
+
+function Layout:Toggle(arg)
+	if(InCombatLockdown()) then return end
+	local enabled = false;
+	local aceConfig = LibStub("AceConfigDialog-3.0")
+	if(aceConfig and SV.OptionsLoaded) then
+		aceConfig:Close(SV.NameID)
+		GameTooltip:Hide()
+	end
+	SVUI_LayoutPrecision:Hide()
+	for frameName, _ in pairs(self.Frames) do
+		local frame = _G[frameName];
+		if(frame) then frame:Hide() end
+	end
+	if(self:IsShown()) then
+		SV:AddonMessage('Frames are now locked!')
+		self:Hide()
+	else
+		--print(arg)
+		arg = arg or 'ALL';
+		local category = upper(arg);
+		if(category == 'HELP') then
+			SV:AddonMessage('You can use the following commands to specify which frame-groups you want to move at a time.')
+			for section,_ in pairs(self.Sections) do
+		        print('/sv move |cff00FF00' .. lower(section) .. '|r')
+			end
+		else
+			SV:AddonMessage('Frames are now unlocked!')
+			SV:AddonMessage('To see move commands type |cff00FF00/sv move help|r.')
+			local list = self.Sections[category]
+			for frameName, _ in pairs(list) do
+				local frame = _G[frameName];
+				if(frame) then frame:Show() end
+			end
+			self:Show()
+		end
+	end
+	-- for section, _ in pairs(self.Sections) do
+	-- 	print(section)
+	-- end
+end
+--[[
+##########################################################
+ALIGNMENT GRAPH
+##########################################################
+]]--
+local Graph = {}
+
+function Graph:Toggle(enabled)
+	if((not self.Grid) or (self.CellSize ~= SV.db.general.graphSize)) then
+		self:UpdateAllReports()
+	end
+	if(not enabled) then
+    self.Grid:Hide()
+	else
+		self.Grid:Show()
+	end
+end
+
+function Graph:UpdateAllReports()
+	-- for the record, this SUCKED trying to optimize the math
+	local cellSize = SV.db.general.graphSize
+	self.CellSize = cellSize
+
+	self.Grid = CreateFrame('Frame', nil, UIParent)
+	self.Grid:SetAllPoints(SV.Screen)
+	self.Grid:SetFrameStrata('BACKGROUND')
+	self.Grid:SetFrameLevel(1)
+
+	local width = SV.Screen:GetWidth();
+	local height = SV.Screen:GetHeight();
+	local ratio = width / height;
+	local size = height * ratio;
+	local interval = size / cellSize;
+	local halfWidth = ceil(cellSize * 0.5);
+	local halfHeight = floor((height / interval) * 0.5);
+	--print('-------')print(width)print(height)
+	--print('-------')print(cellSize)
+	--print('-------')print(size)print(interval)
+	--print('-------')print(halfWidth)print(halfHeight)
+
+	for i = 0, cellSize do
+		local mod = i*interval;
+
+		local xGrid = self.Grid:CreateTexture(nil, 'BACKGROUND')
+		local yGrid = self.Grid:CreateTexture(nil, 'BACKGROUND')
+		if(i == halfWidth) then
+			xGrid:SetColorTexture(0, 1, 0, 0.8)
+		else
+			xGrid:SetColorTexture(0.1, 0.1, 0.1, 0.8)
+		end
+		if(i == halfHeight) then
+			yGrid:SetColorTexture(0, 1, 0, 0.8)
+		else
+			yGrid:SetColorTexture(0.1, 0.1, 0.1, 0.8)
+		end
+
+		xGrid:SetPoint("TOPLEFT", self.Grid, "TOPLEFT", (mod - 0.5), 0)
+		xGrid:SetPoint('BOTTOMRIGHT', self.Grid, 'BOTTOMLEFT', (mod + 0.5), 0)
+		yGrid:SetPoint("TOPLEFT", self.Grid, "TOPLEFT", 0, -mod + 0.5)
+		yGrid:SetPoint('BOTTOMRIGHT', self.Grid, 'TOPRIGHT', 0, -(mod + 0.5))
+	end
+
+	self.Grid:Hide()
+end
+
+function Graph:Initialize()
+	self:UpdateAllReports()
+end
+--[[
+##########################################################
+SCRIPT AND EVENT HANDLERS
+##########################################################
+]]--
+local XML_Layout_OnEvent = function(self)
+	if self:IsShown() then
+		self:Hide()
+		Layout:Toggle()
+	end
+end
+
+local XML_LayoutGridButton_OnClick = function(self)
+	local enabled = true
+	if(Graph.Grid and Graph.Grid:IsShown()) then
+		enabled = false
+	end
+
+	Graph:Toggle(enabled)
+end
+
+local XML_LayoutLockButton_OnClick = function(self)
+	Graph:Toggle()
+	Layout:Toggle()
+	if(SV.OptionsLoaded and SV.OptionsStandby) then
+		SV.OptionsStandby = nil
+		LibStub("AceConfigDialog-3.0"):Open(SV.NameID)
+	end
+end
+
+local SVUI_LayoutPrecisionResetButton_OnClick = function(self)
+	if(not CurrentFrameTarget) then return end
+	local name = CurrentFrameTarget.name
+	Layout:Reset(name)
+end
+
+local XML_LayoutPrecisionInputX_EnterPressed = function(self)
+	local current = tonumber(self:GetText())
+	if(current) then
+		if(CurrentFrameTarget) then
+			local xOffset, yOffset, anchor = CalculateOffsets()
+			yOffset = tonumber(SVUI_LayoutPrecisionSetY.CurrentValue)
+			CurrentFrameTarget:ClearAllPoints()
+			CurrentFrameTarget:SetPoint(anchor, SVUIParent, anchor, current, yOffset)
+			SaveAnchor(CurrentFrameTarget.name)
+		end
+		self.CurrentValue = current
+	end
+	self:SetText(floor((self.CurrentValue or 0) + 0.5))
+	EditBox_ClearFocus(self)
+end
+
+local XML_LayoutPrecisionInputY_EnterPressed = function(self)
+	local current = tonumber(self:GetText())
+	if(current) then
+		if(CurrentFrameTarget) then
+			local xOffset, yOffset, anchor = CalculateOffsets()
+			xOffset = tonumber(SVUI_LayoutPrecisionSetX.CurrentValue)
+			CurrentFrameTarget:ClearAllPoints()
+			CurrentFrameTarget:SetPoint(anchor, SVUIParent, anchor, xOffset, current)
+			SaveAnchor(CurrentFrameTarget.name)
+		end
+		self.CurrentValue = current
+	end
+	self:SetText(floor((self.CurrentValue or 0) + 0.5))
+	EditBox_ClearFocus(self)
+end
+
+local XML_LayoutPrecisionWidthAdjust_OnValueChanged = function(self, widthValue)
+	self.rangeValue:SetText(floor(widthValue))
+	if(CurrentFrameTarget and CurrentFrameTarget.postsize) then
+		local frame = CurrentFrameTarget.parent;
+		local heightValue = SVUI_LayoutPrecisionHeightAdjust:GetValue();
+		CurrentFrameTarget.postsize(frame, widthValue, heightValue);
+	end
+end
+
+local XML_LayoutPrecisionHeightAdjust_OnValueChanged = function(self, heightValue)
+	self.rangeValue:SetText(floor(heightValue))
+	if(CurrentFrameTarget and CurrentFrameTarget.postsize) then
+		local frame = CurrentFrameTarget.parent;
+		local widthValue = SVUI_LayoutPrecisionWidthAdjust:GetValue();
+		CurrentFrameTarget.postsize(frame, widthValue, heightValue);
+	end
+end
+--[[
+##########################################################
+DRAGGABLES
+##########################################################
+]]--
+local Dragger = CreateFrame("Frame", nil);
+Dragger.Frames = {};
+
+local function SetDraggablePoint(frame, data)
+	if((not frame) or (not data)) then return; end
+	local frameName = frame:GetName()
+	local point = Dragger.Frames[frameName];
+	if(point and (type(point) == "string") and (point ~= 'TBD')) then
+		local anchor1, parent, anchor2, x, y = LayoutParser(point);
+		data.cansetpoint = true;
+		data.snapped = false;
+		frame:ClearAllPoints();
+		frame:SetPoint(anchor1, parent, anchor2, x, y);
+	end
+end
+
+local function SaveCurrentPosition(frame)
+	if not frame then return end
+	local result;
+	local frameName = frame:GetName()
+	local anchor1, parent, anchor2, x, y = frame:GetPoint()
+	if((not anchor1) or (not anchor2) or (not x) or (not y)) then
+		result = "TBD";
+	else
+		local parentName
+		if(not parent or (parent and (not parent:GetName()))) then
+			parentName = "UIParent"
+		else
+			parentName = parent:GetName()
+		end
+		result = ("%s|%s|%s|%d|%d"):format(anchor1, parentName, anchor2, parsefloat(x), parsefloat(y))
+	end
+	if(SV.db.general.saveDraggable) then
+		SV.private.Draggables[frameName] = result
+		Dragger.Frames = SV.private.Draggables
+	else
+		Dragger.Frames[frameName] = result
+	end
+end
+
+local DraggerFrame_OnDragStart = function(self)
+	if(not self:IsMovable()) then return; end
+	self:StartMoving();
+	local data = UIPanels[self:GetName()];
+	if(data) then
+		data.moving = true;
+		data.snapped = false;
+		data.canupdate = false;
+	end
+end
+
+local DraggerFrame_OnDragStop = function(self)
+	if(not self:IsMovable()) then return; end
+	self:StopMovingOrSizing();
+	local data = UIPanels[self:GetName()];
+	if(data) then
+		data.moving = false;
+		data.snapped = false;
+		data.canupdate = true;
+		SaveCurrentPosition(self);
+	end
+end
+
+local _hook_DraggerFrame_OnShow = function(self)
+	if(InCombatLockdown() or (not self:IsMovable())) then return; end
+	local data = UIPanels[self:GetName()];
+	if(data and (not data.snapped)) then
+		SetDraggablePoint(self, data)
+	end
+end
+
+local _hook_DraggerFrame_OnHide = function(self)
+	if(InCombatLockdown() or (not self:IsMovable())) then return; end
+	local data = UIPanels[self:GetName()];
+	if(data) then
+		data.moving = false;
+		data.snapped = false;
+		data.canupdate = true;
+	end
+end
+
+local _hook_DraggerFrame_OnUpdate = function(self)
+	if(InCombatLockdown()) then return; end
+	local data = UIPanels[self:GetName()];
+	if(data and (not data.moving) and (not data.snapped)) then
+		SetDraggablePoint(self, data)
+	end
+end
+
+local _hook_DraggerFrame_OnSetPoint = function(self)
+	if(not self:IsMovable()) then return; end
+	local data = UIPanels[self:GetName()];
+	if(data and (not data.moving)) then
+		if(not data.cansetpoint) then
+			data.snapped = true;
+			data.canupdate = false;
+		end
+	end
+end
+
+local _hook_UIParent_ManageFramePositions = function()
+	for frameName, point in pairs(Dragger.Frames) do
+		local data = UIPanels[frameName]
+		if(data and (not data.snapped)) then
+			SetDraggablePoint(_G[frameName], data)
+		end
+	end
+end
+
+local DraggerEventHandler = function(self, event, ...)
+	if(InCombatLockdown()) then return end
+
+	local noMoreChanges = true;
+	local allCentered = SV.db.screen.multiMonitor
+
+	for frameName, data in pairs(UIPanels) do
+		if(not self.Frames[frameName] or (self.Frames[frameName] and type(self.Frames[frameName]) ~= 'string')) then
+			self.Frames[frameName] = 'TBD'
+			noMoreChanges = false;
+		end
+		if(not data.initialized) then
+			local frame = _G[frameName]
+			if(frame) then
+				frame:EnableMouse(true)
+
+				if(frameName == "LFGDungeonReadyPopup") then
+					LFGDungeonReadyDialog:EnableMouse(false)
+				end
+
+				frame:SetMovable(true)
+				frame:RegisterForDrag("LeftButton")
+				frame:SetClampedToScreen(true)
+
+				if(allCentered) then
+					frame:ClearAllPoints()
+					frame:SetPoint('TOP', SV.Screen, 'TOP', 0, -180)
+					data.centered = true
+				end
+
+				if(self.Frames[frameName] == 'TBD') then
+					SaveCurrentPosition(frame);
+				end
+
+				data.canupdate = true
+
+				frame:SetScript("OnDragStart", DraggerFrame_OnDragStart)
+				frame:SetScript("OnDragStop", DraggerFrame_OnDragStop)
+
+				frame:HookScript("OnUpdate", _hook_DraggerFrame_OnUpdate)
+				hooksecurefunc(frame, "SetPoint", _hook_DraggerFrame_OnSetPoint)
+
+				if(SV.db.general.saveDraggable) then
+					frame:HookScript("OnShow", _hook_DraggerFrame_OnShow)
+					frame:HookScript("OnHide", _hook_DraggerFrame_OnHide)
+				end
+
+				data.initialized = true
+			end
+			noMoreChanges = false;
+		end
+	end
+
+	if(noMoreChanges) then
+		self.EventsActive = false;
+		self:UnregisterEvent("ADDON_LOADED")
+		self:UnregisterEvent("LFG_UPDATE")
+		self:UnregisterEvent("ROLE_POLL_BEGIN")
+		self:UnregisterEvent("READY_CHECK")
+		self:UnregisterEvent("UPDATE_WORLD_STATES")
+		self:UnregisterEvent("WORLD_STATE_TIMER_START")
+		self:UnregisterEvent("WORLD_STATE_UI_TIMER_UPDATE")
+		self:SetScript("OnEvent", nil)
+	end
+end
+
+--[[METHODS]]--
+
+function Dragger:New(frameName)
+	if(not UIPanels[frameName]) then
+		UIPanels[frameName] = { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+		if(not self.EventsActive) then
+			self:RegisterEvent("ADDON_LOADED")
+			self:RegisterEvent("LFG_UPDATE")
+			self:RegisterEvent("ROLE_POLL_BEGIN")
+			self:RegisterEvent("READY_CHECK")
+			self:RegisterEvent("UPDATE_WORLD_STATES")
+			self:RegisterEvent("WORLD_STATE_TIMER_START")
+			self:RegisterEvent("WORLD_STATE_UI_TIMER_UPDATE")
+			self:SetScript("OnEvent", DraggerEventHandler)
+			self.EventsActive = true;
+		end
+	end
+end
+
+function Dragger:SetPositions()
+	for frameName, point in pairs(Dragger.Frames) do
+		local data = UIPanels[frameName]
+		if(data and (not data.snapped)) then
+			SetDraggablePoint(_G[frameName], point, data)
+		end
+	end
+end
+
+function Dragger:Reset()
+	if(SV.db.general.saveDraggable) then
+		for frameName, data in pairs(UIPanels) do
+			if(SV.private.Draggables[frameName]) then
+				SV.private.Draggables[frameName] = nil
+			end
+			data.initialized = nil
+		end
+		self.Frames = SV.private.Draggables
+	else
+		for frameName, data in pairs(UIPanels) do
+			if(self.Frames[frameName]) then
+				self.Frames[frameName] = nil
+			end
+			data.initialized = nil
+		end
+	end
+
+	if(not self.EventsActive) then
+		self:RegisterEvent("ADDON_LOADED")
+		self:RegisterEvent("LFG_UPDATE")
+		self:RegisterEvent("ROLE_POLL_BEGIN")
+		self:RegisterEvent("READY_CHECK")
+		self:RegisterEvent("UPDATE_WORLD_STATES")
+		self:RegisterEvent("WORLD_STATE_TIMER_START")
+		self:RegisterEvent("WORLD_STATE_UI_TIMER_UPDATE")
+		self:SetScript("OnEvent", DraggerEventHandler)
+		self.EventsActive = true;
+	end
+
+	ReloadUI()
+end
+--[[
+##########################################################
+LOAD BY TRIGGER
+##########################################################
+]]--
+local function InitializeMovables()
+	CLOAKED_BG:SetAllPoints(SV.Screen);
+	CLOAKED_BG:SetParent(Layout);
+	CLOAKED_BG:SetFrameStrata('BACKGROUND')
+	CLOAKED_BG:SetFrameLevel(0)
+	CLOAKED_BG:SetBackdrop({
+		bgFile = [[Interface\BUTTONS\WHITE8X8]],
+	    tile = false,
+	    tileSize = 0,
+	    edgeFile = [[Interface\AddOns\SVUI_!Core\assets\textures\EMPTY]],
+	    edgeSize = 1,
+	    insets =
+	    {
+	        left = 0,
+	        right = 0,
+	        top = 0,
+	        bottom = 0,
+	    },
+	});
+	CLOAKED_BG:SetBackdropColor(0,0,0,0.15);
+
+	Layout.Anchors = SV.db.LAYOUT or {}
+	--Layout:SetPanelColor("yellow")
+	Layout:RegisterForDrag("LeftButton")
+	Layout:RegisterEvent("PLAYER_REGEN_DISABLED")
+	Layout:SetScript("OnEvent", XML_Layout_OnEvent)
+	Layout.Portrait:SetTexture([[Interface\AddOns\SVUI_!Core\assets\textures\Doodads\MENTALO-OFF]])
+
+	SVUI_LayoutLockButton:SetSize(110, 25)
+	SVUI_LayoutLockButton.Left:SetAlpha(0)
+	SVUI_LayoutLockButton.Middle:SetAlpha(0)
+	SVUI_LayoutLockButton.Right:SetAlpha(0)
+	SVUI_LayoutLockButton:SetNormalTexture("")
+	SVUI_LayoutLockButton:SetPushedTexture("")
+	SVUI_LayoutLockButton:SetPushedTexture("")
+	SVUI_LayoutLockButton:SetDisabledTexture("")
+	SVUI_LayoutLockButton:RemoveTextures()
+	SVUI_LayoutLockButton:SetFrameLevel(SVUI_LayoutLockButton:GetFrameLevel() + 1)
+	SVUI_LayoutLockButton.texture = SVUI_LayoutLockButton:CreateTexture(nil, "BORDER")
+	SVUI_LayoutLockButton.texture:SetSize(110, 50)
+	SVUI_LayoutLockButton.texture:SetPoint("CENTER", SVUI_LayoutLockButton, "CENTER", 0, -4)
+	SVUI_LayoutLockButton.texture:SetTexture([[Interface\AddOns\SVUI_!Core\assets\textures\Doodads\QUESTION]])
+	SVUI_LayoutLockButton.texture:SetVertexColor(1, 1, 1)
+	SVUI_LayoutLockButton.texture:SetTexCoord(1, 0, 1, 1, 0, 0, 0, 1)
+	SVUI_LayoutLockButton.text = SVUI_LayoutLockButton:CreateFontString(nil, "OVERLAY")
+	SVUI_LayoutLockButton.text:SetFont(SV.media.font.caps, 18, "OUTLINE")
+	SVUI_LayoutLockButton.text:SetTextColor(1, 0.5, 0)
+	SVUI_LayoutLockButton.text:SetPoint("CENTER")
+	SVUI_LayoutLockButton.text:SetText("Lock")
+	SVUI_LayoutLockButton:SetScript("OnEnter", function(this)
+		this.texture:SetVertexColor(0.1, 0.1, 0.1)
+		this.text:SetTextColor(1, 1, 0)
+	end)
+	SVUI_LayoutLockButton:SetScript("OnLeave", function(this)
+		this.texture:SetVertexColor(1, 1, 1)
+		this.text:SetTextColor(1, 0.5, 0)
+	end)
+	SVUI_LayoutLockButton:SetScript("OnClick", XML_LayoutLockButton_OnClick)
+
+	SVUI_LayoutGridButton:SetSize(110, 25)
+	SVUI_LayoutGridButton.Left:SetAlpha(0)
+	SVUI_LayoutGridButton.Middle:SetAlpha(0)
+	SVUI_LayoutGridButton.Right:SetAlpha(0)
+	SVUI_LayoutGridButton:SetNormalTexture("")
+	SVUI_LayoutGridButton:SetPushedTexture("")
+	SVUI_LayoutGridButton:SetPushedTexture("")
+	SVUI_LayoutGridButton:SetDisabledTexture("")
+	SVUI_LayoutGridButton:RemoveTextures()
+	SVUI_LayoutGridButton:SetFrameLevel(SVUI_LayoutGridButton:GetFrameLevel() + 1)
+	SVUI_LayoutGridButton.texture = SVUI_LayoutGridButton:CreateTexture(nil, "BORDER")
+	SVUI_LayoutGridButton.texture:SetSize(110, 50)
+	SVUI_LayoutGridButton.texture:SetPoint("CENTER", SVUI_LayoutGridButton, "CENTER", 0, -4)
+	SVUI_LayoutGridButton.texture:SetTexture([[Interface\AddOns\SVUI_!Core\assets\textures\Doodads\QUESTION]])
+	SVUI_LayoutGridButton.texture:SetVertexColor(1, 1, 1)
+	SVUI_LayoutGridButton.text = SVUI_LayoutGridButton:CreateFontString(nil, "OVERLAY")
+	SVUI_LayoutGridButton.text:SetFont(SV.media.font.caps, 18, "OUTLINE")
+	SVUI_LayoutGridButton.text:SetTextColor(1, 0.5, 0)
+	SVUI_LayoutGridButton.text:SetPoint("CENTER")
+	SVUI_LayoutGridButton.text:SetText("Grid")
+	SVUI_LayoutGridButton:SetScript("OnEnter", function(this)
+		this.texture:SetVertexColor(0.1, 0.1, 0.1)
+		this.text:SetTextColor(1, 1, 0)
+	end)
+	SVUI_LayoutGridButton:SetScript("OnLeave", function(this)
+		this.texture:SetVertexColor(1, 1, 1)
+		this.text:SetTextColor(1, 0.5, 0)
+	end)
+	SVUI_LayoutGridButton:SetScript("OnClick", XML_LayoutGridButton_OnClick)
+
+	SVUI_LayoutPrecision:SetFrameLevel(999)
+	SVUI_LayoutPrecision:SetStyle("Frame", "Pattern")
+	SVUI_LayoutPrecision:EnableMouse(true)
+	SVUI_LayoutPrecision:RegisterForDrag("LeftButton")
+
+	SV.API:Set("CloseButton", SVUI_LayoutPrecisionCloseButton)
+
+	SVUI_LayoutPrecisionSetX:SetStyle("Editbox")
+	SVUI_LayoutPrecisionSetX.CurrentValue = 0;
+	SVUI_LayoutPrecisionSetX:SetScript("OnEnterPressed", XML_LayoutPrecisionInputX_EnterPressed)
+	SVUI_LayoutPrecisionSetY:SetStyle("Editbox")
+	SVUI_LayoutPrecisionSetY.CurrentValue = 0;
+	SVUI_LayoutPrecisionSetY:SetScript("OnEnterPressed", XML_LayoutPrecisionInputY_EnterPressed)
+	SVUI_LayoutPrecisionResetButton:SetStyle("Button")
+	SVUI_LayoutPrecisionUpButton:SetStyle("Button")
+	SVUI_LayoutPrecisionDownButton:SetStyle("Button")
+	SVUI_LayoutPrecisionLeftButton:SetStyle("Button")
+	SVUI_LayoutPrecisionRightButton:SetStyle("Button")
+	SVUI_LayoutPrecisionResetButton:SetScript("OnClick", SVUI_LayoutPrecisionResetButton_OnClick)
+
+	SVUI_LayoutPrecisionWidthAdjust:SetValueStep(1);
+	SVUI_LayoutPrecisionHeightAdjust:SetValueStep(1);
+	SVUI_LayoutPrecisionWidthAdjust:SetScript("OnValueChanged", XML_LayoutPrecisionWidthAdjust_OnValueChanged)
+	SVUI_LayoutPrecisionHeightAdjust:SetScript("OnValueChanged", XML_LayoutPrecisionHeightAdjust_OnValueChanged)
+
+	SVUI_LayoutPrecision:SetScript("OnHide", function()
+		if(not CurrentFrameTarget) then return end
+		CurrentFrameTarget.text:SetTextColor(0.8, 0.4, 0)
+		CurrentFrameTarget:SetBackdropBorderColor(0.8, 0.4, 0)
+		CurrentFrameTarget = nil
+	end)
+
+	Layout:Update()
+
+	if(SV.db.general.useDraggable) then
+		if(not SV.private.Draggables) then SV.private.Draggables = {} end
+
+		if(SV.db.general.saveDraggable) then
+			Dragger.Frames = SV.private.Draggables
+		else
+			Dragger.Frames = {}
+		end
+
+		Dragger.EventsActive = true
+
+		Dragger:RegisterEvent("ADDON_LOADED")
+		Dragger:RegisterEvent("LFG_UPDATE")
+		Dragger:RegisterEvent("ROLE_POLL_BEGIN")
+		Dragger:RegisterEvent("READY_CHECK")
+		Dragger:RegisterEvent("UPDATE_WORLD_STATES")
+		Dragger:RegisterEvent("WORLD_STATE_TIMER_START")
+		Dragger:RegisterEvent("WORLD_STATE_UI_TIMER_UPDATE")
+
+		DraggerEventHandler(Dragger)
+		Dragger:SetScript("OnEvent", DraggerEventHandler)
+
+		if(SV.db.general.saveDraggable) then
+			hooksecurefunc("UIParent_ManageFramePositions", _hook_UIParent_ManageFramePositions)
+		end
+	end
+end
+
+SV.Events:On("LOAD_ALL_WIDGETS", InitializeMovables);
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+function SV:NewAnchor(frame, title, postDragFunc)
+	if(not frame or (not frame.GetName)) then return end
+	local frameName = frame:GetName()
+	local moveName = ("%s_MOVE"):format(frameName)
+	SetNewAnchor(frame, moveName, title, postDragFunc)
+	if(self.initialized) then Layout:Update() end
+	return moveName
+end
+
+function SV:SetAnchorResizing(frame, postSizeFunc, minRange, maxRange, min2Range, max2Range)
+	if(not frame or (not frame.Grip)) then return end
+	Layout.Frames[frame.Grip.name].postsize = postSizeFunc;
+	frame.Grip.minRange = minRange;
+	frame.Grip.maxRange = maxRange;
+	frame.Grip.min2Range = min2Range;
+	frame.Grip.max2Range = max2Range;
+	frame.Grip.postsize = postSizeFunc;
+end
+
+function SV:ReAnchor(name, ...)
+	if((not name) or (not _G[name])) then return end
+	local frame = _G[name]
+	if(not frame.Grip) then return end
+	frame.Grip:ClearAllPoints()
+	frame.Grip:SetPoint(...)
+	SaveAnchor(frame.Grip.name)
+end
+
+function SV:MoveAnchors(...)
+	Layout:Toggle(...)
+end
+
+function SV:UpdateAnchors()
+	Layout:Update()
+end
+
+function SV:ResetAnchors(...)
+	Layout:Reset(...)
+end
+
+function SV:ForceAnchors(forced)
+	if(Layout.Frames) then
+        for frame,_ in pairs(Layout.Frames) do
+            if _G[frame] and _G[frame]:IsShown() then
+                forced = true;
+                _G[frame]:Hide()
+            end
+        end
+    end
+    return forced
+end
+
+SV.SystemAlert["RESETBLIZZARD_CHECK"] = {
+	text = L["Are you sure you want to all draggable Blizzard frames to their original positions? This will reload your UI."],
+	button1 = ACCEPT,
+	button2 = CANCEL,
+	OnAccept = function(a) Dragger:Reset() end,
+	timeout = 0,
+	whileDead = 1
+};
+
+SV.SystemAlert["RESETLAYOUT_CHECK"] = {
+	text = L["Are you sure you want to all movable frames to their original positions?"],
+	button1 = ACCEPT,
+	button2 = CANCEL,
+	OnAccept = function(a) Layout:Reset() end,
+	timeout = 0,
+	whileDead = 1
+};
diff --git a/SVUI_!Core/system/letsride.lua b/SVUI_!Core/system/letsride.lua
new file mode 100644
index 0000000..7f13483
--- /dev/null
+++ b/SVUI_!Core/system/letsride.lua
@@ -0,0 +1,503 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 		= _G.unpack;
+local select 		= _G.select;
+local pairs 		= _G.pairs;
+local type          = _G.type;
+local tonumber		= _G.tonumber;
+local table 		= _G.table;
+local math 			= _G.math;
+local bit 			= _G.bit;
+local random 		= math.random;
+local twipe,band 	= table.wipe, bit.band;
+--BLIZZARD API
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+local GameTooltip           = _G.GameTooltip;
+local LoadAddOn             = _G.LoadAddOn;
+local hooksecurefunc        = _G.hooksecurefunc;
+local IsAltKeyDown          = _G.IsAltKeyDown;
+local IsShiftKeyDown        = _G.IsShiftKeyDown;
+local IsControlKeyDown      = _G.IsControlKeyDown;
+local IsModifiedClick       = _G.IsModifiedClick;
+local PlaySound             = _G.PlaySound;
+local PlaySoundFile         = _G.PlaySoundFile;
+local PlayMusic             = _G.PlayMusic;
+local StopMusic             = _G.StopMusic;
+local UnitName              = _G.UnitName;
+local ToggleFrame           = _G.ToggleFrame;
+local ERR_NOT_IN_COMBAT     = _G.ERR_NOT_IN_COMBAT;
+local RAID_CLASS_COLORS     = _G.RAID_CLASS_COLORS;
+local CUSTOM_CLASS_COLORS   = _G.CUSTOM_CLASS_COLORS;
+local C_MountJournal        = _G.C_MountJournal;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...);
+--[[
+##########################################################
+LOCAL VARIABLES
+##########################################################
+]]--
+local TOOLTIP_SUMMARY = "";
+local MountListener = CreateFrame("Frame");
+MountListener.favorites = false
+--[[
+##########################################################
+LOCAL FUNCTIONS
+##########################################################
+]]--
+local function CacheMounts()
+	return C_MountJournal.GetMountIDs()
+end
+
+local function RandomMount()
+	if(MountListener.favorites) then
+		return 0
+	end
+	local maxMounts = C_MountJournal.GetNumMounts()
+	return random(1, maxMounts)
+end
+
+local function MountInfo(index)
+	index = index or RandomMount()
+	return C_MountJournal.GetDisplayedMountInfo(index)
+end
+
+local function MountUp(index)
+	local _, _, _, _, _, _, _, _, _, _, _, id = MountInfo(index);
+	if id then C_MountJournal.SummonByID(id) end
+end
+
+local UnMount = C_MountJournal.Dismiss
+
+local function UpdateMountCheckboxes(button, index)
+	local creatureName = MountInfo(index);
+
+	local n = button.MountBar
+	local bar = _G[n]
+
+	if(bar) then
+		bar["GROUND"].index = index
+		bar["GROUND"].name = creatureName
+		bar["FLYING"].index = index
+		bar["FLYING"].name = creatureName
+		bar["SWIMMING"].index = index
+		bar["SWIMMING"].name = creatureName
+	    bar["SPECIAL"].index = index
+	    bar["SPECIAL"].name = creatureName
+
+		if(SV.private.Mounts.names["GROUND"] == creatureName) then
+			if(SV.private.Mounts.types["GROUND"] ~= index) then
+				SV.private.Mounts.types["GROUND"] = index
+			end
+			bar["GROUND"]:SetChecked(true)
+		else
+			bar["GROUND"]:SetChecked(false)
+		end
+
+		if(SV.private.Mounts.names["FLYING"] == creatureName) then
+			if(SV.private.Mounts.types["FLYING"] ~= index) then
+				SV.private.Mounts.types["FLYING"] = index
+			end
+			bar["FLYING"]:SetChecked(true)
+		else
+			bar["FLYING"]:SetChecked(false)
+		end
+
+		if(SV.private.Mounts.names["SWIMMING"] == creatureName) then
+			if(SV.private.Mounts.types["SWIMMING"] ~= index) then
+				SV.private.Mounts.types["SWIMMING"] = index
+			end
+			bar["SWIMMING"]:SetChecked(true)
+		else
+			bar["SWIMMING"]:SetChecked(false)
+		end
+
+		if(SV.private.Mounts.names["SPECIAL"] == creatureName) then
+			if(SV.private.Mounts.types["SPECIAL"] ~= index) then
+				SV.private.Mounts.types["SPECIAL"] = index
+			end
+			bar["SPECIAL"]:SetChecked(true)
+		else
+			bar["SPECIAL"]:SetChecked(false)
+		end
+	end
+end
+
+local function UpdateMountsCache()
+	if(not MountJournal) then return end
+	local myMounts = CacheMounts();
+	MountListener.favorites = false
+
+	for index, id in pairs(myMounts) do
+		--creatureName, spellID, icon, active, isUsable, sourceType, isFavorite, isFactionSpecific, faction, hideOnChar, isCollected, mountID
+		local info, spellId, _, _, _, _, favorite, _, _, _, _, mId = MountInfo(index);
+		if(favorite == true) then
+			MountListener.favorites = true
+		end
+		if(SV.private.Mounts.names["GROUND"] == info) then
+			if(SV.private.Mounts.types["GROUND"] ~= index) then
+				SV.private.Mounts.types["GROUND"] = index
+			end
+		end
+		if(SV.private.Mounts.names["FLYING"] == info) then
+			if(SV.private.Mounts.types["FLYING"] ~= index) then
+				SV.private.Mounts.types["FLYING"] = index
+			end
+		end
+		if(SV.private.Mounts.names["SWIMMING"] == info) then
+			if(SV.private.Mounts.types["SWIMMING"] ~= index) then
+				SV.private.Mounts.types["SWIMMING"] = index
+			end
+		end
+		if(SV.private.Mounts.names["SPECIAL"] == info) then
+			if(SV.private.Mounts.types["SPECIAL"] ~= index) then
+				SV.private.Mounts.types["SPECIAL"] = index
+			end
+		end
+	end
+end
+
+local function Update_MountCheckButtons()
+	if(not MountJournal) then return end
+	local count = C_MountJournal.GetNumMounts();
+	local scrollFrame = MountJournal.ListScrollFrame;
+	local offset = HybridScrollFrame_GetOffset(scrollFrame);
+  	local buttons = scrollFrame.buttons;
+	for i=1, #buttons do
+        local button = buttons[i];
+        local displayIndex = i + offset;
+        if ( displayIndex <= count ) then
+			UpdateMountCheckboxes(button, displayIndex)
+		end
+	end
+end
+
+local ProxyUpdate_Mounts = function(self, event, ...)
+	if(event == "COMPANION_LEARNED" or event == "COMPANION_UNLEARNED") then
+		UpdateMountsCache()
+	end
+	Update_MountCheckButtons()
+end
+
+local function UpdateCurrentMountSelection()
+	TOOLTIP_SUMMARY = ""
+	local creatureName
+
+	if(SV.private.Mounts.types["FLYING"]) then
+		creatureName = SV.private.Mounts.names["FLYING"]
+		if(creatureName) then
+			TOOLTIP_SUMMARY = TOOLTIP_SUMMARY .. "\nFlying: " .. creatureName
+		end
+	end
+
+	if(SV.private.Mounts.types["SWIMMING"]) then
+		creatureName = SV.private.Mounts.names["SWIMMING"]
+		if(creatureName) then
+			TOOLTIP_SUMMARY = TOOLTIP_SUMMARY .. "\nSwimming: " .. creatureName
+		end
+	end
+
+	if(SV.private.Mounts.types["GROUND"]) then
+		creatureName = SV.private.Mounts.names["GROUND"]
+		if(creatureName) then
+			TOOLTIP_SUMMARY = TOOLTIP_SUMMARY .. "\nGround: " .. creatureName
+		end
+	end
+
+	if(SV.private.Mounts.types["SPECIAL"]) then
+		creatureName = SV.private.Mounts.names["SPECIAL"]
+		if(creatureName) then
+			TOOLTIP_SUMMARY = TOOLTIP_SUMMARY .. "\nSpecial: " .. creatureName
+		end
+	end
+end
+
+local CheckButton_OnClick = function(self)
+	local index = self.index
+	local name = self.name
+	local key = self.key
+
+	if(index) then
+		if(self:GetChecked() == true) then
+			SV.private.Mounts.types[key] = index
+			SV.private.Mounts.names[key] = name
+		else
+			SV.private.Mounts.types[key] = false
+			SV.private.Mounts.names[key] = ""
+		end
+		Update_MountCheckButtons()
+		UpdateCurrentMountSelection()
+	end
+	GameTooltip:Hide()
+end
+
+local CheckButton_OnEnter = function(self)
+	local index = self.name
+	local key = self.key
+	local r,g,b = self:GetBackdropColor()
+	GameTooltip:SetOwner(self, 'ANCHOR_TOPLEFT', 0, 20)
+	GameTooltip:ClearLines()
+	GameTooltip:AddLine(key,r,g,b)
+	GameTooltip:AddLine("",1,1,0)
+	GameTooltip:AddLine("Check this box to enable/disable \nthis mount for \nthe 'Lets Ride' key-binding",1,1,1)
+	if(key == "SPECIAL") then
+		GameTooltip:AddLine("",1,1,0)
+		GameTooltip:AddLine("Hold |cff00FF00[SHIFT]|r or |cff00FF00[CTRL]|r while \nclicking to force this mount \nover all others.",1,1,1)
+	end
+	GameTooltip:AddLine(TOOLTIP_SUMMARY,1,1,1)
+
+	GameTooltip:Show()
+end
+
+local CheckButton_OnLeave = function(self)
+	GameTooltip:Hide()
+end
+
+local _hook_SetChecked = function(self, checked)
+    local r,g,b = 0,0,0
+    if(checked) then
+        r,g,b = self:GetCheckedTexture():GetVertexColor()
+    end
+    self:SetBackdropBorderColor(r,g,b)
+end
+
+local function CreateMountCheckBox(name, parent)
+	local frame = CreateFrame("CheckButton", name, parent, "UICheckButtonTemplate")
+    frame:RemoveTextures()
+	frame:SetBackdrop({
+        bgFile = SV.media.statusbar.gloss,
+        edgeFile = [[Interface\BUTTONS\WHITE8X8]],
+        tile = false,
+        tileSize = 0,
+        edgeSize = 1,
+        insets =
+        {
+            left = 0,
+            right = 0,
+            top = 0,
+            bottom = 0,
+        },
+    });
+
+    if(frame.Left) then frame.Left:SetAlpha(0) end
+    if(frame.Middle) then frame.Middle:SetAlpha(0) end
+    if(frame.Right) then frame.Right:SetAlpha(0) end
+    if(frame.SetNormalTexture) then frame:SetNormalTexture("") end
+    if(frame.SetDisabledTexture) then frame:SetDisabledTexture("") end
+    if(frame.SetCheckedTexture) then frame:SetCheckedTexture("") end
+    if(frame.SetHighlightTexture) then
+        if(not frame.hover) then
+            local hover = frame:CreateTexture(nil, "HIGHLIGHT")
+            hover:InsetPoints(frame.Panel)
+            frame.hover = hover;
+        end
+        frame.hover:SetColorTexture(0.1, 0.8, 0.8, 0.5)
+        frame:SetHighlightTexture(frame.hover)
+    end
+    if(frame.SetPushedTexture) then
+        if(not frame.pushed) then
+            local pushed = frame:CreateTexture(nil, "OVERLAY")
+            pushed:InsetPoints(frame.Panel)
+            frame.pushed = pushed;
+        end
+        frame.pushed:SetColorTexture(0.1, 0.8, 0.1, 0.3)
+        frame:SetPushedTexture(frame.pushed)
+    end
+    if(frame.SetCheckedTexture) then
+        if(not frame.checked) then
+            local checked = frame:CreateTexture(nil, "OVERLAY")
+            checked:InsetPoints(frame.Panel)
+            frame.checked = checked
+        end
+
+        frame.checked:SetTexture(SV.media.statusbar.gloss)
+        frame.checked:SetVertexColor(0, 1, 0, 1)
+
+        frame:SetCheckedTexture(frame.checked)
+    end
+
+    hooksecurefunc(frame, "SetChecked", _hook_SetChecked)
+
+    return frame
+end;
+--[[
+##########################################################
+LOAD BY TRIGGER
+##########################################################
+]]--
+local function InitializeLetsRide()
+	if(SV.GameVersion > 60000) then
+		LoadAddOn("Blizzard_Collections")
+	else
+		LoadAddOn("Blizzard_PetJournal")
+	end
+	SV.private.Mounts = SV.private.Mounts or {}
+
+	if not SV.private.Mounts.types then
+		SV.private.Mounts.types = {
+			["GROUND"] = false,
+			["FLYING"] = false,
+			["SWIMMING"] = false,
+			["SPECIAL"] = false
+		}
+	end
+	if not SV.private.Mounts.names then
+		SV.private.Mounts.names = {
+			["GROUND"] = "",
+			["FLYING"] = "",
+			["SWIMMING"] = "",
+			["SPECIAL"] = ""
+		}
+	end
+
+	UpdateMountsCache()
+
+	local scrollFrame = MountJournal.ListScrollFrame;
+	local scrollBar = _G["MountJournalListScrollFrameScrollBar"]
+  local buttons = scrollFrame.buttons;
+
+	for i = 1, #buttons do
+		local button = buttons[i]
+		local barWidth = button:GetWidth()
+		local width = (barWidth - 18) * 0.25
+		local height = 7
+		local barName = ("SVUI_MountSelectBar%d"):format(i)
+
+		local buttonBar = CreateFrame("Frame", barName, button)
+		buttonBar:SetPoint("BOTTOMLEFT", button, "BOTTOMLEFT", 0, 0)
+		buttonBar:SetSize(barWidth, height + 8)
+
+		--[[ CREATE CHECKBOXES ]]--
+		buttonBar["GROUND"] = CreateMountCheckBox(("%s_GROUND"):format(barName), buttonBar)
+		buttonBar["GROUND"]:SetSize(width,height)
+		buttonBar["GROUND"]:SetPoint("BOTTOMLEFT", buttonBar, "BOTTOMLEFT", 6, 4)
+		buttonBar["GROUND"]:SetBackdropColor(0.2, 0.7, 0.1, 0.25)
+		buttonBar["GROUND"]:SetBackdropBorderColor(0, 0, 0, 1)
+		buttonBar["GROUND"]:GetCheckedTexture():SetVertexColor(0.2, 0.7, 0.1, 1)
+		buttonBar["GROUND"].key = "GROUND"
+		buttonBar["GROUND"]:SetChecked(false)
+		buttonBar["GROUND"]:SetScript("OnClick", CheckButton_OnClick)
+		buttonBar["GROUND"]:SetScript("OnEnter", CheckButton_OnEnter)
+		buttonBar["GROUND"]:SetScript("OnLeave", CheckButton_OnLeave)
+
+		buttonBar["FLYING"] = CreateMountCheckBox(("%s_FLYING"):format(barName), buttonBar)
+		buttonBar["FLYING"]:SetSize(width,height)
+		buttonBar["FLYING"]:SetPoint("BOTTOMLEFT", buttonBar["GROUND"], "BOTTOMRIGHT", 2, 0)
+		buttonBar["FLYING"]:SetBackdropColor(1, 1, 0.2, 0.25)
+		buttonBar["FLYING"]:SetBackdropBorderColor(0, 0, 0, 1)
+		buttonBar["FLYING"]:GetCheckedTexture():SetVertexColor(1, 1, 0.2, 1)
+		buttonBar["FLYING"].key = "FLYING"
+		buttonBar["FLYING"]:SetChecked(false)
+		buttonBar["FLYING"]:SetScript("OnClick", CheckButton_OnClick)
+		buttonBar["FLYING"]:SetScript("OnEnter", CheckButton_OnEnter)
+		buttonBar["FLYING"]:SetScript("OnLeave", CheckButton_OnLeave)
+
+		buttonBar["SWIMMING"] = CreateMountCheckBox(("%s_SWIMMING"):format(barName), buttonBar)
+		buttonBar["SWIMMING"]:SetSize(width,height)
+		buttonBar["SWIMMING"]:SetPoint("BOTTOMLEFT", buttonBar["FLYING"], "BOTTOMRIGHT", 2, 0)
+		buttonBar["SWIMMING"]:SetBackdropColor(0.2, 0.42, 0.76, 0.25)
+		buttonBar["SWIMMING"]:SetBackdropBorderColor(0, 0, 0, 1)
+		buttonBar["SWIMMING"]:GetCheckedTexture():SetVertexColor(0.2, 0.42, 0.76, 1)
+		buttonBar["SWIMMING"].key = "SWIMMING"
+		buttonBar["SWIMMING"]:SetChecked(false)
+		buttonBar["SWIMMING"]:SetScript("OnClick", CheckButton_OnClick)
+		buttonBar["SWIMMING"]:SetScript("OnEnter", CheckButton_OnEnter)
+		buttonBar["SWIMMING"]:SetScript("OnLeave", CheckButton_OnLeave)
+
+		buttonBar["SPECIAL"] = CreateMountCheckBox(("%s_SPECIAL"):format(barName), buttonBar)
+		buttonBar["SPECIAL"]:SetSize(width,height)
+		buttonBar["SPECIAL"]:SetPoint("BOTTOMLEFT", buttonBar["SWIMMING"], "BOTTOMRIGHT", 2, 0)
+		buttonBar["SPECIAL"]:SetBackdropColor(0.7, 0.1, 0.1, 0.25)
+		buttonBar["SPECIAL"]:SetBackdropBorderColor(0, 0, 0, 1)
+		buttonBar["SPECIAL"]:GetCheckedTexture():SetVertexColor(0.7, 0.1, 0.1, 1)
+		buttonBar["SPECIAL"].key = "SPECIAL"
+		buttonBar["SPECIAL"]:SetChecked(false)
+		buttonBar["SPECIAL"]:SetScript("OnClick", CheckButton_OnClick)
+		buttonBar["SPECIAL"]:SetScript("OnEnter", CheckButton_OnEnter)
+		buttonBar["SPECIAL"]:SetScript("OnLeave", CheckButton_OnLeave)
+
+		button.MountBar = barName
+
+		UpdateMountCheckboxes(button, i)
+	end
+
+	UpdateCurrentMountSelection()
+
+	MountListener:RegisterEvent("MOUNT_JOURNAL_USABILITY_CHANGED")
+	MountListener:RegisterEvent("COMPANION_LEARNED")
+	MountListener:RegisterEvent("COMPANION_UNLEARNED")
+	MountListener:RegisterEvent("COMPANION_UPDATE")
+	MountListener:SetScript("OnEvent", ProxyUpdate_Mounts)
+
+	scrollFrame:HookScript("OnMouseWheel", Update_MountCheckButtons)
+	scrollBar:HookScript("OnValueChanged", Update_MountCheckButtons)
+	hooksecurefunc("MountJournal_UpdateMountList", Update_MountCheckButtons)
+end
+
+SV.Events:On("CORE_INITIALIZED", InitializeLetsRide);
+--[[
+##########################################################
+KEYBIND FUNCTION
+##########################################################
+]]--
+_G.SVUILetsRide = function()
+	local myMounts = CacheMounts()
+
+	if(not myMounts or IsMounted()) then
+		UnMount()
+		return
+	end
+
+	if(CanExitVehicle()) then
+		VehicleExit()
+		return
+	end
+
+	SV.private.Mounts = SV.private.Mounts or {}
+	if not SV.private.Mounts.types then
+		SV.private.Mounts.types = {
+			["GROUND"] = false,
+			["FLYING"] = false,
+			["SWIMMING"] = false,
+			["SPECIAL"] = false
+		}
+	end
+
+	local continent = GetCurrentMapContinent()
+	local checkList = SV.private.Mounts.types
+	local letsFly = (IsFlyableArea() and (continent ~= 962 and continent ~= 7))
+	local letsSwim = IsSwimming()
+
+	if(IsModifierKeyDown() and checkList["SPECIAL"]) then
+		MountUp(checkList["SPECIAL"])
+	else
+		if(letsSwim) then
+			if(checkList["SWIMMING"]) then
+				MountUp(checkList["SWIMMING"])
+			elseif(letsFly) then
+				MountUp(checkList["FLYING"])
+			else
+				MountUp(checkList["GROUND"])
+			end
+		elseif(letsFly) then
+			if(checkList["FLYING"]) then
+				MountUp(checkList["FLYING"])
+			else
+				MountUp(checkList["GROUND"])
+			end
+		else
+			MountUp(checkList["GROUND"])
+		end
+	end
+end
diff --git a/SVUI_!Core/system/mail.lua b/SVUI_!Core/system/mail.lua
new file mode 100644
index 0000000..e676cc3
--- /dev/null
+++ b/SVUI_!Core/system/mail.lua
@@ -0,0 +1,317 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pcall         = _G.pcall;
+local print         = _G.print;
+local ipairs        = _G.ipairs;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local rawset        = _G.rawset;
+local rawget        = _G.rawget;
+local tostring      = _G.tostring;
+local tonumber      = _G.tonumber;
+local getmetatable  = _G.getmetatable;
+local setmetatable  = _G.setmetatable;
+--STRING
+local string        = _G.string;
+local upper         = string.upper;
+local format        = string.format;
+local find          = string.find;
+local match         = string.match;
+local gsub          = string.gsub;
+--MATH
+local math          = _G.math;
+local floor         = math.floor;
+local random        = math.random;
+--TABLE
+local table         = _G.table;
+local tsort         = table.sort;
+local tconcat       = table.concat;
+local tremove       = _G.tremove;
+local twipe         = _G.wipe;
+--BLIZZARD API
+local ReloadUI              = _G.ReloadUI;
+local GetLocale             = _G.GetLocale;
+local CreateFrame           = _G.CreateFrame;
+local IsAddOnLoaded         = _G.IsAddOnLoaded;
+local InCombatLockdown      = _G.InCombatLockdown;
+local GetAddOnInfo          = _G.GetAddOnInfo;
+local LoadAddOn             = _G.LoadAddOn;
+local SendAddonMessage      = _G.SendAddonMessage;
+local LibStub               = _G.LibStub;
+local GetAddOnMetadata      = _G.GetAddOnMetadata;
+local GetCVarBool           = _G.GetCVarBool;
+local GameTooltip           = _G.GameTooltip;
+local StaticPopup_Hide      = _G.StaticPopup_Hide;
+local ERR_NOT_IN_COMBAT     = _G.ERR_NOT_IN_COMBAT;
+local InboxFrame_OnClick 		= _G.InboxFrame_OnClick;
+
+local SV = select(2, ...);
+local L = SV.L;
+
+local MailMinion 				= _G["SVUI_MailMinion"];
+local MailMinionGetMail = _G["SVUI_MailMinionGetMail"];
+local MailMinionGetGold = _G["SVUI_MailMinionGetGold"];
+local MailMinionDelete 	= _G["SVUI_MailMinionDelete"];
+--[[
+##########################################################
+LOCAL VARS
+##########################################################
+]]--
+local StartMailMinion, StopMailMinion
+local takingOnlyCash = false;
+local lastopened, lastdeleted = 0, 0;
+local mailElapsed, deleteElapsed, deletedelay = 0, 0, 0.5;
+local GetAllMail, GetAllMailCash, WaitForMail, DeleteAllMail, DeleteMailItem, WaitForDelete;
+local needsToWait, waitToDelete, total_cash, baseInboxFrame_OnClick;
+local dummy = function() return end;
+--[[
+##########################################################
+LOCAL FUNCTIONS
+##########################################################
+]]--
+local function FancifyMoneys(cash)
+	if cash > 10000 then
+		return("%d|cffffd700g|r%d|cffc7c7cfs|r%d|cffeda55fc|r"):format((cash / 10000), ((cash / 100) % 100), (cash % 100))
+	elseif cash > 100 then
+		return("%d|cffc7c7cfs|r%d|cffeda55fc|r"):format(((cash / 100) % 100), (cash % 100))
+	else
+		return("%d|cffeda55fc|r"):format(cash%100)
+	end
+end
+
+local MailMinionOpening_OnUpdate = function(self, elapsed)
+	mailElapsed = mailElapsed + elapsed;
+	if not needsToWait or mailElapsed > deletedelay then
+		if not InboxFrame:IsVisible() then return StopMailMinion("The Mailbox Minion Needs a Mailbox!") end
+		mailElapsed = 0;
+		needsToWait = nil;
+
+		MailMinionGetMail:SetScript("OnUpdate", nil)
+
+		local _, _, _, _, money, CODAmount, _, itemCount = GetInboxHeaderInfo(lastopened)
+		local return_index;
+		if((money and money > 0) or ((not takingOnlyCash) and (not (CODAmount > 0)) and (itemCount and itemCount > 0))) then
+			return_index = lastopened
+		else
+			return_index = lastopened - 1
+		end
+
+		StartMailMinion(return_index, false)
+	end
+end
+
+local MailMinionDeleting_OnUpdate = function(self, elapsed)
+	deleteElapsed = deleteElapsed + elapsed;
+	if not waitToDelete or deleteElapsed > deletedelay then
+		if not InboxFrame:IsVisible() then return StopMailMinion("The Mailbox Minion Needs a Mailbox!") end
+		deleteElapsed = 0;
+		waitToDelete = nil;
+
+		MailMinionDelete:SetScript("OnUpdate", nil)
+
+		local return_index = lastdeleted - 1;
+
+		StartMailMinion(return_index, true)
+	end
+end
+
+function StopMailMinion(mail_message)
+	MailMinionGetMail:SetScript("OnUpdate", nil)
+	MailMinionDelete:SetScript("OnUpdate", nil)
+
+	MailMinionGetMail:Enable()
+	MailMinionDelete:Enable()
+	MailMinionGetGold:Enable()
+
+	if(baseInboxFrame_OnClick) then
+		InboxFrame_OnClick = baseInboxFrame_OnClick;
+	end
+
+	MailMinionGetMail:UnregisterEvent("UI_ERROR_MESSAGE");
+
+	local mail_index = GetInboxNumItems()
+
+	takingOnlyCash = false;
+	total_cash = nil;
+	needsToWait = nil;
+	waitToDelete = nil;
+	lastopened = mail_index;
+	lastdeleted = mail_index;
+
+	mailElapsed = 0;
+	deleteElapsed = 0;
+
+	if(mail_message) then
+		SV:AddonMessage(mail_message)
+	end
+end
+
+function StartMailMinion(mail_index, is_deleting)
+	if(not InboxFrame:IsVisible()) then
+		return StopMailMinion("Mailbox Minion Needs a Mailbox!")
+	elseif(mail_index == 0) then
+		MiniMapMailFrame:Hide()
+		return StopMailMinion("Mailbox Minion Has Finished!")
+	end
+
+	local _, _, _, _, money, CODAmount, _, itemCount = GetInboxHeaderInfo(mail_index)
+	if(not is_deleting) then
+		if((not takingOnlyCash) and ((money and money > 0) or (itemCount and itemCount > 0)) and (CODAmount and CODAmount <= 0)) then
+			AutoLootMailItem(mail_index)
+			needsToWait = true;
+		elseif(money and (money > 0)) then
+			TakeInboxMoney(mail_index)
+			needsToWait = true;
+			if(total_cash) then
+				total_cash = total_cash - money
+			end
+		end
+
+		local numMail = GetInboxNumItems()
+		if((mail_index ~= lastopened) and (itemCount and itemCount > 0) or ((numMail > 1) and (not (mail_index > numMail)))) then
+			lastopened = mail_index;
+			MailMinionGetMail:SetScript("OnUpdate", MailMinionOpening_OnUpdate)
+		else
+			MiniMapMailFrame:Hide()
+			StopMailMinion()
+		end
+	else
+		if(((not money) or (money and money == 0)) and ((not itemCount) or (itemCount and itemCount == 0))) then
+			DeleteInboxItem(mail_index)
+			waitToDelete = true;
+		end
+
+		local numMail = GetInboxNumItems()
+		if((mail_index ~= lastdeleted) and ((numMail > 1) and (not (mail_index > numMail)))) then
+			lastdeleted = mail_index;
+			MailMinionDelete:SetScript("OnUpdate", MailMinionDeleting_OnUpdate)
+		else
+			MiniMapMailFrame:Hide()
+			StopMailMinion()
+		end
+	end
+end
+--[[
+##########################################################
+BUTTON SPECIFIC HANDLERS
+##########################################################
+]]--
+function MailMinionGetMail:ClickHandler(mail_index)
+	--print("MailMinionGetMail:ClickHandler")
+	MailMinionGetMail:RegisterEvent("UI_ERROR_MESSAGE")
+	StartMailMinion(mail_index, false)
+end
+
+function MailMinionGetGold:ClickHandler(mail_index)
+	--print("MailMinionGetGold:ClickHandler")
+	takingOnlyCash = true;
+	StartMailMinion(mail_index, false)
+end
+
+function MailMinionDelete:ClickHandler(mail_index)
+	--print("MailMinionDelete:ClickHandler")
+	StartMailMinion(mail_index, true)
+end
+--[[
+##########################################################
+SCRIPT HANDLERS
+##########################################################
+]]--
+local GoldMinionButton_OnEnter = function(self)
+	if(not total_cash) then
+		total_cash = 0;
+		for i = 0, GetInboxNumItems() do
+			total_cash = total_cash + select(5, GetInboxHeaderInfo(i))
+		end
+	end
+	GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
+	GameTooltip:AddLine(FancifyMoneys(total_cash), 1, 1, 1)
+	GameTooltip:Show()
+end
+
+local MailMinionButton_OnEnter = function(self)
+	GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
+	GameTooltip:AddLine(("%d messages"):format(GetInboxNumItems()), 1, 1, 1)
+	GameTooltip:Show()
+end
+
+local MailMinionButton_OnLeave = function(self)
+	GameTooltip:Hide()
+end
+
+local MailMinionButton_OnClick = function(self, ...)
+	if(GetInboxNumItems() == 0) then return end
+
+	MailMinionGetMail:Disable()
+	MailMinionGetGold:Disable()
+	MailMinionDelete:Disable()
+
+	baseInboxFrame_OnClick = InboxFrame_OnClick;
+	InboxFrame_OnClick = dummy;
+
+	local mail_index = GetInboxNumItems();
+	self:ClickHandler(mail_index);
+end
+
+local MailMinionButton_OnEvent = function(self, event, subEvent)
+	if(event == "UI_ERROR_MESSAGE") then
+		if((subEvent == ERR_INV_FULL) or (subEvent == ERR_ITEM_MAX_COUNT)) then
+			StopMailMinion("Your bags are too full!")
+		end
+	end
+end
+--[[
+##########################################################
+MAIL HELPER
+##########################################################
+]]--
+function SV:ToggleMailMinions()
+	if not SV.db.Extras.mailOpener then
+		MailMinion:Hide()
+	else
+		MailMinion:Show()
+	end
+end
+--[[
+##########################################################
+LOAD BY TRIGGER
+##########################################################
+]]--
+local function LoadMailMinions()
+	if IsAddOnLoaded("Postal") then
+		SV.db.Extras.mailOpener = false
+	else
+		MailMinion:Show()
+
+		MailMinionGetMail:SetStyle("Button")
+		MailMinionGetMail:SetScript("OnClick", MailMinionButton_OnClick)
+		MailMinionGetMail:SetScript("OnEnter", MailMinionButton_OnEnter)
+		MailMinionGetMail:SetScript("OnLeave", MailMinionButton_OnLeave)
+		MailMinionGetMail:SetScript("OnEvent", MailMinionButton_OnEvent)
+
+		MailMinionGetGold:SetStyle("Button")
+		MailMinionGetGold:SetScript("OnClick", MailMinionButton_OnClick)
+		MailMinionGetGold:SetScript("OnEnter", GoldMinionButton_OnEnter)
+		MailMinionGetGold:SetScript("OnLeave", MailMinionButton_OnLeave)
+
+		MailMinionDelete:SetStyle("Button", 1, 1, "red")
+		MailMinionDelete:SetScript("OnClick", MailMinionButton_OnClick)
+		MailMinionDelete:SetScript("OnEnter", MailMinionButton_OnEnter)
+		MailMinionDelete:SetScript("OnLeave", MailMinionButton_OnLeave)
+
+		SV:ToggleMailMinions()
+	end
+end
+
+SV.Events:On("CORE_INITIALIZED", LoadMailMinions);
diff --git a/SVUI_!Core/system/media.lua b/SVUI_!Core/system/media.lua
new file mode 100644
index 0000000..d7de399
--- /dev/null
+++ b/SVUI_!Core/system/media.lua
@@ -0,0 +1,1148 @@
+--- Handlers for media functions
+-- @submodule SVUI_Core
+
+local _G = _G;
+local select  = _G.select;
+local unpack  = _G.unpack;
+local pairs   = _G.pairs;
+local ipairs  = _G.ipairs;
+local type    = _G.type;
+local print   = _G.print;
+local string  = _G.string;
+local math    = _G.math;
+local table   = _G.table;
+local GetTime = _G.GetTime;
+local format = string.format;
+local floor, modf = math.floor, math.modf;
+local twipe, tsort = table.wipe, table.sort;
+local NAMEPLATE_FONT      = _G.NAMEPLATE_FONT
+local CHAT_FONT_HEIGHTS   = _G.CHAT_FONT_HEIGHTS
+local STANDARD_TEXT_FONT  = _G.STANDARD_TEXT_FONT
+local UNIT_NAME_FONT      = _G.UNIT_NAME_FONT
+local CUSTOM_CLASS_COLORS = _G.CUSTOM_CLASS_COLORS
+local RAID_CLASS_COLORS   = _G.RAID_CLASS_COLORS
+local UIDROPDOWNMENU_DEFAULT_TEXT_HEIGHT  = _G.UIDROPDOWNMENU_DEFAULT_TEXT_HEIGHT
+---- GET ADDON DATA ----
+local SV = select(2, ...)
+local SVUILib = Librarian("Registry")
+local L = SV.L
+local classToken = select(2,UnitClass("player"))
+SV.MaxBackdrops = {Pattern = 14, Art = 5, Unit = 17}
+---- DEFINE SOUND EFFECTS ----
+local SOUND = SV.Sounds;
+
+SOUND:Register("Buttons", [[sound\interface\uchatscrollbutton.ogg]])
+SOUND:Register("Levers", [[sound\interface\ui_blizzardstore_buynow.ogg]])
+SOUND:Register("Levers", [[sound\doodad\g_levermetalcustom0.ogg]])
+SOUND:Register("Levers", [[sound\item\weapons\gun\gunload01.ogg]])
+SOUND:Register("Levers", [[sound\item\weapons\gun\gunload02.ogg]])
+SOUND:Register("Levers", [[sound\creature\gyrocopter\gyrocoptergearshift2.ogg]])
+SOUND:Register("Gears", [[sound\creature\gyrocopter\gyrocoptergearshift3.ogg]])
+SOUND:Register("Gears", [[sound\doodad\g_buttonbigredcustom0.ogg]])
+SOUND:Register("Sparks", [[sound\doodad\fx_electricitysparkmedium_02.ogg]])
+SOUND:Register("Sparks", [[sound\doodad\fx_electrical_zaps01.ogg]])
+SOUND:Register("Sparks", [[sound\doodad\fx_electrical_zaps02.ogg]])
+SOUND:Register("Sparks", [[sound\doodad\fx_electrical_zaps03.ogg]])
+SOUND:Register("Sparks", [[sound\doodad\fx_electrical_zaps04.ogg]])
+SOUND:Register("Sparks", [[sound\doodad\fx_electrical_zaps05.ogg]])
+SOUND:Register("Static", [[sound\spells\uni_fx_radiostatic_01.ogg]])
+SOUND:Register("Static", [[sound\spells\uni_fx_radiostatic_02.ogg]])
+SOUND:Register("Static", [[sound\spells\uni_fx_radiostatic_03.ogg]])
+SOUND:Register("Static", [[sound\spells\uni_fx_radiostatic_04.ogg]])
+SOUND:Register("Static", [[sound\spells\uni_fx_radiostatic_05.ogg]])
+SOUND:Register("Static", [[sound\spells\uni_fx_radiostatic_06.ogg]])
+SOUND:Register("Static", [[sound\spells\uni_fx_radiostatic_07.ogg]])
+SOUND:Register("Static", [[sound\spells\uni_fx_radiostatic_08.ogg]])
+SOUND:Register("Wired", [[sound\doodad\goblin_christmaslight_green_01.ogg]])
+SOUND:Register("Wired", [[sound\doodad\goblin_christmaslight_green_02.ogg]])
+SOUND:Register("Wired", [[sound\doodad\goblin_christmaslight_green_03.ogg]])
+SOUND:Register("Phase", [[sound\doodad\be_scryingorb_explode.ogg]])
+---- DEFINE SHARED MEDIA ----
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+
+LSM:Register("background", "SVUI Default BG", [[Interface\AddOns\SVUI_!Core\assets\backgrounds\DEFAULT]])
+LSM:Register("background", "SVUI Transparent BG", [[Interface\AddOns\SVUI_!Core\assets\backgrounds\TRANSPARENT]])
+LSM:Register("background", "SVUI Button BG", [[Interface\AddOns\SVUI_!Core\assets\backgrounds\BUTTON]])
+LSM:Register("background", "SVUI Model BG", [[Interface\AddOns\SVUI_!Core\assets\backgrounds\MODEL]])
+
+for i = 1, SV.MaxBackdrops.Pattern do
+	LSM:Register("background", "SVUI Backdrop "..i, [[Interface\AddOns\SVUI_!Core\assets\backgrounds\pattern\PATTERN]]..i)
+end
+
+for i = 1, SV.MaxBackdrops.Art do
+	LSM:Register("background", "SVUI Artwork "..i, [[Interface\AddOns\SVUI_!Core\assets\backgrounds\art\ART]]..i)
+end
+
+for i = 1, SV.MaxBackdrops.Unit do
+	LSM:Register("background", "SVUI UnitBG "..i, [[Interface\AddOns\SVUI_!Core\assets\backgrounds\unit\UNIT-BG]]..i)
+	LSM:Register("background", "SVUI SmallUnitBG "..i, [[Interface\AddOns\SVUI_!Core\assets\backgrounds\unit\UNIT-SMALL-BG]]..i)
+end
+
+LSM:Register("border", "SVUI Border", [[Interface\AddOns\SVUI_!Core\assets\borders\DEFAULT]])
+LSM:Register("border", "SVUI Border 2", [[Interface\BUTTONS\WHITE8X8]])
+LSM:Register("border", "SVUI Textured Border", [[Interface\AddOns\SVUI_!Core\assets\borders\TEXTURED]])
+LSM:Register("border", "SVUI Inset Shadow", [[Interface\AddOns\SVUI_!Core\assets\borders\INSET]])
+LSM:Register("border", "SVUI Shadow Border", [[Interface\AddOns\SVUI_!Core\assets\borders\SHADOW]])
+
+LSM:Register("statusbar", "SVUI BasicBar", [[Interface\AddOns\SVUI_!Core\assets\statusbars\DEFAULT]])
+LSM:Register("statusbar", "SVUI MultiColorBar", [[Interface\AddOns\SVUI_!Core\assets\statusbars\GRADIENT]])
+LSM:Register("statusbar", "SVUI SmoothBar", [[Interface\AddOns\SVUI_!Core\assets\statusbars\SMOOTH]])
+LSM:Register("statusbar", "SVUI PlainBar", [[Interface\AddOns\SVUI_!Core\assets\statusbars\FLAT]])
+LSM:Register("statusbar", "SVUI FancyBar", [[Interface\AddOns\SVUI_!Core\assets\statusbars\TEXTURED]])
+LSM:Register("statusbar", "SVUI GlossBar", [[Interface\AddOns\SVUI_!Core\assets\statusbars\GLOSS]])
+LSM:Register("statusbar", "SVUI GlowBar", [[Interface\AddOns\SVUI_!Core\assets\statusbars\GLOWING]])
+LSM:Register("statusbar", "SVUI LazerBar", [[Interface\AddOns\SVUI_!Core\assets\statusbars\LAZER]])
+
+LSM:Register("sound", "Whisper Alert", [[Interface\AddOns\SVUI_!Core\assets\sounds\whisper.mp3]])
+LSM:Register("sound", "Mention Alert", [[Interface\AddOns\SVUI_!Core\assets\sounds\whisper.mp3]])
+LSM:Register("sound", "Toasty", [[Interface\AddOns\SVUI_!Core\assets\sounds\toasty.mp3]])
+
+LSM:Register("font", "SVUI Default Font", [[Interface\AddOns\SVUI_!Core\assets\fonts\Default.ttf]],LSM.LOCALE_BIT_ruRU+LSM.LOCALE_BIT_western)
+LSM:Register("font", "SVUI Pixel Font", [[Interface\AddOns\SVUI_!Core\assets\fonts\Pixel.ttf]],LSM.LOCALE_BIT_ruRU+LSM.LOCALE_BIT_western)
+LSM:Register("font", "SVUI Caps Font", [[Interface\AddOns\SVUI_!Core\assets\fonts\Caps.ttf]],LSM.LOCALE_BIT_ruRU+LSM.LOCALE_BIT_western)
+LSM:Register("font", "SVUI Classic Font", [[Interface\AddOns\SVUI_!Core\assets\fonts\Classic.ttf]])
+LSM:Register("font", "SVUI Combat Font", [[Interface\AddOns\SVUI_!Core\assets\fonts\Combat.ttf]])
+LSM:Register("font", "SVUI Dialog Font", [[Interface\AddOns\SVUI_!Core\assets\fonts\Dialog.ttf]])
+LSM:Register("font", "SVUI Number Font", [[Interface\AddOns\SVUI_!Core\assets\fonts\Numbers.ttf]])
+LSM:Register("font", "SVUI Zone Font", [[Interface\AddOns\SVUI_!Core\assets\fonts\Zone.ttf]])
+LSM:Register("font", "SVUI Flash Font", [[Interface\AddOns\SVUI_!Core\assets\fonts\Flash.ttf]])
+LSM:Register("font", "SVUI Alert Font", [[Interface\AddOns\SVUI_!Core\assets\fonts\Alert.ttf]])
+LSM:Register("font", "SVUI Narrator Font", [[Interface\AddOns\SVUI_!Core\assets\fonts\Narrative.ttf]])
+LSM:Register("font", "Open-Dyslexic", [[Interface\AddOns\SVUI_!Core\assets\fonts\Dyslexic.ttf]])
+---- CREATE AND POPULATE MEDIA DATA ----
+do
+	local cColor = RAID_CLASS_COLORS[classToken]
+	local r1,g1,b1 = cColor.r,cColor.g,cColor.b
+	local r2,g2,b2 = cColor.r*.25, cColor.g*.25, cColor.b*.25
+	local ir1,ig1,ib1 = (1 - r1), (1 - g1), (1 - b1)
+	local ir2,ig2,ib2 = (1 - cColor.r)*.25, (1 - cColor.g)*.25, (1 - cColor.b)*.25
+
+	SV.mediadefaults = {
+		["extended"] = {},
+		["shared"] = {
+			["font"] = {
+				["default"]     = {file = "SVUI Default Font",  size = 12,  outline = "OUTLINE"},
+				["dialog"]      = {file = "SVUI Default Font",  size = 12,  outline = "OUTLINE"},
+				["title"]       = {file = "SVUI Default Font",  size = 16,  outline = "OUTLINE"},
+				["number"]      = {file = "SVUI Number Font",   size = 11,  outline = "OUTLINE"},
+				["number_big"]  = {file = "SVUI Number Font",   size = 18,  outline = "OUTLINE"},
+				["header"]      = {file = "SVUI Number Font",   size = 18,  outline = "OUTLINE"},
+				["combat"]      = {file = "SVUI Combat Font",   size = 64,  outline = "OUTLINE"},
+				["alert"]       = {file = "SVUI Alert Font",    size = 20,  outline = "OUTLINE"},
+				["flash"]      	= {file = "SVUI Flash Font",    size = 18,  outline = "OUTLINE"},
+				["zone"]      	= {file = "SVUI Zone Font",     size = 16,  outline = "OUTLINE"},
+				["caps"]      	= {file = "SVUI Caps Font",     size = 12,  outline = "OUTLINE"},
+				["aura"]      	= {file = "SVUI Number Font",   size = 10,  outline = "OUTLINE"},
+				["data"]      	= {file = "SVUI Number Font",   size = 11,  outline = "OUTLINE"},
+				["narrator"]    = {file = "SVUI Narrator Font", size = 12,  outline = "OUTLINE"},
+				["lootdialog"]  = {file = "SVUI Default Font",  size = 14,  outline = "OUTLINE"},
+				["lootnumber"]  = {file = "SVUI Number Font",   size = 11,  outline = "OUTLINE"},
+				["rolldialog"]  = {file = "SVUI Default Font",  size = 14,  outline = "OUTLINE"},
+				["rollnumber"]  = {file = "SVUI Number Font",   size = 11,  outline = "OUTLINE"},
+				["tipdialog"]   = {file = "SVUI Default Font",  size = 12,  outline = "NONE"},
+				["tipheader"]   = {file = "SVUI Default Font",  size = 14,  outline = "NONE"},
+				["pixel"]       = {file = "SVUI Pixel Font",    size = 8,   outline = "MONOCHROMEOUTLINE"},
+			},
+			["statusbar"] = {
+				["default"]   	= {file = "SVUI BasicBar",  	offset = 0},
+				["gradient"]  	= {file = "SVUI MultiColorBar", offset = 0},
+				["smooth"]    	= {file = "SVUI SmoothBar",  	offset = 0},
+				["flat"]      	= {file = "SVUI PlainBar",  	offset = 0},
+				["textured"]  	= {file = "SVUI FancyBar",  	offset = 0},
+				["gloss"]     	= {file = "SVUI GlossBar",  	offset = 0},
+				["glow"]      	= {file = "SVUI GlowBar",  		offset = 2},
+				["lazer"]     	= {file = "SVUI LazerBar",  	offset = 10},
+			},
+			["background"] = {
+				["default"]     = {file = "SVUI Default BG",  		size = 0, tiled = false},
+				["transparent"] = {file = "SVUI Transparent BG",	size = 0, tiled = false},
+				["button"]      = {file = "SVUI Button BG",  		size = 0, tiled = false},
+				["pattern"]     = {file = "SVUI Backdrop 1",  		size = 0, tiled = false},
+				["premium"]     = {file = "SVUI Artwork 1",  		size = 0, tiled = false},
+				["model"]     	= {file = "SVUI Model BG",  		size = 0, tiled = false},
+				["unitlarge"]   = {file = "SVUI UnitBG 1",  		size = 0, tiled = false},
+				["unitsmall"]   = {file = "SVUI SmallUnitBG 1",  	size = 0, tiled = false},
+			},
+			["border"] = {
+				["default"] 	= {file = "SVUI Border", 		  	size = 1},
+				["transparent"] = {file = "SVUI Border", 			size = 1},
+				["button"]      = {file = "SVUI Border 2", 			size = 1},
+				["pattern"]     = {file = "SVUI Border", 		size = 1},
+				["premium"]     = {file = "SVUI Textured Border", 	size = 15},
+				["model"]     	= {file = "SVUI Border", 		size = 1},
+				["shadow"]      = {file = "SVUI Shadow Border",   	size = 3},
+				["inset"]       = {file = "SVUI Inset Shadow",   	size = 6},
+				["unitlarge"]   = {file = "SVUI Border 2",  		size = 0},
+				["unitsmall"]   = {file = "SVUI Border 2",  		size = 0},
+			},
+		},
+		["font"] = {
+			["default"]   	= [[Interface\AddOns\SVUI_!Core\assets\fonts\Default.ttf]],
+			["dialog"]    	= [[Interface\AddOns\SVUI_!Core\assets\fonts\Default.ttf]],
+			["number"]    	= [[Interface\AddOns\SVUI_!Core\assets\fonts\Numbers.ttf]],
+			["combat"]    	= [[Interface\AddOns\SVUI_!Core\assets\fonts\Combat.ttf]],
+			["zone"]      	= [[Interface\AddOns\SVUI_!Core\assets\fonts\Zone.ttf]],
+			["alert"]     	= [[Interface\AddOns\SVUI_!Core\assets\fonts\Alert.ttf]],
+			["caps"]      	= [[Interface\AddOns\SVUI_!Core\assets\fonts\Caps.ttf]],
+			["narrator"]  	= [[Interface\AddOns\SVUI_!Core\assets\fonts\Narrative.ttf]],
+			["flash"]     	= [[Interface\AddOns\SVUI_!Core\assets\fonts\Flash.ttf]],
+			["pixel"]     	= [[Interface\AddOns\SVUI_!Core\assets\fonts\Pixel.ttf]],
+		},
+		["statusbar"] = {
+			["default"]   	= [[Interface\AddOns\SVUI_!Core\assets\statusbars\DEFAULT]],
+			["gradient"]  	= [[Interface\AddOns\SVUI_!Core\assets\statusbars\GRADIENT]],
+			["smooth"]    	= [[Interface\AddOns\SVUI_!Core\assets\statusbars\SMOOTH]],
+			["flat"]      	= [[Interface\AddOns\SVUI_!Core\assets\statusbars\FLAT]],
+			["textured"]  	= [[Interface\AddOns\SVUI_!Core\assets\statusbars\TEXTURED]],
+			["gloss"]     	= [[Interface\AddOns\SVUI_!Core\assets\statusbars\GLOSS]],
+			["glow"]      	= [[Interface\AddOns\SVUI_!Core\assets\statusbars\GLOWING]],
+			["lazer"]     	= [[Interface\AddOns\SVUI_!Core\assets\statusbars\LAZER]],
+		},
+		["background"] = {
+			["default"] 	= [[Interface\AddOns\SVUI_!Core\assets\backgrounds\DEFAULT]],
+			["transparent"] = [[Interface\AddOns\SVUI_!Core\assets\backgrounds\TRANSPARENT]],
+			["button"]      = [[Interface\AddOns\SVUI_!Core\assets\backgrounds\BUTTON]],
+			["pattern"]     = [[Interface\AddOns\SVUI_!Core\assets\backgrounds\pattern\PATTERN1]],
+			["premium"]     = [[Interface\AddOns\SVUI_!Core\assets\backgrounds\art\ART1]],
+			["model"]     	= [[Interface\AddOns\SVUI_!Core\assets\backgrounds\MODEL]],
+			["unitlarge"] 	= [[Interface\AddOns\SVUI_!Core\assets\backgrounds\unit\UNIT-BG1]],
+			["unitsmall"] 	= [[Interface\AddOns\SVUI_!Core\assets\backgrounds\unit\UNIT-SMALL-BG1]],
+			["checkbox"]    = [[Interface\AddOns\SVUI_!Core\assets\buttons\CHECK-BG]],
+			["dark"]    	= [[Interface\AddOns\SVUI_!Core\assets\backgrounds\DARK]],
+		},
+		["border"] = {
+			["default"] 	= [[Interface\AddOns\SVUI_!Core\assets\borders\DEFAULT]],
+			["button"]      = [[Interface\AddOns\SVUI_!Core\assets\borders\DEFAULT]],
+			["pattern"]     = [[Interface\AddOns\SVUI_!Core\assets\borders\DEFAULT]],
+			["premium"]     = [[Interface\AddOns\SVUI_!Core\assets\borders\TEXTURED]],
+			["model"]     	= [[Interface\AddOns\SVUI_!Core\assets\borders\DEFAULT]],
+			["shadow"]      = [[Interface\AddOns\SVUI_!Core\assets\borders\SHADOW]],
+			["inset"]       = [[Interface\AddOns\SVUI_!Core\assets\borders\INSET]],
+			["unitlarge"] 	= [[Interface\BUTTONS\WHITE8X8]],
+			["unitsmall"] 	= [[Interface\BUTTONS\WHITE8X8]],
+			["checkbox"] 	= [[Interface\AddOns\SVUI_!Core\assets\borders\DEFAULT]],
+		},
+		["color"] = {
+			["default"]     = {0.15, 0.15, 0.15, 1},
+			["secondary"]   = {0.2, 0.2, 0.2, 1},
+			["button"]      = {0.2, 0.2, 0.2, 1},
+			["special"]     = {0.37, 0.32, 0.29, 1},
+			["specialdark"] = {.23, .22, .21, 1},
+			["unique"]      = {0.32, 0.258, 0.21, 1},
+			["paper"]     	= {0.77, 0.72, 0.69, 1},
+			["dusty"]   	= {.28, .27, .26, 1},
+			["class"]       = {r1, g1, b1, 1},
+			["bizzaro"]     = {ir1, ig1, ib1, 1},
+			["medium"]      = {0.47, 0.47, 0.47},
+			["dark"]        = {0.1, 0.1, 0.1, 1},
+			["darkest"]     = {0, 0, 0, 1},
+			["light"]       = {0.95, 0.95, 0.95, 1},
+			["light2"]      = {0.65, 0.65, 0.65, 1},
+			["lightgrey"]   = {0.32, 0.35, 0.38, 1},
+			["highlight"]   = {0.28, 0.75, 1, 1},
+			["checked"]     = {0.25, 0.9, 0.08, 1},
+			["green"]       = {0.25, 0.9, 0.08, 1},
+			["blue"]        = {0.08, 0.25, 0.82, 1},
+			["tan"]         = {0.4, 0.32, 0.23, 1},
+			["red"]         = {0.9, 0.08, 0.08, 1},
+			["yellow"]      = {1, 1, 0, 1},
+			["gold"]        = {1, 0.68, 0.1, 1},
+			["transparent"] = {0, 0, 0, 0.5},
+			["hinted"]      = {0, 0, 0, 0.35},
+			["invisible"]   = {0, 0, 0, 0},
+			["white"]       = {1, 1, 1, 1},
+		},
+		["bordercolor"] = {
+			["default"]     = {0, 0, 0, 1},
+			["class"]       = {r1, g1, b1, 1},
+			["checkbox"]    = {0.1, 0.1, 0.1, 1},
+		},
+		["gradient"]  = {
+			["default"]   	= {"VERTICAL", 0.08, 0.08, 0.08, 0.22, 0.22, 0.22},
+			["secondary"]  	= {"VERTICAL", 0.08, 0.08, 0.08, 0.22, 0.22, 0.22},
+			["button"]   	= {"VERTICAL", 0.08, 0.08, 0.08, 0.22, 0.22, 0.22},
+			["special"]   	= {"VERTICAL", 0.33, 0.25, 0.13, 0.47, 0.39, 0.27},
+			["specialdark"] = {"VERTICAL", 0.23, 0.15, 0.03, 0.33, 0.25, 0.13},
+			["paper"]   	= {"VERTICAL", 0.53, 0.45, 0.33, 0.77, 0.72, 0.69},
+			["dusty"] 		= {"VERTICAL", 0.12, 0.11, 0.1, 0.22, 0.21, 0.2},
+			["class"]     	= {"VERTICAL", r2, g2, b2, r1, g1, b1},
+			["bizzaro"]   	= {"VERTICAL", ir2, ig2, ib2, ir1, ig1, ib1},
+			["medium"]    	= {"VERTICAL", 0.22, 0.22, 0.22, 0.47, 0.47, 0.47},
+			["dark"]      	= {"VERTICAL", 0.02, 0.02, 0.02, 0.22, 0.22, 0.22},
+			["darkest"]   	= {"VERTICAL", 0.15, 0.15, 0.15, 0, 0, 0},
+			["darkest2"]  	= {"VERTICAL", 0, 0, 0, 0.12, 0.12, 0.12},
+			["light"]     	= {"VERTICAL", 0.65, 0.65, 0.65, 0.95, 0.95, 0.95},
+			["light2"]    	= {"VERTICAL", 0.95, 0.95, 0.95, 0.65, 0.65, 0.65},
+			["highlight"] 	= {"VERTICAL", 0.3, 0.8, 1, 0.1, 0.9, 1},
+			["checked"]   	= {"VERTICAL", 0.08, 0.9, 0.25, 0.25, 0.9, 0.08},
+			["green"]     	= {"VERTICAL", 0.08, 0.9, 0.25, 0.25, 0.9, 0.08},
+			["red"]       	= {"VERTICAL", 0.5, 0, 0, 0.9, 0.08, 0.08},
+			["yellow"]    	= {"VERTICAL", 1, 0.3, 0, 1, 1, 0},
+			["tan"]       	= {"VERTICAL", 0.15, 0.08, 0, 0.37, 0.22, 0.1},
+			["inverse"]   	= {"VERTICAL", 0.25, 0.25, 0.25, 0.12, 0.12, 0.12},
+			["icon"]      	= {"VERTICAL", 0.5, 0.53, 0.55, 0.8, 0.8, 1},
+			["white"]     	= {"VERTICAL", 0.75, 0.75, 0.75, 1, 1, 1},
+		},
+		["button"] = {
+			["check"]     	= [[Interface\AddOns\SVUI_!Core\assets\buttons\CHECK]],
+			["checkbg"]     = [[Interface\AddOns\SVUI_!Core\assets\buttons\CHECK-BG]],
+			["uncheck"]     = [[Interface\AddOns\SVUI_!Core\assets\buttons\CHECK-DISABLED]],
+			["round"]     	= [[Interface\AddOns\SVUI_!Core\assets\buttons\ROUND-BORDER]],
+			["roundbg"]     = [[Interface\AddOns\SVUI_!Core\assets\buttons\ROUND-BG]],
+			["scrollup"]    = [[Interface\AddOns\SVUI_!Core\assets\buttons\SCROLLBAR-UP]],
+			["scrolldown"]  = [[Interface\AddOns\SVUI_!Core\assets\buttons\SCROLLBAR-DOWN]],
+			["knob"]     	= [[Interface\AddOns\SVUI_!Core\assets\buttons\SCROLLBAR-KNOB]],
+			["option"] 		= [[Interface\AddOns\SVUI_!Core\assets\buttons\SETUP-OPTION]],
+			["arrow"] 		= [[Interface\AddOns\SVUI_!Core\assets\buttons\SETUP-ARROW]],
+			["radio"] 		= [[Interface\AddOns\SVUI_!Core\assets\buttons\RADIO]],
+		},
+		["icon"] = {
+			["default"]     = [[Interface\AddOns\SVUI_!Core\assets\icons\SVUI]],
+			["theme"]       = [[Interface\AddOns\SVUI_!Core\assets\icons\THEME]],
+			["vs"]          = [[Interface\AddOns\SVUI_!Core\assets\icons\VS]],
+			["close"]       = [[Interface\AddOns\SVUI_!Core\assets\icons\CLOSE]],
+			["star"]        = [[Interface\AddOns\SVUI_!Core\assets\icons\FAVORITE-STAR]],
+			["info"]        = [[Interface\AddOns\SVUI_!Core\assets\icons\FAVORITE-STAR]],
+			["move_up"]     = [[Interface\AddOns\SVUI_!Core\assets\icons\MOVE-UP]],
+			["move_down"]   = [[Interface\AddOns\SVUI_!Core\assets\icons\MOVE-DOWN]],
+			["move_left"]   = [[Interface\AddOns\SVUI_!Core\assets\icons\MOVE-LEFT]],
+			["move_right"]  = [[Interface\AddOns\SVUI_!Core\assets\icons\MOVE-RIGHT]],
+			["exitIcon"] 	= [[Interface\AddOns\SVUI_!Core\assets\icons\EXIT]]
+		},
+		["dock"] = {
+			["durabilityLabel"] 	= [[Interface\AddOns\SVUI_!Core\assets\textures\Dock\LABEL-DUR]],
+			["reputationLabel"] 	= [[Interface\AddOns\SVUI_!Core\assets\textures\Dock\LABEL-REP]],
+			["experienceLabel"] 	= [[Interface\AddOns\SVUI_!Core\assets\textures\Dock\LABEL-XP]],
+			["sizeIcon"] 			= [[Interface\AddOns\SVUI_!Core\assets\textures\Dock\DOCK-ICON-SIZE]],
+			["optionsIcon"] 		= [[Interface\AddOns\SVUI_!Core\assets\textures\Dock\DOCK-ICON-OPTIONS]],
+			["breakStuffIcon"] 		= [[Interface\AddOns\SVUI_!Core\assets\textures\Dock\DOCK-ICON-BREAKSTUFF]],
+			["hearthIcon"] 			= [[Interface\AddOns\SVUI_!Core\assets\textures\Dock\DOCK-ICON-HEARTH]],
+			["raidToolIcon"] 		= [[Interface\AddOns\SVUI_!Core\assets\textures\Dock\DOCK-ICON-RAIDTOOL]],
+			["garrisonToolIcon"] 	= [[Interface\AddOns\SVUI_!Core\assets\textures\Dock\DOCK-ICON-GARRISON]],
+			["specSwapIcon"] 		= [[Interface\AddOns\SVUI_!Core\assets\textures\Dock\DOCK-ICON-SPECSWAP]],
+			["powerIcon"] 			= [[Interface\AddOns\SVUI_!Core\assets\textures\Dock\DOCK-ICON-POWER]],
+			["professionIconFile"] 	= [[Interface\AddOns\SVUI_!Core\assets\textures\Dock\PROFESSIONS]],
+			["professionIconCoords"]= {
+				[171] 	= {0,0.25,0,0.25}, 				-- PRO-ALCHEMY
+			    [794] 	= {0.25,0.5,0,0.25,80451}, 		-- PRO-ARCHAELOGY
+			    [164] 	= {0.5,0.75,0,0.25}, 			-- PRO-BLACKSMITH
+			    [185] 	= {0.75,1,0,0.25,818,67097}, 	-- PRO-COOKING
+			    [333] 	= {0,0.25,0.25,0.5,13262}, 		-- PRO-ENCHANTING
+			    [202] 	= {0.25,0.5,0.25,0.5}, 			-- PRO-ENGINEERING
+			    [129] 	= {0.5,0.75,0.25,0.5}, 			-- PRO-FIRSTAID
+			    [773] 	= {0,0.25,0.5,0.75,51005}, 		-- PRO-INSCRIPTION
+			    [755] 	= {0.25,0.5,0.5,0.75,31252},	-- PRO-JEWELCRAFTING
+			    [165] 	= {0.5,0.75,0.5,0.75}, 			-- PRO-LEATHERWORKING
+			    [186] 	= {0.75,1,0.5,0.75}, 			-- PRO-MINING
+			    [197] 	= {0.25,0.5,0.75,1}, 			-- PRO-TAILORING
+			},
+			["sparks"] = {
+				[[Interface\AddOns\SVUI_!Core\assets\textures\Dock\DOCK-SPARKS-1]],
+				[[Interface\AddOns\SVUI_!Core\assets\textures\Dock\DOCK-SPARKS-2]],
+				[[Interface\AddOns\SVUI_!Core\assets\textures\Dock\DOCK-SPARKS-3]],
+			},
+		},
+		["backdrop"] = {
+			["default"] = {
+				bgFile = [[Interface\AddOns\SVUI_!Core\assets\backgrounds\DEFAULT]],
+			    tile = false,
+			    tileSize = 0,
+			    edgeFile = [[Interface\AddOns\SVUI_!Core\assets\borders\DEFAULT]],
+			    edgeSize = 1,
+			    insets =
+			    {
+			        left = 0,
+			        right = 0,
+			        top = 0,
+			        bottom = 0,
+			    },
+			},
+			["button"] = {
+				bgFile = [[Interface\AddOns\SVUI_!Core\assets\backgrounds\BUTTON]],
+			    tile = false,
+			    tileSize = 0,
+			    edgeFile = [[Interface\BUTTONS\WHITE8X8]],
+			    edgeSize = 1,
+			    insets =
+			    {
+			        left = 0,
+			        right = 0,
+			        top = 0,
+			        bottom = 0,
+			    },
+			},
+			["pattern"] = {
+				bgFile = [[Interface\AddOns\SVUI_!Core\assets\backgrounds\pattern\PATTERN1]],
+			    tile = false,
+			    tileSize = 0,
+			    edgeFile = [[Interface\AddOns\SVUI_!Core\assets\borders\TEXTURED]],
+					edgeSize = 1,
+			    insets =
+			    {
+			        left = 0,
+			        right = 0,
+			        top = 0,
+			        bottom = 0,
+			    },
+			},
+			["premium"] = {
+				bgFile = [[Interface\AddOns\SVUI_!Core\assets\backgrounds\art\ART1]],
+			    tile = false,
+			    tileSize = 0,
+			    edgeFile = [[Interface\AddOns\SVUI_!Core\assets\borders\TEXTURED]],
+			    edgeSize = 15,
+			    insets =
+			    {
+							left = 3,
+							right = 3,
+							top = 3,
+							bottom = 3,
+			    },
+			},
+			["model"] = {
+				bgFile = [[Interface\AddOns\SVUI_!Core\assets\backgrounds\MODEL]],
+			    tile = false,
+			    tileSize = 0,
+			    edgeFile = [[Interface\AddOns\SVUI_!Core\assets\borders\DEFAULT]],
+					edgeSize = 1,
+			    insets =
+			    {
+			        left = 0,
+			        right = 0,
+			        top = 0,
+			        bottom = 0,
+			    },
+			},
+			["buttonred"] = {
+				bgFile = [[Interface\AddOns\SVUI_!Core\assets\backgrounds\BUTTON]],
+			    tile = false,
+			    tileSize = 0,
+			    edgeFile = [[Interface\AddOns\SVUI_!Core\assets\borders\DEFAULT]],
+			    edgeSize = 1,
+			    insets =
+			    {
+			        left = 0,
+			        right = 0,
+			        top = 0,
+			        bottom = 0,
+			    },
+			},
+			["aura"] = {
+				bgFile = [[Interface\BUTTONS\WHITE8X8]],
+			    tile = false,
+			    tileSize = 0,
+			    edgeFile = [[Interface\AddOns\SVUI_!Core\assets\borders\SHADOW]],
+			    edgeSize = 1,
+			    insets =
+			    {
+			        left = 1,
+			        right = 1,
+			        top = 1,
+			        bottom = 1,
+			    },
+			},
+			["glow"] = {
+				bgFile = [[Interface\BUTTONS\WHITE8X8]],
+			    tile = false,
+			    tileSize = 0,
+			    edgeFile = [[Interface\AddOns\SVUI_!Core\assets\borders\SHADOW]],
+			    edgeSize = 3,
+			    insets =
+			    {
+			        left = 0,
+			        right = 0,
+			        top = 0,
+			        bottom = 0,
+			    },
+			},
+			["tooltip"] = {
+				bgFile = [[Interface\DialogFrame\UI-DialogBox-Background]],
+			    tile = false,
+			    tileSize = 0,
+			    edgeFile = [[Interface\AddOns\SVUI_!Core\assets\textures\EMPTY]],
+			    edgeSize = 1,
+			    insets =
+			    {
+			        left = 0,
+			        right = 0,
+			        top = 0,
+			        bottom = 0,
+			    },
+			},
+			["outline"] = {
+				bgFile = [[Interface\AddOns\SVUI_!Core\assets\textures\EMPTY]],
+			    tile = false,
+			    tileSize = 0,
+			    edgeFile = [[Interface\AddOns\SVUI_!Core\assets\borders\DEFAULT]],
+			    edgeSize = 1,
+			    insets =
+			    {
+			        left = 0,
+			        right = 0,
+			        top = 0,
+			        bottom = 0,
+			    },
+			},
+			["shadowoutline"] = {
+				bgFile = [[Interface\AddOns\SVUI_!Core\assets\textures\EMPTY]],
+			    tile = false,
+			    tileSize = 0,
+			    edgeFile = [[Interface\AddOns\SVUI_!Core\assets\borders\SHADOW]],
+			    edgeSize = 3,
+			    insets =
+			    {
+			        left = 0,
+			        right = 0,
+			        top = 0,
+			        bottom = 0,
+			    },
+			},
+			["darkened"] = {
+				bgFile = [[Interface\AddOns\SVUI_!Core\assets\backgrounds\DARK]],
+			    tile = false,
+			    tileSize = 0,
+			    edgeFile = [[Interface\AddOns\SVUI_!Core\assets\borders\SHADOW]],
+			    edgeSize = 3,
+			    insets =
+			    {
+			        left = 0,
+			        right = 0,
+			        top = 0,
+			        bottom = 0,
+			    },
+			},
+		}
+	};
+end
+---- SOME CORE VARS ----
+SV.DialogFontDefault = "SVUI Dialog Font";
+if(GetLocale() ~= "enUS") then
+	SV.DialogFontDefault = "SVUI Default Font";
+end
+SV.SplashImage 	= [[Interface\AddOns\SVUI_!Core\assets\textures\SPLASH]];
+SV.BaseTexture 	= [[Interface\AddOns\SVUI_!Core\assets\backgrounds\DEFAULT]];
+SV.NoTexture 	  = [[Interface\AddOns\SVUI_!Core\assets\textures\EMPTY]];
+
+---------------------------------------------------------------------
+-- Returns a color value based on percentages.
+-- @function ColorGradient
+-- @tparam number percentage The needed gradient percent.
+-- @param ... (vararg) remaining arguments are up to 3 sets of numeric color values (r,g,b).
+-- @return red value, green value, blue value
+-- @usage SV:ColorGradient(50,1,0,0,1,1,0,0,1,0)
+---------------------------------------------------------------------
+
+function SV:ColorGradient(percentage, ...)
+	if percentage >= 1 then
+		return select(select('#', ...) - 2, ...)
+	elseif percentage <= 0 then
+		return ...
+	end
+	local num = select('#', ...) / 3
+	local segment, relative = modf(percentage*(num-1))
+	local r1, g1, b1, r2, g2, b2 = select((segment*3)+1, ...)
+	local rOut = r1 + (r2-r1)*relative;
+	local gOut = g1 + (g2-g1)*relative;
+	local bOut = b1 + (b2-b1)*relative;
+	return rOut, gOut, bOut
+end
+
+---------------------------------------------------------------------
+-- Returns a hexadecimal color value.
+-- @function HexColor
+-- @tparam number red Color, red value.
+-- @tparam number green Color, green value.
+-- @tparam number blue Color, blue value.
+-- @return Hexadecimal string color
+-- @usage SV:HexColor(0.1, 0.2, 0.3)
+---------------------------------------------------------------------
+
+function SV:HexColor(red, green, blue)
+	local r,g,b;
+	if red and type(red) == "string" then
+		local t
+		if(self.media) then
+			t = self.media.color[red]
+			if((not t) and (self.media.extended and self.media.extended.unitframes)) then
+				t = self.media.extended.unitframes[red]
+			end
+		end
+		if t then
+			r,g,b = t[1],t[2],t[3]
+		else
+			r,g,b = 0,0,0
+		end
+	else
+		r = type(red) == "number" and red or 0;
+		g = type(green) == "number" and green or 0;
+		b = type(blue) == "number" and blue or 0;
+	end
+	r = (r < 0 or r > 1) and 0 or (r * 255)
+	g = (g < 0 or g > 1) and 0 or (g * 255)
+	b = (b < 0 or b > 1) and 0 or (b * 255)
+	local hexString = ("%02x%02x%02x"):format(r,g,b)
+	return hexString
+end
+
+---- ALTERING GLOBAL FONTS ----
+
+local function UpdateChatFontSizes()
+	_G.CHAT_FONT_HEIGHTS[1] = 8
+	_G.CHAT_FONT_HEIGHTS[2] = 9
+	_G.CHAT_FONT_HEIGHTS[3] = 10
+	_G.CHAT_FONT_HEIGHTS[4] = 11
+	_G.CHAT_FONT_HEIGHTS[5] = 12
+	_G.CHAT_FONT_HEIGHTS[6] = 13
+	_G.CHAT_FONT_HEIGHTS[7] = 14
+	_G.CHAT_FONT_HEIGHTS[8] = 15
+	_G.CHAT_FONT_HEIGHTS[9] = 16
+	_G.CHAT_FONT_HEIGHTS[10] = 17
+	_G.CHAT_FONT_HEIGHTS[11] = 18
+	_G.CHAT_FONT_HEIGHTS[12] = 19
+	_G.CHAT_FONT_HEIGHTS[13] = 20
+end
+
+hooksecurefunc("FCF_ResetChatWindows", UpdateChatFontSizes)
+
+local function ChangeGlobalFonts()
+	local fontsize = SV.media.shared.font.default.size;
+	STANDARD_TEXT_FONT = LSM:Fetch("font", SV.media.shared.font.default.file);
+	UNIT_NAME_FONT = LSM:Fetch("font", SV.media.shared.font.caps.file);
+	NAMEPLATE_FONT = STANDARD_TEXT_FONT
+	UpdateChatFontSizes()
+	UIDROPDOWNMENU_DEFAULT_TEXT_HEIGHT = fontsize
+end
+
+---- FONT TEMPLATING METHODS ----
+
+local ManagedFonts = {};
+
+---------------------------------------------------------------------
+-- Adds a font object to the custom SVUI font manager.
+-- @function FontManager
+-- @param obj Font object.
+-- @tparam string template Internal name of the media-font to be assigned.
+-- @param abstract A multi-use flag.
+-- @param sizeMod Font size override.
+-- @param styleOverride Outline override.
+-- @tparam number red Color, red value.
+-- @tparam number green Color, green value.
+-- @tparam number blue Color, blue value.
+-- @usage SV:FontManager(FontObject, 'default', false, false, 'OUTLINE', 1, 1, 1)
+---------------------------------------------------------------------
+
+function SV:FontManager(obj, template, abstract, sizeMod, styleOverride, red, green, blue)
+	-- @todo document this better
+	if not obj then return end
+	template = template or "default";
+	local info = SV.media.shared.font[template] or SV.media.shared.font.default;
+	if(not info) then return end
+
+	local isSystemFont = false;
+	if(abstract and (abstract == 'SYSTEM')) then
+		isSystemFont = true;
+	end
+
+	local file = SV.media.font[template] or SV.media.font.default;
+	local size = info.size;
+	local outline = info.outline;
+
+	if(styleOverride) then
+		obj.___fontOutline = styleOverride;
+		outline = styleOverride;
+	end
+
+	obj.___fontSizeMod = sizeMod or 0;
+	obj:SetFont(file, (size + obj.___fontSizeMod), outline)
+
+	if(abstract == 'SHADOW') then
+		obj:SetShadowColor(0, 0, 0, 0.75)
+		obj:SetShadowOffset(2, -2)
+	elseif(not isSystemFont) then
+		if((not info.outline) or info.outline ~= "NONE") then
+			obj:SetShadowColor(0, 0, 0, 0)
+		elseif(info.outline and info.outline == "NONE") then
+			obj:SetShadowColor(0, 0, 0, 0.75)
+		else
+			obj:SetShadowColor(0, 0, 0, 0.2)
+		end
+		if(not obj.noShadowOffset) then
+			obj:SetShadowOffset(1, -1)
+		else
+			obj:SetShadowOffset(0, 0)
+		end
+		obj:SetJustifyH(abstract or "CENTER")
+		obj:SetJustifyV("MIDDLE")
+	end
+
+	if(red and green and blue) then
+		obj:SetTextColor(red, green, blue);
+	end
+
+	if(not ManagedFonts[template]) then
+		ManagedFonts[template] = {}
+	end
+
+	ManagedFonts[template][obj] = true
+end
+
+local function _shadowFont(globalName, template, sizeMod, styleOverride, cR, cG, cB)
+	if(not template) then return end
+	if(not _G[globalName]) then return end
+	styleOverride = styleOverride or "NONE"
+	SV:FontManager(_G[globalName], template, "SHADOW", sizeMod, styleOverride, cR, cG, cB);
+end
+
+local function _alterFont(globalName, template, sizeMod, styleOverride, cR, cG, cB)
+	if(not template) then return end
+	if(not _G[globalName]) then return end
+	styleOverride = styleOverride or "NONE"
+	SV:FontManager(_G[globalName], template, "SYSTEM", sizeMod, styleOverride, cR, cG, cB);
+end
+
+local function ChangeSystemFonts()
+	_shadowFont("GameFontNormal", "default", 0, "NONE")
+	_alterFont("GameFontWhite", "default", 0, 'OUTLINE', 1, 1, 1)
+	_alterFont("GameFontWhiteSmall", "default", 0, 'NONE', 1, 1, 1)
+	_alterFont("GameFontBlack", "default", 0, 'NONE', 0, 0, 0)
+	_alterFont("GameFontBlackSmall", "default", -1, 'NONE', 0, 0, 0)
+	_alterFont("GameFontNormalMed2", "default", 2)
+	_alterFont("Game15Font_o1", "number", 1, "OUTLINE")
+	_alterFont("GameFontNormalLarge", "default")
+	_alterFont("GameFontNormalLargeOutline", "default")
+	_alterFont("GameFontHighlightSmall", "default")
+	_alterFont("GameFontHighlight", "default", 1)
+	_alterFont("GameFontHighlightLeft", "default", 1)
+	_alterFont("GameFontHighlightRight", "default", 1)
+	_alterFont("GameFontHighlightLarge2", "default", 2)
+	_alterFont("MailFont_Large", "default", 3)
+	_alterFont("SystemFont_Med1", "default")
+	_alterFont("SystemFont_Med3", "default")
+	_alterFont("SystemFont_Outline_Small", "default", 0, "OUTLINE")
+	_alterFont("FriendsFont_Normal", "default")
+	_alterFont("FriendsFont_Small", "default")
+	_alterFont("FriendsFont_Large", "default", 3)
+	_alterFont("FriendsFont_UserText", "default", -1)
+	_alterFont("SystemFont_Small", "default", -1)
+	_alterFont("GameFontNormalSmall", "default", -1)
+	_alterFont("GameFontNormalSmall2", "default")
+	_alterFont("NumberFont_Shadow_Med", "default", -1, "OUTLINE")
+	_alterFont("NumberFont_Shadow_Small", "default", -1, "OUTLINE")
+	_alterFont("SystemFont_Tiny", "default", -1)
+	_alterFont("SystemFont_Shadow_Med1", "default")
+	_alterFont("SystemFont_Shadow_Med1_Outline", "default")
+	_alterFont("SystemFont_Shadow_Med2", "default")
+	_alterFont("SystemFont_Shadow_Med3", "default")
+	_alterFont("SystemFont_Large", "default")
+	_alterFont("SystemFont_Huge1", "default", 4)
+	_alterFont("SystemFont_Huge1_Outline", "default", 4)
+	_alterFont("SystemFont_Shadow_Small", "default")
+	_alterFont("SystemFont_Shadow_Large", "default", 3)
+	_alterFont("QuestFont", "dialog");
+	_alterFont("QuestFont_Enormous", "zone", 15, "OUTLINE");
+	_alterFont("SpellFont_Small", "dialog", 0, "OUTLINE", 1, 1, 1);
+	_alterFont("SystemFont_Shadow_Outline_Large", "title", 0, "OUTLINE");
+	_alterFont("SystemFont_Shadow_Outline_Huge2", "title", 8, "OUTLINE");
+	_alterFont("GameFont_Gigantic", "alert", 0, "OUTLINE", 32)
+	_alterFont("SystemFont_Shadow_Huge1", "alert", 0, "OUTLINE")
+	_alterFont("SystemFont_OutlineThick_Huge4", "zone", 6, "OUTLINE");
+	_alterFont("SystemFont_OutlineThick_WTF", "zone", 9, "OUTLINE");
+	_alterFont("SystemFont_OutlineThick_WTF2", "zone", 15, "OUTLINE");
+	_alterFont("QuestFont_Large", "zone", -3);
+	_alterFont("QuestFont_Huge", "zone", -2);
+	_alterFont("QuestFont_Super_Huge", "zone");
+	_alterFont("QuestFont_Shadow_Huge", "zone");
+	_alterFont("SystemFont_OutlineThick_Huge2", "zone", 2, "OUTLINE");
+	_alterFont("Game18Font", "number", 1)
+	_alterFont("Game24Font", "number", 3)
+	_alterFont("Game27Font", "number", 5)
+	_alterFont("Game30Font", "number_big")
+	_alterFont("Game32Font", "number_big", 1)
+	_alterFont("NumberFont_OutlineThick_Mono_Small", "number", 0, "OUTLINE")
+	_alterFont("NumberFont_Outline_Huge", "number_big", 0, "OUTLINE")
+	_shadowFont("NumberFont_Outline_Large", "number", 2, "OUTLINE")
+	_alterFont("NumberFont_Outline_Med", "number", 1, "OUTLINE")
+	_alterFont("NumberFontNormal", "number", 0, "OUTLINE")
+	_alterFont("NumberFont_GameNormal", "number", 0, "OUTLINE")
+	_alterFont("NumberFontNormalRight", "number", 0, "OUTLINE")
+	_alterFont("NumberFontNormalRightRed", "number", 0, "OUTLINE")
+	_alterFont("NumberFontNormalRightYellow", "number", 0, "OUTLINE")
+	_alterFont("GameTooltipHeader", "tipheader")
+	_alterFont("Tooltip_Med", "tipdialog")
+	_alterFont("Tooltip_Small", "tipdialog", -1)
+	_alterFont("SystemFont_Shadow_Huge3", "combat", -10, "OUTLINE")
+	_alterFont("CombatTextFont", "combat", 64, "OUTLINE")
+end
+
+local function _defineFont(globalName, template)
+	if(not template) then return end
+	if(not _G[globalName]) then return end
+	SV:FontManager(_G[globalName], template);
+end
+
+local function UpdateFontTemplate(template)
+	template = template or "default";
+	local info = SV.media.shared.font[template];
+	if(not info) then return end
+	local file = LSM:Fetch("font", info.file);
+	local size = info.size;
+	local line = info.outline;
+	local list = ManagedFonts[template];
+	if(not list) then return end
+	for object in pairs(list) do
+		if object then
+			if(object.___fontOutline) then
+				object:SetFont(file, (size + object.___fontSizeMod), object.___fontOutline);
+			else
+				object:SetFont(file, (size + object.___fontSizeMod), line);
+			end
+		else
+			ManagedFonts[template][object] = nil;
+		end
+	end
+end
+
+local function UpdateAllFontTemplates()
+	for template, _ in pairs(ManagedFonts) do
+		UpdateFontTemplate(template)
+	end
+	ChangeGlobalFonts();
+end
+
+local function UpdateFontGroup(...)
+	for i = 1, select('#', ...) do
+		local template = select(i, ...)
+		if not template then break end
+		UpdateFontTemplate(template)
+	end
+end
+
+SV.Events:On("ALL_FONTS_UPDATED", UpdateAllFontTemplates, true);
+SV.Events:On("FONT_GROUP_UPDATED", UpdateFontGroup, true);
+
+---------------------------------------------------------------------
+-- Create an add-in set of specific font configuration options.
+-- @function GenerateFontOptionGroup
+-- @tparam string groupName Options group to insert into.
+-- @tparam number groupCount Option order for this option.
+-- @tparam string groupOverview Option group name for this option.
+-- @tparam table groupList Array of relevant font data.
+-- @usage SV:GenerateFontOptionGroup(groupName, groupCount, groupOverview, groupList)
+---------------------------------------------------------------------
+
+function SV:GenerateFontOptionGroup(groupName, groupCount, groupOverview, groupList)
+    self.Options.args.Fonts.args.fontGroup.args[groupName] = {
+        order = groupCount,
+        type = "group",
+        name = groupName,
+        args = {
+            overview = {
+                order = 1,
+                name = groupOverview,
+                type = "description",
+                width = "full",
+            },
+            spacer0 = {
+                order = 2,
+                name = "",
+                type = "description",
+                width = "full",
+            },
+        },
+    };
+
+    local orderCount = 3;
+    for template, info in pairs(groupList) do
+        self.Options.args.Fonts.args.fontGroup.args[groupName].args[template] = {
+            order = orderCount + info.order,
+            type = "group",
+            guiInline = true,
+            name = info.name,
+            get = function(key)
+                return self.media.shared.font[template][key[#key]]
+            end,
+            set = function(key,value)
+                self.media.shared.font[template][key[#key]] = value;
+                if(groupCount == 1) then
+                    self:StaticPopup_Show("RL_CLIENT")
+                else
+                    self.Events:Trigger("FONT_GROUP_UPDATED", template);
+                end
+            end,
+            args = {
+                description = {
+                    order = 1,
+                    name = info.desc,
+                    type = "description",
+                    width = "full",
+                },
+                spacer1 = {
+                    order = 2,
+                    name = "",
+                    type = "description",
+                    width = "full",
+                },
+                spacer2 = {
+                    order = 3,
+                    name = "",
+                    type = "description",
+                    width = "full",
+                },
+                file = {
+                    type = "select",
+                    dialogControl = 'LSM30_Font',
+                    order = 4,
+                    name = self.L["Font File"],
+                    desc = self.L["Set the font file to use with this font-type."],
+                    values = _G.AceVillainWidgets.font,
+                },
+                outline = {
+                    order = 5,
+                    name = self.L["Font Outline"],
+                    desc = self.L["Set the outlining to use with this font-type."],
+                    type = "select",
+                    values = {
+                        ["NONE"] = self.L["None"],
+                        ["OUTLINE"] = "OUTLINE",
+                        ["MONOCHROMEOUTLINE"] = "MONOCROMEOUTLINE",
+                        ["THICKOUTLINE"] = "THICKOUTLINE"
+                    },
+                },
+                size = {
+                    order = 6,
+                    name = self.L["Font Size"],
+                    desc = self.L["Set the font size to use with this font-type."],
+                    type = "range",
+                    min = 6,
+                    max = 64,
+                    step = 1,
+                },
+            }
+        }
+    end
+end
+
+---- MEDIA CORE ----
+
+local function tablesplice(mergeTable, targetTable)
+    if type(targetTable) ~= "table" then targetTable = {} end
+    if type(mergeTable) == 'table' then
+	    for key,val in pairs(mergeTable) do
+	        if type(val) == "table" then
+	            targetTable[key] = tablesplice(val, targetTable[key])
+	        else
+	            targetTable[key] = val
+	        end
+	    end
+    end
+    return targetTable
+end
+
+SV.media = tablesplice(SV.mediadefaults, {});
+
+local GLOBAL_SVUI_FONTS = {
+	["SVUI_Font_Default"] = "default",
+	["SVUI_Font_Aura"] = "aura",
+	["SVUI_Font_Number"] = "number",
+	["SVUI_Font_Number_Huge"] = "number_big",
+	["SVUI_Font_Header"] = "header",
+	["SVUI_Font_Data"] = "data",
+	["SVUI_Font_Caps"] = "caps",
+	["SVUI_Font_Narrator"] = "narrator",
+	["SVUI_Font_Pixel"] = "pixel",
+	["SVUI_Font_Roll"] = "rolldialog",
+	["SVUI_Font_Roll_Number"] = "rollnumber",
+	["SVUI_Font_Loot"] = "lootdialog",
+	["SVUI_Font_Loot_Number"] = "lootnumber",
+};
+
+function SV:AssignMedia(mediaType, id, ...)
+	if((not mediaType) or (not id)) then return end
+
+	if(mediaType == "globalfont") then
+		local globalName = ...;
+		if(globalName) then
+			GLOBAL_SVUI_FONTS[globalName] = id;
+		end
+		return
+	end
+
+	if(mediaType == "template") then
+		local globalName = ...;
+		if(globalName) then
+			self.API.Templates[id] = globalName;
+		end
+		return
+	end
+
+	local settings = self.mediadefaults.shared[mediaType];
+	if(settings) then
+		if(mediaType == "font") then
+			local file, size, outline = ...
+			if(settings[id]) then
+				if(file) then settings[id].file = file end
+				if(size) then settings[id].size = size end
+				if(outline) then settings[id].outline = outline end
+			else
+				file = file or "SVUI Default Font";
+				size = size or 12;
+				outline = outline or "OUTLINE";
+				settings[id] = {file = file, size = size, outline = outline}
+			end
+		elseif(mediaType == "statusbar") then
+			local file, offset = ...
+			if(settings[id]) then
+				if(file) then settings[id].file = file end
+				if(offset) then settings[id].offset = offset end
+			else
+				file = file or "SVUI BasicBar";
+				offset = offset or 0;
+				settings[id] = {file = file, offset = offset}
+			end
+		elseif(mediaType == "background") then
+			local file, size, tiled = ...
+			if(settings[id]) then
+				if(file) then settings[id].file = file end
+				if(size) then settings[id].size = size end
+				if(tiled) then settings[id].tiled = tiled end
+			else
+				file = file or "SVUI Default BG";
+				size = size or 0;
+				tiled = tiled or false;
+				settings[id] = {file = file, size = size, tiled = tiled}
+			end
+		elseif(mediaType == "border") then
+			local file, size = ...
+			if(settings[id]) then
+				if(file) then settings[id].file = file end
+				if(size) then settings[id].size = size end
+			else
+				file = file or "SVUI Border";
+				size = size or 1;
+				settings[id] = {file = file, size = size}
+			end
+		end
+	else
+		settings = self.mediadefaults[mediaType];
+		if(settings) then
+			if(settings[id]) then
+				if(type(settings[id]) == "table") then
+					for i = 1, select('#', ...) do
+						local v = select(i, ...)
+						if(not v) then break end
+						if(type(v) == "table") then
+							settings[id] = tablesplice(v, settings[id]);
+						else
+							settings[id][i] = v;
+						end
+					end
+				else
+					local newMedia = ...;
+					if(newMedia) then
+						settings[id] = newMedia;
+					end
+				end
+			else
+				local valueCount = select('#', ...)
+				if(valueCount > 1) then
+					settings[id] = {};
+					for i = 1, select('#', ...) do
+						local v = select(i, ...)
+						if(not v) then break end
+						if(type(v) == "table") then
+							settings[id] = tablesplice(v, settings[id]);
+						else
+							settings[id][i] = v;
+						end
+					end
+				else
+					local newMedia = ...;
+					if(newMedia) then
+						settings[id] = newMedia;
+					end
+				end
+			end
+		end
+	end
+end
+
+function SV:UpdateSharedMedia()
+	local settings = self.media.shared
+	for mediaType, mediaData in pairs(settings) do
+		if(self.media[mediaType]) then
+			for name,userSettings in pairs(mediaData) do
+				if(userSettings.file) then
+					self.media[mediaType][name] = LSM:Fetch(mediaType, userSettings.file)
+				end
+			end
+		end
+	end
+
+	for name, bd in pairs(self.media.backdrop) do
+		if(self.media.background[name] and self.media.border[name]) then
+			local bordersetup = self.media.shared.border[name];
+			local bgsetup = self.media.shared.background[name];
+			bd.bgFile = self.media.background[name];
+		  bd.tile = bgsetup.tiled;
+		  bd.tileSize = bgsetup.size;
+			bd.edgeFile = self.media.border[name];
+			bd.edgeSize = bordersetup.size;
+			local offset = bordersetup.size * 0.2;
+			bd.insets = {
+				left = offset,
+				right = offset,
+				top = offset,
+				bottom = offset,
+			}
+		end
+	end
+
+	local default = self.media.color.default
+	self.media.gradient.default = {"VERTICAL", default[1]*.25, default[2]*.25, default[3]*.25, default[1], default[2], default[3]}
+
+	local secondary = self.media.color.secondary
+	self.media.gradient.secondary = {"VERTICAL", secondary[1]*.25, secondary[2]*.25, secondary[3]*.25, secondary[1], secondary[2], secondary[3]}
+
+	local cColor1 = CUSTOM_CLASS_COLORS[classToken]
+	local cColor2 = RAID_CLASS_COLORS[classToken]
+    if(not self.db.general.customClassColor or not CUSTOM_CLASS_COLORS[classToken]) then
+        cColor1 = RAID_CLASS_COLORS[classToken]
+    end
+	local r1,g1,b1 = cColor1.r,cColor1.g,cColor1.b
+	local r2,g2,b2 = cColor2.r*.25, cColor2.g*.25, cColor2.b*.25
+	local ir1,ig1,ib1 = (1 - r1), (1 - g1), (1 - b1)
+	local ir2,ig2,ib2 = (1 - cColor2.r)*.25, (1 - cColor2.g)*.25, (1 - cColor2.b)*.25
+	self.media.color.class = {r1, g1, b1, 1}
+	self.media.color.bizzaro = {ir1, ig1, ib1, 1}
+	self.media.bordercolor.class = {r1, g1, b1, 1}
+	self.media.gradient.class = {"VERTICAL", r2, g2, b2, r1, g1, b1}
+	self.media.gradient.bizzaro = {"VERTICAL", ir2, ig2, ib2, ir1, ig1, ib1}
+
+	local special = self.media.color.special
+	---- self.media.gradient.special = {"VERTICAL", special[1], special[2], special[3], r1, g1, b1} ----
+	---- self.media.color.special = {r1*.5, g1*.5, b1*.5, 1} ----
+	self.media.gradient.special = {"VERTICAL", special[1]*.25, special[2]*.25, special[3]*.25, special[1], special[2], special[3]}
+	---- self.media.gradient.special = {"VERTICAL",special[1], special[2], special[3], default[1], default[2], default[3]} ----
+
+	self.Events:Trigger("SHARED_MEDIA_UPDATED");
+	if(not InCombatLockdown()) then
+		collectgarbage("collect");
+	end
+end
+
+function SV:RefreshAllMedia()
+	self:UpdateSharedMedia();
+
+	ChangeGlobalFonts();
+	ChangeSystemFonts();
+
+	for globalName, id in pairs(GLOBAL_SVUI_FONTS) do
+		local obj = _G[globalName];
+		if(obj) then
+			self:FontManager(obj, id);
+		end
+	end
+
+	self.Events:Trigger("ALL_FONTS_UPDATED");
+	self.MediaInitialized = true;
+end
diff --git a/SVUI_!Core/system/misc.lua b/SVUI_!Core/system/misc.lua
new file mode 100644
index 0000000..a25494c
--- /dev/null
+++ b/SVUI_!Core/system/misc.lua
@@ -0,0 +1,860 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack            = _G.unpack;
+local select            = _G.select;
+local assert            = _G.assert;
+local type              = _G.type;
+local error             = _G.error;
+local pcall             = _G.pcall;
+local print             = _G.print;
+local ipairs            = _G.ipairs;
+local pairs             = _G.pairs;
+local next              = _G.next;
+local tostring          = _G.tostring;
+local tonumber          = _G.tonumber;
+local collectgarbage    = _G.collectgarbage;
+local string        = _G.string;
+local split         = string.split;
+local upper         = string.upper;
+local format        = string.format;
+local find          = string.find;
+local match         = string.match;
+local gsub          = string.gsub;
+local math 			= _G.math;
+local min 			= math.min;
+local cos, deg, rad, sin = math.cos, math.deg, math.rad, math.sin;
+local random 		= math.random;
+local wipe          = _G.wipe;
+--BLIZZARD API
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+local GameTooltip           = _G.GameTooltip;
+local ReloadUI              = _G.ReloadUI;
+local hooksecurefunc        = _G.hooksecurefunc;
+local IsAltKeyDown          = _G.IsAltKeyDown;
+local IsShiftKeyDown        = _G.IsShiftKeyDown;
+local IsControlKeyDown      = _G.IsControlKeyDown;
+local IsModifiedClick       = _G.IsModifiedClick;
+local PlaySound             = _G.PlaySound;
+local PlaySoundFile         = _G.PlaySoundFile;
+local PlayMusic             = _G.PlayMusic;
+local StopMusic             = _G.StopMusic;
+local ToggleFrame           = _G.ToggleFrame;
+local ERR_NOT_IN_COMBAT     = _G.ERR_NOT_IN_COMBAT;
+local RAID_CLASS_COLORS     = _G.RAID_CLASS_COLORS;
+local CUSTOM_CLASS_COLORS   = _G.CUSTOM_CLASS_COLORS;
+local SendChatMessage       = _G.SendChatMessage;
+local GetSpellLink          = _G.GetSpellLink;
+local UnitName              = _G.UnitName;
+local UnitClass             = _G.UnitClass;
+local UnitIsPlayer          = _G.UnitIsPlayer;
+local UnitReaction          = _G.UnitReaction;
+local UnitExists            = _G.UnitExists;
+local UnitIsUnit            = _G.UnitIsUnit;
+local UnitInRaid            = _G.UnitInRaid;
+local UnitInParty           = _G.UnitInParty;
+local UnitGUID              = _G.UnitGUID;
+local UnitIsDead            = _G.UnitIsDead;
+local UnitIsGroupLeader     = _G.UnitIsGroupLeader;
+local UnitIsGroupAssistant  = _G.UnitIsGroupAssistant;
+local IsEveryoneAssistant   = _G.IsEveryoneAssistant;
+local GetItemInfo           = _G.GetItemInfo;
+local BuyMerchantItem       = _G.BuyMerchantItem;
+local GetMerchantItemLink   = _G.GetMerchantItemLink;
+local GetMerchantItemMaxStack     = _G.GetMerchantItemMaxStack;
+local UnitDetailedThreatSituation = _G.UnitDetailedThreatSituation;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...);
+local L = SV.L;
+--[[
+##########################################################
+LOCALS
+##########################################################
+]]--
+local PlayerName = UnitName("player");
+local ThreatMeter = _G["SVUI_ThreatOMeter"];
+
+--[[ LOCALS ]]--
+local BARFILE = [[Interface\AddOns\SVUI_!Core\assets\textures\Doodads\THREAT-BAR]];
+local TEXTUREFILE = [[Interface\AddOns\SVUI_!Core\assets\textures\Doodads\THREAT-BAR-ELEMENTS]];
+local REACTION_COLORS = {
+	[1] = {0.92, 0.15, 0.15},
+	[2] = {0.92, 0.15, 0.15},
+	[3] = {0.92, 0.15, 0.15},
+	[4] = {0.85, 0.85, 0.13},
+	[5] = {0.19, 0.85, 0.13},
+	[6] = {0.19, 0.85, 0.13},
+	[7] = {0.19, 0.85, 0.13},
+	[8] = {0.19, 0.85, 0.13},
+};
+local Reactions = {
+	Woot = {
+		[29166] = true, [20484] = true, [61999] = true,
+		[20707] = true, [50769] = true, [2006] = true,
+		[7328] = true, [2008] = true, [115178] = true,
+		[110478] = true, [110479] = true, [110482] = true,
+		[110483] = true, [110484] = true, [110485] = true,
+		[110486] = true, [110488] = true, [110490] = true,
+		[110491] = true
+	},
+	LookWhatICanDo = {
+		34477, 19801, 57934, 633, 20484, 113269, 61999,
+		20707, 2908, 120668, 16190, 64901, 108968
+	},
+	Toys = {
+		[61031] = true, [49844] = true
+	},
+	Bots = {
+		[22700] = true, [44389] = true, [54711] = true,
+		[67826] = true, [126459] = true
+	},
+	Portals = {
+		[10059] = true, [11416] = true, [11419] = true,
+		[32266] = true, [49360] = true, [33691] = true,
+		[88345] = true, [132620] = true, [11417] = true,
+		[11420] = true, [11418] = true, [32267] = true,
+		[49361] = true, [35717] = true, [88346] = true,
+		[132626] = true, [53142] = true
+	},
+	StupidHat = {
+		[1] = {88710, 33820, 19972, 46349, 92738},
+		[2] = {32757},
+		[8] = {50287, 19969},
+		[15] = {65360, 65274},
+		[16] = {44050, 19970, 84660, 84661, 45992, 86559, 45991},
+		[17] = {86558}
+	}
+};
+local SAPPED_MESSAGE = {
+	"Oh Hell No ... {rt8}SAPPED{rt8}",
+	"{rt8}SAPPED{rt8} ...Someone's about to get slapped!",
+	"Mother Fu... {rt8}SAPPED{rt8}",
+	"{rt8}SAPPED{rt8} ...How cute",
+	"{rt8}SAPPED{rt8} ...Ain't Nobody Got Time For That!",
+	"Uh-Oh... {rt8}SAPPED{rt8}"
+};
+local ReactionEmotes = {
+	"SALUTE",
+	"THANK",
+	"DRINK"
+};
+local REACTION_INTERRUPT, REACTION_WOOT, REACTION_LOOKY, REACTION_SHARE, REACTION_EMOTE, REACTION_CHAT = false, false, false, false, false, false;
+
+local MsgTest = function(warning)
+	if IsInGroup(LE_PARTY_CATEGORY_INSTANCE) then
+		return "INSTANCE_CHAT"
+	elseif IsInRaid(LE_PARTY_CATEGORY_HOME) then
+		if warning and (UnitIsGroupLeader("player") or UnitIsGroupAssistant("player") or IsEveryoneAssistant()) then
+			return "RAID_WARNING"
+		else
+			return "RAID"
+		end
+	elseif IsInGroup(LE_PARTY_CATEGORY_HOME) then
+		return "PARTY"
+	end
+	return "SAY"
+end
+--[[
+##########################################################
+MERCHANT MAX STACK
+##########################################################
+]]--
+local BuyMaxStack = function(self, ...)
+	if ( IsAltKeyDown() ) then
+		local index = self:GetID()
+		local itemLink = GetMerchantItemLink(index)
+		if not itemLink then return end
+		local price = select(3, GetMerchantItemInfo(index))
+		local maxStack = select(8, GetItemInfo(itemLink))
+		local currencyCount = GetMerchantItemCostInfo(index)
+		if ( maxStack and maxStack > 1 ) then
+			local maxAllowed = GetMerchantItemMaxStack(index);
+			if(currencyCount == 0) then
+				local canAfford = GetMoney() / maxStack;
+				BuyMerchantItem(index, min(maxAllowed,canAfford));
+			else
+				BuyMerchantItem(index, maxAllowed);
+			end
+		end
+	end
+end
+
+local MaxStackTooltip = function(self)
+	if(not GameTooltip.InjectedDouble) then
+		GameTooltip.InjectedDouble = {}
+	else
+		wipe(GameTooltip.InjectedDouble)
+	end
+	local itemLink = GetMerchantItemLink(self:GetID())
+	if not itemLink then return end
+	local maxStack = select(8, GetItemInfo(itemLink))
+	if((not maxStack) or (maxStack < 2)) then return end
+    GameTooltip.InjectedDouble[1] = "[Alt + Click]"
+    GameTooltip.InjectedDouble[2] = "Buy a full stack."
+    GameTooltip.InjectedDouble[3] = 0
+    GameTooltip.InjectedDouble[4] = 0.5
+    GameTooltip.InjectedDouble[5] = 1
+    GameTooltip.InjectedDouble[6] = 0.5
+    GameTooltip.InjectedDouble[7] = 1
+    GameTooltip.InjectedDouble[8] = 0.5
+end
+--[[
+##########################################################
+RAIDMARKERS
+##########################################################
+]]--
+local RaidMarkFrame = _G["SVUI_RaidMarkFrame"];
+RaidMarkFrame.Active = false;
+
+do
+	RaidMarkFrame:EnableMouse(true)
+	RaidMarkFrame:SetSize(100, 100)
+	RaidMarkFrame:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
+	RaidMarkFrame:SetFrameStrata("DIALOG")
+
+	local RaidMarkButton_OnEnter = function(self)
+		self.Texture:ClearAllPoints()
+		self.Texture:SetPoint("TOPLEFT",-10,10)
+		self.Texture:SetPoint("BOTTOMRIGHT",10,-10)
+	end
+
+	local RaidMarkButton_OnLeave = function(self)
+		self.Texture:SetAllPoints()
+	end
+
+	local RaidMarkButton_OnClick = function(self, button)
+		PlaySound("UChatScrollButton")
+		SetRaidTarget("target", button ~= "RightButton" and self:GetID() or 0)
+		self:GetParent():FadeOut(0.2, 1, 0, true)
+	end
+
+	for i=1,8 do
+		local mark = CreateFrame("Button", "RaidMarkIconButton"..i, RaidMarkFrame)
+		mark:SetSize(40, 40)
+		mark:SetID(i)
+		mark.Texture = mark:CreateTexture(mark:GetName().."NormalTexture", "ARTWORK")
+		mark.Texture:SetTexture([[Interface\TargetingFrame\UI-RaidTargetingIcons]])
+		mark.Texture:SetAllPoints()
+		SetRaidTargetIconTexture(mark.Texture, i)
+		mark:RegisterForClicks("LeftbuttonUp", "RightbuttonUp")
+		mark:SetScript("OnClick", RaidMarkButton_OnClick)
+		mark:SetScript("OnEnter", RaidMarkButton_OnEnter)
+		mark:SetScript("OnLeave", RaidMarkButton_OnLeave)
+		if(i == 8) then
+			mark:SetPoint("CENTER")
+		else
+			local radian = 360 / 7 * i;
+			mark:SetPoint("CENTER", sin(radian) * 60, cos(radian) * 60)
+		end
+	end
+end
+
+function RaidMarkFrame:IsAllowed(button)
+	if(button and button == "down") then
+		if GetNumGroupMembers()>0 then
+			if UnitIsGroupLeader('player') or UnitIsGroupAssistant("player") then
+				self.Active = true
+			elseif IsInGroup() and not IsInRaid() then
+				self.Active = true
+			else
+				UIErrorsFrame:AddMessage(L["You don't have permission to mark targets."], 1.0, 0.1, 0.1, 1.0, UIERRORS_HOLD_TIME)
+				self.Active = false
+			end
+		else
+			self.Active = true
+		end
+	else
+		self.Active = false
+	end
+end
+
+function RaidMarkFrame:Toggle(button)
+	local canFade = false;
+	if(button) then
+		canFade = true;
+		self:IsAllowed(button)
+	end
+	if(self.Active) then
+		if not UnitExists("target") or UnitIsDead("target") then return end
+		local x,y = GetCursorPosition()
+		local scale = SV.Screen:GetEffectiveScale()
+		self:SetPoint("CENTER", SV.Screen, "BOTTOMLEFT", (x / scale), (y / scale))
+		self:FadeIn()
+	elseif(canFade) then
+		self:FadeOut(0.2, 1, 0, true)
+	end
+end
+
+local RaidMarkFrame_OnEvent = function(self, event)
+	self:Toggle();
+end
+
+_G.RaidMark_HotkeyPressed = function(button)
+	RaidMarkFrame:Toggle(button)
+end
+--[[
+##########################################################
+DRESSUP HELPERS by: Leatrix
+##########################################################
+]]--
+local CreateCharacterToggles;
+do
+	local HelmetToggle;
+	local CloakToggle;
+	local DressUpdateTimer = 0;
+	local HShowing, CShowing, HChecked, CChecked
+
+
+	local function LockItem(item, lock)
+		if lock then
+			item:Disable()
+			item:SetAlpha(0.3)
+		else
+			item:Enable()
+			item:SetAlpha(1.0)
+		end
+	end
+
+	local function SetVanityPlacement()
+		HelmetToggle:ClearAllPoints();
+		HelmetToggle:SetPoint("TOPLEFT", 166, -326)
+		HelmetToggle:SetHitRectInsets(0, -10, 0, 0);
+		HelmetToggle.text:SetText("H");
+		HelmetToggle:SetAlpha(0.7);
+
+		CloakToggle:ClearAllPoints();
+		CloakToggle:SetPoint("TOPLEFT", 206, -326)
+		CloakToggle:SetHitRectInsets(0, -10, 0, 0);
+		CloakToggle.text:SetText("C");
+		CloakToggle:SetAlpha(0.7);
+	end
+
+	local MouseEventHandler = function(self, btn)
+		if btn == "RightButton" and IsShiftKeyDown() then
+			SetVanityPlacement();
+		end
+	end
+
+	local DressUpdateHandler = function(self, elapsed)
+		DressUpdateTimer = DressUpdateTimer + elapsed;
+		while (DressUpdateTimer > 0.05) do
+			if UnitIsDeadOrGhost("player") then
+				LockItem(HelmetToggle,true)
+				LockItem(CloakToggle,true)
+				return
+			else
+				LockItem(HelmetToggle,false)
+				LockItem(CloakToggle,false)
+			end
+
+			--[[
+			HShowing = ShowingHelm()
+			CShowing = ShowingCloak()
+			HChecked = HelmetToggle:GetChecked()
+			CChecked = CloakToggle:GetChecked()
+
+			if(HChecked ~= HShowing) then
+				if HelmetToggle:IsEnabled() then
+					HelmetToggle:Disable()
+				end
+			else
+				if not HelmetToggle:IsEnabled() then
+					HelmetToggle:Enable()
+				end
+			end
+
+			if(CChecked ~= CShowing) then
+				if CloakToggle:IsEnabled() then
+					CloakToggle:Disable()
+				end
+			else
+				if not CloakToggle:IsEnabled() then
+					CloakToggle:Enable()
+				end
+			end
+
+			HelmetToggle:SetChecked(HShowing);
+			CloakToggle:SetChecked(CShowing);
+			]]--
+			DressUpdateTimer = 0;
+		end
+	end
+
+	local DressUp_OnEnter = function(self)
+		if InCombatLockdown() then return end
+		GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT", 0, 4)
+		GameTooltip:ClearLines()
+		GameTooltip:AddLine(self.TText, 1, 1, 1)
+		GameTooltip:Show()
+	end
+
+	local DressUp_OnLeave = function(self)
+		if InCombatLockdown() then return end
+		if(GameTooltip:IsShown()) then GameTooltip:Hide() end
+	end
+
+	local Button_OnEnter = function(self, ...)
+	    if InCombatLockdown() then return end
+	    GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT", 0, 4)
+	    GameTooltip:ClearLines()
+	    GameTooltip:AddLine(self.TText, 1, 1, 1)
+	    GameTooltip:Show()
+	end
+
+	local function CreateSimpleButton(frame, label, anchor, x, y, width, height, tooltip)
+	    local button = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
+	    button:SetWidth(width)
+	    button:SetHeight(height)
+	    button:SetPoint(anchor, x, y)
+	    button:SetText(label)
+	    button:RegisterForClicks("AnyUp")
+	    button:SetHitRectInsets(0, 0, 0, 0);
+	    button:SetFrameStrata("FULLSCREEN_DIALOG");
+	    button.TText = tooltip
+	    button:SetStyle("Button")
+	    button:SetScript("OnEnter", Button_OnEnter)
+	    button:SetScript("OnLeave", GameTooltip_Hide)
+	    return button
+	end
+
+	function CreateCharacterToggles()
+		local BtnStrata = SideDressUpModelResetButton:GetFrameStrata();
+		local BtnLevel = SideDressUpModelResetButton:GetFrameLevel();
+
+		local tabard1 = CreateSimpleButton(DressUpFrame, "Tabard", "BOTTOMLEFT", 12, 12, 80, 22, "")
+		tabard1:SetScript("OnClick", function()
+			DressUpModel:UndressSlot(19)
+		end)
+
+		local tabard2 = CreateSimpleButton(SideDressUpFrame, "Tabard", "BOTTOMLEFT", 14, 20, 60, 22, "")
+		tabard2:SetFrameStrata(BtnStrata);
+		tabard2:SetFrameLevel(BtnLevel);
+		tabard2:SetScript("OnClick", function()
+			SideDressUpModel:UndressSlot(19)
+		end)
+
+		local nude1 = CreateSimpleButton(DressUpFrame, "Nude", "BOTTOMLEFT", 104, 12, 80, 22, "")
+		nude1:SetScript("OnClick", function()
+			DressUpFrameResetButton:Click()
+			for i = 1, 19 do
+				DressUpModel:UndressSlot(i)
+			end
+		end)
+
+		local nude2 = CreateSimpleButton(SideDressUpFrame, "Nude", "BOTTOMRIGHT", -18, 20, 60, 22, "")
+		nude2:SetFrameStrata(BtnStrata);
+		nude2:SetFrameLevel(BtnLevel);
+		nude2:SetScript("OnClick", function()
+			SideDressUpModelResetButton:Click()
+			for i = 1, 19 do
+				SideDressUpModel:UndressSlot(i)
+			end
+		end)
+
+		--[[
+		HelmetToggle = CreateFrame('CheckButton', nil, CharacterModelFrame, "OptionsCheckButtonTemplate")
+		HelmetToggle:SetSize(16, 16)
+		HelmetToggle:SetStyle("Checkbox")
+		HelmetToggle.text = HelmetToggle:CreateFontString(nil, 'OVERLAY', "GameFontNormal")
+		HelmetToggle.text:SetPoint("LEFT", 24, 0)
+		HelmetToggle.TText = "Show/Hide Helmet"
+		HelmetToggle:SetScript('OnEnter', DressUp_OnEnter)
+		HelmetToggle:SetScript('OnLeave', DressUp_OnLeave)
+		HelmetToggle:SetScript('OnUpdate', DressUpdateHandler)
+
+		CloakToggle = CreateFrame('CheckButton', nil, CharacterModelFrame, "OptionsCheckButtonTemplate")
+		CloakToggle:SetSize(16, 16)
+		CloakToggle:SetStyle("Checkbox")
+		CloakToggle.text = CloakToggle:CreateFontString(nil, 'OVERLAY', "GameFontNormal")
+		CloakToggle.text:SetPoint("LEFT", 24, 0)
+		CloakToggle.TText = "Show/Hide Cloak"
+		CloakToggle:SetScript('OnEnter', DressUp_OnEnter)
+		CloakToggle:SetScript('OnLeave', DressUp_OnLeave)
+
+		HelmetToggle:SetScript('OnClick', function(self, btn)
+			ShowHelm(HelmetToggle:GetChecked())
+		end)
+		CloakToggle:SetScript('OnClick', function(self, btn)
+			ShowCloak(CloakToggle:GetChecked())
+		end)
+
+		HelmetToggle:SetScript('OnMouseDown', MouseEventHandler)
+		CloakToggle:SetScript('OnMouseDown', MouseEventHandler)
+
+		CharacterModelFrame:HookScript("OnShow", SetVanityPlacement)
+		]]--
+	end
+end
+--[[
+##########################################################
+VARIOUS COMBAT REACTIONS
+##########################################################
+]]--
+local ReactionListener = CreateFrame("Frame")
+
+local function Thanks_Emote(sourceName)
+	if not REACTION_EMOTE then return end
+	local index = random(1,#ReactionEmotes)
+	DoEmote(ReactionEmotes[index], sourceName)
+end
+
+local function StupidHatEventHandler()
+	if(not IsInInstance()) then return end
+	local item = {}
+	for i = 1, 17 do
+		if Reactions.StupidHat[i] ~= nil then
+			item[i] = GetInventoryItemID("player", i) or 0
+			for j, baditem in pairs(Reactions.StupidHat[i]) do
+				if item[i] == baditem then
+					PlaySound("RaidWarning", "master")
+					RaidNotice_AddMessage(RaidWarningFrame, format("%s %s", CURRENTLY_EQUIPPED, GetItemInfo(item[i]).."!!!"), ChatTypeInfo["RAID_WARNING"])
+					print(format("|cffff3300%s %s", CURRENTLY_EQUIPPED, GetItemInfo(item[i]).."!!!|r"))
+				end
+			end
+		end
+	end
+end
+
+local function ChatLogEventHandler(...)
+	local _, subEvent, _, sourceGUID, sourceName, _, _, destGUID, destName, _, _, spellID, _, _, otherSpellID = ...
+
+	if not sourceName then return end
+
+	if(REACTION_INTERRUPT) then
+		if ((spellID == 6770) and (destName == PlayerName) and (subEvent == "SPELL_AURA_APPLIED" or subEvent == "SPELL_AURA_REFRESH")) then
+			local msg = SAPPED_MESSAGE[random(1,6)]
+			SendChatMessage(msg, "SAY")
+			SV:AddonMessage("Sapped by: "..sourceName)
+			DoEmote("CRACK", sourceName)
+		elseif(subEvent == "SPELL_INTERRUPT" and sourceGUID == UnitGUID("player") and IsInGroup()) then
+			SendChatMessage(INTERRUPTED.." "..destName..": "..GetSpellLink(otherSpellID), MsgTest())
+		end
+	end
+
+	if(REACTION_WOOT) then
+		for key, value in pairs(Reactions.Woot) do
+			if spellID == key and value == true and destName == PlayerName and sourceName ~= PlayerName and (subEvent == "SPELL_AURA_APPLIED" or subEvent == "SPELL_CAST_SUCCESS") then
+				Thanks_Emote(sourceName)
+				--SendChatMessage(L["Thanks for "]..GetSpellLink(spellID)..", "..sourceName, "WHISPER", nil, sourceName)
+				print(GetSpellLink(spellID)..L[" received from "]..sourceName)
+			end
+		end
+	end
+
+	if(REACTION_LOOKY) then
+		local outbound;
+		local spells = Reactions.LookWhatICanDo
+		local _, _, difficultyID = GetInstanceInfo()
+
+		if(difficultyID ~= 0 and subEvent == "SPELL_CAST_SUCCESS") then
+			if(not (sourceGUID == UnitGUID("player") and sourceName == PlayerName)) then
+				for i, spells in pairs(spells) do
+					if(spellID == spells) then
+						if(destName == nil) then
+							outbound = (L["%s used a %s."]):format(sourceName, GetSpellLink(spellID))
+						else
+							outbound = (L["%s used a %s."]):format(sourceName, GetSpellLink(spellID).." -> "..destName)
+						end
+						if(REACTION_CHAT) then
+							SendChatMessage(outbound, MsgTest())
+						else
+							print(outbound)
+						end
+					end
+				end
+			else
+				if(not (sourceGUID == UnitGUID("player") and sourceName == PlayerName)) then return end
+				for i, spells in pairs(spells) do
+					if(spellID == spells) then
+						if(destName == nil) then
+							outbound = (L["%s used a %s."]):format(sourceName, GetSpellLink(spellID))
+						else
+							outbound = GetSpellLink(spellID).." -> "..destName
+						end
+						if(REACTION_CHAT) then
+							SendChatMessage(outbound, MsgTest())
+						else
+							print(outbound)
+						end
+					end
+				end
+			end
+		end
+	end
+
+	if(REACTION_SHARE) then
+		if not IsInGroup() or InCombatLockdown() or not subEvent or not spellID then return end
+		if not UnitInRaid(sourceName) and not UnitInParty(sourceName) then return end
+
+		local sourceName = format(sourceName:gsub("%-[^|]+", ""))
+		if(not sourceName) then return end
+		local thanks = false
+		local outbound
+		if subEvent == "SPELL_CAST_SUCCESS" then
+			-- Feasts
+			if (spellID == 126492 or spellID == 126494) then
+				outbound = (L["%s has prepared a %s - [%s]."]):format(sourceName, GetSpellLink(spellID), SPELL_STAT1_NAME)
+			elseif (spellID == 126495 or spellID == 126496) then
+				outbound = (L["%s has prepared a %s - [%s]."]):format(sourceName, GetSpellLink(spellID), SPELL_STAT2_NAME)
+			elseif (spellID == 126501 or spellID == 126502) then
+				outbound = (L["%s has prepared a %s - [%s]."]):format(sourceName, GetSpellLink(spellID), SPELL_STAT3_NAME)
+			elseif (spellID == 126497 or spellID == 126498) then
+				outbound = (L["%s has prepared a %s - [%s]."]):format(sourceName, GetSpellLink(spellID), SPELL_STAT4_NAME)
+			elseif (spellID == 126499 or spellID == 126500) then
+				outbound = (L["%s has prepared a %s - [%s]."]):format(sourceName, GetSpellLink(spellID), SPELL_STAT5_NAME)
+			elseif (spellID == 104958 or spellID == 105193 or spellID == 126503 or spellID == 126504 or spellID == 145166 or spellID == 145169 or spellID == 145196) then
+				outbound = (L["%s has prepared a %s."]):format(sourceName, GetSpellLink(spellID))
+			-- Refreshment Table
+			elseif spellID == 43987 then
+				outbound = (L["%s has prepared a %s."]):format(sourceName, GetSpellLink(spellID))
+			-- Ritual of Summoning
+			elseif spellID == 698 then
+				outbound = (L["%s is casting %s. Click!"]):format(sourceName, GetSpellLink(spellID))
+			-- Piccolo of the Flaming Fire
+			elseif spellID == 18400 then
+				outbound = (L["%s used a %s."]):format(sourceName, GetSpellLink(spellID))
+			end
+			if(outbound) then thanks = true end
+		elseif subEvent == "SPELL_SUMMON" then
+			-- Repair Bots
+			if Reactions.Bots[spellID] then
+				outbound = (L["%s has put down a %s."]):format(sourceName, GetSpellLink(spellID))
+				thanks = true
+			end
+		elseif subEvent == "SPELL_CREATE" then
+			-- Ritual of Souls and MOLL-E
+			if (spellID == 29893 or spellID == 54710) then
+				outbound = (L["%s has put down a %s."]):format(sourceName, GetSpellLink(spellID))
+				thanks = true
+			-- Toys
+			elseif Reactions.Toys[spellID] then
+				outbound = (L["%s has put down a %s."]):format(sourceName, GetSpellLink(spellID))
+			-- Portals
+			elseif Reactions.Portals[spellID] then
+				outbound = (L["%s is casting %s."]):format(sourceName, GetSpellLink(spellID))
+			end
+		elseif subEvent == "SPELL_AURA_APPLIED" then
+			-- Turkey Feathers and Party G.R.E.N.A.D.E.
+			if (spellID == 61781 or ((spellID == 51508 or spellID == 51510) and destName == PlayerName)) then
+				outbound = (L["%s used a %s."]):format(sourceName, GetSpellLink(spellID))
+			end
+		end
+
+		if(outbound) then
+			if(REACTION_CHAT) then
+				SendChatMessage(outbound, MsgTest(true))
+			else
+				print(outbound)
+			end
+			if(thanks and sourceName) then
+				Thanks_Emote(sourceName)
+			end
+		end
+	end
+end
+
+local ReactionListener_OnEvent = function(self, event, ...)
+	if(event == "ZONE_CHANGED_NEW_AREA") then
+		StupidHatEventHandler()
+	elseif(event == "COMBAT_LOG_EVENT_UNFILTERED") then
+		ChatLogEventHandler(...)
+	end
+end
+
+function SV:ToggleReactions()
+	local settings = SV.db.Extras
+
+	REACTION_INTERRUPT = settings.pvpinterrupt
+	REACTION_WOOT = settings.woot
+	REACTION_LOOKY = settings.lookwhaticando
+	REACTION_SHARE = settings.sharingiscaring
+	REACTION_EMOTE = settings.reactionEmote
+	REACTION_CHAT = settings.reactionChat
+
+	if(settings.stupidhat) then
+		ReactionListener:RegisterEvent("ZONE_CHANGED_NEW_AREA")
+	else
+		ReactionListener:UnregisterEvent("ZONE_CHANGED_NEW_AREA")
+	end
+
+	if(not REACTION_SHARE) and (not REACTION_INTERRUPT) and (not REACTION_WOOT) and (not REACTION_LOOKY) then
+		ReactionListener:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
+	else
+		ReactionListener:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
+	end
+end
+
+--[[ HELPER ]]--
+local function GetThreatBarColor(highest)
+	local unitReaction = UnitReaction(highest, 'player');
+	local r, g, b = 0.5, 0.5, 0.5;
+
+	if(UnitIsPlayer(highest)) then
+		local _,token = UnitClass(highest);
+		local colors = RAID_CLASS_COLORS[token];
+		if(colors) then
+			r, g, b = colors.r*255, colors.g*255, colors.b*255
+		end
+	elseif(unitReaction) then
+		local colors = REACTION_COLORS[unitReaction];
+		if(colors) then
+			r, g, b = colors[1], colors[2], colors[3]
+		end
+	end
+
+	return r, g, b
+end
+
+--[[ HANDLER ]]--
+local ThreatBar_OnEvent = function(self, event)
+	local isTanking, status, scaledPercent = UnitDetailedThreatSituation('player', 'target')
+	if(scaledPercent and (scaledPercent > 0)) then
+		-- if SVUI is installed then fade instead of show
+		if(self.FadeIn) then
+			self:FadeIn()
+		else
+			self:Show()
+		end
+
+		local r,g,b = 0,0.9,0;
+		local peak = 0;
+		local unitKey, highest;
+
+		if(UnitExists('pet')) then
+			local threat = select(3, UnitDetailedThreatSituation('pet', 'target'))
+			if(threat and threat > peak) then
+				peak = threat;
+				highest = 'pet';
+			end
+		end
+
+		if(IsInRaid()) then
+			for i=1,40 do
+				unitKey = 'raid'..i;
+				if(UnitExists(unitKey) and not UnitIsUnit(unitKey, 'player')) then
+					local threat = select(3, UnitDetailedThreatSituation(unitKey, 'target'))
+					if(threat and threat > peak) then
+						peak = threat;
+						highest = 'pet';
+					end
+				end
+			end
+		elseif(IsInGroup()) then
+			for i=1,4 do
+				unitKey = 'party'..i;
+				if(UnitExists(unitKey)) then
+					local threat = select(3, UnitDetailedThreatSituation(unitKey, 'target'))
+					if(threat and threat > peak) then
+						peak = threat;
+						highest = 'pet';
+					end
+				end
+			end
+		end
+
+		if(highest) then
+			if(isTanking or (scaledPercent == 100)) then
+				peak = (scaledPercent - peak);
+				if(peak > 0) then
+					scaledPercent = peak;
+				end
+			else
+				r,g,b = GetThreatBarColor(highest)
+			end
+		elseif(status) then
+			r,g,b = GetThreatStatusColor(status);
+		end
+
+		self:SetStatusBarColor(r,g,b)
+		self:SetValue(scaledPercent)
+		self.text:SetFormattedText('%.0f%%', scaledPercent)
+	else
+		-- if SVUI is installed then fade instead of hide
+		if(self.FadeOut) then
+			self:FadeOut(0.2, 1, 0, true)
+		else
+			self:Hide()
+		end
+	end
+end
+--[[
+##########################################################
+LOAD BY TRIGGER
+##########################################################
+]]--
+local function InitializeMisc()
+	hooksecurefunc("MerchantItemButton_OnEnter", MaxStackTooltip);
+	hooksecurefunc("MerchantItemButton_OnModifiedClick", BuyMaxStack);
+
+	RaidMarkFrame:RegisterEvent("PLAYER_TARGET_CHANGED")
+	RaidMarkFrame:SetScript("OnEvent", RaidMarkFrame_OnEvent)
+
+	if(not IsAddOnLoaded("DressingRoomFunctions")) then
+		CreateCharacterToggles()
+	end
+
+	SV:ToggleReactions()
+	ReactionListener:SetScript("OnEvent", ReactionListener_OnEvent)
+
+	if(SV.db.Extras.threatbar) then
+		ThreatMeter:SetParent(SV.Screen)
+		ThreatMeter:SetPoint('CENTER', UIParent, 'CENTER', 150, -150)
+		ThreatMeter:SetSize(50, 100)
+		ThreatMeter:SetStatusBarTexture(BARFILE)
+		ThreatMeter:SetFrameStrata('MEDIUM')
+		ThreatMeter:SetOrientation("VERTICAL")
+		ThreatMeter:SetMinMaxValues(0, 100)
+
+		ThreatMeter.backdrop = ThreatMeter:CreateTexture(nil,"BACKGROUND")
+		ThreatMeter.backdrop:SetAllPoints(ThreatMeter)
+		ThreatMeter.backdrop:SetTexture(TEXTUREFILE)
+		ThreatMeter.backdrop:SetTexCoord(0.5,0.75,0,0.5)
+		ThreatMeter.backdrop:SetBlendMode("ADD")
+
+		ThreatMeter.overlay = ThreatMeter:CreateTexture(nil,"OVERLAY",nil,1)
+		ThreatMeter.overlay:SetAllPoints(ThreatMeter)
+		ThreatMeter.overlay:SetTexture(TEXTUREFILE)
+		ThreatMeter.overlay:SetTexCoord(0.75,1,0,0.5)
+
+		ThreatMeter.text = ThreatMeter:CreateFontString(nil, 'OVERLAY')
+		ThreatMeter.text:SetFontObject(NumberFontNormal)
+		ThreatMeter.text:SetPoint('TOP',ThreatMeter,'BOTTOM',0,0)
+
+		ThreatMeter:RegisterEvent('PLAYER_TARGET_CHANGED');
+		ThreatMeter:RegisterEvent('UNIT_THREAT_LIST_UPDATE');
+		ThreatMeter:RegisterEvent('GROUP_ROSTER_UPDATE');
+		ThreatMeter:RegisterEvent('UNIT_PET');
+		ThreatMeter:SetScript("OnEvent", ThreatBar_OnEvent);
+		SV:NewAnchor(ThreatMeter, L["Threat-O-Meter"])
+	end
+
+	local cfg = CreateFrame("Button", "GameMenuButtonSVUI", GameMenuFrame, "GameMenuButtonTemplate")
+	cfg:SetSize(GameMenuButtonHelp:GetWidth(), GameMenuButtonHelp:GetHeight())
+	cfg:SetPoint(GameMenuButtonHelp:GetPoint())
+	cfg:SetScript("OnClick", function() SV:ToggleConfig() HideUIPanel(GameMenuFrame) end)
+	cfg:SetText("|cffFF9900SuperVillain UI|r")
+	GameMenuFrame:HookScript("OnShow", function()
+		GameMenuFrame:SetHeight(GameMenuFrame:GetHeight() + GameMenuButtonHelp:GetHeight() + 10)
+	end)
+	GameMenuButtonHelp:ClearAllPoints()
+	GameMenuButtonHelp:SetPoint("TOP", cfg, "BOTTOM", 0, -11)
+end
+
+SV.Events:On("CORE_INITIALIZED", InitializeMisc);
+--[[
+##########################################################
+DIRTY DEEDS
+##########################################################
+]]--
+LFRParentFrame:SetScript("OnHide", nil)
diff --git a/SVUI_!Core/system/overrides.lua b/SVUI_!Core/system/overrides.lua
new file mode 100644
index 0000000..964a71b
--- /dev/null
+++ b/SVUI_!Core/system/overrides.lua
@@ -0,0 +1,1126 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pcall         = _G.pcall;
+local print         = _G.print;
+local ipairs        = _G.ipairs;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local rawset        = _G.rawset;
+local rawget        = _G.rawget;
+local tostring      = _G.tostring;
+local tonumber      = _G.tonumber;
+local string 	= _G.string;
+local math 		= _G.math;
+--[[ STRING METHODS ]]--
+local find, format, len, split = string.find, string.format, string.len, string.split;
+--[[ MATH METHODS ]]--
+local abs, ceil, floor, round, max = math.abs, math.ceil, math.floor, math.round, math.max;
+--BLIZZARD API
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+local GameTooltip           = _G.GameTooltip;
+local LootFrame           	= _G.LootFrame;
+local ConfirmLootRoll       = _G.ConfirmLootRoll;
+local StaticPopup_Hide      = _G.StaticPopup_Hide;
+local C_LootHistory         = _G.C_LootHistory;
+local UnitName              = _G.UnitName;
+local UnitIsDead            = _G.UnitIsDead;
+local UnitIsFriend          = _G.UnitIsFriend;
+local UnitInVehicle         = _G.UnitInVehicle;
+local UnitControllingVehicle= _G.UnitControllingVehicle;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...)
+local SVUILib = Librarian("Registry");
+local L = SV.L;
+--[[
+##########################################################
+LOCAL VARS
+##########################################################
+]]--
+local POSITION, ANCHOR_POINT, YOFFSET = "TOP", "BOTTOM", -10
+local FORCE_POSITION = false;
+local NewHook = hooksecurefunc;
+local lastQuality,lastID,lastName;
+local dead_rollz = {};
+-- UPVALUES
+local AUTOROLL_ENABLED = false;
+local AUTOROLL_SOULBOUND = false;
+local AUTOROLL_LEVEL = false;
+local AUTOROLL_QUALITY = 2;
+local AUTOROLL_DE = true;
+--[[
+##########################################################
+MIRROR BARS
+##########################################################
+]]--
+local MirrorBarEventFrame = CreateFrame("Frame", nil)
+local mirrorYOffset={
+	["BREATH"] = 96,
+	["EXHAUSTION"] = 119,
+	["FEIGNDEATH"] = 142
+}
+local mirrorTypeColor={
+	EXHAUSTION = {1,.9,0},
+	BREATH = {0.31,0.45,0.63},
+	DEATH = {1,.7,0},
+	FEIGNDEATH = {1,.7,0}
+}
+local RegisteredMirrorBars = {}
+
+local MirrorBar_OnUpdate = function(self, elapsed)
+	if self.paused then
+		return
+	end
+	self.lastupdate = (self.lastupdate or 0) + elapsed;
+	if self.lastupdate < .1 then
+		return
+	end
+	self.lastupdate = 0;
+	self:SetValue(GetMirrorTimerProgress(self.type) / 1e3)
+end
+
+local MirrorBar_Start = function(self, min, max, s, t, text)
+	if t > 0 then
+		self.paused = 1
+	elseif self.paused then
+		self.paused = nil
+	end
+	self.text:SetText(text)
+	self:SetMinMaxValues(0, max / 1e3)
+	self:SetValue(min / 1e3)
+	if not self:IsShown() then
+		self:Show()
+	end
+end
+
+
+local function MirrorBarRegistry(barType)
+	if RegisteredMirrorBars[barType] then
+		return RegisteredMirrorBars[barType]
+	end
+	local bar = CreateFrame('StatusBar', nil, UIParent)
+	bar:SetStyle("Frame", "Bar", false, 3, 3, 3)
+	bar:SetScript("OnUpdate", MirrorBar_OnUpdate)
+	local r, g, b = unpack(mirrorTypeColor[barType])
+	bar.text = bar:CreateFontString(nil, 'OVERLAY')
+	bar.text:SetFontObject(SVUI_Font_Default)
+	bar.text:SetJustifyH('CENTER')
+	bar.text:SetTextColor(1, 1, 1)
+	bar.text:SetPoint('LEFT', bar)
+	bar.text:SetPoint('RIGHT', bar)
+	bar.text:SetPoint('TOP', bar, 0, 2)
+	bar.text:SetPoint('BOTTOM', bar)
+	bar:SetSize(222, 18)
+	bar:SetStatusBarTexture(SV.media.statusbar.gradient)
+	bar:SetStatusBarColor(r, g, b)
+	bar.type = barType;
+	bar.Start = MirrorBar_Start;
+
+	local yOffset = mirrorYOffset[bar.type]
+	bar:SetPoint("TOP", SV.Screen, "TOP", 0, -yOffset)
+	RegisteredMirrorBars[barType] = bar;
+	return bar
+end
+
+local function SetTimerStyle(bar)
+	for i=1, bar:GetNumRegions()do
+		local child = select(i, bar:GetRegions())
+		if child:GetObjectType() == "Texture"then
+			child:SetTexture("")
+		elseif child:GetObjectType() == "FontString" then
+			child:SetFontObject(SVUI_Font_Default)
+		end
+	end
+	bar:SetStatusBarTexture(SV.media.statusbar.gradient)
+	bar:SetStatusBarColor(0.37, 0.92, 0.08)
+	bar:SetStyle("Frame", "Bar", false, 3, 3, 3)
+end
+
+local MirrorBar_OnEvent = function(self, event, arg, ...)
+	if(event == 'CVAR_UPDATE' or event == 'PLAYER_ENTERING_WORLD') then
+		if not GetCVarBool("lockActionBars") and SV.db.ActionBars.enable then
+			SetCVar("lockActionBars", 1)
+		end
+		if(event == "PLAYER_ENTERING_WORLD") then
+			for i = 1, MIRRORTIMER_NUMTIMERS do
+				local v, q, r, s, t, u = GetMirrorTimerInfo(i)
+				if v ~= "UNKNOWN"then
+					MirrorBarRegistry(v):Start(q, r, s, t, u)
+				end
+			end
+		end
+	else
+		if(event == "START_TIMER") then
+			for _,timer in pairs(TimerTracker.timerList)do
+				if timer["bar"] and not timer["bar"].styled then
+					SetTimerStyle(timer["bar"])
+					timer["bar"].styled = true
+				end
+			end
+		elseif(event == "MIRROR_TIMER_START") then
+			return MirrorBarRegistry(arg):Start(...)
+		elseif(event == "MIRROR_TIMER_STOP") then
+			return MirrorBarRegistry(arg):Hide()
+		elseif(event == "MIRROR_TIMER_PAUSE") then
+			local pausedValue = (arg > 0 and arg or nil);
+			for barType,bar in next,RegisteredMirrorBars do
+				bar.paused = pausedValue;
+			end
+		end
+	end
+end
+--[[
+##########################################################
+LOOTING
+##########################################################
+]]--
+local LootingEventFrame = CreateFrame("Frame", nil);
+local RollTypePresets = {
+	[0] = {
+		"Interface\\Buttons\\UI-GroupLoot-Pass-Up",
+		"",
+		"Interface\\Buttons\\UI-GroupLoot-Pass-Down",
+		[[0]],
+		[[2]]
+	},
+	[1] = {
+		"Interface\\Buttons\\UI-GroupLoot-Dice-Up",
+		"Interface\\Buttons\\UI-GroupLoot-Dice-Highlight",
+		"Interface\\Buttons\\UI-GroupLoot-Dice-Down",
+		[[5]],
+		[[-1]]
+	},
+	[2] = {
+		"Interface\\Buttons\\UI-GroupLoot-Coin-Up",
+		"Interface\\Buttons\\UI-GroupLoot-Coin-Highlight",
+		"Interface\\Buttons\\UI-GroupLoot-Coin-Down",
+		[[0]],
+		[[-1]]
+	},
+	[3] = {
+		"Interface\\Buttons\\UI-GroupLoot-DE-Up",
+		"Interface\\Buttons\\UI-GroupLoot-DE-Highlight",
+		"Interface\\Buttons\\UI-GroupLoot-DE-Down",
+		[[0]],
+		[[-1]]
+	}
+};
+local LootRollType = {[1] = "need", [2] = "greed", [3] = "disenchant", [0] = "pass"};
+local LOOT_WIDTH, LOOT_HEIGHT = 328, 28;
+
+local SVUI_LootFrameHolder = CreateFrame("Frame", "SVUI_LootFrameHolder", UIParent);
+SVUI_LootFrameHolder:SetPoint("BOTTOMRIGHT", SVUI_DockTopLeft, "BOTTOMRIGHT", 0, 0);
+SVUI_LootFrameHolder:SetSize(150, 22);
+SVUI_LootFrameHolder:SetFrameStrata("FULLSCREEN_DIALOG");
+SVUI_LootFrameHolder:SetToplevel(true);
+
+local SVUI_LootFrame = CreateFrame('Button', 'SVUI_LootFrame', SVUI_LootFrameHolder);
+SVUI_LootFrame:SetClampedToScreen(true);
+SVUI_LootFrame:SetPoint('TOPLEFT');
+SVUI_LootFrame:SetSize(256, 64);
+SVUI_LootFrame.title = SVUI_LootFrame:CreateFontString(nil,'OVERLAY');
+SVUI_LootFrame.title:SetPoint('BOTTOMLEFT',SVUI_LootFrame,'TOPLEFT',0,1);
+SVUI_LootFrame.slots = {};
+SVUI_LootFrame:Hide();
+SVUI_LootFrame:SetScript("OnHide", function(self)
+	SV:StaticPopup_Hide("CONFIRM_LOOT_DISTRIBUTION");
+	CloseLoot()
+end);
+
+local function UpdateLootUpvalues()
+	LOOT_WIDTH = SV.db.general.lootRollWidth
+	LOOT_HEIGHT = SV.db.general.lootRollHeight
+end
+
+local DoDaRoll = function(self)
+	RollOnLoot(self.parent.rollID, self.rolltype)
+end
+
+local LootRoll_OnLeave = function(self)
+	GameTooltip:Hide()
+end
+
+local LootItem_OnLeave = function(self)
+	GameTooltip:Hide()
+	ResetCursor()
+end
+
+local LootRoll_SetTooltip = function(self)
+	GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
+	GameTooltip:SetText(self.tiptext)
+	if self:IsEnabled() == 0 then
+		GameTooltip:AddLine("|cffff3333"..L["Can't Roll"])
+	end
+	for r, s in pairs(self.parent.rolls)do
+		if LootRollType[s] == LootRollType[self.rolltype] then
+			GameTooltip:AddLine(r, 1, 1, 1)
+		end
+	end
+	GameTooltip:Show()
+end
+
+local LootItem_SetTooltip = function(self)
+	if not self.link then
+		return
+	end
+	GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT")
+	GameTooltip:SetHyperlink(self.link)
+	if IsShiftKeyDown() then
+		GameTooltip_ShowCompareItem()
+	end
+	if IsModifiedClick("DRESSUP") then
+		ShowInspectCursor()
+	else
+		ResetCursor()
+	end
+end
+
+local LootItem_OnUpdate = function(self)
+	if IsShiftKeyDown() then
+		GameTooltip_ShowCompareItem()
+	end
+	CursorOnUpdate(self)
+end
+
+local LootRoll_OnClick = function(self)
+	if IsControlKeyDown() then
+		DressUpItemLink(self.link)
+	elseif IsShiftKeyDown() then
+		ChatEdit_InsertLink(self.link)
+	end
+end
+
+local LootRoll_OnEvent = function(self, event, value)
+	dead_rollz[value] = true;
+	if self.rollID ~= value then
+		return
+	end
+	self.rollID = nil;
+	self.time = nil;
+	self:Hide()
+end
+
+local LootRoll_OnUpdate = function(self)
+	if not self.parent.rollID then return end
+	local remaining = GetLootRollTimeLeft(self.parent.rollID)
+	local mu = remaining / self.parent.time;
+	self.spark:SetPoint("CENTER", self, "LEFT", mu * self:GetWidth(), 0)
+	self:SetValue(remaining)
+	if remaining > 1000000000 then
+		self:GetParent():Hide()
+	end
+end
+
+local LootSlot_OnEnter = function(self)
+	local slotID = self:GetID()
+	if LootSlotHasItem(slotID) then
+		GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
+		GameTooltip:SetLootItem(slotID)
+		CursorUpdate(self)
+	end
+	self.drop:Show()
+	self.drop:SetVertexColor(1, 1, 0)
+end
+
+local LootSlot_OnLeave = function(self)
+	if self.quality and self.quality > 1 then
+		local color = ITEM_QUALITY_COLORS[self.quality]
+		self.drop:SetVertexColor(color.r, color.g, color.b)
+	else
+		self.drop:Hide()
+	end
+	GameTooltip:Hide()
+	ResetCursor()
+end
+
+local LootSlot_OnClick = function(self)
+	LootFrame.selectedQuality = self.quality;
+	LootFrame.selectedItemName = self.name:GetText()
+	LootFrame.selectedSlot = self:GetID()
+	LootFrame.selectedLootButton = self:GetName()
+	LootFrame.selectedTexture = self.icon:GetTexture()
+	if IsModifiedClick() then
+		HandleModifiedItemClick(GetLootSlotLink(self:GetID()))
+	else
+		StaticPopup_Hide("CONFIRM_LOOT_DISTRIBUTION")
+		lastID = self:GetID()
+		lastQuality = self.quality;
+		lastName = self.name:GetText()
+		LootSlot(lastID)
+	end
+end
+
+local LootSlot_OnShow = function(self)
+	if GameTooltip:IsOwned(self) then
+		GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
+		GameTooltip:SetLootItem(self:GetID())
+		CursorOnUpdate(self)
+	end
+end
+
+local function HandleSlots(frame)
+	local scale = 30;
+	local counter = 0;
+	for i = 1, #frame.slots do
+		local slot = frame.slots[i]
+		if slot:IsShown() then
+			counter = counter + 1;
+			slot:SetPoint("TOP", SVUI_LootFrame, 4, (-8 + scale) - (counter * scale))
+		end
+	end
+	frame:SetHeight(max(counter * scale + 16, 20))
+end
+
+local function MakeSlots(id)
+	local size = LOOT_HEIGHT;
+	local slot = CreateFrame("Button", "SVUI_LootSlot"..id, SVUI_LootFrame)
+	slot:SetPoint("LEFT", 8, 0)
+	slot:SetPoint("RIGHT", -8, 0)
+	slot:SetHeight(size)
+	slot:SetID(id)
+	slot:RegisterForClicks("LeftButtonUp", "RightButtonUp")
+	slot:SetScript("OnEnter", LootSlot_OnEnter)
+	slot:SetScript("OnLeave", LootSlot_OnLeave)
+	slot:SetScript("OnClick", LootSlot_OnClick)
+	slot:SetScript("OnShow", LootSlot_OnShow)
+
+	slot.iconFrame = CreateFrame("Frame", nil, slot)
+	slot.iconFrame:SetHeight(size)
+	slot.iconFrame:SetWidth(size)
+	slot.iconFrame:SetPoint("RIGHT", slot)
+	slot.iconFrame:SetStyle("Frame", "Transparent")
+
+	slot.icon = slot.iconFrame:CreateTexture(nil, "ARTWORK")
+	slot.icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+	slot.icon:InsetPoints()
+
+	slot.count = slot.iconFrame:CreateFontString(nil, "OVERLAY")
+	slot.count:SetJustifyH("RIGHT")
+	slot.count:SetPoint("BOTTOMRIGHT", slot.iconFrame, -2, 2)
+	slot.count:SetFontObject(SVUI_Font_Loot_Number)
+	slot.count:SetText(1)
+
+	slot.name = slot:CreateFontString(nil, "OVERLAY")
+	slot.name:SetJustifyH("LEFT")
+	slot.name:SetPoint("LEFT", slot)
+	slot.name:SetPoint("RIGHT", slot.icon, "LEFT")
+	slot.name:SetNonSpaceWrap(true)
+	slot.name:SetFontObject(SVUI_Font_Loot)
+
+	slot.drop = slot:CreateTexture(nil, "ARTWORK")
+	slot.drop:SetTexture("Interface\\QuestFrame\\UI-QuestLogTitleHighlight")
+	slot.drop:SetPoint("LEFT", slot.icon, "RIGHT", 0, 0)
+	slot.drop:SetPoint("RIGHT", slot)
+	slot.drop:SetAllPoints(slot)
+	slot.drop:SetAlpha(.3)
+
+	slot.questTexture = slot.iconFrame:CreateTexture(nil, "OVERLAY")
+	slot.questTexture:InsetPoints()
+	slot.questTexture:SetTexture(TEXTURE_ITEM_QUEST_BANG)
+	slot.questTexture:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+
+	SVUI_LootFrame.slots[id] = slot;
+	return slot
+end
+
+local function CreateRollButton(rollFrame, type, locale, anchor)
+	local btnSize = LOOT_HEIGHT - 4;
+	local preset = RollTypePresets[type];
+	local rollButton = CreateFrame("Button", nil, rollFrame)
+	rollButton:SetPoint("LEFT", anchor, "RIGHT", tonumber(preset[4]), tonumber(preset[5]))
+	rollButton:SetSize(btnSize, btnSize)
+	rollButton:SetNormalTexture(preset[1])
+	if preset[2] and preset[2] ~= "" then
+		rollButton:SetPushedTexture(preset[2])
+	end
+	rollButton:SetHighlightTexture(preset[3])
+	rollButton.rolltype = type;
+	rollButton.parent = rollFrame;
+	rollButton.tiptext = locale;
+	rollButton:SetScript("OnEnter", LootRoll_SetTooltip)
+	rollButton:SetScript("OnLeave", LootRoll_OnLeave)
+	rollButton:SetScript("OnClick", DoDaRoll)
+	rollButton:SetMotionScriptsWhileDisabled(true)
+	local text = rollButton:CreateFontString(nil, nil)
+	text:SetFontObject(SVUI_Font_Roll)
+	text:SetPoint("CENTER", 0, ((type == 2 and 1) or (type == 0 and -1.2) or 0))
+	return rollButton, text
+end
+
+local function CreateRollFrame()
+	UpdateLootUpvalues()
+	local btnSize = LOOT_HEIGHT - 2;
+	local rollFrame = CreateFrame("Frame", nil, UIParent)
+	rollFrame:SetSize(LOOT_WIDTH,LOOT_HEIGHT)
+	rollFrame:SetStyle("!_Frame", 'Default')
+	rollFrame:SetScript("OnEvent",LootRoll_OnEvent)
+	rollFrame:RegisterEvent("CANCEL_LOOT_ROLL")
+	rollFrame:Hide()
+	rollFrame.button = CreateFrame("Button",nil,rollFrame)
+	rollFrame.button:SetPoint("RIGHT",rollFrame,'LEFT',0,0)
+	rollFrame.button:SetSize(btnSize, btnSize)
+	rollFrame.button:SetStyle("Frame", 'Default')
+	rollFrame.button:SetScript("OnEnter",LootItem_SetTooltip)
+	rollFrame.button:SetScript("OnLeave",LootItem_OnLeave)
+	rollFrame.button:SetScript("OnUpdate",LootItem_OnUpdate)
+	rollFrame.button:SetScript("OnClick",LootRoll_OnClick)
+	rollFrame.button.icon = rollFrame.button:CreateTexture(nil,'OVERLAY')
+	rollFrame.button.icon:SetAllPoints()
+	rollFrame.button.icon:SetTexCoord(0.1,0.9,0.1,0.9 )
+	local border = rollFrame:CreateTexture(nil,"BORDER")
+	border:SetPoint("TOPLEFT",rollFrame,"TOPLEFT",4,0)
+	border:SetPoint("BOTTOMRIGHT",rollFrame,"BOTTOMRIGHT",-4,0)
+	border:SetTexture("Interface\\ChatFrame\\ChatFrameBackground")
+	border:SetBlendMode("ADD")
+	border:SetGradientAlpha("VERTICAL",.1,.1,.1,0,.1,.1,.1,0)
+	rollFrame.status=CreateFrame("StatusBar",nil,rollFrame)
+	rollFrame.status:InsetPoints()
+	rollFrame.status:SetScript("OnUpdate",LootRoll_OnUpdate)
+	rollFrame.status:SetFrameLevel(rollFrame.status:GetFrameLevel() - 1)
+	rollFrame.status:SetStatusBarTexture(SV.media.statusbar.gradient)
+	rollFrame.status:SetStatusBarColor(.8,.8,.8,.9)
+	rollFrame.status.parent = rollFrame;
+	rollFrame.status.bg = rollFrame.status:CreateTexture(nil,'BACKGROUND')
+	rollFrame.status.bg:SetAlpha(0.1)
+	rollFrame.status.bg:SetAllPoints()
+	rollFrame.status.bg:SetDrawLayer('BACKGROUND',2)
+	rollFrame.status.spark = rollFrame:CreateTexture(nil,"OVERLAY")
+	rollFrame.status.spark:SetSize(LOOT_HEIGHT * 0.5, LOOT_HEIGHT)
+	rollFrame.status.spark:SetTexture("Interface\\CastingBar\\UI-CastingBar-Spark")
+	rollFrame.status.spark:SetBlendMode("ADD")
+
+	local needButton,needText = CreateRollButton(rollFrame,1,NEED,rollFrame.button)
+	local greedButton,greedText = CreateRollButton(rollFrame,2,GREED,needButton,"RIGHT")
+	local deButton,deText = CreateRollButton(rollFrame,3,ROLL_DISENCHANT,greedButton)
+	local passButton,passText = CreateRollButton(rollFrame,0,PASS,deButton or greedButton)
+	rollFrame.NeedIt,rollFrame.WantIt,rollFrame.BreakIt = needButton,greedButton,deButton;
+	rollFrame.need,rollFrame.greed,rollFrame.pass,rollFrame.disenchant = needText,greedText,passText,deText;
+	rollFrame.bindText = rollFrame:CreateFontString()
+	rollFrame.bindText:SetPoint("LEFT",passButton,"RIGHT",3,1)
+	rollFrame.bindText:SetFontObject(SVUI_Font_Roll_Number)
+	rollFrame.lootText = rollFrame:CreateFontString(nil,"ARTWORK")
+	rollFrame.lootText:SetFontObject(SVUI_Font_Roll_Number)
+	rollFrame.lootText:SetPoint("LEFT",rollFrame.bindText,"RIGHT",0,0)
+	rollFrame.lootText:SetPoint("RIGHT",rollFrame,"RIGHT",-5,0)
+	rollFrame.lootText:SetSize(200,10)
+	rollFrame.lootText:SetJustifyH("LEFT")
+
+	rollFrame.yourRoll = rollFrame:CreateFontString(nil,"ARTWORK")
+	rollFrame.yourRoll:SetFontObject(SVUI_Font_Roll_Number)
+	rollFrame.yourRoll:SetSize(22,22)
+	rollFrame.yourRoll:SetPoint("LEFT",rollFrame,"RIGHT",5,0)
+	rollFrame.yourRoll:SetJustifyH("CENTER")
+
+	rollFrame.rolls = {}
+	return rollFrame
+end
+
+local function FetchRollFrame()
+	local rollFrames = SV.RollFrames;
+	local rollCount = #rollFrames;
+	for i=1, rollCount do
+		local frame = rollFrames[i];
+		if not frame.rollID then
+			return frame
+		end
+	end
+
+	local anchorParent = rollFrames[rollCount] or SVUI_AlertFrame;
+	local roll = CreateRollFrame();
+	roll:SetPoint("TOP", anchorParent, "BOTTOM", 0, -4);
+	rollFrames[rollCount+1] = roll;
+	return roll
+end
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+local function AutoGreed(rollID, quality, DE, BoP)
+	if(not AUTOROLL_ENABLED) then return end
+	-- if(AUTOROLL_LEVEL and (UnitLevel('player') < MAX_PLAYER_LEVEL)) then
+	-- 	return
+	-- end
+	if(quality <= AUTOROLL_QUALITY) then
+		if(DE and AUTOROLL_DE) then
+			if(not (BoP and (not AUTOROLL_SOULBOUND))) then
+				RollOnLoot(rollID, 3)
+			else
+				RollOnLoot(rollID, 2)
+			end
+		else
+			RollOnLoot(rollID, 2)
+		end
+	end
+end
+
+local EventFunc = {};
+
+EventFunc["CONFIRM_LOOT_ROLL"] = function(arg1, arg2, ...)
+	ConfirmLootRoll(arg1, arg2)
+	StaticPopup_Hide("CONFIRM_LOOT_ROLL")
+end
+
+EventFunc["CONFIRM_DISENCHANT_ROLL"] = function(arg1, arg2, ...)
+	ConfirmLootRoll(arg1, arg2)
+	StaticPopup_Hide("CONFIRM_LOOT_ROLL")
+end
+
+EventFunc["LOOT_BIND_CONFIRM"] = function(arg1, arg2, ...)
+	ConfirmLootSlot(arg1, arg2)
+	StaticPopup_Hide("LOOT_BIND", ...)
+end
+
+EventFunc["LOOT_SLOT_CLEARED"] = function(slot)
+	if not SVUI_LootFrame:IsShown() then return; end
+	SVUI_LootFrame.slots[slot]:Hide()
+	HandleSlots(SVUI_LootFrame)
+end
+
+EventFunc["LOOT_CLOSED"] = function(...)
+	StaticPopup_Hide("LOOT_BIND")
+	SVUI_LootFrame:Hide()
+	for _,slot in pairs(SVUI_LootFrame.slots)do
+		slot:Hide()
+	end
+end
+
+EventFunc["OPEN_MASTER_LOOT_LIST"] = function(...)
+	ToggleDropDownMenu(1, nil, GroupLootDropDown, SVUI_LootFrame.slots[lastID], 0, 0)
+end
+
+EventFunc["UPDATE_MASTER_LOOT_LIST"] = function(...)
+	MasterLooterFrame_UpdatePlayers()
+end
+
+EventFunc["LOOT_HISTORY_ROLL_CHANGED"] = function(arg1, arg2)
+	local rollID,_,_,_,_,_ = C_LootHistory.GetItem(arg1);
+	local name,_,rollType,rollResult,_ = C_LootHistory.GetPlayerInfo(arg1,arg2);
+	if name and rollType then
+		for _,roll in ipairs(SV.RollFrames)do
+			if roll.rollID == rollID then
+				roll.rolls[name] = rollType;
+				roll[LootRollType[rollType]]:SetText(tonumber(roll[LootRollType[rollType]]:GetText()) + 1);
+				return
+			end
+			if rollResult then
+				roll.yourRoll:SetText(tostring(rollResult))
+			end
+		end
+	end
+end
+
+EventFunc["START_LOOT_ROLL"] = function(rollID, rollTime)
+	if dead_rollz[rollID] then return end
+	local texture,name,count,quality,bindOnPickUp,canNeed,canGreed,canBreak = GetLootRollItemInfo(rollID);
+	local color = ITEM_QUALITY_COLORS[quality];
+	local rollFrame = FetchRollFrame();
+	rollFrame.rollID = rollID;
+	rollFrame.time = rollTime;
+	for i in pairs(rollFrame.rolls)do
+		rollFrame.rolls[i] = nil
+	end
+	rollFrame.need:SetText(0)
+	rollFrame.greed:SetText(0)
+	rollFrame.pass:SetText(0)
+	rollFrame.disenchant:SetText(0)
+	rollFrame.button.icon:SetTexture(texture)
+	rollFrame.button.link = GetLootRollItemLink(rollID)
+	if canNeed then
+		rollFrame.NeedIt:Enable()
+		rollFrame.NeedIt:SetAlpha(1)
+	else
+		rollFrame.NeedIt:SetAlpha(0.2)
+		rollFrame.NeedIt:Disable()
+	end
+	if canGreed then
+		rollFrame.WantIt:Enable()
+		rollFrame.WantIt:SetAlpha(1)
+	else
+		rollFrame.WantIt:SetAlpha(0.2)
+		rollFrame.WantIt:Disable()
+	end
+	if canBreak then
+		rollFrame.BreakIt:Enable()
+		rollFrame.BreakIt:SetAlpha(1)
+	else
+		rollFrame.BreakIt:SetAlpha(0.2)
+		rollFrame.BreakIt:Disable()
+	end
+	SetDesaturation(rollFrame.NeedIt:GetNormalTexture(),not canNeed)
+	SetDesaturation(rollFrame.WantIt:GetNormalTexture(),not canGreed)
+	SetDesaturation(rollFrame.BreakIt:GetNormalTexture(),not canBreak)
+	rollFrame.bindText:SetText(bindOnPickUp and "BoP" or "BoE")
+	rollFrame.bindText:SetVertexColor(bindOnPickUp and 1 or 0.3, bindOnPickUp and 0.3 or 1, bindOnPickUp and 0.1 or 0.3)
+	rollFrame.lootText:SetText(name)
+	rollFrame.yourRoll:SetText("")
+	rollFrame.status:SetStatusBarColor(color.r,color.g,color.b,0.7)
+	rollFrame.status.bg:SetTexture(color.r,color.g,color.b)
+	rollFrame.status:SetMinMaxValues(0,rollTime)
+	rollFrame.status:SetValue(rollTime)
+	rollFrame:SetPoint("CENTER",WorldFrame,"CENTER")
+	rollFrame:Show()
+	AlertFrame_FixAnchors()
+	AutoGreed(rollID, quality, canBreak, bindOnPickUp)
+end
+EventFunc["LOOT_READY"] = function(autoLoot)
+	local drops = GetNumLootItems()
+	if drops > 0 then
+		SVUI_LootFrame:Show()
+	else
+		CloseLoot(autoLoot == 0)
+	end
+
+	if IsFishingLoot() then
+		SVUI_LootFrame.title:SetText(L["Fishy Loot"])
+	elseif not UnitIsFriend("player", "target") and UnitIsDead"target" then
+		SVUI_LootFrame.title:SetText(UnitName("target"))
+	else
+		SVUI_LootFrame.title:SetText(LOOT)
+	end
+
+	if GetCVar("lootUnderMouse") == "1" then
+		local cursorX,cursorY = GetCursorPosition()
+		cursorX = cursorX / SVUI_LootFrame:GetEffectiveScale()
+		cursorY = (cursorY / (SVUI_LootFrame:GetEffectiveScale()));
+		SVUI_LootFrame:ClearAllPoints()
+		SVUI_LootFrame:SetPoint("TOPLEFT", nil, "BOTTOMLEFT", cursorX - 40, cursorY + 20)
+		SVUI_LootFrame:GetCenter()
+	else
+		SVUI_LootFrame:ClearAllPoints()
+		SVUI_LootFrame:SetPoint("TOPLEFT", SVUI_LootFrameHolder, "TOPLEFT")
+	end
+
+	SVUI_LootFrame:Raise()
+
+	local iQuality, nameWidth, titleWidth = 0, 0, SVUI_LootFrame.title:GetStringWidth()
+	UpdateLootUpvalues()
+	if drops > 0 then
+		for i = 1, drops do
+			local slot = SVUI_LootFrame.slots[i] or MakeSlots(i)
+			local textureID, item, quantity, quality, locked, isQuestItem, questId, isActive = GetLootSlotInfo(i)
+			local color = ITEM_QUALITY_COLORS[quality]
+			if quantity and quantity > 1 then
+				slot.count:SetText(quantity)
+				slot.count:Show()
+			else
+				slot.count:Hide()
+			end
+			if quality and quality > 1 then
+				slot.drop:SetVertexColor(color.r, color.g, color.b)
+				slot.drop:Show()
+			else
+				slot.drop:Hide()
+			end
+			slot.quality = quality;
+			slot.name:SetText(item)
+			if color then
+				slot.name:SetTextColor(color.r, color.g, color.b)
+			end
+			slot.icon:SetTexture(textureID)
+			if quality then
+				iQuality = max(iQuality, quality)
+			end
+			nameWidth = max(nameWidth, slot.name:GetStringWidth())
+			local qTex = slot.questTexture;
+			if questId and not isActive then
+				qTex:Show()
+				ActionButton_ShowOverlayGlow(slot.iconFrame)
+			elseif questId or isQuestItem then
+				qTex:Hide()
+				ActionButton_ShowOverlayGlow(slot.iconFrame)
+			else
+				qTex:Hide()
+				ActionButton_HideOverlayGlow(slot.iconFrame)
+			end
+			slot:Enable()
+			slot:Show()
+			ConfirmLootSlot(i)
+		end
+	else
+		local slot = SVUI_LootFrame.slots[1] or MakeSlots(1)
+		local color = ITEM_QUALITY_COLORS[0]
+		slot.name:SetText(L["Empty Slot"])
+		if color then
+			slot.name:SetTextColor(color.r, color.g, color.b)
+		end
+		slot.icon:SetTexture[[Interface\Icons\INV_Misc_Herb_AncientLichen]]
+		drops = 1;
+		nameWidth = max(nameWidth, slot.name:GetStringWidth())
+		slot.count:Hide()
+		slot.drop:Hide()
+		slot:Disable()
+		slot:Show()
+	end
+
+	HandleSlots(SVUI_LootFrame)
+	nameWidth = nameWidth + 60;
+	titleWidth = titleWidth + 5;
+	local color = ITEM_QUALITY_COLORS[iQuality]
+	SVUI_LootFrame:SetBackdropBorderColor(color.r, color.g, color.b, .8)
+	SVUI_LootFrame:SetWidth(max(nameWidth, titleWidth))
+end
+
+local LootFrame_OnEvent = function(self, event, ...)
+	if(EventFunc[event]) then
+		EventFunc[event](...)
+	end
+end
+
+_G.GroupLootDropDown_GiveLoot = function(self)
+	if lastQuality >= MASTER_LOOT_THREHOLD then
+		local confirmed = SV:StaticPopup_Show("CONFIRM_LOOT_DISTRIBUTION",ITEM_QUALITY_COLORS[lastQuality].hex..lastName..FONT_COLOR_CODE_CLOSE,self:GetText());
+		if confirmed then confirmed.data = self.value end
+	else
+		GiveMasterLoot(lastID, self.value)
+	end
+	CloseDropDownMenus()
+	SV.SystemAlert["CONFIRM_LOOT_DISTRIBUTION"].OnAccept = function(self,index) GiveMasterLoot(lastID,index) end
+end
+--[[
+##########################################################
+BAIL OUT BUTTON
+##########################################################
+]]--
+local BailOut_TaxiTimer, BailOut_EarlyLandingRequested;
+local SVUI_BailOut = CreateFrame("Button", "SVUI_BailOut", UIParent)
+SVUI_BailOut:SetSize(50, 50)
+SVUI_BailOut:SetPoint("TOP", SVUI_DockTopCenter, "BOTTOM", 0, -10)
+
+local function UpdateTaxiBailOut()
+	if(not UnitOnTaxi("player")) then
+		SV.Timers:RemoveLoop(BailOut_TaxiTimer)
+		BailOut_TaxiTimer = nil;
+		BailOut_EarlyLandingRequested = nil;
+		SVUI_BailOut:Hide()
+	end
+end
+
+local BailOut_OnHook = function()
+	SVUI_BailOut:Show()
+	BailOut_TaxiTimer = SV.Timers:ExecuteLoop(UpdateMiniMapCoords, 1)
+end
+
+local BailOut_OnEvent = function(self, event, ...)
+	if((event == "UNIT_ENTERED_VEHICLE" and CanExitVehicle()) or UnitControllingVehicle("player") or UnitInVehicle("player")) then
+ 		self:Show()
+ 	else
+ 		self:Hide()
+ 	end
+end
+
+local BailOut_OnClick = function(self, event, ...)
+	if(UnitOnTaxi("player")) then
+ 		TaxiRequestEarlyLanding()
+ 		if(not BailOut_EarlyLandingRequested) then
+ 			BailOut_EarlyLandingRequested = true;
+ 			SV:CharacterMessage('Let me off at the next stop!')
+ 		end
+ 	else
+ 		VehicleExit()
+ 	end
+end
+--[[
+##########################################################
+MISC OVERRIDES
+##########################################################
+]]--
+local SVUI_WorldStateHolder = CreateFrame("Frame", "SVUI_WorldStateHolder", UIParent)
+SVUI_WorldStateHolder:SetPoint("TOP", SVUI_DockTopCenter, "BOTTOM", 0, -10)
+SVUI_WorldStateHolder:SetSize(200, 45)
+
+local SVUI_AltPowerBar = CreateFrame("Frame", "SVUI_AltPowerBar", UIParent)
+SVUI_AltPowerBar:SetPoint("TOP", SVUI_DockTopCenter, "BOTTOM", 0, -60)
+SVUI_AltPowerBar:SetSize(128, 50)
+
+local PVPRaidNoticeHandler = function(self, event, msg)
+	local _, instanceType = IsInInstance()
+	if((instanceType == 'pvp') or (instanceType == 'arena')) then
+		RaidNotice_AddMessage(RaidBossEmoteFrame, msg, ChatTypeInfo["RAID_BOSS_EMOTE"]);
+	end
+end
+
+local CaptureBarHandler = function()
+	local lastFrame = SVUI_WorldStateHolder
+	local offset = "TOP";
+
+	if(NUM_ALWAYS_UP_UI_FRAMES) then
+		for i=1, NUM_ALWAYS_UP_UI_FRAMES do
+			local frame = _G["AlwaysUpFrame"..i]
+			if(frame and frame:IsVisible()) then
+				frame:ClearAllPoints()
+				frame:SetPoint("TOP", lastFrame, offset, 0, 0)
+				lastFrame = frame
+				offset = "BOTTOM";
+			end
+		end
+	end
+
+	if(NUM_EXTENDED_UI_FRAMES) then
+		for i=1, NUM_EXTENDED_UI_FRAMES do
+			local name = "WorldStateCaptureBar"..i;
+			local frame = _G[name]
+			if(frame and frame:IsVisible()) then
+				if(_G[name .. "LeftBar"]) then _G[name .. "LeftBar"]:SetTexture("Interface\\AddOns\\SVUI_!Core\\assets\\textures\\WorldState-CaptureBar") end
+				if(_G[name .. "RightBar"]) then _G[name .. "RightBar"]:SetTexture("Interface\\AddOns\\SVUI_!Core\\assets\\textures\\WorldState-CaptureBar") end
+				if(_G[name .. "MiddleBar"]) then _G[name .. "MiddleBar"]:SetTexture("Interface\\AddOns\\SVUI_!Core\\assets\\textures\\WorldState-CaptureBar") end
+				if(_G[name .. "LeftLine"]) then _G[name .. "LeftLine"]:SetTexture("Interface\\AddOns\\SVUI_!Core\\assets\\textures\\WorldState-CaptureBar") end
+				if(_G[name .. "RightLine"]) then _G[name .. "RightLine"]:SetTexture("Interface\\AddOns\\SVUI_!Core\\assets\\textures\\WorldState-CaptureBar") end
+				if(_G[name .. "LeftIconHighlight"]) then _G[name .. "LeftIconHighlight"]:SetTexture("Interface\\AddOns\\SVUI_!Core\\assets\\textures\\WorldState-CaptureBar") end
+				if(_G[name .. "RightIconHighlight"]) then _G[name .. "RightIconHighlight"]:SetTexture("Interface\\AddOns\\SVUI_!Core\\assets\\textures\\WorldState-CaptureBar") end
+				if(_G[name .. "IndicatorLeft"]) then _G[name .. "IndicatorLeft"]:SetTexture("Interface\\AddOns\\SVUI_!Core\\assets\\textures\\WorldState-CaptureBar") end
+				if(_G[name .. "IndicatorRight"]) then _G[name .. "IndicatorRight"]:SetTexture("Interface\\AddOns\\SVUI_!Core\\assets\\textures\\WorldState-CaptureBar") end
+				frame:ClearAllPoints()
+				frame:SetPoint("TOP", lastFrame, offset, 0, 0)
+				lastFrame = frame
+				offset = "BOTTOM";
+			end
+		end
+	end
+end
+
+local Vehicle_OnSetPoint = function(self, _, parent)
+	if(parent == "MinimapCluster" or parent == _G["MinimapCluster"]) then
+		VehicleSeatIndicator:ClearAllPoints()
+		if _G.VehicleSeatIndicator_MOVE then
+			VehicleSeatIndicator:SetPoint("BOTTOM", VehicleSeatIndicator_MOVE, "BOTTOM", 0, 0)
+		else
+			VehicleSeatIndicator:SetPoint("TOPLEFT", SV.Dock.TopLeft, "TOPLEFT", 0, 0)
+			SV:NewAnchor(VehicleSeatIndicator, L["Vehicle Seat Frame"])
+		end
+		VehicleSeatIndicator:SetScale(0.8)
+	end
+end
+
+local PlayerPowerBarAlt_OnClearAllPoints = function(self)
+		self:SetPoint("CENTER", SVUI_AltPowerBar, "CENTER", 0, 0)
+end
+
+local Dura_OnSetPoint = function(self, _, parent)
+	if(parent ~= Minimap) then
+		self:ClearAllPoints()
+		self:SetPoint("RIGHT", Minimap, "RIGHT")
+		self:SetScale(0.6)
+	end
+end
+
+local function AlterBlizzMainBar()
+	if(not SV.ActionBars and MainMenuBar) then
+		MainMenuBar:ClearAllPoints()
+		MainMenuBar:SetPoint("BOTTOM", SV.Dock.BottomCenter, "TOP", 0, 4)
+		if(MainMenuBarTexture0) then
+			MainMenuBarTexture0:SetTexture("")
+		end
+		if(MainMenuBarTexture1) then
+			MainMenuBarTexture1:SetTexture("")
+		end
+		if(MainMenuBarTexture2) then
+			MainMenuBarTexture2:SetTexture("")
+		end
+		if(MainMenuBarTexture3) then
+			MainMenuBarTexture3:SetTexture("")
+		end
+		if(MainMenuBarLeftEndCap) then
+			MainMenuBarLeftEndCap:SetTexture("")
+		end
+		if(MainMenuBarRightEndCap) then
+			MainMenuBarRightEndCap:SetTexture("")
+		end
+		if(MainMenuXPBar) then
+			MainMenuXPBar:Die()
+		end
+		if(ReputationWatchBar) then
+			ReputationWatchBar:Die()
+		end
+		-- if(MainMenuXPBarTextureLeftCap) then
+		-- 	MainMenuXPBarTextureLeftCap:SetTexture("")
+		-- end
+		-- if(MainMenuXPBarTextureRightCap) then
+		-- 	MainMenuXPBarTextureRightCap:SetTexture("")
+		-- end
+		-- if(MainMenuXPBarTextureMid) then
+		-- 	MainMenuXPBarTextureMid:SetTexture("")
+		-- end
+		-- if(ReputationWatchBarTexture0) then
+		-- 	ReputationWatchBarTexture0:SetTexture("")
+		-- end
+		-- if(ReputationWatchBarTexture1) then
+		-- 	ReputationWatchBarTexture1:SetTexture("")
+		-- end
+		-- if(ReputationWatchBarTexture2) then
+		-- 	ReputationWatchBarTexture2:SetTexture("")
+		-- end
+		-- if(ReputationWatchBarTexture3) then
+		-- 	ReputationWatchBarTexture3:SetTexture("")
+		-- end
+		-- if(ReputationXPBarTexture0) then
+		-- 	ReputationXPBarTexture0:SetTexture("")
+		-- end
+		-- if(ReputationXPBarTexture1) then
+		-- 	ReputationXPBarTexture1:SetTexture("")
+		-- end
+		-- if(ReputationXPBarTexture2) then
+		-- 	ReputationXPBarTexture2:SetTexture("")
+		-- end
+		-- if(ReputationXPBarTexture3) then
+		-- 	ReputationXPBarTexture3:SetTexture("")
+		-- end
+	end
+end
+--[[
+##########################################################
+LOAD
+##########################################################
+]]--
+local function UpdateLootingUpvalues()
+	AUTOROLL_ENABLED = SV.db.Extras.autoRoll;
+	AUTOROLL_SOULBOUND = SV.db.Extras.autoRollSoulbound;
+	AUTOROLL_LEVEL = SV.db.Extras.autoRollMaxLevel;
+	local dbQuality = SV.db.Extras.autoRollQuality;
+	AUTOROLL_QUALITY = tonumber(dbQuality);
+	if(type(AUTOROLL_QUALITY) ~= 'number') then
+		AUTOROLL_QUALITY = 2;
+	end
+	AUTOROLL_DE = SV.db.Extras.autoRollDisenchant;
+end
+
+local function SetOverrides()
+	if(CollectionsMicroButtonAlert) then
+		CollectionsMicroButtonAlert:Die()
+	end
+
+	DurabilityFrame:SetFrameStrata("HIGH")
+	NewHook(DurabilityFrame, "SetPoint", Dura_OnSetPoint)
+
+	TicketStatusFrame:ClearAllPoints()
+	TicketStatusFrame:SetPoint("TOPRIGHT", SV.Dock.TopLeft, "TOPRIGHT", 0, 0)
+	-- SV:NewAnchor(TicketStatusFrame, L["GM Ticket Frame"], nil, nil, "GM")
+	SV:NewAnchor(TicketStatusFrame, L["GM Ticket Frame"])
+
+	HelpPlate:Die()
+	HelpPlateTooltip:Die()
+	HelpOpenTicketButtonTutorial:Die()
+	HelpOpenTicketButton:SetParent(Minimap)
+	HelpOpenTicketButton:ClearAllPoints()
+	HelpOpenTicketButton:SetPoint("TOPRIGHT", Minimap, "TOPRIGHT")
+
+	NewHook(VehicleSeatIndicator, "SetPoint", Vehicle_OnSetPoint)
+	VehicleSeatIndicator:SetPoint("TOPLEFT", MinimapCluster, "TOPLEFT", 2, 2)
+
+	SVUI_WorldStateHolder:SetSize(200, 45)
+	SV:NewAnchor(SVUI_WorldStateHolder, L["Capture Bars"])
+	NewHook("UIParent_ManageFramePositions", CaptureBarHandler)
+	WorldStateAlwaysUpFrame:ClearAllPoints()
+	WorldStateAlwaysUpFrame:SetPoint("TOP",SVUI_WorldStateHolder,"TOP",0,0)
+
+	SVUI_AltPowerBar:SetSize(128, 50)
+	PlayerPowerBarAlt:ClearAllPoints()
+	PlayerPowerBarAlt:SetPoint("CENTER", SVUI_AltPowerBar, "CENTER", 0, 0)
+	PlayerPowerBarAlt:SetParent(SVUI_AltPowerBar)
+	PlayerPowerBarAlt.ignoreFramePositionManager = true;
+	NewHook(PlayerPowerBarAlt, "ClearAllPoints", PlayerPowerBarAlt_OnClearAllPoints)
+	SV:NewAnchor(SVUI_AltPowerBar, L["Alternative Power"])
+
+	if(SVUI_Player) then
+		SVUI_BailOut:ClearAllPoints()
+		local size = SVUI_Player:GetHeight()
+		SVUI_BailOut:SetSize(size, size)
+		SVUI_BailOut:SetPoint("TOPLEFT", SVUI_Player, "TOPRIGHT", 4, 0)
+	end
+	SVUI_BailOut:SetNormalTexture(SV.media.icon.exitIcon)
+	SVUI_BailOut:SetPushedTexture(SV.media.icon.exitIcon)
+	SVUI_BailOut:SetHighlightTexture(SV.media.icon.exitIcon)
+	SVUI_BailOut:SetStyle("!_Frame", "Transparent")
+	SVUI_BailOut:RegisterForClicks("AnyUp")
+	SVUI_BailOut:SetScript("OnClick", BailOut_OnClick)
+	SVUI_BailOut:RegisterEvent("UNIT_ENTERED_VEHICLE")
+ 	SVUI_BailOut:RegisterEvent("UNIT_EXITED_VEHICLE")
+ 	SVUI_BailOut:RegisterEvent("VEHICLE_UPDATE")
+ 	SVUI_BailOut:RegisterEvent("PLAYER_ENTERING_WORLD")
+ 	SVUI_BailOut:SetScript("OnEvent", BailOut_OnEvent)
+ 	NewHook("TakeTaxiNode", BailOut_OnHook)
+	SV:NewAnchor(SVUI_BailOut, L["Bail Out"])
+	SVUI_BailOut:Hide()
+
+	LossOfControlFrame:ClearAllPoints()
+	LossOfControlFrame:SetSize(75, 75)
+	LossOfControlFrame:SetPoint("CENTER", SV.Screen, "CENTER", -146, -40)
+	-- SV:NewAnchor(LossOfControlFrame, L["Loss Control Icon"], nil, nil, "LoC")
+	SV:NewAnchor(LossOfControlFrame, L["Loss Control Icon"])
+
+	SV:RegisterEvent("CHAT_MSG_BG_SYSTEM_HORDE", PVPRaidNoticeHandler)
+	SV:RegisterEvent("CHAT_MSG_BG_SYSTEM_ALLIANCE", PVPRaidNoticeHandler)
+	SV:RegisterEvent("CHAT_MSG_BG_SYSTEM_NEUTRAL", PVPRaidNoticeHandler)
+
+	UIParent:UnregisterEvent("MIRROR_TIMER_START")
+	MirrorBarEventFrame:RegisterEvent("CVAR_UPDATE")
+	MirrorBarEventFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
+	MirrorBarEventFrame:RegisterEvent("MIRROR_TIMER_START")
+	MirrorBarEventFrame:RegisterEvent("MIRROR_TIMER_STOP")
+	MirrorBarEventFrame:RegisterEvent("MIRROR_TIMER_PAUSE")
+	MirrorBarEventFrame:RegisterEvent("START_TIMER")
+	MirrorBarEventFrame:SetScript("OnEvent", MirrorBar_OnEvent)
+
+	if(SV.db.general.loot) then
+		UIPARENT_MANAGED_FRAME_POSITIONS["GroupLootContainer"] = nil;
+		LootFrame:UnregisterAllEvents();
+
+		SVUI_LootFrameHolder:SetSize(150, 22);
+		-- SV:NewAnchor(SVUI_LootFrameHolder, L["Loot Frame"], nil, nil, "SVUI_LootFrame");
+		SV:NewAnchor(SVUI_LootFrameHolder, L["Loot Frame"]);
+
+		SVUI_LootFrame:SetSize(256, 64);
+		SVUI_LootFrame:SetStyle("!_Frame", 'Transparent');
+		SVUI_LootFrame.title:SetFontObject(SVUI_Font_Header)
+		SV:ManageVisibility(SVUI_LootFrame);
+		SVUI_LootFrame:Hide();
+
+		UIParent:UnregisterEvent("LOOT_BIND_CONFIRM")
+		UIParent:UnregisterEvent("CONFIRM_DISENCHANT_ROLL")
+		UIParent:UnregisterEvent("CONFIRM_LOOT_ROLL")
+
+		LootingEventFrame:RegisterEvent("CONFIRM_DISENCHANT_ROLL")
+		LootingEventFrame:RegisterEvent("CONFIRM_LOOT_ROLL")
+		LootingEventFrame:RegisterEvent("LOOT_BIND_CONFIRM")
+		LootingEventFrame:RegisterEvent("LOOT_READY")
+		LootingEventFrame:RegisterEvent("LOOT_SLOT_CLEARED");
+		LootingEventFrame:RegisterEvent("LOOT_CLOSED");
+		LootingEventFrame:RegisterEvent("OPEN_MASTER_LOOT_LIST");
+		LootingEventFrame:RegisterEvent("UPDATE_MASTER_LOOT_LIST");
+
+		if SV.db.general.lootRoll then
+			LootingEventFrame:RegisterEvent("LOOT_HISTORY_ROLL_CHANGED");
+			LootingEventFrame:RegisterEvent("START_LOOT_ROLL");
+			UIParent:UnregisterEvent("START_LOOT_ROLL");
+			UIParent:UnregisterEvent("CANCEL_LOOT_ROLL");
+			SV.Events:On("LOOTING_UPVALUES_UPDATED", UpdateLootingUpvalues, true);
+			UpdateLootingUpvalues()
+		end
+
+		LootingEventFrame:SetScript("OnEvent", LootFrame_OnEvent);
+	end
+
+	ColorPickerFrame:SetFrameStrata("FULLSCREEN_DIALOG")
+	ColorPickerFrame:SetBackdrop(SV.media.backdrop.darkened)
+	ColorPickerFrame:SetFrameLevel(999)
+
+	AlterBlizzMainBar()
+end
+
+SV:NewScript(SetOverrides)
\ No newline at end of file
diff --git a/SVUI_!Core/system/profile.lua b/SVUI_!Core/system/profile.lua
new file mode 100644
index 0000000..91ec6a7
--- /dev/null
+++ b/SVUI_!Core/system/profile.lua
@@ -0,0 +1,165 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+############################################################################## ]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack            = _G.unpack;
+local select            = _G.select;
+local assert            = _G.assert;
+local type              = _G.type;
+local error             = _G.error;
+local pcall             = _G.pcall;
+local print             = _G.print;
+local ipairs            = _G.ipairs;
+local pairs             = _G.pairs;
+local next              = _G.next;
+local rawset            = _G.rawset;
+local rawget            = _G.rawget;
+local tostring          = _G.tostring;
+local tonumber          = _G.tonumber;
+local getmetatable      = _G.getmetatable;
+local setmetatable      = _G.setmetatable;
+local collectgarbage    = _G.collectgarbage;
+local string    = _G.string;
+local math      = _G.math;
+local table     = _G.table;
+local wipe      = _G.wipe;
+--[[ STRING METHODS ]]--
+local format, find, lower, match, gsub = string.format, string.find, string.lower, string.match, string.gsub;
+--[[ MATH METHODS ]]--
+local floor, abs, min, max = math.floor, math.abs, math.min, math.max;
+--[[ TABLE METHODS ]]--
+local tremove, tcopy, twipe, tsort, tconcat = table.remove, table.copy, table.wipe, table.sort, table.concat;
+local tprint = table.tostring;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G["SVUI"];
+local L = SV.L;
+local SVUILib = Librarian("Registry");
+
+SV.ProfileInterface = _G["SVUI_ProfileInterface"];
+local ProfileInterfaceDialog = _G["SVUI_ProfileInterfaceDialog"];
+local ProfileInterfaceHelp = _G["SVUI_ProfileInterfaceHelp"];
+local ProfileInterfaceScrollBar = _G["SVUI_ProfileInterfaceDialogScrollBar"];
+--[[
+##########################################################
+CUSTOM MESSAGE WINDOW
+##########################################################
+]]--
+local exportHelpText = "TO EXPORT: First click the 'Generate Export Key' button. Once your key has been generated, you will want to select and copy the entire code and paste it into a NEW (.txt) document. Save your new document and share the hell out of it!";
+local importHelpText = "TO IMPORT: First click the 'Clear' button, then simply copy any profile key from its saved document, paste it into this window, then click the 'Import From Key' button. After confirming the import, your UI will be reloaded. Your current profile will have now been changed with the encoded settings!";
+local completeHelpText = exportHelpText .. "\n\n" .. importHelpText;
+
+local ProfileInterface_OnTextChanged = function(self, userInput)
+  if userInput then
+    --ProfileInterfaceHelp.Text:SetText(completeHelpText);
+  else
+    local _, max = ProfileInterfaceScrollBar:GetMinMaxValues()
+    for i = 1, max do
+      ScrollFrameTemplate_OnMouseWheel(ProfileInterfaceDialog, -1)
+    end
+  end
+end
+
+function SV.ProfileInterface:Toggle()
+  local aceConfig = LibStub("AceConfigDialog-3.0")
+  if(aceConfig and SV.OptionsLoaded) then
+    aceConfig:Close(SV.NameID)
+    GameTooltip:Hide()
+  end
+  if not SV.ProfileInterface:IsShown() then
+    SV.ProfileInterface:Show()
+  else
+    SV.ProfileInterface:Hide()
+  end
+end
+
+function SV:LinkProfile(key)
+    self.SystemAlert["COPY_PROFILE_PROMPT"].text = "Are you sure you want to use the shared profile '" .. key .. "'?"
+    self.SystemAlert["COPY_PROFILE_PROMPT"].OnAccept = function() SVUILib:CopyDatabase(key, true) end
+    self:StaticPopup_Show("COPY_PROFILE_PROMPT")
+end
+
+function SV:CopyProfile(key)
+    self.SystemAlert["COPY_PROFILE_PROMPT"].text = "Are you sure you want to copy from the profile '" .. key .. "'?"
+    self.SystemAlert["COPY_PROFILE_PROMPT"].OnAccept = function() SVUILib:CopyDatabase(key) end
+    self:StaticPopup_Show("COPY_PROFILE_PROMPT")
+end
+
+local ProfileInterface_ExportProfile = function(self)
+    local t = SVUILib:ExportDatabase();
+    ProfileInterfaceDialog.Input:SetText(t);
+    ProfileInterfaceDialog.Input:HighlightText(0);
+    ProfileInterfaceHelp.Text:SetText(exportHelpText);
+end
+
+local ProfileInterface_ImportProfile = function(self)
+    ProfileInterfaceHelp.Text:SetText(importHelpText);
+    SV.SystemAlert["IMPORT_PROFILE_PROMPT"].OnAccept = function()
+        local input = ProfileInterfaceDialog.Input:GetText()
+        if(input and input ~= '') then
+            SVUILib:ImportDatabase(input)
+        else
+            ProfileInterfaceHelp.Text:SetText('You did not enter a profile key.');
+        end
+    end
+    SV:StaticPopup_Show("IMPORT_PROFILE_PROMPT")
+end
+
+local ProfileInterface_ClearProfile = function(self)
+    ProfileInterfaceDialog.Input:SetText('');
+    ProfileInterfaceHelp.Text:SetText(completeHelpText);
+end
+
+local function InitializeProfileInterface()
+    SV.ProfileInterface:SetParent(SV.Screen)
+    SV.ProfileInterface.Source = "";
+    SV.ProfileInterface:SetStyle("Frame", "Container")
+    SV.ProfileInterface.Export:SetStyle("Button")
+    SV.ProfileInterface.Export:SetScript("OnClick", ProfileInterface_ExportProfile)
+    SV.ProfileInterface.Import:SetStyle("Button")
+    SV.ProfileInterface.Import:SetScript("OnClick", ProfileInterface_ImportProfile)
+    SV.ProfileInterface.Clear:SetStyle("Button")
+    SV.ProfileInterface.Clear:SetScript("OnClick", ProfileInterface_ClearProfile)
+    SV.API:Set("CloseButton", SV.ProfileInterface.Close)
+    ProfileInterfaceDialog:SetStyle("Frame", "Transparent")
+    ProfileInterfaceDialog.Input:SetScript("OnTextChanged", ProfileInterface_OnTextChanged)
+    SV.ProfileInterface:RegisterForDrag("LeftButton");
+    ProfileInterfaceHelp:SetStyle("Frame", "Default")
+    ProfileInterfaceHelp.Text:SetText(completeHelpText);
+end
+
+SV.Events:On("LOAD_ALL_ESSENTIALS", InitializeProfileInterface);
+
+function SV:GenerateSharedProfileOptions()
+    local sharedGroup = {};
+
+    sharedGroup.spacer1 = {
+        order = 1,
+        type = "description",
+        name = "Shared settings allow you to transfer even more options from enabled modules.".."\n",
+        width = "full",
+    }
+
+    local currentCount = 2;
+    for schema,data in pairs(self.private.SAFEDATA.SHARED) do
+        local obj = self[schema];
+        if(obj and obj.___canShare) then
+            sharedGroup[schema] = {
+                order = currentCount,
+                type = "toggle",
+                name = L["Shared " .. schema .. " Settings"],
+                desc = L["Do you want all " .. schema .. " settings available when copying the current profile?"],
+                get = function(a) return obj:IsSharingEnabled(); end,
+                set = function(a,b) obj:ToggleSharedData(b); end,
+            };
+            currentCount = currentCount + 1;
+        end
+    end
+
+    return sharedGroup;
+end
diff --git a/SVUI_!Core/system/reports.lua b/SVUI_!Core/system/reports.lua
new file mode 100644
index 0000000..ba8cb8f
--- /dev/null
+++ b/SVUI_!Core/system/reports.lua
@@ -0,0 +1,770 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pcall         = _G.pcall;
+local print         = _G.print;
+local ipairs        = _G.ipairs;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local rawset        = _G.rawset;
+local rawget        = _G.rawget;
+local tostring      = _G.tostring;
+local tonumber      = _G.tonumber;
+local string    = _G.string;
+local math      = _G.math;
+local table 	= _G.table;
+--[[ STRING METHODS ]]--
+local join, len = string.join, string.len;
+--[[ MATH METHODS ]]--
+local min = math.min;
+--TABLE
+local table         = _G.table;
+local tsort         = table.sort;
+local tconcat       = table.concat;
+local tinsert       = _G.tinsert;
+local tremove       = _G.tremove;
+local wipe         = _G.wipe;
+--BLIZZARD API
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+local GameTooltip           = _G.GameTooltip;
+local hooksecurefunc        = _G.hooksecurefunc;
+local IsAltKeyDown          = _G.IsAltKeyDown;
+local IsShiftKeyDown        = _G.IsShiftKeyDown;
+local IsControlKeyDown      = _G.IsControlKeyDown;
+local IsModifiedClick       = _G.IsModifiedClick;
+local NONE                  = _G.NONE;
+local IsInInstance          = _G.IsInInstance;
+local GetCurrentMapAreaID          		= _G.GetCurrentMapAreaID;
+local RequestBattlefieldScoreData       = _G.RequestBattlefieldScoreData;
+local GetBattlefieldStatData            = _G.GetBattlefieldStatData;
+local GetNumBattlefieldScores           = _G.GetNumBattlefieldScores;
+local GetBattlefieldScore            	= _G.GetBattlefieldScore;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...)
+local L = SV.L
+local SVLib = _G.Librarian("Registry")
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local LDB = LibStub("LibDataBroker-1.1", true)
+local MOD = SV:NewPackage("Reports", L["Informative Panels"]);
+
+MOD.Sockets = {};
+MOD.Plugins = {};
+MOD.References = {};
+MOD.ToolTip = CreateFrame("GameTooltip", "SVUI_Report_ToolTip", UIParent, "GameTooltipTemplate");
+MOD.CallBacks = _G.LibStub:GetLibrary("CallbackHandler-1.0"):New(MOD)
+
+local PVP_SOCKETS = {};
+local PVP_INFO_SORTING = {
+	{"Honor", "Kills", "Assists"},
+	{"Damage", "Healing", "Deaths"}
+};
+local PVP_INFO_LOOKUP = {
+	["Name"] = {1, NAME},
+	["Kills"] = {2, KILLS},
+	["Assists"] = {3, PET_ASSIST},
+	["Deaths"] = {4, DEATHS},
+	["Honor"] = {5, HONOR},
+	["Faction"] = {6, FACTION},
+	["Race"] = {7, RACE},
+	["Class"] = {8, CLASS},
+	["Damage"] = {10, DAMAGE},
+	["Healing"] = {11, SHOW_COMBAT_HEALING},
+	["Rating"] = {12, BATTLEGROUND_RATING},
+	["Changes"] = {13, RATING_CHANGE},
+	["Spec"] = {16, SPECIALIZATION}
+};
+local LDB_TEXT_PATTERN = "|cff22CFFF(|r%s|cff22CFFF)|r";
+local LDB_ICON_PATTERN = "\124T%s:12\124t %s";
+local DIRTY_LIST = true;
+--[[
+##########################################################
+LOCALIZED GLOBALS
+##########################################################
+]]--
+local RAID_CLASS_COLORS = _G.RAID_CLASS_COLORS
+--[[
+##########################################################
+LOCAL VARIABLES
+##########################################################
+]]--
+local playerName = UnitName("player");
+local playerRealm = GetRealmName();
+local BGStatString = "%s: %s"
+local myName = UnitName("player");
+local myClass = select(2,UnitClass("player"));
+local classColor = RAID_CLASS_COLORS[myClass];
+local SCORE_CACHE = {};
+local hexHighlight = "FFFFFF";
+local StatMenuListing = {}
+--[[
+##########################################################
+LOCAL FUNCTIONS
+##########################################################
+]]--
+local UpdateAnchor = function()
+	local backdrops, width, height = SV.db.Reports.backdrop
+	for _, parent in ipairs(MOD.Sockets) do
+		local point1, point2, x, y = "LEFT", "RIGHT", 4, 0;
+		local slots = parent.Stats.Slots
+		local numPoints = #slots
+		if(parent.Stats.Orientation == "VERTICAL") then
+			width = parent:GetWidth() - 4;
+			height = parent:GetHeight() / numPoints - 4;
+
+			point1, point2, x, y = "TOP", "BOTTOM", 0, -4
+		else
+			width = parent:GetWidth() / numPoints - 4;
+			height = parent:GetHeight() - 4;
+			if(backdrops) then
+				height = height + 6
+
+			end
+		end
+
+		for i = 1, numPoints do
+			slots[i]:SetWidth(width)
+			slots[i]:SetHeight(height)
+			if(i == 1) then
+				slots[i]:SetPoint(point1, parent, point1, x, y)
+			else
+				slots[i]:SetPoint(point1, slots[i - 1], point2, x, y)
+			end
+		end
+	end
+end
+
+local _hook_TooltipOnShow = function(self)
+	self:SetBackdrop({
+		bgFile = SV.media.background.default,
+		edgeFile = [[Interface\BUTTONS\WHITE8X8]],
+		tile = false,
+		edgeSize = 1
+		})
+	self:SetBackdropColor(0.05, 0.05, 0.05, 0.95)
+	self:SetBackdropBorderColor(0, 0, 0)
+end
+
+local function TruncateString(value)
+	if(not value or value == 0) then return 0 end
+	if value >= 1e9 then
+		return ("%.1fb"):format(value/1e9):gsub("%.?0+([kmb])$","%1")
+	elseif value >= 1e6 then
+		return ("%.1fm"):format(value/1e6):gsub("%.?0+([kmb])$","%1")
+	elseif value >= 1e3 or value <= -1e3 then
+		return ("%.1fk"):format(value/1e3):gsub("%.?0+([kmb])$","%1")
+	else
+		return value
+	end
+end
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+function MOD:SetDataTip(stat)
+	local parent = stat:GetParent()
+	MOD.ToolTip:Hide()
+	MOD.ToolTip:SetOwner(parent, parent.Stats.TooltipAnchor)
+	MOD.ToolTip:ClearLines()
+	GameTooltip:Hide()
+end
+
+function MOD:SetBrokerTip(stat)
+	local parent = stat:GetParent()
+	MOD.ToolTip:Hide()
+	MOD.ToolTip:SetOwner(parent, "ANCHOR_CURSOR")
+	MOD.ToolTip:ClearLines()
+	GameTooltip:Hide()
+end
+
+function MOD:PrependDataTip()
+	MOD.ToolTip:AddDoubleLine("[Alt + Click]", "Swap Stats", 0, 1, 0, 0.5, 1, 0.5)
+	MOD.ToolTip:AddLine(" ")
+end
+
+function MOD:ShowDataTip(noSpace)
+	if(not noSpace) then
+		MOD.ToolTip:AddLine(" ")
+	end
+	MOD.ToolTip:AddDoubleLine("[Alt + Click]", "Swap Stats", 0, 1, 0, 0.5, 1, 0.5)
+	MOD.ToolTip:Show()
+end
+
+local function GetDataSlot(parent, index)
+	if(not parent.Stats.Slots[index]) then
+		local GlobalName = parent:GetName() .. 'StatSlot' .. index;
+
+		local slot = CreateFrame("Button", GlobalName, parent);
+		slot:RegisterForClicks("AnyUp")
+
+
+		slot.barframe = CreateFrame("Frame", nil, slot)
+		slot:SetStyle(parent.Stats.templateType, parent.Stats.templateName, false, 2, 0, 0)
+
+		if(not SV.db.Reports.backdrop) then
+			slot.barframe:SetPoint("TOPLEFT", slot, "TOPLEFT", 24, 2)
+			slot.barframe:SetPoint("BOTTOMRIGHT", slot, "BOTTOMRIGHT", 2, -2)
+			slot.barframe.bg = slot.barframe:CreateTexture(nil, "BORDER")
+			slot.barframe.bg:InsetPoints(slot.barframe, 2, 2)
+			slot.barframe.bg:SetTexture([[Interface\BUTTONS\WHITE8X8]])
+			slot.barframe.bg:SetGradient(unpack(SV.media.gradient.dark))
+			slot.Panel:Hide()
+		else
+			slot.barframe:SetPoint("TOPLEFT", slot, "TOPLEFT", 24, -2)
+			slot.barframe:SetPoint("BOTTOMRIGHT", slot, "BOTTOMRIGHT", -2, 2)
+			slot.Panel:Show()
+		end
+
+		slot.barframe:SetFrameLevel(slot:GetFrameLevel()-1)
+		slot.barframe:SetBackdrop({
+			bgFile = [[Interface\BUTTONS\WHITE8X8]],
+			edgeFile = SV.media.border.shadow,
+			tile = false,
+			tileSize = 0,
+			edgeSize = 2,
+			insets = {left = 0, right = 0, top = 0, bottom = 0}
+			})
+		slot.barframe:SetBackdropColor(0, 0, 0, 0.5)
+		slot.barframe:SetBackdropBorderColor(0, 0, 0, 0.8)
+
+		slot.barframe.icon = CreateFrame("Frame", nil, slot.barframe)
+		slot.barframe.icon:SetPoint("TOPLEFT", slot, "TOPLEFT", 0, 6)
+		slot.barframe.icon:SetPoint("BOTTOMRIGHT", slot, "BOTTOMLEFT", 26, -6)
+		slot.barframe.icon.texture = slot.barframe.icon:CreateTexture(nil, "OVERLAY")
+		slot.barframe.icon.texture:InsetPoints(slot.barframe.icon, 2, 2)
+		slot.barframe.icon.texture:SetTexture("")
+
+		slot.barframe.bar = CreateFrame("StatusBar", nil, slot.barframe)
+		slot.barframe.bar:InsetPoints(slot.barframe, 2, 2)
+		slot.barframe.bar:SetStatusBarTexture(SV.media.statusbar.default)
+
+		slot.barframe.bar.extra = CreateFrame("StatusBar", nil, slot.barframe.bar)
+		slot.barframe.bar.extra:SetAllPoints()
+		slot.barframe.bar.extra:SetStatusBarTexture(SV.media.statusbar.default)
+		slot.barframe.bar.extra:Hide()
+
+		slot.barframe:Hide()
+
+		slot.textframe = CreateFrame("Frame", nil, slot)
+		slot.textframe:SetAllPoints(slot)
+		slot.textframe:SetFrameStrata(parent.Stats.textStrata)
+
+		slot.text = slot.textframe:CreateFontString(nil, "OVERLAY", nil, 7)
+		slot.text:SetAllPoints()
+
+		SV:FontManager(slot.text, "data")
+		if(SV.db.Reports.backdrop) then
+			slot.text:SetShadowColor(0, 0, 0, 0.5)
+			slot.text:SetShadowOffset(2, -4)
+		end
+
+		slot.SlotKey = index;
+		slot.TokenKey = 738;
+		slot.MenuList = {};
+		slot.TokenList = {};
+
+		parent.Stats.Slots[index] = slot;
+		return slot;
+	end
+
+	return parent.Stats.Slots[index];
+end
+
+local function LDB_AttributeChanged(event, data_name, key, value, obj)
+	local name = obj.ReportName
+	local socket = MOD.References[name]
+	if(not socket) then return end
+	value = value or obj.text
+	local icon = obj.icon
+	if(type(value) ~= "string") then
+		value = name
+	end
+	if(not value or value == name) then
+		local prev = socket.text:GetText()
+		if((not prev) or (not prev:find(name)) or (prev == "")) then
+			socket.text:SetText(name)
+		end
+	elseif(icon and type(icon) == "string") then
+		socket.text:SetText(LDB_ICON_PATTERN:format(icon, value))
+	else
+		socket.text:SetText(LDB_TEXT_PATTERN:format(value))
+	end
+end
+
+local function CreateLDB_OnEventHandler(name, obj)
+	return function(self, ...)
+		LDB:RegisterCallback("LibDataBroker_AttributeChanged_"..name, LDB_AttributeChanged)
+		LDB_AttributeChanged(nil, name, nil, nil, obj)
+	end
+end
+
+local Socket_OnEvent = function(self, ...)
+	if(self.eventFunc) then
+		self.eventFunc(self, ...)
+	end
+end
+
+local Socket_OnUpdate = function(self, ...)
+	if(self.updateFunc) then
+		self.updateFunc(self, ...)
+	end
+end
+
+local LDB_OnEnter = function(self, ...)
+	self.OnTooltipShow(GameTooltip)
+end
+
+local Socket_OnEnter = function(self, ...)
+	if(self.enterFunc) then
+		self.enterFunc(self, ...)
+	end
+end
+
+local Socket_OnLeave = function(self, ...)
+	if(self.leaveFunc) then
+		self.leaveFunc(self, ...)
+	end
+	MOD.ToolTip:Hide()
+end
+
+local Socket_OnClick = function(self, button)
+	if IsAltKeyDown() then
+		SV.Dropdown:Open(self, self.MenuList, "Select Report");
+	elseif(self.clickFunc) then
+		self.clickFunc(self, button);
+	end
+end
+
+function MOD:EnableReport(socket, name)
+	local obj = self.Plugins[name]
+	if(not obj) then return end
+
+	if(socket.InnerData) then
+		wipe(socket.InnerData)
+	end
+
+	if obj.OnInit then
+		obj.OnInit(socket)
+	end
+
+	if obj.OnEvent and obj.events then
+		for i=1, #obj.events do
+			socket:RegisterEvent(obj.events[i])
+		end
+		socket.eventFunc = obj.OnEvent
+		socket:SetScript("OnEvent", Socket_OnEvent)
+		Socket_OnEvent(socket, "SVUI_FORCE_RUN")
+	end
+
+	if obj.OnUpdate then
+		socket.updateFunc = obj.OnUpdate
+	end
+	socket:SetScript("OnUpdate", Socket_OnUpdate)
+	Socket_OnUpdate(socket, 20000)
+
+	if(LDB and obj.LDBName and obj.OnTooltipShow) then
+		socket:SetScript("OnEnter", LDB_OnEnter)
+	end
+
+	if obj.OnEnter then
+		socket.enterFunc = obj.OnEnter
+	end
+	socket:SetScript("OnEnter", Socket_OnEnter)
+
+	if obj.OnLeave then
+		socket.leaveFunc = obj.OnLeave
+	end
+	socket:SetScript("OnLeave", Socket_OnLeave)
+
+	if obj.OnClick then
+		socket.clickFunc = obj.OnClick
+	end
+	socket:SetScript("OnClick", Socket_OnClick)
+
+	socket:Show()
+
+	if(not SV.db.Reports.backdrop) then
+		socket.Panel:Hide()
+	else
+		socket.Panel:Show()
+	end
+
+	if(LDB and obj.LDBName) then
+		LDB:RegisterCallback("LibDataBroker_AttributeChanged_"..obj.LDBName, LDB_AttributeChanged)
+		LDB_AttributeChanged(nil, name, nil, nil, obj)
+	end
+end
+
+function MOD:NewReport(name, obj, LDBname)
+	local pluginList = self.Plugins;
+	local statMenu = StatMenuListing;
+	if pluginList[name] then return end
+	pluginList[name] = obj or {}
+	if(LDBname) then
+		pluginList[name].LDBName = LDBname
+		pluginList[name].ReportName = name
+	end
+	local statCount = #statMenu + 1;
+	StatMenuListing[statCount] = name;
+	return obj
+end
+
+do
+	local BG_OnUpdate = function(self)
+		local scoreString;
+		local scoreindex = self.scoreindex;
+		local scoreType = self.scoretype;
+		local scoreCount = GetNumBattlefieldScores()
+		for i = 1, scoreCount do
+			SCORE_CACHE = {GetBattlefieldScore(i)}
+			if(SCORE_CACHE[1] and SCORE_CACHE[1] == myName and SCORE_CACHE[scoreindex]) then
+				scoreString = TruncateString(SCORE_CACHE[scoreindex])
+				self.text:SetFormattedText(BGStatString, scoreType, scoreString)
+				break
+			end
+		end
+	end
+
+	local BG_OnEnter = function(self)
+		MOD:SetDataTip(self)
+		local bgName;
+		local mapToken = GetCurrentMapAreaID()
+		local r, g, b;
+		if(classColor) then
+			r, g, b = classColor.r, classColor.g, classColor.b
+		else
+			r, g, b = 1, 1, 1
+		end
+
+		local scoreCount = GetNumBattlefieldScores()
+
+		for i = 1, scoreCount do
+			bgName = GetBattlefieldScore(i)
+			if(bgName and bgName == myName) then
+				MOD.ToolTip:AddDoubleLine(L["Stats For:"], bgName, 1, 1, 1, r, g, b)
+				MOD.ToolTip:AddLine(" ")
+				if(mapToken == 443 or mapToken == 626) then
+					MOD.ToolTip:AddDoubleLine(L["Flags Captured"], GetBattlefieldStatData(i, 1), 1, 1, 1)
+					MOD.ToolTip:AddDoubleLine(L["Flags Returned"], GetBattlefieldStatData(i, 2), 1, 1, 1)
+				elseif(mapToken == 482) then
+					MOD.ToolTip:AddDoubleLine(L["Flags Captured"], GetBattlefieldStatData(i, 1), 1, 1, 1)
+				elseif(mapToken == 401) then
+					MOD.ToolTip:AddDoubleLine(L["Graveyards Assaulted"], GetBattlefieldStatData(i, 1), 1, 1, 1)
+					MOD.ToolTip:AddDoubleLine(L["Graveyards Defended"], GetBattlefieldStatData(i, 2), 1, 1, 1)
+					MOD.ToolTip:AddDoubleLine(L["Towers Assaulted"], GetBattlefieldStatData(i, 3), 1, 1, 1)
+					MOD.ToolTip:AddDoubleLine(L["Towers Defended"], GetBattlefieldStatData(i, 4), 1, 1, 1)
+				elseif(mapToken == 512) then
+					MOD.ToolTip:AddDoubleLine(L["Demolishers Destroyed"], GetBattlefieldStatData(i, 1), 1, 1, 1)
+					MOD.ToolTip:AddDoubleLine(L["Gates Destroyed"], GetBattlefieldStatData(i, 2), 1, 1, 1)
+				elseif(mapToken == 540 or mapToken == 736 or mapToken == 461) then
+					MOD.ToolTip:AddDoubleLine(L["Bases Assaulted"], GetBattlefieldStatData(i, 1), 1, 1, 1)
+					MOD.ToolTip:AddDoubleLine(L["Bases Defended"], GetBattlefieldStatData(i, 2), 1, 1, 1)
+				elseif(mapToken == 856) then
+					MOD.ToolTip:AddDoubleLine(L["Orb Possessions"], GetBattlefieldStatData(i, 1), 1, 1, 1)
+					MOD.ToolTip:AddDoubleLine(L["Victory Points"], GetBattlefieldStatData(i, 2), 1, 1, 1)
+				elseif(mapToken == 860) then
+					MOD.ToolTip:AddDoubleLine(L["Carts Controlled"], GetBattlefieldStatData(i, 1), 1, 1, 1)
+				end
+				break
+			end
+		end
+		MOD:ShowDataTip()
+	end
+
+	local ForceHideBGStats;
+	local BG_OnClick = function()
+		ForceHideBGStats = true;
+		MOD:UpdateAllReports()
+		SV:AddonMessage(L["Battleground statistics temporarily hidden, to show type \"/sv bg\" or \"/sv pvp\""])
+	end
+
+	local function setMenuLists()
+		local anchorTable = MOD.Sockets;
+		local statMenu = StatMenuListing;
+		tsort(statMenu)
+		for reportIndex, parent in ipairs(anchorTable) do
+			local slotKey = tostring(reportIndex)
+			local slots = parent.Stats.Slots;
+			local numPoints = #slots;
+			for i = 1, numPoints do
+				local subList = wipe(slots[i].MenuList)
+				tinsert(subList,{text = NONE, func = function() SV.db.REPORT_SLOTS[slotKey][i] = ""; MOD:UpdateAllReports() end});
+				for _,name in pairs(statMenu) do
+					tinsert(subList,{text = name, func = function() SV.db.REPORT_SLOTS[slotKey][i] = name; MOD:UpdateAllReports() end});
+				end
+			end
+		end
+
+		DIRTY_LIST = false;
+	end
+
+	function MOD:UpdateAllReports()
+		if(LDB) then
+			for dataName, dataObj in LDB:DataObjectIterator() do
+				local listName = dataName:gsub("Broker_", "");
+				if(not MOD.Plugins[listName]) then
+		  			MOD:ReportAdded(nil, dataName, dataObj, true)
+		  		end
+		  	end
+		end
+		if(DIRTY_LIST) then setMenuLists() end
+
+		local instance, groupType = IsInInstance()
+		local anchorTable = MOD.Sockets
+		local reportTable = MOD.Plugins
+		local docks = SV.db.REPORT_SLOTS
+		local allowPvP = (SV.db.Reports.battleground and not ForceHideBGStats) or false
+
+		for reportIndex, parent in ipairs(anchorTable) do
+			if(parent.Stats and parent.Stats.Slots) then
+				local slots = parent.Stats.Slots;
+				local numPoints = #slots;
+				local pvpIndex = parent.Stats.BGStats;
+				local pvpSwitch = (allowPvP and pvpIndex and (PVP_SOCKETS[pvpIndex] == reportIndex))
+
+				for i = 1, numPoints do
+					local pvpTable = (pvpSwitch and PVP_INFO_SORTING[pvpIndex]) and PVP_INFO_SORTING[pvpIndex][i]
+					local socket = slots[i];
+
+					socket:UnregisterAllEvents()
+					socket:SetScript("OnUpdate", nil)
+					socket:SetScript("OnEnter", nil)
+					socket:SetScript("OnLeave", nil)
+					socket:SetScript("OnClick", nil)
+
+					if socket.barframe then
+						socket.barframe:Hide()
+					end
+
+					socket:Hide()
+
+					if(pvpTable and ((instance and groupType == "pvp") or parent.lockedOpen)) then
+						socket.scoreindex = PVP_INFO_LOOKUP[pvpTable][1]
+						socket.scoretype = PVP_INFO_LOOKUP[pvpTable][2]
+						socket:RegisterEvent("UPDATE_BATTLEFIELD_SCORE")
+						socket:SetScript("OnEvent", BG_OnUpdate)
+						socket:SetScript("OnEnter", BG_OnEnter)
+						socket:SetScript("OnLeave", Socket_OnLeave)
+						socket:SetScript("OnClick", BG_OnClick)
+
+						BG_OnUpdate(socket)
+
+						socket:Show()
+					else
+						local loaded = false;
+						local x = tostring(reportIndex)
+						for n, _ in pairs(reportTable) do
+							for s, d in pairs(docks) do
+								if(d and ((type(d) == "table" and x == s and d[i] and d[i] == n) or (type(d) == "string" and d == n))) then
+									MOD.References[n] = socket
+									MOD:EnableReport(socket, n)
+									loaded = true
+								end
+							end
+						end
+						if(not loaded) then
+							socket.text:SetText(nil)
+						end
+					end
+				end
+			end
+		end
+
+		if ForceHideBGStats then ForceHideBGStats = nil end
+
+		local baseWidth, dockHeight = SV.Dock.BottomCenter:GetSize()
+		local dockWidth = baseWidth * 0.5;
+		MOD.ReportGroup1:SetSize(dockWidth, dockHeight);
+		MOD.ReportGroup2:SetSize(dockWidth, dockHeight);
+		MOD.ReportGroup3:SetSize(dockWidth, dockHeight);
+		MOD.ReportGroup4:SetSize(dockWidth, dockHeight);
+	end
+end
+
+local currentIndex = 1;
+
+function MOD:NewHolder(parent, maxCount, tipAnchor, pvpSet, customTemplate, isVertical)
+	DIRTY_LIST = true
+	local parentName = parent:GetName();
+
+	self.Sockets[currentIndex] = parent;
+	parent.Stats = {};
+	parent.Stats.Slots = {};
+	parent.Stats.Orientation = isVertical and "VERTICAL" or "HORIZONTAL";
+	parent.Stats.TooltipAnchor = tipAnchor or "ANCHOR_CURSOR";
+	if(pvpSet) then
+		parent.Stats.BGStats = pvpSet;
+		PVP_SOCKETS[pvpSet] = currentIndex;
+	end
+
+	local point1, point2, x, y = "LEFT", "RIGHT", 4, 0;
+	if(isVertical) then
+		point1, point2, x, y = "TOP", "BOTTOM", 0, -4;
+	end
+
+	if(customTemplate) then
+		parent.Stats.templateType = "Frame"
+		parent.Stats.templateName = customTemplate
+		parent.Stats.textStrata = "LOW"
+	else
+		parent.Stats.templateType = "Frame";
+		parent.Stats.templateName = "Transparent";
+		parent.Stats.textStrata = "MEDIUM";
+	end
+
+	for i = 1, maxCount do
+		local slot = GetDataSlot(parent, i)
+		if(i == 1) then
+			parent.Stats.Slots[i]:SetPoint(point1, parent, point1, x, y)
+		else
+			parent.Stats.Slots[i]:SetPoint(point1, parent.Stats.Slots[i - 1], point2, x, y)
+		end
+	end
+
+	parent:SetScript("OnSizeChanged", UpdateAnchor);
+	local slotKey = tostring(currentIndex);
+	if(slotKey and (not SV.db.REPORT_SLOTS[slotKey])) then
+		SV.db.REPORT_SLOTS[slotKey] = {};
+        for i = 1, maxCount do
+        	SV.db.REPORT_SLOTS[slotKey][i] = "None"
+        end
+	end
+
+	currentIndex = currentIndex + 1;
+
+	UpdateAnchor(parent);
+end
+
+local function SlashPvPStats()
+	MOD.ForceHideBGStats = nil;
+	MOD:UpdateAllReports()
+	SV:AddonMessage(L['Battleground statistics will now show again if you are inside a battleground.'])
+end
+--[[
+##########################################################
+BUILD FUNCTION / UPDATE
+##########################################################
+]]--
+function SV:GetReportData(key)
+	return MOD.Accountant[key]
+end
+
+function MOD:SetAccountantData(key, cacheType, defaultValue)
+	self.Accountant[key] = self.Accountant[key] or {};
+	local cache = self.Accountant[key];
+	if(type(cache) == 'number') then
+		cache = defaultValue;
+	elseif(not cache[playerName] or type(cache[playerName]) ~= cacheType) then
+		cache[playerName] = defaultValue;
+	end
+end
+
+function MOD:SetSubSettingsData(key, cacheType, defaultValue)
+	self.SubSettings[key] = self.SubSettings[key] or {};
+	local cache = self.SubSettings[key];
+	if(type(cache) == 'number') then
+		cache = defaultValue;
+	elseif(not cache[playerName] or type(cache[playerName]) ~= cacheType) then
+		cache[playerName] = defaultValue;
+	end
+end
+
+function MOD:ReportAdded(event, dataName, dataObj, noupdate)
+	local t = dataObj.type
+	if(t) then
+		if(t == "data source" or t == "launcher") then
+		    local listName = dataName:gsub("Broker_", "");
+		    MOD:NewReport(listName, dataObj, dataName);
+		    DIRTY_LIST = true
+		else
+			SV:HandleError("LibDataBroker", dataName, "Data type (" .. t .. ") is not allowed")
+		end
+	--else
+		--SV:HandleError("LibDataBroker", dataName, "CAUTION: This is a badly written addon")
+	end
+end
+
+function MOD:Load()
+	local baseWidth, dockHeight = SV.Dock.BottomCenter:GetSize()
+	local dockWidth = baseWidth * 0.5;
+
+	hexHighlight = SV:HexColor("highlight") or "FFFFFF"
+	local hexClass = classColor.colorStr
+	BGStatString = "|cff" .. hexHighlight .. "%s: |c" .. hexClass .. "%s|r";
+
+	local accountant = SVLib:NewGlobal("Accountant")
+	accountant[playerRealm] = accountant[playerRealm] or {};
+	self.Accountant = accountant[playerRealm];
+
+	local subsettings = SVLib:NewGlobal("ReportSubSettings")
+	subsettings[playerRealm] = subsettings[playerRealm] or {};
+	self.SubSettings = subsettings[playerRealm];
+
+	--BOTTOM CENTER BARS
+	local bottomLeft = CreateFrame("Frame", "SVUI_ReportsGroup1", SV.Dock.BottomCenter)
+	bottomLeft:SetSize(dockWidth, dockHeight)
+	bottomLeft:SetPoint("BOTTOMLEFT", SV.Dock.BottomCenter, "BOTTOMLEFT", 0, 0)
+	SV:NewAnchor(bottomLeft, L["Data Reports 1"])
+	self:NewHolder(bottomLeft, 3, "ANCHOR_CURSOR")
+
+	local bottomRight = CreateFrame("Frame", "SVUI_ReportsGroup2", SV.Dock.BottomCenter)
+	bottomRight:SetSize(dockWidth, dockHeight)
+	bottomRight:SetPoint("BOTTOMRIGHT", SV.Dock.BottomCenter, "BOTTOMRIGHT", 0, 0)
+	SV:NewAnchor(bottomRight, L["Data Reports 2"])
+	self:NewHolder(bottomRight, 3, "ANCHOR_CURSOR")
+
+	--TOP CENTER BARS
+	local topLeft = CreateFrame("Frame", "SVUI_ReportsGroup3", SV.Dock.TopCenter)
+	topLeft:SetSize(dockWidth, dockHeight)
+	topLeft:SetPoint("TOPLEFT", SV.Dock.TopCenter, "TOPLEFT", 0, 0)
+
+	SV:NewAnchor(topLeft, L["Data Reports 3"])
+	self:NewHolder(topLeft, 3, "ANCHOR_CURSOR", 1)
+
+	local topRight = CreateFrame("Frame", "SVUI_ReportsGroup4", SV.Dock.TopCenter)
+	topRight:SetSize(dockWidth, dockHeight)
+	topRight:SetPoint("TOPRIGHT", SV.Dock.TopCenter, "TOPRIGHT", 0, 0)
+
+	SV:NewAnchor(topRight, L["Data Reports 4"])
+	self:NewHolder(topRight, 3, "ANCHOR_CURSOR", 2)
+
+	self.ReportGroup1 = bottomLeft;
+	self.ReportGroup2 = bottomRight;
+	self.ReportGroup3 = topLeft;
+	self.ReportGroup4 = topRight;
+
+	-- self.ToolTip:SetParent(SV.Screen)
+	self.ToolTip:SetFrameStrata("DIALOG")
+	self.ToolTip:HookScript("OnShow", _hook_TooltipOnShow)
+
+	if(LDB) then
+		for dataName, dataObj in LDB:DataObjectIterator() do
+	  		MOD:ReportAdded(nil, dataName, dataObj, true)
+	  	end
+	  	LDB.RegisterCallback(MOD, "LibDataBroker_DataObjectCreated", "ReportAdded")
+	end
+	MOD:UpdateAllReports()
+
+	self:RegisterEvent("PLAYER_ENTERING_WORLD", "UpdateAllReports");
+
+	local slashDesc = "Toggle PvP stats on docks";
+	SV:AddSlashCommand("bg", slashDesc, SlashPvPStats);
+	SV:AddSlashCommand("pvp", slashDesc, SlashPvPStats);
+	SV.Events:On("DOCKS_UPDATED", MOD.UpdateAllReports, true);
+end
diff --git a/SVUI_!Core/system/slash.lua b/SVUI_!Core/system/slash.lua
new file mode 100644
index 0000000..5b83a58
--- /dev/null
+++ b/SVUI_!Core/system/slash.lua
@@ -0,0 +1,225 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local select  		= _G.select;
+local unpack  		= _G.unpack;
+local pairs   		= _G.pairs;
+local ipairs  		= _G.ipairs;
+local type    		= _G.type;
+local tostring    = _G.tostring;
+local tonumber    = _G.tonumber;
+local print       = _G.print;
+local string  		= _G.string;
+local math    		= _G.math;
+local table   		= _G.table;
+local GetTime 		= _G.GetTime;
+--[[ STRING METHODS ]]--
+local format = string.format;
+local lower, trim, split = string.lower, string.trim, string.split
+--[[ MATH METHODS ]]--
+local floor, modf = math.floor, math.modf;
+--[[ TABLE METHODS ]]--
+local twipe, tsort = table.wipe, table.sort;
+--BLIZZARD API
+local ReloadUI              = _G.ReloadUI;
+local EnableAddOn           = _G.EnableAddOn;
+local DisableAddOn          = _G.DisableAddOn;
+local GetAddOnInfo          = _G.GetAddOnInfo;
+local GetAddOnMetadata      = _G.GetAddOnMetadata;
+
+local SV = select(2, ...)
+local L = SV.L;
+local SVUILib = Librarian("Registry");
+--[[
+##########################################################
+LOCAL SLASH FUNCTIONS
+##########################################################
+]]--
+local msgPattern = "|cff00FF00/sv %s|r |cffFFFFFF%s|r";
+local SVUI_SLASH_COMMAND_INFO = {
+	["install"] = "Open the SVUI installer window.",
+	["move"] = "Lock/Unlock frames for moving.",
+	["reset"] = "Reset All SVUI Settings.",
+	["profile"] = "Open the profile interface.",
+	["help"] = "I feel like you MIGHT have already discovered this one.",
+};
+local SVUI_SLASH_COMMANDS = {
+	["install"] = SV.Setup.Install,
+	["move"] = SV.MoveAnchors,
+	["reset"] = SV.ResetAllUI,
+	["profile"] = SV.ProfileInterface.Toggle,
+	["killshared"] = SVUILib.WipeAllSharedData,
+	["help"] = function()
+		for cmd,desc in pairs(SVUI_SLASH_COMMAND_INFO) do
+			local outbound = (msgPattern):format(cmd, desc);
+	        print(outbound)
+		end
+	end,
+};
+
+function SV:AddSlashCommand(cmd, desc, fn)
+	if((not cmd) or (not desc) or (not fn or (fn and type(fn) ~= "function"))) then return end
+    SVUI_SLASH_COMMANDS[cmd] = fn;
+    SVUI_SLASH_COMMAND_INFO[cmd] = desc;
+end
+
+local function SVUIMasterCommand(args)
+	if args then
+		-- print(args)
+		local arg1, arg2 = split(" ", args)
+		-- print(arg1)
+		-- print(arg2)
+		local msg = lower(trim(arg1))
+		if(SVUI_SLASH_COMMANDS[msg] and (type(SVUI_SLASH_COMMANDS[msg]) == 'function')) then
+			SVUI_SLASH_COMMANDS[msg](SV, arg2)
+		else
+			SV:ToggleConfig()
+		end
+	else
+		SV:ToggleConfig()
+	end
+end
+
+local function EnableAddon(addon)
+	local _, _, _, _, _, reason, _ = GetAddOnInfo(addon)
+	if reason ~= "MISSING" then
+		EnableAddOn(addon)
+		ReloadUI()
+	else
+		print("|cffff0000Error, Addon '"..addon.."' not found.|r")
+	end
+end
+
+local function DisableAddon(addon)
+	local _, _, _, _, _, reason, _ = GetAddOnInfo(addon)
+	if reason ~= "MISSING" then
+		DisableAddOn(addon)
+		ReloadUI()
+	else
+		print("|cffff0000Error, Addon '"..addon.."' not found.|r")
+	end
+end
+--[[
+##########################################################
+LOAD ALL SLASH FUNCTIONS
+##########################################################
+]]--
+_G.SlashCmdList["SVUISV"] = SVUIMasterCommand;
+_G.SLASH_SVUISV1 = "/sv"
+
+_G.SlashCmdList["SVUIENABLE"] = EnableAddon;
+_G.SLASH_SVUIENABLE1="/enable"
+
+_G.SlashCmdList["SVUIDISABLE"] = DisableAddon;
+_G.SLASH_SVUIDISABLE1="/disable"
+--[[
+##########################################################
+LEEEEEROY
+##########################################################
+]]--
+local UnitName   			= _G.UnitName;
+local IsInGroup             = _G.IsInGroup;
+local CreateFrame           = _G.CreateFrame;
+local IsInRaid         		= _G.IsInRaid;
+local UnitIsGroupLeader     = _G.UnitIsGroupLeader;
+local SendChatMessage   	= _G.SendChatMessage;
+local IsEveryoneAssistant   = _G.IsEveryoneAssistant;
+local UnitIsGroupAssistant  = _G.UnitIsGroupAssistant;
+local LE_PARTY_CATEGORY_HOME = _G.LE_PARTY_CATEGORY_HOME;
+local LE_PARTY_CATEGORY_INSTANCE = _G.LE_PARTY_CATEGORY_INSTANCE;
+local COUNT_TEX = [[Interface\AddOns\SVUI_!Core\assets\textures\Numbers\TYPE2\NUM]]
+do
+	local interval = 1.5;
+
+	local COUNT_COLOR = {
+		{0.1, 1, 0.1, 1},
+		{1, 0.5, 0.1, 1},
+		{1, 0.1, 0, 1}
+	};
+
+	local SVUI_CountToThree = CreateFrame("Frame", "SVUI_CountToThree", UIParent)
+	SVUI_CountToThree:SetPoint("CENTER", UIParent, "CENTER", 0, -50)
+	SVUI_CountToThree:SetSize(50, 50)
+	SVUI_CountToThree.text = SVUI_CountToThree:CreateTexture(nil, "OVERLAY")
+	SVUI_CountToThree.text:SetAllPoints(SVUI_CountToThree)
+	SVUI_CountToThree.text:SetVertexColor(0,1,0.12,0.5)
+	SVUI_CountToThree:SetScale(1)
+	SV.Animate:Kapow(SVUI_CountToThree)
+
+	SVUI_CountToThree.delay = 0;
+	SVUI_CountToThree.lastupdate = 0;
+
+	local function _getchannel(warning)
+		if IsInGroup(LE_PARTY_CATEGORY_INSTANCE) then
+			return "INSTANCE_CHAT"
+		elseif IsInRaid(LE_PARTY_CATEGORY_HOME) then
+			if warning and (UnitIsGroupLeader("player") or UnitIsGroupAssistant("player") or IsEveryoneAssistant()) then
+				return "RAID_WARNING"
+			else
+				return "RAID"
+			end
+		elseif IsInGroup(LE_PARTY_CATEGORY_HOME) then
+			return "PARTY"
+		end
+		return "SAY"
+	end
+
+	local CountToThree_OnUpdate = function(self, elapsed)
+		self.lastupdate = self.lastupdate + elapsed
+
+		if(self.lastupdate >= interval) then
+			self.lastupdate = 0
+			if(self.delay > 0) then
+				SendChatMessage(tostring(self.delay).."..", _getchannel(true))
+				if(COUNT_COLOR[self.delay]) then
+					self.text:SetTexture(COUNT_TEX .. self.delay)
+					self.text:SetVertexColor(unpack(COUNT_COLOR[self.delay]))
+					if not self.anim:IsPlaying() then
+				        self.anim:Play()
+				    end
+				end
+				self.delay = self.delay - 1
+			else
+				SendChatMessage(L["Pulling Now!"], _getchannel(true))
+				self:Stop()
+			end
+		end
+	end
+
+	function SVUI_CountToThree:Stop()
+		self:SetScript("OnUpdate", nil);
+		self.delay = 0;
+		self.lastupdate = 0;
+	end
+
+	function SVUI_CountToThree:Start(timer)
+		self.delay = timer or 3;
+		self.text:SetTexture("");
+		if self:GetScript("OnUpdate") then
+			self:Stop()
+			SendChatMessage(L["Pull ABORTED!"], _getchannel(true))
+		else
+			local target = UnitName("target") or "";
+			SendChatMessage((L["Pulling %s in %s.."]):format(target, tostring(self.delay)), _getchannel(true))
+			if(self.delay == 3) then
+				self.text:SetTexture(COUNT_TEX .. 3)
+				self.text:SetVertexColor(unpack(COUNT_COLOR[3]))
+				if not self.anim:IsPlaying() then
+			        self.anim:Play()
+			    end
+			end
+			self.delay = self.delay - 1
+			self:SetScript("OnUpdate", CountToThree_OnUpdate)
+		end
+	end
+
+	_G.SLASH_PULLCOUNTDOWN1 = "/jenkins"
+	_G.SlashCmdList["PULLCOUNTDOWN"] = function(msg)
+		local timer = tonumber(msg) or 3
+		SVUI_CountToThree:Start(timer)
+	end
+end
diff --git a/SVUI_!Core/system/utilities.lua b/SVUI_!Core/system/utilities.lua
new file mode 100644
index 0000000..98d29e9
--- /dev/null
+++ b/SVUI_!Core/system/utilities.lua
@@ -0,0 +1,390 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pcall         = _G.pcall;
+local print         = _G.print;
+local ipairs        = _G.ipairs;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local rawset        = _G.rawset;
+local rawget        = _G.rawget;
+local tostring      = _G.tostring;
+local tonumber      = _G.tonumber;
+local table         = _G.table;
+local string        = _G.string;
+local math          = _G.math;
+local tremove       = _G.tremove;
+local twipe         = _G.wipe;
+--[[ STRING METHODS ]]--
+local lower, upper = string.lower, string.upper;
+local find, format, len, split = string.find, string.format, string.len, string.split;
+local match, sub, join = string.match, string.sub, string.join;
+local gmatch, gsub = string.gmatch, string.gsub;
+--[[ MATH METHODS ]]--
+local abs, ceil, floor, round, mod, modf = math.abs, math.ceil, math.floor, math.round, math.fmod, math.modf;  -- Basic
+--[[ TABLE METHODS ]]--
+local twipe, tsort = table.wipe, table.sort;
+--BLIZZARD API
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+local GameTooltip           = _G.GameTooltip;
+local ReloadUI              = _G.ReloadUI;
+local hooksecurefunc        = _G.hooksecurefunc;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...)
+local L = SV.L
+--[[
+##########################################################
+FRAME VISIBILITY MANAGEMENT
+##########################################################
+]]--
+do
+    local FRAMELIST = {};
+
+    function SV:ManageVisibility(frame)
+        if(not frame) then return end
+        local parent = UIParent;
+        if(frame.GetParent) then
+            parent = frame:GetParent();
+        end
+        local frameCount = #FRAMELIST + 1;
+        FRAMELIST[frameCount] = {frame = frame, parent = parent};
+    end
+
+    function SV:AuditVisibility(hidden)
+        if(hidden) then
+          self.NeedsFrameAudit = true
+          if(InCombatLockdown()) then return end
+          for i=1, #FRAMELIST do
+            local data = FRAMELIST[i]
+            data.frame:SetParent(self.Hidden)
+          end
+        else
+          if(InCombatLockdown()) then return end
+          for i=1, #FRAMELIST do
+            local data = FRAMELIST[i]
+            data.frame:SetParent(data.parent or UIParent)
+          end
+          self.NeedsFrameAudit = false
+        end
+    end
+end
+--[[
+##########################################################
+MISC UTILITY FUNCTIONS
+##########################################################
+]]--
+local PlayerClass = select(2,UnitClass("player"));
+local PlayerName = UnitName("player");
+
+function SV:DisbandRaidGroup()
+    if InCombatLockdown() then return end
+    if UnitInRaid("player") then
+        for i = 1, GetNumGroupMembers() do
+            local name, _, _, _, _, _, _, online = GetRaidRosterInfo(i)
+            if(online and (name ~= PlayerName)) then
+                UninviteUnit(name)
+            end
+        end
+    else
+        for i = MAX_PARTY_MEMBERS, 1, -1 do
+            if UnitExists("party"..i) then
+                UninviteUnit(UnitName("party"..i))
+            end
+        end
+    end
+    LeaveParty()
+end
+
+function SV:PlayerInfoUpdate()
+    local spec = GetSpecialization();
+    if not spec then return end
+    self.CurrentSpec = spec
+
+    local roleToken = GetSpecializationRole(spec);
+    local actualRole = roleToken;
+    if(roleToken == "DAMAGER") then
+        local intellect = select(2, UnitStat("player", 4))
+        local agility = select(2, UnitStat("player", 2))
+        local baseAP, posAP, negAP = UnitAttackPower("player")
+        local totalAP = baseAP  +  posAP  +  negAP;
+        if totalAP > intellect or agility > intellect then
+          actualRole = "MELEE"
+        else
+          actualRole = "CASTER"
+        end
+    elseif(roleToken == "HEALER") then
+      actualRole = "CASTER"
+    end
+
+    if((self.SpecificClassRole ~= actualRole) or (self.ClassRole ~= roleToken)) then
+        self.SpecificClassRole = actualRole;
+        self.ClassRole = roleToken;
+        SV.Events:Trigger("PLAYER_ROLE_CHANGED")
+    end
+
+    self:GearSwap()
+end
+--[[
+##########################################################
+POSITIONING UTILITY FUNCTIONS
+##########################################################
+]]--
+SV.PointIndexes = {
+    ["TOP"] = "TOP",
+    ["BOTTOM"] = "BOTTOM",
+    ["LEFT"] = "LEFT",
+    ["RIGHT"] = "RIGHT",
+    ["TOPRIGHT"] = "UP AND RIGHT",
+    ["TOPLEFT"] = "UP AND LEFT",
+    ["BOTTOMRIGHT"] = "DOWN AND RIGHT",
+    ["BOTTOMLEFT"] = "DOWN AND LEFT",
+    ["CENTER"] = "CENTER",
+    ["RIGHTTOP"] = "RIGHT AND UP",
+    ["LEFTTOP"] = "LEFT AND UP",
+    ["RIGHTBOTTOM"] = "RIGHT AND DOWN",
+    ["LEFTBOTTOM"] = "LEFT AND DOWN",
+    ["INNERRIGHT"] = "INNER RIGHT",
+    ["INNERLEFT"] = "INNER LEFT",
+    ["INNERTOPRIGHT"] = "INNER TOP RIGHT",
+    ["INNERTOPLEFT"] = "INNER TOP LEFT",
+    ["INNERBOTTOMRIGHT"] = "INNER BOTTOM RIGHT",
+    ["INNERBOTTOMLEFT"] = "INNER BOTTOM LEFT",
+}
+
+do
+    local _reversed = {
+        TOP = "BOTTOM",
+        BOTTOM = "TOP",
+        LEFT = "RIGHT",
+        RIGHT = "LEFT",
+        TOPRIGHT = "TOPLEFT",
+        TOPLEFT = "TOPRIGHT",
+        BOTTOMRIGHT = "BOTTOMLEFT",
+        BOTTOMLEFT = "BOTTOMRIGHT",
+    }
+
+    local _inverted = {
+        TOP = "BOTTOM",
+        BOTTOM = "TOP",
+        LEFT = "RIGHT",
+        RIGHT = "LEFT",
+        TOPRIGHT = "BOTTOMRIGHT",
+        TOPLEFT = "BOTTOMLEFT",
+        BOTTOMRIGHT = "TOPRIGHT",
+        BOTTOMLEFT = "TOPLEFT",
+        CENTER = "CENTER",
+        RIGHTTOP = "TOPLEFT",
+        LEFTTOP = "TOPRIGHT",
+        RIGHTBOTTOM = "BOTTOMLEFT",
+        LEFTBOTTOM = "BOTTOMRIGHT",
+        INNERRIGHT = "RIGHT",
+        INNERLEFT = "LEFT",
+        INNERTOPRIGHT = "TOPRIGHT",
+        INNERTOPLEFT = "TOPLEFT",
+        INNERBOTTOMRIGHT = "BOTTOMRIGHT",
+        INNERBOTTOMLEFT = "BOTTOMLEFT",
+    }
+    setmetatable(_inverted, { __index = function(t, k)
+        return "CENTER"
+    end})
+
+    local _translated = {
+        TOP = "TOP",
+        BOTTOM = "BOTTOM",
+        LEFT = "LEFT",
+        RIGHT = "RIGHT",
+        TOPRIGHT = "TOPRIGHT",
+        TOPLEFT = "TOPLEFT",
+        BOTTOMRIGHT = "BOTTOMRIGHT",
+        BOTTOMLEFT = "BOTTOMLEFT",
+        CENTER = "CENTER",
+        RIGHTTOP = "TOPRIGHT",
+        LEFTTOP = "TOPLEFT",
+        RIGHTBOTTOM = "BOTTOMRIGHT",
+        LEFTBOTTOM = "BOTTOMLEFT",
+        INNERRIGHT = "RIGHT",
+        INNERLEFT = "LEFT",
+        INNERTOPRIGHT = "TOPRIGHT",
+        INNERTOPLEFT = "TOPLEFT",
+        INNERBOTTOMRIGHT = "BOTTOMRIGHT",
+        INNERBOTTOMLEFT = "BOTTOMLEFT",
+    }
+    setmetatable(_translated, { __index = function(t, k)
+        return "CENTER"
+    end})
+
+    function SV:GetReversePoint(point)
+        return _inverted[point];
+    end
+
+    function SV:SetReversePoint(frame, point, target, x, y)
+        if((not frame) or (not point)) then return; end
+        target = target or frame:GetParent()
+        if(not target) then print(frame:GetName()) return; end
+        local anchor = _inverted[point];
+        local relative = _translated[point];
+        x = x or 0;
+        y = y or 0;
+        frame:SetPoint(anchor, target, relative, x, y)
+        --[[ auto-set specific properties to save on logic ]]--
+        frame.initialAnchor = anchor;
+    end
+end
+
+function SV:GetScreenXY(frame)
+    local screenHeight = GetScreenHeight();
+    local screenWidth = GetScreenWidth();
+    local screenX, screenY = frame:GetCenter();
+    local isLeft = (screenX < (screenHeight * 0.5));
+    if (screenY < (screenWidth * 0.5)) then
+        if(isLeft) then
+            return "BOTTOMLEFT", "TOPLEFT"
+        else
+            return "BOTTOMRIGHT", "TOPRIGHT"
+        end
+    else
+        if(isLeft) then
+            return "TOPLEFT", "BOTTOMLEFT"
+        else
+            return "TOPRIGHT", "BOTTOMRIGHT"
+        end
+    end
+end
+
+function SV:AnchorToCursor(frame)
+    local x, y = GetCursorPosition()
+    local vHold = (UIParent:GetHeight() * 0.33)
+    local scale = self.Screen:GetEffectiveScale()
+    local initialAnchor = "CENTER"
+    local mod = 0
+
+    if(y > (vHold * 2)) then
+        initialAnchor = "TOPLEFT"
+        mod = -12
+    elseif(y < vHold) then
+        initialAnchor = "BOTTOMLEFT"
+        mod = 12
+    end
+
+    frame:ClearAllPoints()
+    frame:SetPoint(initialAnchor, self.Screen, "BOTTOMLEFT", (x  /  scale), (y  /  scale) + mod)
+end
+--[[
+##########################################################
+TIME UTILITIES
+##########################################################
+]]--
+local SECONDS_PER_HOUR = 60 * 60
+local SECONDS_PER_DAY = 24 * SECONDS_PER_HOUR
+
+function SV:ParseSeconds(seconds)
+    local negative = ""
+
+    if not seconds then
+        seconds = 0
+    end
+
+    if seconds < 0 then
+        negative = "-"
+        seconds = -seconds
+    end
+    local L_DAY_ONELETTER_ABBR = _G.DAY_ONELETTER_ABBR:gsub("%s*%%d%s*", "")
+
+    if not seconds or seconds >= SECONDS_PER_DAY * 36500 then -- 100 years
+        return ("%s**%s **:**"):format(negative, L_DAY_ONELETTER_ABBR)
+    elseif seconds >= SECONDS_PER_DAY then
+        return ("%s%d%s %d:%02d"):format(negative, seconds / SECONDS_PER_DAY, L_DAY_ONELETTER_ABBR, math.fmod(seconds / SECONDS_PER_HOUR, 24), math.fmod(seconds / 60, 60))
+    else
+        return ("%s%d:%02d:%02d"):format(negative, seconds / SECONDS_PER_HOUR, math.fmod(seconds / 60, 60), math.fmod(seconds, 60))
+    end
+end
+--[[
+##########################################################
+CONTROL UTILITIES
+##########################################################
+]]--
+local Frame_ForceHide = function(self, locked)
+  if(locked) then
+    self.Show = self.___HideFunc
+    self.___visibilityLocked = true
+  elseif(self.___visibilityLocked) then
+    self.Show = self.___ShowFunc
+    self.___visibilityLocked = nil
+  end
+end
+
+local Frame_ForceShow = function(self, locked)
+  if(locked) then
+    self.Hide = self.___ShowFunc
+    self.___visibilityLocked = true
+  elseif(self.___visibilityLocked) then
+    self.Hide = self.___HideFunc
+    self.___visibilityLocked = nil
+  end
+end
+
+function SV:SetFrameVisibilityLocks(frame)
+    if(frame.___ShowFunc or frame.___HideFunc or frame.ForceHide or frame.ForceShow) then return end
+    local fnShow = frame.Show
+    local fnHide = frame.Hide
+    frame.___ShowFunc = fnShow
+    frame.___HideFunc = fnHide
+    frame.ForceHide = Frame_ForceHide
+    frame.ForceShow = Frame_ForceShow
+end
+--[[
+##########################################################
+MISC HELPERS
+##########################################################
+]]--
+do
+  local COPPER_PATTERN = "%d" .. L.copperabbrev;
+  local SILVER_PATTERN = "%d" .. L.silverabbrev .. " %.2d" .. L.copperabbrev;
+  local GOLD_PATTERN = "%s" .. L.goldabbrev .. " %.2d" .. L.silverabbrev .. " %.2d" .. L.copperabbrev;
+  local SILVER_ABBREV_PATTERN = "%d" .. L.silverabbrev;
+  local GOLD_ABBREV_PATTERN = "%s" .. L.goldabbrev;
+
+  local function _formatCurrency(amount, short)
+  	if not amount then return end
+  	local gold, silver, copper = floor(abs(amount/10000)), abs(mod(amount/100,100)), abs(mod(amount,100))
+  	if(short) then
+  		if gold ~= 0 then
+  			gold = BreakUpLargeNumbers(gold)
+  			return GOLD_ABBREV_PATTERN:format(gold)
+  		elseif silver ~= 0 then
+  			return SILVER_ABBREV_PATTERN:format(silver)
+  		else
+  			return COPPER_PATTERN:format(copper)
+  		end
+  	else
+  		if gold ~= 0 then
+  			gold = BreakUpLargeNumbers(gold)
+  			return GOLD_PATTERN:format(gold, silver, copper)
+  		elseif silver ~= 0 then
+  			return SILVER_PATTERN:format(silver, copper)
+  		else
+  			return COPPER_PATTERN:format(copper)
+  		end
+  	end
+  end
+
+  function SV:FormatCurrency(...)
+    return _formatCurrency(...)
+  end
+end
diff --git a/SVUI_!Core/xml/docks.xml b/SVUI_!Core/xml/docks.xml
new file mode 100644
index 0000000..a91563d
--- /dev/null
+++ b/SVUI_!Core/xml/docks.xml
@@ -0,0 +1,307 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+    <Frame name="SVUI_DockBarBottomLeft" frameStrata="BACKGROUND">
+        <Size y="22"/>
+        <Attributes>
+            <Attribute name="spacingSize" type="number" value="4" />
+            <Attribute name="buttonSize" type="number" value="22" />
+        </Attributes>
+        <Anchors>
+            <Anchor point="BOTTOMLEFT" x="1" y="1" />
+        </Anchors>
+        <Frames>
+            <Button name="$parentButton" parentKey="Button">
+                <Size x="22" y="22"/>
+                <Anchors>
+                    <Anchor point="BOTTOMLEFT" relativeTo="$parent" />
+                </Anchors>
+                <Attributes>
+                    <Attribute name="tipText" type="string" value="Toggle Left Dock" />
+                    <Attribute name="tipExtraText" type="string" value="Expand Left Dock" />
+                </Attributes>
+                <Layers>
+                    <Layer level="OVERLAY">
+                        <Texture parentKey="Icon" file="Interface\AddOns\SVUI_!Core\assets\textures\EMPTY">
+                            <Anchors>
+                                <Anchor point="TOPLEFT" relativePoint="TOPLEFT" x="2" y="-2" />
+                                <Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMRIGHT" x="-2" y="2" />
+                            </Anchors>
+                        </Texture>
+                    </Layer>
+                </Layers>
+                <Scripts>
+                    <OnLoad>
+                        self:RegisterForClicks("LeftButtonUp", "RightButtonUp");
+                    </OnLoad>
+                </Scripts>
+            </Button>
+            <Button name="$parentButton2" parentKey="Button2">
+                <Size x="22" y="22"/>
+                <Anchors>
+                    <Anchor point="BOTTOMLEFT" relativeTo="$parentButton" relativePoint="BOTTOMRIGHT" x="4" y="0" />
+                </Anchors>
+                <Attributes>
+                    <Attribute name="tipText" type="string" value="Toggle Left Dock" />
+                    <Attribute name="tipExtraText" type="string" value="Expand Left Dock" />
+                </Attributes>
+                <Layers>
+                    <Layer level="OVERLAY">
+                        <Texture parentKey="Icon" file="Interface\AddOns\SVUI_!Core\assets\textures\EMPTY">
+                            <Anchors>
+                                <Anchor point="TOPLEFT" relativePoint="TOPLEFT" x="2" y="-2" />
+                                <Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMRIGHT" x="-2" y="2" />
+                            </Anchors>
+                        </Texture>
+                    </Layer>
+                </Layers>
+                <Scripts>
+                    <OnLoad>
+                        self:RegisterForClicks("LeftButtonUp", "RightButtonUp");
+                    </OnLoad>
+                </Scripts>
+            </Button>
+            <Frame name="$parentToolBar" parentKey="ToolBar">
+                <Size x="1" y="22"/>
+                <Anchors>
+                    <Anchor point="BOTTOMLEFT" relativeTo="$parentButton2" relativePoint="BOTTOMRIGHT" x="4" y="0" />
+                </Anchors>
+            </Frame>
+        </Frames>
+    </Frame>
+
+    <Frame name="SVUI_DockBottomLeft" frameStrata="BACKGROUND">
+        <Attributes>
+            <Attribute name="spacingSize" type="number" value="4" />
+            <Attribute name="buttonSize" type="number" value="22" />
+        </Attributes>
+        <Anchors>
+            <Anchor point="BOTTOMLEFT" relativePoint="BOTTOMLEFT" x="1" y="32" />
+        </Anchors>
+        <Frames>
+            <Frame name="$parentAlert" parentKey="Alert" frameStrata="BACKGROUND">
+                <Size y="1"/>
+                <Anchors>
+                    <Anchor point="BOTTOMLEFT" x="0" y="4" />
+                    <Anchor point="BOTTOMRIGHT" x="0" y="4" />
+                </Anchors>
+            </Frame>
+            <Frame name="$parentWindow" parentKey="Window" frameStrata="BACKGROUND">
+                <Anchors>
+                    <Anchor point="BOTTOMRIGHT" relativeTo="$parentAlert" relativePoint="TOPRIGHT" x="-4" y="4" />
+                    <Anchor point="BOTTOMLEFT" relativeTo="$parentAlert" relativePoint="TOPLEFT" x="4" y="4" />
+                    <Anchor point="TOPLEFT" relativeTo="$parent" relativePoint="TOPLEFT" x="4" y="0" />
+                    <Anchor point="TOPRIGHT" relativeTo="$parent" relativePoint="TOPRIGHT" x="-4" y="0" />
+                </Anchors>
+            </Frame>
+        </Frames>
+    </Frame>
+
+    <Frame name="SVUI_DockBarBottomRight" frameStrata="BACKGROUND">
+        <Size y="22"/>
+        <Attributes>
+            <Attribute name="spacingSize" type="number" value="4" />
+            <Attribute name="buttonSize" type="number" value="22" />
+        </Attributes>
+        <Anchors>
+            <Anchor point="BOTTOMRIGHT" x="-1" y="1" />
+        </Anchors>
+        <Frames>
+            <Button name="$parentButton" parentKey="Button">
+                <Size x="22" y="22"/>
+                <Anchors>
+                    <Anchor point="BOTTOMRIGHT" relativeTo="$parent" />
+                </Anchors>
+                <Attributes>
+                    <Attribute name="tipText" type="string" value="Toggle Right Dock" />
+                    <Attribute name="tipExtraText" type="string" value="Expand Right Dock" />
+                </Attributes>
+                <Layers>
+                    <Layer level="OVERLAY">
+                        <Texture parentKey="Icon" file="Interface\AddOns\SVUI_!Core\assets\textures\EMPTY">
+                            <Anchors>
+                                <Anchor point="TOPLEFT" relativePoint="TOPLEFT" x="2" y="-2" />
+                                <Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMRIGHT" x="-2" y="2" />
+                            </Anchors>
+                        </Texture>
+                    </Layer>
+                </Layers>
+                <Scripts>
+                    <OnLoad>
+                        self:RegisterForClicks("LeftButtonUp", "RightButtonUp");
+                    </OnLoad>
+                </Scripts>
+            </Button>
+            <Button name="$parentButton2" parentKey="Button2">
+                <Size x="22" y="22"/>
+                <Anchors>
+                    <Anchor point="BOTTOMRIGHT" relativeTo="$parentButton" relativePoint="BOTTOMLEFT" x="-4" y="0" />
+                </Anchors>
+                <Attributes>
+                    <Attribute name="tipText" type="string" value="Toggle Right Dock" />
+                    <Attribute name="tipExtraText" type="string" value="Expand Right Dock" />
+                </Attributes>
+                <Layers>
+                    <Layer level="OVERLAY">
+                        <Texture parentKey="Icon" file="Interface\AddOns\SVUI_!Core\assets\textures\EMPTY">
+                            <Anchors>
+                                <Anchor point="TOPLEFT" relativePoint="TOPLEFT" x="2" y="-2" />
+                                <Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMRIGHT" x="-2" y="2" />
+                            </Anchors>
+                        </Texture>
+                    </Layer>
+                </Layers>
+                <Scripts>
+                    <OnLoad>
+                        self:RegisterForClicks("LeftButtonUp", "RightButtonUp");
+                    </OnLoad>
+                </Scripts>
+            </Button>
+            <Frame name="$parentToolBar" parentKey="ToolBar">
+                <Size x="1" y="22"/>
+                <Anchors>
+                    <Anchor point="BOTTOMRIGHT" relativeTo="$parentButton2" relativePoint="BOTTOMLEFT" x="-4" y="0" />
+                </Anchors>
+            </Frame>
+        </Frames>
+    </Frame>
+
+    <Frame name="SVUI_DockBottomRight" frameStrata="BACKGROUND">
+        <Attributes>
+            <Attribute name="spacingSize" type="number" value="4" />
+            <Attribute name="buttonSize" type="number" value="22" />
+        </Attributes>
+        <Anchors>
+            <Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMRIGHT" x="-1" y="32" />
+        </Anchors>
+        <Frames>
+            <Frame name="$parentAlert" parentKey="Alert" frameStrata="BACKGROUND">
+                <Size y="1"/>
+                <Anchors>
+                    <Anchor point="BOTTOMRIGHT" x="0" y="4" />
+                    <Anchor point="BOTTOMLEFT" x="0" y="4" />
+                </Anchors>
+            </Frame>
+            <Frame name="$parentWindow" parentKey="Window" frameStrata="BACKGROUND">
+                <Anchors>
+                    <Anchor point="BOTTOMRIGHT" relativeTo="$parentAlert" relativePoint="TOPRIGHT" x="-4" y="4" />
+                    <Anchor point="BOTTOMLEFT" relativeTo="$parentAlert" relativePoint="TOPLEFT" x="4" y="4" />
+                    <Anchor point="TOPLEFT" relativeTo="$parent" relativePoint="TOPLEFT" x="4" y="0" />
+                    <Anchor point="TOPRIGHT" relativeTo="$parent" relativePoint="TOPRIGHT" x="-4" y="0" />
+                </Anchors>
+            </Frame>
+        </Frames>
+    </Frame>
+
+    <Frame name="SVUI_DockBarTopLeft" frameStrata="BACKGROUND">
+        <Size y="22"/>
+        <Attributes>
+            <Attribute name="spacingSize" type="number" value="4" />
+            <Attribute name="buttonSize" type="number" value="22" />
+        </Attributes>
+        <Anchors>
+            <Anchor point="TOPLEFT" />
+        </Anchors>
+        <Frames>
+            <Frame name="$parentToolBar" parentKey="ToolBar">
+                <Size x="1" y="22"/>
+                <Anchors>
+                    <Anchor point="TOPLEFT" relativeTo="$parent" />
+                </Anchors>
+            </Frame>
+        </Frames>
+    </Frame>
+
+    <Frame name="SVUI_DockTopLeft" frameStrata="BACKGROUND">
+        <Attributes>
+            <Attribute name="spacingSize" type="number" value="4" />
+            <Attribute name="buttonSize" type="number" value="22" />
+        </Attributes>
+        <Anchors>
+            <Anchor point="TOPLEFT" />
+        </Anchors>
+        <Frames>
+            <Frame name="$parentAlert" parentKey="Alert" frameStrata="BACKGROUND">
+                <Size y="1"/>
+                <Anchors>
+                    <Anchor point="TOPRIGHT" x="0" y="4" />
+                    <Anchor point="TOPLEFT" x="0" y="4" />
+                </Anchors>
+            </Frame>
+            <Frame name="$parentWindow" parentKey="Window" frameStrata="BACKGROUND">
+                <Anchors>
+                    <Anchor point="TOPRIGHT" relativeTo="$parentAlert" relativePoint="BOTTOMRIGHT" x="0" y="4" />
+                    <Anchor point="TOPLEFT" relativeTo="$parentAlert" relativePoint="BOTTOMLEFT" x="0" y="4" />
+                    <Anchor point="BOTTOMLEFT" relativeTo="$parent" relativePoint="BOTTOMLEFT" x="0" y="0" />
+                    <Anchor point="BOTTOMRIGHT" relativeTo="$parent" relativePoint="BOTTOMRIGHT" x="0" y="0" />
+                </Anchors>
+            </Frame>
+        </Frames>
+    </Frame>
+
+    <Frame name="SVUI_DockBarTopRight" frameStrata="BACKGROUND">
+        <Size y="22"/>
+        <Attributes>
+            <Attribute name="spacingSize" type="number" value="4" />
+            <Attribute name="buttonSize" type="number" value="22" />
+        </Attributes>
+        <Anchors>
+            <Anchor point="TOPRIGHT" />
+        </Anchors>
+        <Frames>
+            <Frame name="$parentToolBar" parentKey="ToolBar">
+                <Size x="1" y="22"/>
+                <Anchors>
+                    <Anchor point="TOPRIGHT" relativeTo="$parent" />
+                </Anchors>
+            </Frame>
+        </Frames>
+    </Frame>
+
+    <Frame name="SVUI_DockTopRight" frameStrata="BACKGROUND">
+        <Attributes>
+            <Attribute name="spacingSize" type="number" value="4" />
+            <Attribute name="buttonSize" type="number" value="22" />
+        </Attributes>
+        <Anchors>
+            <Anchor point="TOPRIGHT" />
+        </Anchors>
+        <Frames>
+            <Frame name="$parentAlert" parentKey="Alert" frameStrata="BACKGROUND">
+                <Size y="1"/>
+                <Anchors>
+                    <Anchor point="TOPRIGHT" x="0" y="4" />
+                    <Anchor point="TOPLEFT" x="0" y="4" />
+                </Anchors>
+            </Frame>
+            <Frame name="$parentWindow" parentKey="Window" frameStrata="BACKGROUND">
+                <Anchors>
+                    <Anchor point="TOPRIGHT" relativeTo="$parentAlert" relativePoint="BOTTOMRIGHT" x="0" y="4" />
+                    <Anchor point="TOPLEFT" relativeTo="$parentAlert" relativePoint="BOTTOMLEFT" x="0" y="4" />
+                    <Anchor point="BOTTOMLEFT" relativeTo="$parent" relativePoint="BOTTOMLEFT" x="0" y="0" />
+                    <Anchor point="BOTTOMRIGHT" relativeTo="$parent" relativePoint="BOTTOMRIGHT" x="0" y="0" />
+                </Anchors>
+            </Frame>
+        </Frames>
+    </Frame>
+
+    <Frame name="SVUI_DockBottomCenter" frameStrata="BACKGROUND">
+        <Size x="500" y="22"/>
+        <Attributes>
+            <Attribute name="spacingSize" type="number" value="4" />
+            <Attribute name="buttonSize" type="number" value="22" />
+        </Attributes>
+        <Anchors>
+            <Anchor point="BOTTOM" />
+        </Anchors>
+    </Frame>
+
+    <Frame name="SVUI_DockTopCenter" frameStrata="BACKGROUND">
+        <Size x="500" y="22"/>
+        <Attributes>
+            <Attribute name="spacingSize" type="number" value="4" />
+            <Attribute name="buttonSize" type="number" value="22" />
+        </Attributes>
+        <Anchors>
+            <Anchor point="TOP" />
+        </Anchors>
+    </Frame>
+</Ui>
diff --git a/SVUI_!Core/xml/fonts.xml b/SVUI_!Core/xml/fonts.xml
new file mode 100644
index 0000000..2d54196
--- /dev/null
+++ b/SVUI_!Core/xml/fonts.xml
@@ -0,0 +1,139 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+    <Font name="SVUI_Font_Default" font="Fonts\ARIALN.TTF" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="12"/>
+        </FontHeight>
+    </Font>
+    <Font name="SVUI_Font_Aura" font="Fonts\MORPHEUS.ttf" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="10"/>
+        </FontHeight>
+    </Font>
+    <Font name="SVUI_Font_Number" font="Fonts\MORPHEUS.ttf" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="11"/>
+        </FontHeight>
+    </Font>
+    <Font name="SVUI_Font_Number_Huge" font="Fonts\MORPHEUS.ttf" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="18"/>
+        </FontHeight>
+    </Font>
+    <Font name="SVUI_Font_Header" font="Fonts\MORPHEUS.ttf" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="15"/>
+        </FontHeight>
+    </Font>
+    <Font name="SVUI_Font_Data" font="Fonts\ARIALN.TTF" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="11"/>
+        </FontHeight>
+    </Font>
+    <Font name="SVUI_Font_Caps" font="Fonts\skurri.ttf" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="12"/>
+        </FontHeight>
+    </Font>
+    <Font name="SVUI_Font_Narrator" font="Fonts\ARIALN.TTF" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="12"/>
+        </FontHeight>
+    </Font>
+    <Font name="SVUI_Font_Pixel" font="Fonts\skurri.ttf" monochrome="true" virtual="true">
+        <FontHeight>
+            <AbsValue val="8"/>
+        </FontHeight>
+    </Font>
+    <Font name="SVUI_Font_Loot" font="Fonts\ARIALN.TTF" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="12"/>
+        </FontHeight>
+    </Font>
+    <Font name="SVUI_Font_Loot_Number" font="Fonts\MORPHEUS.ttf" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="11"/>
+        </FontHeight>
+    </Font>
+    <Font name="SVUI_Font_Roll" font="Fonts\ARIALN.TTF" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="12"/>
+        </FontHeight>
+    </Font>
+    <Font name="SVUI_Font_Roll_Number" font="Fonts\MORPHEUS.ttf" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="11"/>
+        </FontHeight>
+    </Font>
+</Ui>
\ No newline at end of file
diff --git a/SVUI_!Core/xml/styles.xml b/SVUI_!Core/xml/styles.xml
new file mode 100644
index 0000000..4262ff2
--- /dev/null
+++ b/SVUI_!Core/xml/styles.xml
@@ -0,0 +1,616 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+	<Frame name="SVUI_CoreStyle_Default" virtual="true">
+        <Attributes>
+            <Attribute name="panelID" type="string" value="default" />
+            <Attribute name="panelPadding" type="number" value="1" />
+            <Attribute name="panelColor" type="string" value="default" />
+            <Attribute name="panelGradient" type="string" value="default" />
+            <Attribute name="panelTexUpdate" type="boolean" value="false" />
+            <Attribute name="panelSkipUpdate" type="boolean" value="false" />
+        </Attributes>
+        <Backdrop bgFile="Interface\AddOns\SVUI_!Core\assets\backgrounds\DEFAULT" edgeFile="Interface\BUTTONS\WHITE8X8" tile="false">
+            <EdgeSize val="1" />
+            <TileSize val="0" />
+            <BackgroundInsets left="0" right="0" top="0" bottom="0" />
+            <Color r="0.2" g="0.2" b="0.2" a="1" />
+            <BorderColor r="0" g="0" b="0" a="1" />
+        </Backdrop>
+        <Layers>
+            <Layer level="BACKGROUND" textureSubLevel="1">
+                <Texture parentKey="Skin" nonBlocking="true" file="Interface\AddOns\SVUI_!Core\assets\backgrounds\DEFAULT" setAllPoints="true" />
+                <Color r="0.2" g="0.2" b="0.2" a="1" />
+            </Layer>
+        </Layers>
+    </Frame>
+
+    <Frame name="SVUI_CoreStyle_Transparent" virtual="true">
+        <Attributes>
+            <Attribute name="panelID" type="string" value="transparent" />
+            <Attribute name="panelPadding" type="number" value="2" />
+            <Attribute name="panelColor" type="string" value="transparent" />
+            <Attribute name="panelGradient" type="boolean" value="false" />
+            <Attribute name="panelTexUpdate" type="boolean" value="false" />
+            <Attribute name="panelSkipUpdate" type="boolean" value="true" />
+        </Attributes>
+        <Backdrop bgFile="Interface\BUTTONS\WHITE8X8" edgeFile="Interface\BUTTONS\WHITE8X8" tile="false">
+            <EdgeSize val="2" />
+            <TileSize val="0" />
+            <BackgroundInsets left="0" right="0" top="0" bottom="0" />
+            <Color r="0" g="0" b="0" a="0.5" />
+            <BorderColor r="0" g="0" b="0" a="1" />
+        </Backdrop>
+    </Frame>
+
+    <Frame name="SVUI_CoreStyle_Button" virtual="true">
+        <Attributes>
+            <Attribute name="panelID" type="string" value="button" />
+            <Attribute name="panelPadding" type="number" value="1" />
+            <Attribute name="panelColor" type="string" value="default" />
+            <Attribute name="panelGradient" type="boolean" value="false" />
+            <Attribute name="panelTexUpdate" type="boolean" value="false" />
+            <Attribute name="panelSkipUpdate" type="boolean" value="false" />
+        </Attributes>
+        <Backdrop bgFile="Interface\AddOns\SVUI_!Core\assets\backgrounds\BUTTON" edgeFile="Interface\BUTTONS\WHITE8X8" tile="false">
+            <EdgeSize val="1" />
+            <TileSize val="0" />
+            <BackgroundInsets left="0" right="0" top="0" bottom="0" />
+            <Color r="0.2" g="0.2" b="0.2" a="1" />
+            <BorderColor r="0" g="0" b="0" a="1" />
+        </Backdrop>
+        <Frames>
+            <Frame parentKey="Shadow" inherits="SVUI_ShadowTemplate" />
+        </Frames>
+    </Frame>
+
+    <Frame name="SVUI_CoreStyle_DockButton" virtual="true">
+        <Attributes>
+            <Attribute name="panelID" type="string" value="dockbutton" />
+            <Attribute name="panelPadding" type="number" value="1" />
+            <Attribute name="panelColor" type="string" value="default" />
+            <Attribute name="panelGradient" type="string" value="default" />
+            <Attribute name="panelTexUpdate" type="boolean" value="true" />
+            <Attribute name="panelSkipUpdate" type="boolean" value="false" />
+            <Attribute name="panelOffset" type="number" value="0" />
+        </Attributes>
+        <Backdrop bgFile="Interface\BUTTONS\WHITE8X8" edgeFile="Interface\BUTTONS\WHITE8X8" tile="false">
+            <EdgeSize val="1" />
+            <TileSize val="0" />
+            <BackgroundInsets left="0" right="0" top="0" bottom="0" />
+            <Color r="0.2" g="0.2" b="0.2" a="1" />
+            <BorderColor r="0" g="0" b="0" a="1" />
+        </Backdrop>
+        <Frames>
+            <Frame parentKey="Shadow" inherits="SVUI_ShadowTemplate" />
+        </Frames>
+    </Frame>
+
+    <Frame name="SVUI_CoreStyle_ActionSlot" virtual="true">
+        <Attributes>
+            <Attribute name="panelID" type="string" value="actionslot" />
+            <Attribute name="panelPadding" type="number" value="1" />
+            <Attribute name="panelColor" type="string" value="transparent" />
+            <Attribute name="panelGradient" type="boolean" value="false" />
+            <Attribute name="panelTexUpdate" type="boolean" value="false" />
+            <Attribute name="panelSkipUpdate" type="boolean" value="true" />
+            <Attribute name="panelOffset" type="number" value="0" />
+            <Attribute name="shadowAlpha" type="number" value="0.75" />
+        </Attributes>
+        <Backdrop bgFile="Interface\DialogFrame\UI-DialogBox-Background" edgeFile="Interface\BUTTONS\WHITE8X8" tile="false">
+            <EdgeSize val="1" />
+            <TileSize val="0" />
+            <BackgroundInsets left="1" right="1" top="1" bottom="1" />
+            <Color r="0" g="0" b="0" a="0.5" />
+            <BorderColor r="0" g="0" b="0" a="1" />
+        </Backdrop>
+        <Layers>
+            <Layer level="BORDER">
+                <Texture parentKey="BorderLeft" file="Interface\BUTTONS\WHITE8X8">
+                    <Anchors>
+                        <Anchor point="TOPLEFT" relativePoint="TOPLEFT" />
+                        <Anchor point="BOTTOMLEFT" relativePoint="BOTTOMLEFT" />
+                    </Anchors>
+                    <Size>
+                        <AbsDimension x="1" />
+                    </Size>
+                    <Color r="0" g="0" b="0" a="1" />
+                </Texture>
+                <Texture parentKey="BorderRight" file="Interface\BUTTONS\WHITE8X8">
+                    <Anchors>
+                        <Anchor point="TOPRIGHT" relativePoint="TOPRIGHT" />
+                        <Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMRIGHT" />
+                    </Anchors>
+                    <Size>
+                        <AbsDimension x="1" />
+                    </Size>
+                    <Color r="0" g="0" b="0" a="1" />
+                </Texture>
+                <Texture parentKey="BorderTop" file="Interface\BUTTONS\WHITE8X8">
+                    <Anchors>
+                        <Anchor point="TOPLEFT" relativePoint="TOPLEFT" />
+                        <Anchor point="TOPRIGHT" relativePoint="TOPRIGHT" />
+                    </Anchors>
+                    <Size>
+                        <AbsDimension y="1" />
+                    </Size>
+                    <Color r="0" g="0" b="0" a="1" />
+                </Texture>
+                <Texture parentKey="BorderBottom" file="Interface\BUTTONS\WHITE8X8">
+                    <Anchors>
+                        <Anchor point="BOTTOMLEFT" relativePoint="BOTTOMLEFT" />
+                        <Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMRIGHT" />
+                    </Anchors>
+                    <Size>
+                        <AbsDimension y="1" />
+                    </Size>
+                    <Color r="0" g="0" b="0" a="1" />
+                </Texture>
+            </Layer>
+        </Layers>
+        <Frames>
+            <Frame parentKey="Shadow" inherits="SVUI_ShadowTemplate" />
+        </Frames>
+    </Frame>
+
+    <Frame name="SVUI_CoreStyle_Icon" virtual="true">
+        <Attributes>
+            <Attribute name="panelID" type="string" value="icon" />
+            <Attribute name="panelPadding" type="number" value="2" />
+            <Attribute name="panelColor" type="string" value="invisible" />
+            <Attribute name="panelGradient" type="boolean" value="false" />
+            <Attribute name="panelTexUpdate" type="boolean" value="false" />
+            <Attribute name="panelSkipUpdate" type="boolean" value="true" />
+            <Attribute name="panelOffset" type="number" value="0" />
+            <Attribute name="shadowAlpha" type="number" value="0.5" />
+        </Attributes>
+        <Backdrop bgFile="Interface\AddOns\SVUI_!Core\assets\backgrounds\EMPTY" edgeFile="Interface\BUTTONS\WHITE8X8" tile="false">
+            <EdgeSize val="1" />
+            <TileSize val="0" />
+            <BackgroundInsets left="1" right="1" top="1" bottom="1" />
+            <Color r="0" g="0" b="0" a="0" />
+            <BorderColor r="0" g="0" b="0" a="1" />
+        </Backdrop>
+        <Layers>
+            <Layer level="BORDER">
+                <Texture parentKey="BorderLeft" file="Interface\BUTTONS\WHITE8X8">
+                    <Anchors>
+                        <Anchor point="TOPLEFT" relativePoint="TOPLEFT" />
+                        <Anchor point="BOTTOMLEFT" relativePoint="BOTTOMLEFT" />
+                    </Anchors>
+                    <Size>
+                        <AbsDimension x="2" />
+                    </Size>
+                    <Color r="0" g="0" b="0" a="1" />
+                </Texture>
+                <Texture parentKey="BorderRight" file="Interface\BUTTONS\WHITE8X8">
+                    <Anchors>
+                        <Anchor point="TOPRIGHT" relativePoint="TOPRIGHT" />
+                        <Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMRIGHT" />
+                    </Anchors>
+                    <Size>
+                        <AbsDimension x="2" />
+                    </Size>
+                    <Color r="0" g="0" b="0" a="1" />
+                </Texture>
+                <Texture parentKey="BorderTop" file="Interface\BUTTONS\WHITE8X8">
+                    <Anchors>
+                        <Anchor point="TOPLEFT" relativePoint="TOPLEFT" />
+                        <Anchor point="TOPRIGHT" relativePoint="TOPRIGHT" />
+                    </Anchors>
+                    <Size>
+                        <AbsDimension y="2" />
+                    </Size>
+                    <Color r="0" g="0" b="0" a="1" />
+                </Texture>
+                <Texture parentKey="BorderBottom" file="Interface\BUTTONS\WHITE8X8">
+                    <Anchors>
+                        <Anchor point="BOTTOMLEFT" relativePoint="BOTTOMLEFT" />
+                        <Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMRIGHT" />
+                    </Anchors>
+                    <Size>
+                        <AbsDimension y="2" />
+                    </Size>
+                    <Color r="0" g="0" b="0" a="1" />
+                </Texture>
+            </Layer>
+        </Layers>
+        <Frames>
+            <Frame parentKey="Shadow" inherits="SVUI_ShadowTemplate" />
+        </Frames>
+    </Frame>
+
+    <Frame name="SVUI_CoreStyle_CheckButton" virtual="true">
+        <Attributes>
+            <Attribute name="panelID" type="string" value="checkbox" />
+            <Attribute name="panelPadding" type="number" value="1" />
+            <Attribute name="panelColor" type="string" value="default" />
+            <Attribute name="panelGradient" type="boolean" value="false" />
+            <Attribute name="panelTexUpdate" type="boolean" value="false" />
+            <Attribute name="panelSkipUpdate" type="boolean" value="false" />
+        </Attributes>
+        <Backdrop bgFile="Interface\AddOns\SVUI_!Core\assets\buttons\CHECK-BG" edgeFile="Interface\AddOns\SVUI_!Core\assets\borders\DEFAULT" tile="false">
+            <EdgeSize val="1" />
+            <TileSize val="0" />
+            <BackgroundInsets left="0" right="0" top="0" bottom="0" />
+            <Color r="0.2" g="0.2" b="0.2" a="1" />
+            <BorderColor r="0.1" g="0.1" b="0.1" a="1" />
+        </Backdrop>
+    </Frame>
+
+    <Frame name="SVUI_CoreStyle_Inset" virtual="true">
+        <Attributes>
+            <Attribute name="panelID" type="string" value="inset" />
+            <Attribute name="panelPadding" type="number" value="1" />
+            <Attribute name="panelColor" type="string" value="transparent" />
+            <Attribute name="panelGradient" type="boolean" value="false" />
+            <Attribute name="panelTexUpdate" type="boolean" value="false" />
+            <Attribute name="panelSkipUpdate" type="boolean" value="true" />
+        </Attributes>
+        <Backdrop bgFile="Interface\DialogFrame\UI-DialogBox-Background" edgeFile="Interface\AddOns\SVUI_!Core\assets\borders\INSET" tile="false">
+            <EdgeSize val="6" />
+            <TileSize val="0" />
+            <BackgroundInsets left="0" right="0" top="0" bottom="0" />
+            <Color r="0" g="0" b="0" a="1" />
+            <BorderColor r="0" g="0" b="0" a="0.5" />
+        </Backdrop>
+    </Frame>
+
+    <Frame name="SVUI_CoreStyle_EditBox" virtual="true">
+        <Attributes>
+            <Attribute name="panelID" type="string" value="editbox" />
+            <Attribute name="panelPadding" type="number" value="1" />
+            <Attribute name="panelColor" type="string" value="transparent" />
+            <Attribute name="panelGradient" type="boolean" value="false" />
+            <Attribute name="panelTexUpdate" type="boolean" value="false" />
+            <Attribute name="panelSkipUpdate" type="boolean" value="true" />
+        </Attributes>
+        <Backdrop bgFile="Interface\AddOns\SVUI_!Core\assets\backgrounds\EMPTY" tile="true" edgeFile="Interface\BUTTONS\WHITE8X8">
+            <EdgeSize val="1" />
+            <TileSize val="20" />
+            <BackgroundInsets left="0" right="0" top="0" bottom="0" />
+            <BorderColor r="0" g="0" b="0" a="1" />
+            <Color r="0" g="0" b="0" a="0" />
+        </Backdrop>
+        <Frames>
+            <Frame parentKey="InnerGlow">
+                <Anchors>
+                    <Anchor point="TOPLEFT" relativePoint="TOPLEFT" x="1" y="-1" />
+                    <Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMRIGHT" x="-1" y="1" />
+                </Anchors>
+                <Backdrop bgFile="Interface\AddOns\SVUI_!Core\assets\backgrounds\DEFAULT" edgeFile="Interface\AddOns\SVUI_!Core\assets\borders\INSET" tile="false">
+                    <EdgeSize val="12" />
+                    <TileSize val="0" />
+                    <BackgroundInsets left="0" right="0" top="0" bottom="0" />
+                    <Color r="0" g="0" b="0" a="0.25" />
+                    <BorderColor r="0" g="0" b="0" a="1" />
+                </Backdrop>
+            </Frame>
+        </Frames>
+    </Frame>
+
+    <Frame name="SVUI_CoreStyle_Lite" virtual="true">
+        <Attributes>
+            <Attribute name="panelID" type="string" value="lite" />
+            <Attribute name="panelPadding" type="number" value="1" />
+            <Attribute name="panelColor" type="string" value="hinted" />
+            <Attribute name="panelGradient" type="boolean" value="false" />
+            <Attribute name="panelTexUpdate" type="boolean" value="false" />
+            <Attribute name="panelSkipUpdate" type="boolean" value="false" />
+        </Attributes>
+        <Backdrop bgFile="Interface\DialogFrame\UI-DialogBox-Background" tile="true" edgeFile="Interface\BUTTONS\WHITE8X8">
+            <EdgeSize val="1" />
+            <TileSize val="20" />
+            <BackgroundInsets left="0" right="0" top="0" bottom="0" />
+            <BorderColor r="0" g="0" b="0" a="1" />
+            <Color r="0" g="0" b="0" a="0.25" />
+        </Backdrop>
+    </Frame>
+
+    <Frame name="SVUI_CoreStyle_Bar" virtual="true">
+        <Attributes>
+            <Attribute name="panelID" type="string" value="bar" />
+            <Attribute name="panelPadding" type="number" value="1" />
+            <Attribute name="panelColor" type="string" value="transparent" />
+            <Attribute name="panelGradient" type="boolean" value="false" />
+            <Attribute name="panelTexUpdate" type="boolean" value="false" />
+            <Attribute name="panelSkipUpdate" type="boolean" value="true" />
+        </Attributes>
+        <Backdrop bgFile="Interface\AddOns\SVUI_!Core\assets\backgrounds\DEFAULT" edgeFile="Interface\AddOns\SVUI_!Core\assets\borders\DEFAULT" tile="false">
+            <EdgeSize val="1" />
+            <TileSize val="0" />
+            <BackgroundInsets left="0" right="0" top="0" bottom="0" />
+            <Color r="0" g="0" b="0" a="0.5" />
+            <BorderColor r="0" g="0" b="0" a="1" />
+        </Backdrop>
+        <Layers>
+            <Layer level="BACKGROUND" textureSubLevel="1">
+                <Texture parentKey="Skin" nonBlocking="true" file="Interface\AddOns\SVUI_!Core\assets\backgrounds\DEFAULT" setAllPoints="true" />
+                <Color r="0" g="0" b="0" a="0.5" />
+            </Layer>
+        </Layers>
+    </Frame>
+
+    <Frame name="SVUI_CoreStyle_Paper" virtual="true">
+        <Attributes>
+            <Attribute name="panelID" type="string" value="paper" />
+            <Attribute name="panelPadding" type="number" value="3" />
+            <Attribute name="panelColor" type="string" value="paper" />
+            <Attribute name="panelGradient" type="string" value="paper" />
+            <Attribute name="panelTexUpdate" type="boolean" value="false" />
+            <Attribute name="panelSkipUpdate" type="boolean" value="true" />
+        </Attributes>
+        <Backdrop bgFile="Interface\AddOns\SVUI_!Core\assets\backgrounds\pattern\PATTERN6" edgeFile="Interface\BUTTONS\WHITE8X8" tile="false">
+            <EdgeSize val="1" />
+            <TileSize val="0" />
+            <BackgroundInsets left="0" right="0" top="0" bottom="0" />
+            <Color r="1" g="1" b="1" a="1" />
+            <BorderColor r="0" g="0" b="0" a="1" />
+        </Backdrop>
+        <Layers>
+            <Layer level="BACKGROUND" textureSubLevel="1">
+                <Texture parentKey="Skin" nonBlocking="true" file="Interface\AddOns\SVUI_!Core\assets\backgrounds\pattern\PATTERN6" setAllPoints="true" />
+                <Color r="1" g="1" b="1" a="1" />
+            </Layer>
+        </Layers>
+    </Frame>
+
+    <Frame name="SVUI_CoreStyle_Container" virtual="true">
+        <Attributes>
+            <Attribute name="panelID" type="string" value="container" />
+            <Attribute name="panelPadding" type="number" value="2" />
+            <Attribute name="panelColor" type="string" value="special" />
+            <Attribute name="panelGradient" type="string" value="special" />
+            <Attribute name="panelTexUpdate" type="boolean" value="true" />
+            <Attribute name="panelSkipUpdate" type="boolean" value="false" />
+        </Attributes>
+        <Backdrop bgFile="Interface\AddOns\SVUI_!Core\assets\backgrounds\pattern\PATTERN6" edgeFile="Interface\BUTTONS\WHITE8X8" tile="false">
+            <EdgeSize val="1" />
+            <TileSize val="0" />
+            <BackgroundInsets left="0" right="0" top="0" bottom="0" />
+            <Color r="0.22" g="0.21" b="0.2" a="1" />
+            <BorderColor r="0" g="0" b="0" a="1" />
+        </Backdrop>
+        <Layers>
+            <Layer level="BACKGROUND" textureSubLevel="1">
+                <Texture parentKey="Skin" nonBlocking="true" file="Interface\AddOns\SVUI_!Core\assets\backgrounds\pattern\PATTERN6" setAllPoints="true" />
+                <Color r="0.22" g="0.21" b="0.2" a="1" />
+            </Layer>
+        </Layers>
+    </Frame>
+
+    <Frame name="SVUI_CoreStyle_Pattern" virtual="true">
+        <Attributes>
+            <Attribute name="panelID" type="string" value="pattern" />
+            <Attribute name="panelPadding" type="number" value="1" />
+            <Attribute name="panelColor" type="string" value="secondary" />
+            <Attribute name="panelGradient" type="string" value="secondary" />
+            <Attribute name="panelTexUpdate" type="boolean" value="true" />
+            <Attribute name="panelSkipUpdate" type="boolean" value="false" />
+        </Attributes>
+        <Backdrop bgFile="Interface\AddOns\SVUI_!Core\assets\backgrounds\pattern\PATTERN1" edgeFile="Interface\BUTTONS\WHITE8X8" tile="false">
+            <EdgeSize val="1" />
+            <TileSize val="0" />
+            <BackgroundInsets left="0" right="0" top="0" bottom="0" />
+            <Color r="0.37" g="0.32" b="0.29" a="1" />
+            <BorderColor r="0" g="0" b="0" a="1" />
+        </Backdrop>
+        <Frames>
+            <Frame parentKey="Shadow" inherits="SVUI_ShadowTemplate" />
+        </Frames>
+    </Frame>
+
+    <Frame name="SVUI_CoreStyle_Premium" virtual="true">
+        <Attributes>
+            <Attribute name="panelID" type="string" value="premium" />
+            <Attribute name="panelPadding" type="number" value="1" />
+            <Attribute name="panelColor" type="string" value="special" />
+            <Attribute name="panelGradient" type="string" value="special" />
+            <Attribute name="panelTexUpdate" type="boolean" value="true" />
+            <Attribute name="panelSkipUpdate" type="boolean" value="false" />
+            <Attribute name="panelOffset" type="number" value="4" />
+        </Attributes>
+        <Backdrop bgFile="Interface\AddOns\SVUI_!Core\assets\backgrounds\art\ART1" edgeFile="Interface\BUTTONS\WHITE8X8" tile="false">
+            <EdgeSize val="2" />
+            <TileSize val="0" />
+            <BackgroundInsets left="0" right="0" top="0" bottom="0" />
+            <Color r="0.37" g="0.32" b="0.29" a="1" />
+            <BorderColor r="0" g="0" b="0" a="1" />
+        </Backdrop>
+    </Frame>
+
+    <Frame name="SVUI_CoreStyle_Model" virtual="true">
+        <Attributes>
+            <Attribute name="panelID" type="string" value="model" />
+            <Attribute name="panelPadding" type="number" value="1" />
+            <Attribute name="panelColor" type="string" value="special" />
+            <Attribute name="panelGradient" type="string" value="special" />
+            <Attribute name="panelTexUpdate" type="boolean" value="true" />
+            <Attribute name="panelSkipUpdate" type="boolean" value="false" />
+            <Attribute name="panelOffset" type="number" value="0" />
+        </Attributes>
+        <Backdrop bgFile="Interface\AddOns\SVUI_!Core\assets\backgrounds\MODEL" edgeFile="Interface\BUTTONS\WHITE8X8" tile="false">
+            <EdgeSize val="2" />
+            <TileSize val="0" />
+            <BackgroundInsets left="0" right="0" top="0" bottom="0" />
+            <Color r="0.37" g="0.32" b="0.29" a="1" />
+            <BorderColor r="0" g="0" b="0" a="1" />
+        </Backdrop>
+    </Frame>
+
+    <Frame name="SVUI_CoreStyle_Window" virtual="true">
+        <Attributes>
+            <Attribute name="panelID" type="string" value="window" />
+            <Attribute name="panelPadding" type="number" value="2" />
+            <Attribute name="panelColor" type="string" value="specialdark" />
+            <Attribute name="panelGradient" type="boolean" value="false" />
+            <Attribute name="panelTexUpdate" type="boolean" value="false" />
+            <Attribute name="panelSkipUpdate" type="boolean" value="false" />
+        </Attributes>
+        <Backdrop bgFile="Interface\BUTTONS\WHITE8X8" edgeFile="Interface\BUTTONS\WHITE8X8" tile="false">
+            <EdgeSize val="2" />
+            <TileSize val="0" />
+            <BackgroundInsets left="1" right="1" top="1" bottom="1" />
+            <Color r="0.2" g="0.2" b="0.2" a="1" />
+            <BorderColor r="0" g="0" b="0" a="1" />
+        </Backdrop>
+        <Layers>
+            <Layer level="BACKGROUND" textureSubLevel="2">
+                <Texture parentKey="TopLeft" nonBlocking="true" file="Interface\AddOns\SVUI_!Core\assets\backgrounds\window\COMPOSITE1-TOPLEFT">
+                    <Anchors>
+                        <Anchor point="TOPLEFT" relativePoint="TOPLEFT" />
+                        <Anchor point="TOPRIGHT" relativePoint="TOP" />
+                        <Anchor point="BOTTOMLEFT" relativePoint="LEFT" />
+                    </Anchors>
+                    <Color r="0.05" g="0.05" b="0.05" a="0.5" />
+                </Texture>
+                <Texture parentKey="TopRight" nonBlocking="true" file="Interface\AddOns\SVUI_!Core\assets\backgrounds\window\COMPOSITE1-TOPRIGHT">
+                    <Anchors>
+                        <Anchor point="TOPRIGHT" relativePoint="TOPRIGHT" />
+                        <Anchor point="TOPLEFT" relativePoint="TOP" />
+                        <Anchor point="BOTTOMRIGHT" relativePoint="RIGHT" />
+                    </Anchors>
+                    <Color r="0.05" g="0.05" b="0.05" a="0.5" />
+                </Texture>
+                <Texture parentKey="BottomLeft" nonBlocking="true" file="Interface\AddOns\SVUI_!Core\assets\backgrounds\window\COMPOSITE1-BOTTOMLEFT">
+                    <Anchors>
+                        <Anchor point="BOTTOMLEFT" relativePoint="BOTTOMLEFT" />
+                        <Anchor point="BOTTOMRIGHT" relativePoint="BOTTOM" />
+                        <Anchor point="TOPLEFT" relativePoint="LEFT" />
+                    </Anchors>
+                    <Color r="0.1" g="0.1" b="0.1" a="0.5" />
+                </Texture>
+                <Texture parentKey="BottomRight" nonBlocking="true" file="Interface\AddOns\SVUI_!Core\assets\backgrounds\window\COMPOSITE1-BOTTOMRIGHT">
+                    <Anchors>
+                        <Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMRIGHT" />
+                        <Anchor point="BOTTOMLEFT" relativePoint="BOTTOM" />
+                        <Anchor point="TOPRIGHT" relativePoint="RIGHT" />
+                    </Anchors>
+                    <Color r="0.1" g="0.1" b="0.1" a="0.5" />
+                </Texture>
+            </Layer>
+        </Layers>
+        <Frames>
+            <Frame parentKey="Shadow" inherits="SVUI_ShadowTemplate" />
+        </Frames>
+    </Frame>
+
+    <Frame name="SVUI_CoreStyle_Window2" virtual="true">
+        <Attributes>
+            <Attribute name="panelID" type="string" value="window2" />
+            <Attribute name="panelPadding" type="number" value="2" />
+            <Attribute name="panelColor" type="string" value="specialdark" />
+            <Attribute name="panelGradient" type="boolean" value="false" />
+            <Attribute name="panelTexUpdate" type="boolean" value="false" />
+            <Attribute name="panelSkipUpdate" type="boolean" value="false" />
+        </Attributes>
+        <Backdrop bgFile="Interface\BUTTONS\WHITE8X8" edgeFile="Interface\BUTTONS\WHITE8X8" tile="false">
+            <EdgeSize val="2" />
+            <TileSize val="0" />
+            <BackgroundInsets left="1" right="1" top="1" bottom="1" />
+            <Color r="0.2" g="0.2" b="0.2" a="1" />
+            <BorderColor r="0" g="0" b="0" a="1" />
+        </Backdrop>
+        <Layers>
+            <Layer level="BACKGROUND" textureSubLevel="2">
+                <Texture parentKey="TopLeft" nonBlocking="true" file="Interface\AddOns\SVUI_!Core\assets\backgrounds\window\COMPOSITE2-TOPLEFT">
+                    <Anchors>
+                        <Anchor point="TOPLEFT" relativePoint="TOPLEFT" />
+                        <Anchor point="TOPRIGHT" relativePoint="TOP" />
+                        <Anchor point="BOTTOMLEFT" relativePoint="LEFT" />
+                    </Anchors>
+                    <Color r="0.05" g="0.05" b="0.05" a="0.5" />
+                </Texture>
+                <Texture parentKey="TopRight" nonBlocking="true" file="Interface\AddOns\SVUI_!Core\assets\backgrounds\window\COMPOSITE2-TOPRIGHT">
+                    <Anchors>
+                        <Anchor point="TOPRIGHT" relativePoint="TOPRIGHT" />
+                        <Anchor point="TOPLEFT" relativePoint="TOP" />
+                        <Anchor point="BOTTOMRIGHT" relativePoint="RIGHT" />
+                    </Anchors>
+                    <Color r="0.05" g="0.05" b="0.05" a="0.5" />
+                </Texture>
+                <Texture parentKey="BottomLeft" nonBlocking="true" file="Interface\AddOns\SVUI_!Core\assets\backgrounds\window\COMPOSITE2-BOTTOMLEFT">
+                    <Anchors>
+                        <Anchor point="BOTTOMLEFT" relativePoint="BOTTOMLEFT" />
+                        <Anchor point="BOTTOMRIGHT" relativePoint="BOTTOM" />
+                        <Anchor point="TOPLEFT" relativePoint="LEFT" />
+                    </Anchors>
+                    <Color r="0.1" g="0.1" b="0.1" a="0.5" />
+                </Texture>
+                <Texture parentKey="BottomRight" nonBlocking="true" file="Interface\AddOns\SVUI_!Core\assets\backgrounds\window\COMPOSITE2-BOTTOMRIGHT">
+                    <Anchors>
+                        <Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMRIGHT" />
+                        <Anchor point="BOTTOMLEFT" relativePoint="BOTTOM" />
+                        <Anchor point="TOPRIGHT" relativePoint="RIGHT" />
+                    </Anchors>
+                    <Color r="0.1" g="0.1" b="0.1" a="0.5" />
+                </Texture>
+            </Layer>
+        </Layers>
+        <Frames>
+            <Frame parentKey="Shadow" inherits="SVUI_ShadowTemplate" />
+        </Frames>
+    </Frame>
+
+    <Frame name="SVUI_CoreStyle_Blackout" virtual="true">
+        <Attributes>
+            <Attribute name="panelID" type="string" value="blackout" />
+            <Attribute name="panelPadding" type="number" value="2" />
+            <Attribute name="panelColor" type="string" value="transparent" />
+            <Attribute name="panelGradient" type="boolean" value="false" />
+            <Attribute name="panelTexUpdate" type="boolean" value="false" />
+            <Attribute name="panelOffset" type="number" value="2" />
+            <Attribute name="panelSkipUpdate" type="boolean" value="false" />
+        </Attributes>
+        <Backdrop bgFile="Interface\AddOns\SVUI_!Core\assets\backgrounds\DARK" edgeFile="Interface\BUTTONS\WHITE8X8" tile="false">
+            <EdgeSize val="2" />
+            <TileSize val="0" />
+            <BackgroundInsets left="1" right="1" top="1" bottom="1" />
+            <Color r="0" g="0" b="0" a="0.5" />
+            <BorderColor r="0" g="0" b="0" a="1" />
+        </Backdrop>
+        <Layers>
+            <Layer level="BACKGROUND" textureSubLevel="1">
+                <Texture parentKey="Skin" nonBlocking="true" file="Interface\AddOns\SVUI_!Core\assets\backgrounds\DARK" setAllPoints="true" />
+                <Color r="0" g="0" b="0" a="0.5" />
+            </Layer>
+        </Layers>
+        <Frames>
+            <Frame parentKey="Shadow" inherits="SVUI_ShadowTemplate" />
+        </Frames>
+    </Frame>
+
+    <Frame name="SVUI_CoreStyle_UnitLarge" virtual="true">
+        <Attributes>
+            <Attribute name="panelID" type="string" value="unitlarge" />
+            <Attribute name="panelPadding" type="number" value="2" />
+            <Attribute name="panelColor" type="string" value="special" />
+            <Attribute name="panelGradient" type="boolean" value="false" />
+            <Attribute name="panelTexUpdate" type="boolean" value="true" />
+            <Attribute name="panelSkipUpdate" type="boolean" value="false" />
+            <Attribute name="panelHookVertex" type="boolean" value="true" />
+        </Attributes>
+        <Layers>
+            <Layer level="BACKGROUND" textureSubLevel="1">
+                <Texture parentKey="Skin" nonBlocking="true" file="Interface\AddOns\SVUI_!Core\assets\backgrounds\unit\UNIT-BG1" setAllPoints="true" />
+                <Color r="0.37" g="0.32" b="0.29" a="1" />
+            </Layer>
+        </Layers>
+    </Frame>
+
+    <Frame name="SVUI_CoreStyle_UnitSmall" virtual="true">
+        <Attributes>
+            <Attribute name="panelID" type="string" value="unitsmall" />
+            <Attribute name="panelPadding" type="number" value="2" />
+            <Attribute name="panelColor" type="string" value="special" />
+            <Attribute name="panelGradient" type="boolean" value="false" />
+            <Attribute name="panelTexUpdate" type="boolean" value="true" />
+            <Attribute name="panelSkipUpdate" type="boolean" value="false" />
+            <Attribute name="panelHookVertex" type="boolean" value="true" />
+        </Attributes>
+        <Layers>
+            <Layer level="BACKGROUND" textureSubLevel="1">
+                <Texture parentKey="Skin" nonBlocking="true" file="Interface\AddOns\SVUI_!Core\assets\backgrounds\unit\UNIT-SMALL-BG1" setAllPoints="true" />
+                <Color r="0.37" g="0.32" b="0.29" a="1" />
+            </Layer>
+        </Layers>
+    </Frame>
+</Ui>
diff --git a/SVUI_!Core/xml/templates.xml b/SVUI_!Core/xml/templates.xml
new file mode 100644
index 0000000..b1dbac5
--- /dev/null
+++ b/SVUI_!Core/xml/templates.xml
@@ -0,0 +1,340 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+    <Slider name="SVUI_TinySliderTemplate" orientation="HORIZONTAL" virtual="true" enableMouse="true">
+      <Size>
+        <AbsDimension x="100" y="6"/>
+      </Size>
+      <Backdrop bgFile="Interface\BUTTONS\WHITE8X8" edgeFile="Interface\BUTTONS\WHITE8X8" tile="false">
+          <EdgeSize val="1" />
+          <TileSize val="0" />
+          <BackgroundInsets left="0" right="0" top="0" bottom="0" />
+          <Color r="0" g="0" b="0" a="0.5" />
+          <BorderColor r="0" g="0" b="0" a="1" />
+      </Backdrop>
+      <Layers>
+        <Layer level="ARTWORK">
+          <FontString parentKey="Text" inherits="GameFontHighlightSmall">
+            <Anchors>
+              <Anchor point="BOTTOM" relativePoint="TOP"/>
+            </Anchors>
+          </FontString>
+          <FontString parentKey="Low" inherits="GameFontHighlightSmall" text="LOW">
+            <Anchors>
+              <Anchor point="TOPLEFT" relativePoint="BOTTOMLEFT">
+                <Offset>
+                  <AbsDimension x="0" y="0"/>
+                </Offset>
+              </Anchor>
+            </Anchors>
+          </FontString>
+          <FontString parentKey="High" inherits="GameFontHighlightSmall" text="HIGH">
+            <Anchors>
+              <Anchor point="TOPRIGHT" relativePoint="BOTTOMRIGHT">
+                <Offset>
+                  <AbsDimension x="0" y="0"/>
+                </Offset>
+              </Anchor>
+            </Anchors>
+          </FontString>
+        </Layer>
+      </Layers>
+      <Scripts>
+        <OnEnter>
+          if ( self:IsEnabled() ) then
+            if ( self.tooltipText ) then
+              GameTooltip:SetOwner(self, self.tooltipOwnerPoint or "ANCHOR_RIGHT");
+              GameTooltip:SetText(self.tooltipText, nil, nil, nil, nil, true);
+            end
+          end
+        </OnEnter>
+        <OnLeave>
+          GameTooltip:Hide();
+        </OnLeave>
+      </Scripts>
+      <ThumbTexture parentKey="Thumb" file="Interface\AddOns\SVUI_!Core\assets\buttons\SCROLLBAR-KNOB">
+        <Size>
+          <AbsDimension x="20" y="20"/>
+        </Size>
+      </ThumbTexture>
+    </Slider>
+
+    <Slider name="SVUI_HSliderTemplate" orientation="HORIZONTAL" virtual="true" enableMouse="true">
+      <Size>
+        <AbsDimension x="144" y="12"/>
+      </Size>
+      <HitRectInsets>
+        <AbsInset left="0" right="0" top="-10" bottom="-10"/>
+      </HitRectInsets>
+      <Backdrop bgFile="Interface\BUTTONS\WHITE8X8" edgeFile="Interface\BUTTONS\WHITE8X8" tile="false">
+          <EdgeSize val="2" />
+          <TileSize val="0" />
+          <BackgroundInsets left="0" right="0" top="0" bottom="0" />
+          <Color r="0" g="0" b="0" a="0.5" />
+          <BorderColor r="0" g="0" b="0" a="1" />
+      </Backdrop>
+      <Layers>
+        <Layer level="ARTWORK">
+          <FontString name="$parentText" inherits="GameFontNormal">
+            <Anchors>
+              <Anchor point="BOTTOM" relativePoint="TOP"/>
+            </Anchors>
+          </FontString>
+          <FontString name="$parentLow" inherits="GameFontNormal" text="LOW">
+            <Anchors>
+              <Anchor point="RIGHT" relativePoint="LEFT">
+                <Offset>
+                  <AbsDimension x="-8" y="0"/>
+                </Offset>
+              </Anchor>
+            </Anchors>
+          </FontString>
+          <FontString name="$parentHigh" inherits="GameFontNormal" text="HIGH">
+            <Anchors>
+              <Anchor point="LEFT" relativePoint="RIGHT">
+                <Offset>
+                  <AbsDimension x="8" y="0"/>
+                </Offset>
+              </Anchor>
+            </Anchors>
+          </FontString>
+        </Layer>
+      </Layers>
+      <Scripts>
+        <OnEnter>
+          if ( self:IsEnabled() ) then
+            if ( self.tooltipText ) then
+              GameTooltip:SetOwner(self, self.tooltipOwnerPoint or "ANCHOR_RIGHT");
+              GameTooltip:SetText(self.tooltipText, nil, nil, nil, nil, true);
+            end
+          end
+        </OnEnter>
+        <OnLeave>
+          GameTooltip:Hide();
+        </OnLeave>
+      </Scripts>
+      <ThumbTexture name="$parentThumb" file="Interface\AddOns\SVUI_!Core\assets\buttons\SCROLLBAR-KNOB">
+        <Size>
+          <AbsDimension x="20" y="20"/>
+        </Size>
+      </ThumbTexture>
+    </Slider>
+
+    <Slider name="SVUI_VSliderTemplate" orientation="VERTICAL" virtual="true" enableMouse="true">
+      <Size>
+        <AbsDimension x="12" y="144"/>
+      </Size>
+      <HitRectInsets>
+        <AbsInset left="-10" right="-10" top="0" bottom="0"/>
+      </HitRectInsets>
+      <Backdrop bgFile="Interface\BUTTONS\WHITE8X8" edgeFile="Interface\BUTTONS\WHITE8X8" tile="false">
+          <EdgeSize val="2" />
+          <TileSize val="0" />
+          <BackgroundInsets left="0" right="0" top="0" bottom="0" />
+          <Color r="0" g="0" b="0" a="0.5" />
+          <BorderColor r="0" g="0" b="0" a="1" />
+      </Backdrop>
+      <Layers>
+        <Layer level="ARTWORK">
+          <FontString name="$parentText" inherits="GameFontHighlight">
+            <Anchors>
+              <Anchor point="BOTTOM" relativePoint="TOP"/>
+            </Anchors>
+          </FontString>
+          <FontString name="$parentLow" inherits="GameFontHighlightSmall" text="LOW">
+            <Anchors>
+              <Anchor point="BOTTOMLEFT" relativePoint="BOTTOMLEFT">
+                <Offset>
+                  <AbsDimension x="3" y="-4"/>
+                </Offset>
+              </Anchor>
+            </Anchors>
+          </FontString>
+          <FontString name="$parentHigh" inherits="GameFontHighlightSmall" text="HIGH">
+            <Anchors>
+              <Anchor point="TOPLEFT" relativePoint="TOPLEFT">
+                <Offset>
+                  <AbsDimension x="3" y="4"/>
+                </Offset>
+              </Anchor>
+            </Anchors>
+          </FontString>
+        </Layer>
+      </Layers>
+      <Scripts>
+        <OnEnter>
+          if ( self:IsEnabled() ) then
+            if ( self.tooltipText ) then
+              GameTooltip:SetOwner(self, self.tooltipOwnerPoint or "ANCHOR_RIGHT");
+              GameTooltip:SetText(self.tooltipText, nil, nil, nil, nil, true);
+            end
+          end
+        </OnEnter>
+        <OnLeave>
+          GameTooltip:Hide();
+        </OnLeave>
+      </Scripts>
+      <ThumbTexture name="$parentThumb" file="Interface\AddOns\SVUI_!Core\assets\buttons\SCROLLBAR-KNOB">
+        <Size>
+          <AbsDimension x="20" y="20"/>
+        </Size>
+      </ThumbTexture>
+    </Slider>
+
+    <Frame name="SVUI_ShadowTemplate" virtual="true">
+        <Attributes>
+            <Attribute name="shadowAlpha" type="number" value="0.5" />
+        </Attributes>
+        <Backdrop edgeFile="Interface\AddOns\SVUI_!Core\assets\borders\SHADOW">
+            <EdgeSize val="3" />
+            <BackgroundInsets left="0" right="0" top="0" bottom="0" />
+            <Color r="0" g="0" b="0" a="0" />
+            <BorderColor r="0" g="0" b="0" a="0.5" />
+        </Backdrop>
+    </Frame>
+
+    <Frame name="SVUI_ShadowBoxTemplate" virtual="true">
+        <Layers>
+            <Layer level="BACKGROUND" textureSubLevel="2">
+                <Texture parentKey="Left" nonBlocking="true" file="Interface\BUTTONS\WHITE8X8">
+                    <Anchors>
+                        <Anchor point="BOTTOMLEFT" relativePoint="BOTTOMLEFT" x="0" y="0" />
+                        <Anchor point="TOPLEFT" relativePoint="TOPLEFT" x="0" y="0" />
+                    </Anchors>
+                    <Size>
+                      <AbsDimension x="2"/>
+                    </Size>
+                    <Color r="0" g="0" b="0" a="1" />
+                </Texture>
+                <Texture parentKey="Top" nonBlocking="true" file="Interface\BUTTONS\WHITE8X8">
+                    <Anchors>
+                        <Anchor point="TOPLEFT" relativePoint="TOPLEFT" x="0" y="0" />
+                        <Anchor point="TOPRIGHT" relativePoint="TOPRIGHT" x="0" y="0" />
+                    </Anchors>
+                    <Size>
+                      <AbsDimension y="2"/>
+                    </Size>
+                    <Color r="0" g="0" b="0" a="1" />
+                </Texture>
+                <Texture parentKey="Right" nonBlocking="true" file="Interface\BUTTONS\WHITE8X8">
+                    <Anchors>
+                        <Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMRIGHT" x="0" y="0" />
+                        <Anchor point="TOPRIGHT" relativePoint="TOPRIGHT" x="0" y="0" />
+                    </Anchors>
+                    <Size>
+                      <AbsDimension x="2"/>
+                    </Size>
+                    <Color r="0" g="0" b="0" a="1" />
+                </Texture>
+                <Texture parentKey="Bottom" nonBlocking="true" file="Interface\BUTTONS\WHITE8X8">
+                    <Anchors>
+                        <Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMRIGHT" x="0" y="0" />
+                        <Anchor point="BOTTOMLEFT" relativePoint="BOTTOMLEFT" x="0" y="0" />
+                    </Anchors>
+                    <Size>
+                      <AbsDimension y="2"/>
+                    </Size>
+                    <Color r="0" g="0" b="0" a="1" />
+                </Texture>
+            </Layer>
+        </Layers>
+    </Frame>
+
+    <Button name="SVUI_DockletButtonTemplate" virtual="true" hidden="true">
+        <Size x="22" y="22"/>
+        <Attributes>
+            <Attribute name="tipText" type="string" value="" />
+            <Attribute name="tipExtraText" type="string" value="" />
+        </Attributes>
+        <Layers>
+            <Layer level="OVERLAY">
+                <Texture parentKey="Icon" file="Interface\AddOns\SVUI_!Core\assets\backgrounds\DEFAULT">
+                    <Anchors>
+                        <Anchor point="TOPLEFT" relativePoint="TOPLEFT" x="2" y="-2" />
+                        <Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMRIGHT" x="-2" y="2" />
+                    </Anchors>
+                </Texture>
+            </Layer>
+        </Layers>
+        <Scripts>
+            <OnLoad>
+                self:RegisterForClicks("LeftButtonUp", "RightButtonUp");
+            </OnLoad>
+        </Scripts>
+    </Button>
+
+    <Frame name="SVUI_MovingPanelTemplate" virtual="true" movable="true" clampedToScreen="true" toplevel="true">
+        <Layers>
+            <Layer level="BACKGROUND">
+                <Texture name="$parentBG" setAllPoints="true"/>
+            </Layer>
+            <Layer level="OVERLAY">
+                <Texture name="$parentTitleBG">
+                    <Anchors>
+                        <Anchor point="TOPLEFT"/>
+                        <Anchor point="BOTTOMRIGHT" relativePoint="TOPRIGHT">
+                            <Offset x="0" y="-30"/>
+                        </Anchor>
+                    </Anchors>
+                </Texture>
+            </Layer>
+        </Layers>
+        <Frames>
+            <Frame name="$parentTitleButton">
+                <Anchors>
+                    <Anchor point="TOPLEFT" relativeTo="$parentTitleBG"/>
+                    <Anchor point="BOTTOMRIGHT" relativeTo="$parentTitleBG"/>
+                </Anchors>
+            </Frame>
+        </Frames>
+    </Frame>
+
+    <Frame name="SVUI_MessagePanelTemplate" virtual="true" toplevel="true">
+        <Layers>
+            <Layer level="BACKGROUND">
+                <Texture name="$parentBG" setAllPoints="true"/>
+            </Layer>
+            <Layer level="OVERLAY">
+                <Texture name="$parentTitleBG">
+                    <Anchors>
+                        <Anchor point="TOPLEFT">
+                            <Offset x="8" y="-8"/>
+                        </Anchor>
+                        <Anchor point="BOTTOMRIGHT" relativePoint="TOPRIGHT">
+                            <Offset x="-32" y="-24"/>
+                        </Anchor>
+                    </Anchors>
+                </Texture>
+                <Texture name="$parentDialogBG">
+                    <Anchors>
+                        <Anchor point="TOPLEFT">
+                            <Offset x="8" y="-32"/>
+                        </Anchor>
+                        <Anchor point="BOTTOMRIGHT">
+                            <Offset x="-32" y="32"/>
+                        </Anchor>
+                    </Anchors>
+                </Texture>
+            </Layer>
+            <Layer level="ARTWORK">
+                <FontString parentKey="Title" inherits="GameFontNormal">
+                    <Anchors>
+                        <Anchor point="TOPLEFT">
+                            <Offset x="8" y="-8"/>
+                        </Anchor>
+                        <Anchor point="TOPRIGHT">
+                            <Offset x="-32" y="-24"/>
+                        </Anchor>
+                    </Anchors>
+                </FontString>
+            </Layer>
+        </Layers>
+        <Frames>
+            <Button parentKey="Close" inherits="UIPanelCloseButton">
+                <Anchors>
+                    <Anchor point="TOPRIGHT">
+                        <Offset x="-2" y="-2"/>
+                    </Anchor>
+                </Anchors>
+            </Button>
+        </Frames>
+    </Frame>
+</Ui>
diff --git a/SVUI_!Core/xml/widgets.xml b/SVUI_!Core/xml/widgets.xml
new file mode 100644
index 0000000..4ad553e
--- /dev/null
+++ b/SVUI_!Core/xml/widgets.xml
@@ -0,0 +1,870 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+    <Font name="SVUI_Font_Super_Text" inherits="SVUI_Font_Number" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="2" y="-2"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.5"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="22"/>
+        </FontHeight>
+    </Font>
+    <Font name="SVUI_Font_Super_Title" inherits="SVUI_Font_Number_Huge" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="2" y="-2"/>
+            </Offset>
+            <Color r="0" g="0" b="0" />
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="128"/>
+        </FontHeight>
+    </Font>
+
+    <Frame name="SVUI_SuperTitleFrame" frameStrata="BACKGROUND" hidden="true">
+        <Size x="400" y="100"/>
+        <Anchors>
+            <Anchor point="LEFT" relativePoint="CENTER" x="150" y="-50" />
+        </Anchors>
+        <Layers>
+            <Layer level="ARTWORK">
+
+              <FontString name="$parentList" font="SVUI_Font_Super_Title">
+                <Color r="1" g="0.5" b="0" a="0.85"/>
+                <Anchors>
+                    <Anchor point="LEFT" x="0" y="0" />
+                </Anchors>
+                <Shadow>
+                    <Offset>
+                        <AbsDimension x="2" y="-2"/>
+                    </Offset>
+                    <Color r="0" g="0" b="0" />
+                </Shadow>
+              </FontString>
+
+              <FontString name="$parentTitle" inherits="SVUI_Font_Super_Text">
+                <Color r="1" g="1" b="0" a="0.85"/>
+                  <Anchors>
+                      <Anchor point="BOTTOMLEFT" relativeTo="$parentList" relativePoint="TOPLEFT" x="0" y="6" />
+                  </Anchors>
+              </FontString>
+          </Layer>
+        </Layers>
+    </Frame>
+
+    <Frame name="SVUI_CreditFrame" frameStrata="BACKGROUND" hidden="true">
+        <Size x="400" y="100"/>
+        <Anchors>
+            <Anchor point="LEFT" relativePoint="CENTER" x="200" y="-50" />
+        </Anchors>
+        <Layers>
+            <Layer level="ARTWORK">
+
+              <FontString name="$parentList" font="SystemFont_Shadow_Outline_Huge2" justifyH="LEFT">
+                <Color r="1" g="1" b="1" a="0.65"/>
+                <Anchors>
+                    <Anchor point="LEFT" x="0" y="0" />
+                </Anchors>
+              </FontString>
+
+              <FontString name="$parentTitle" inherits="SystemFont_Shadow_Large">
+                <Color r="1" g="1" b="1" a="0.65"/>
+                  <Anchors>
+                      <Anchor point="BOTTOMLEFT" relativeTo="$parentList" relativePoint="TOPLEFT" x="0" y="6" />
+                  </Anchors>
+              </FontString>
+          </Layer>
+        </Layers>
+    </Frame>
+
+    <Frame name="SVUI_DropdownFrame" frameStrata="DIALOG" hidden="true" />
+
+    <Frame name="SVUI_MailMinion" parent="InboxFrame" hidden="true">
+        <Size x="150" y="25"/>
+        <Anchors>
+            <Anchor point="CENTER" relativePoint="TOP" x="-22" y="-400" />
+        </Anchors>
+        <Frames>
+            <Button name="$parentGetMail" parentKey="GetMail" inherits="UIPanelButtonTemplate" text="Get All">
+                <Size x="70" y="25"/>
+                <Anchors>
+                    <Anchor point="LEFT" />
+                </Anchors>
+            </Button>
+            <Button name="$parentGetGold" parentKey="GetGold" inherits="UIPanelButtonTemplate" text="Get Gold">
+                <Size x="70" y="25"/>
+                <Anchors>
+                    <Anchor point="RIGHT" />
+                </Anchors>
+            </Button>
+            <Button name="$parentDelete" parentKey="Delete" inherits="UIPanelButtonTemplate" text="Delete All">
+                <Size x="70" y="25"/>
+                <Anchors>
+                    <Anchor point="TOPLEFT" relativeTo="InboxFrame" relativePoint="TOPLEFT">
+                        <Offset x="16" y="-30"/>
+                    </Anchor>
+                </Anchors>
+            </Button>
+        </Frames>
+    </Frame>
+
+    <Frame name="SVUI_RaidMarkFrame" frameStrata="DIALOG" hidden="true" />
+
+    <Frame name="SVUI_LayoutPrecision" movable="true" hidden="true" frameStrata="DIALOG">
+        <Size x="200" y="144"/>
+        <Anchors>
+            <Anchor point="CENTER"/>
+        </Anchors>
+        <Layers>
+            <Layer level="BACKGROUND">
+                <Texture name="$parentBG" setAllPoints="true"/>
+            </Layer>
+            <Layer level="OVERLAY">
+                <Texture name="$parentTitleBG">
+                    <Anchors>
+                        <Anchor point="TOPLEFT" relativeTo="$parentBG" relativePoint="TOPLEFT">
+                            <Offset x="30" y="0"/>
+                        </Anchor>
+                        <Anchor point="TOPRIGHT" relativeTo="$parentBG" relativePoint="TOPRIGHT">
+                            <Offset x="-30" y="0"/>
+                        </Anchor>
+                    </Anchors>
+                    <Size y="20"/>
+                </Texture>
+            </Layer>
+            <Layer level="ARTWORK">
+                <FontString parentKey="Title" inherits="GameFontNormal" justifyV="TOP" text="Focused Position">
+                    <Anchors>
+                        <Anchor point="TOPLEFT" relativeTo="$parentTitleBG" relativePoint="TOPLEFT"/>
+                        <Anchor point="TOPRIGHT" relativeTo="$parentTitleBG" relativePoint="TOPRIGHT"/>
+                    </Anchors>
+                </FontString>
+                <FontString inherits="NumberFont_Outline_Huge" text="X">
+                    <Anchors>
+                        <Anchor point="TOPRIGHT" relativeTo="$parentTitleBG" relativePoint="BOTTOMLEFT">
+                            <Offset x="-8" y="-10"/>
+                        </Anchor>
+                    </Anchors>
+                    <Color r="1" g="0.5" b="0" a="1"/>
+                </FontString>
+                <FontString inherits="NumberFont_Outline_Huge" text="Y">
+                    <Anchors>
+                        <Anchor point="TOPLEFT" relativeTo="$parentTitleBG" relativePoint="BOTTOMRIGHT">
+                            <Offset x="8" y="-10"/>
+                        </Anchor>
+                    </Anchors>
+                    <Color r="1" g="0.5" b="0" a="1"/>
+                </FontString>
+            </Layer>
+        </Layers>
+        <Frames>
+          <Button name="$parentCloseButton" parentKey="Close" inherits="UIPanelCloseButton">
+              <Anchors>
+                  <Anchor point="TOPRIGHT" relativeTo="$parentBG" relativePoint="TOPRIGHT">
+                      <Offset x="6" y="6"/>
+                  </Anchor>
+              </Anchors>
+          </Button>
+            <EditBox name="$parentSetX" inherits="InputBoxTemplate" autoFocus="false">
+                <Size x="50" y="17"/>
+                <Anchors>
+                    <Anchor point="TOPRIGHT" relativeTo="$parentTitleBG" relativePoint="BOTTOM">
+                        <Offset x="-27" y="0"/>
+                    </Anchor>
+                </Anchors>
+
+                <Scripts>
+                    <OnEscapePressed>
+                        self:SetText(math.floor((self.CurrentValue or 0) + 0.5))
+                        EditBox_ClearFocus(self)
+                    </OnEscapePressed>
+                    <OnEditFocusLost>
+                        self:SetText(math.floor((self.CurrentValue or 0) + 0.5))
+                    </OnEditFocusLost>
+                    <OnShow>
+                        EditBox_ClearFocus(self)
+                        self:SetText(math.floor((self.CurrentValue or 0) + 0.5))
+                    </OnShow>
+                </Scripts>
+            </EditBox>
+
+            <EditBox name="$parentSetY" inherits="InputBoxTemplate" autoFocus="false">
+                <Size x="50" y="17"/>
+                <Anchors>
+                    <Anchor point="TOPLEFT" relativeTo="$parentTitleBG" relativePoint="BOTTOM">
+                        <Offset x="27" y="0"/>
+                    </Anchor>
+                </Anchors>
+                <Scripts>
+                    <OnEscapePressed>
+                        self:SetText(math.floor((self.CurrentValue or 0) + 0.5))
+                        EditBox_ClearFocus(self)
+                    </OnEscapePressed>
+                    <OnEditFocusLost>
+                        self:SetText(math.floor((self.CurrentValue or 0) + 0.5))
+                    </OnEditFocusLost>
+                    <OnShow>
+                        EditBox_ClearFocus(self)
+                        self:SetText(math.floor((self.CurrentValue or 0) + 0.5))
+                    </OnShow>
+                </Scripts>
+            </EditBox>
+
+            <Button name="$parentResetButton" inherits="OptionsButtonTemplate" text="Reset">
+                <Size x="48" y="20"/>
+                <Anchors>
+                    <Anchor point="TOP" relativeTo="$parentTitleBG" relativePoint="BOTTOM" x="0" y="-22" />
+                </Anchors>
+                <Scripts>
+                    <OnLoad>
+                        self:RegisterForClicks("AnyUp");
+                    </OnLoad>
+                </Scripts>
+            </Button>
+
+            <Button name="$parentUpButton" inherits="UIPanelSquareButton">
+                <Size x="25" y="20"/>
+                <Anchors>
+                    <Anchor point="LEFT" relativeTo="$parentResetButton" relativePoint="RIGHT">
+                        <Offset x="2" y="0"/>
+                    </Anchor>
+                </Anchors>
+                <Scripts>
+                    <OnLoad>
+                        SquareButton_SetIcon(self, "UP");
+                        self:RegisterForClicks("AnyUp");
+                    </OnLoad>
+                    <OnClick>
+                        local frame = _G["SVUI_LayoutPrecisionSetY"];
+                        frame.CurrentValue = frame.CurrentValue + 1
+                        frame:SetText(frame.CurrentValue)
+                        frame:GetScript('OnEnterPressed')(frame)
+                    </OnClick>
+                </Scripts>
+            </Button>
+
+            <Button name="$parentDownButton" inherits="UIPanelSquareButton">
+                <Size x="25" y="20"/>
+                <Anchors>
+                    <Anchor point="LEFT" relativeTo="$parentUpButton" relativePoint="RIGHT">
+                        <Offset x="2" y="0"/>
+                    </Anchor>
+                </Anchors>
+                <Scripts>
+                    <OnLoad>
+                        SquareButton_SetIcon(self, "DOWN");
+                        self:RegisterForClicks("AnyUp");
+                    </OnLoad>
+                    <OnClick>
+                        local frame = _G["SVUI_LayoutPrecisionSetY"];
+                        frame.CurrentValue = frame.CurrentValue - 1
+                        frame:SetText(frame.CurrentValue)
+                        frame:GetScript('OnEnterPressed')(frame)
+                    </OnClick>
+                </Scripts>
+            </Button>
+
+            <Button name="$parentRightButton" inherits="UIPanelSquareButton">
+                <Size x="25" y="20"/>
+                <Anchors>
+                    <Anchor point="RIGHT" relativeTo="$parentResetButton" relativePoint="LEFT">
+                        <Offset x="-2" y="0"/>
+                    </Anchor>
+                </Anchors>
+                <Scripts>
+                    <OnLoad>
+                        SquareButton_SetIcon(self, "RIGHT");
+                        self:RegisterForClicks("AnyUp");
+                    </OnLoad>
+                    <OnClick>
+                        local frame = _G["SVUI_LayoutPrecisionSetX"];
+                        frame.CurrentValue = frame.CurrentValue + 1
+                        frame:SetText(frame.CurrentValue)
+                        frame:GetScript('OnEnterPressed')(frame)
+                    </OnClick>
+                </Scripts>
+            </Button>
+
+            <Button name="$parentLeftButton" inherits="UIPanelSquareButton">
+                <Size x="25" y="20"/>
+                <Anchors>
+                    <Anchor point="RIGHT" relativeTo="$parentRightButton" relativePoint="LEFT">
+                        <Offset x="-2" y="0"/>
+                    </Anchor>
+                </Anchors>
+                <Scripts>
+                    <OnLoad>
+                        SquareButton_SetIcon(self, "LEFT");
+                        self:RegisterForClicks("AnyUp");
+                    </OnLoad>
+                    <OnClick>
+                        local frame = _G["SVUI_LayoutPrecisionSetX"];
+                        frame.CurrentValue = frame.CurrentValue - 1
+                        frame:SetText(frame.CurrentValue)
+                        frame:GetScript('OnEnterPressed')(frame)
+                    </OnClick>
+                </Scripts>
+            </Button>
+
+            <Slider name="$parentWidthAdjust" inherits="SVUI_HSliderTemplate">
+      				<Size x="132" y="12"/>
+      				<Anchors>
+      					<Anchor point="TOP" relativeTo="$parentResetButton" relativePoint="BOTTOM">
+      						<Offset>
+      							<AbsDimension x="0" y="-20"/>
+      						</Offset>
+      					</Anchor>
+      				</Anchors>
+      				<Scripts>
+      					<OnLoad>
+      						local name = self:GetName();
+                  self.rangeLow = _G[name.."Low"];
+                  self.rangeHigh = _G[name.."High"];
+                  self.rangeValue = _G[name.."Text"];
+      					</OnLoad>
+      				</Scripts>
+      			</Slider>
+
+            <Slider name="$parentHeightAdjust" inherits="SVUI_HSliderTemplate">
+      				<Size x="132" y="12"/>
+      				<Anchors>
+      					<Anchor point="TOP" relativeTo="$parentWidthAdjust" relativePoint="BOTTOM">
+      						<Offset>
+      							<AbsDimension x="0" y="-20"/>
+      						</Offset>
+      					</Anchor>
+      				</Anchors>
+      				<Scripts>
+      					<OnLoad>
+      						local name = self:GetName();
+                  self.rangeLow = _G[name.."Low"];
+                  self.rangeHigh = _G[name.."High"];
+                  self.rangeValue = _G[name.."Text"];
+      					</OnLoad>
+      				</Scripts>
+      			</Slider>
+        </Frames>
+        <Scripts>
+            <OnDragStart>
+                self.moving = true;
+                self:StartMoving();
+            </OnDragStart>
+            <OnDragStop>
+                self.moving = nil;
+                self:StopMovingOrSizing();
+            </OnDragStop>
+        </Scripts>
+    </Frame>
+
+    <Frame name="SVUI_Layout" movable="true" hidden="true" frameStrata="DIALOG">
+        <Size x="220" y="30"/>
+        <Anchors>
+            <Anchor point="CENTER">
+                <Offset x="0" y="30"/>
+            </Anchor>
+        </Anchors>
+        <Layers>
+            <Layer level="BACKGROUND">
+                <Texture name="$parentBG" setAllPoints="true"/>
+            </Layer>
+            <Layer level="OVERLAY">
+                <Texture name="$parentTitleBG">
+                    <Anchors>
+                        <Anchor point="TOPLEFT"/>
+                        <Anchor point="BOTTOMRIGHT" relativePoint="TOPRIGHT">
+                            <Offset x="0" y="-30"/>
+                        </Anchor>
+                    </Anchors>
+                </Texture>
+            </Layer>
+            <Layer level="ARTWORK">
+                <FontString parentKey="Title" inherits="SVUI_Font_Narrator" justifyH="CENTER" text="Mentalo The Frame Mover!">
+                    <Anchors>
+                        <Anchor point="CENTER" relativeTo="$parentTitleBG" relativePoint="CENTER" />
+                    </Anchors>
+                    <Color r="1" g="1" b="1" a="1"/>
+                </FontString>
+                <FontString name="$parentSubTitle" parentKey="SubTitle" inherits="SVUI_Font_Caps" justifyH="CENTER" text="Right-click frames to move with precision.">
+                    <Anchors>
+                        <Anchor point="TOP" relativeTo="$parentTitleBG" relativePoint="BOTTOM" x="0" y="5" />
+                    </Anchors>
+                    <Color r="1" g="1" b="0" a="0.8"/>
+                </FontString>
+                <FontString parentKey="SubInfo" inherits="SVUI_Font_Caps" justifyH="CENTER" text="Hold shift to enable snapping.">
+                    <Anchors>
+                        <Anchor point="TOP" relativeTo="$parentSubTitle" relativePoint="BOTTOM" x="0" y="-4" />
+                    </Anchors>
+                    <Color r="1" g="0.5" b="0" a="0.8"/>
+                </FontString>
+                <Texture name="$parentPortrait" parentKey="Portrait" file="Interface\AddOns\SVUI_!Core\assets\textures\EMPTY">
+                    <Size x="132" y="132"/>
+                    <Anchors>
+                        <Anchor point="BOTTOM" relativeTo="$parentBG" relativePoint="TOP" x="0" y="-28" />
+                    </Anchors>
+                </Texture>
+            </Layer>
+        </Layers>
+        <Frames>
+            <Button name="$parentGridButton" inherits="OptionsButtonTemplate" text="">
+                <Size x="104" y="24"/>
+                <Anchors>
+                    <Anchor point="CENTER" relativeTo="$parentPortrait" relativePoint="TOPRIGHT" x="0" y="0" />
+                </Anchors>
+            </Button>
+            <Button name="$parentLockButton" inherits="OptionsButtonTemplate" text="">
+                <Size x="104" y="24"/>
+                <Anchors>
+                    <Anchor point="CENTER" relativeTo="$parentPortrait" relativePoint="TOPLEFT" x="0" y="0" />
+                </Anchors>
+            </Button>
+        </Frames>
+        <Scripts>
+            <OnHide>
+                _G["SVUI_LayoutPrecision"]:Hide();
+            </OnHide>
+            <OnDragStart>
+                self.moving = true;
+                self:StartMoving();
+            </OnDragStart>
+            <OnDragStop>
+                self.moving = nil;
+                self:StopMovingOrSizing();
+            </OnDragStop>
+        </Scripts>
+    </Frame>
+
+    <Frame name="SVUI_GameMenuFrame" parent="GameMenuFrame">
+        <Layers>
+            <Layer level="BACKGROUND" textureSubLevel="-7">
+                <Texture file="Interface\AddOns\SVUI_!Core\assets\backgrounds\DEFAULT">
+                    <Anchors>
+                        <Anchor point="TOPLEFT" relativePoint="TOPLEFT" x="0" y="0" />
+                        <Anchor point="BOTTOMRIGHT" relativePoint="TOPRIGHT" x="0" y="-300" />
+                    </Anchors>
+                    <Color r="0" g="0" b="0" a="0.8" />
+                </Texture>
+                <Texture file="Interface\AddOns\SVUI_!Core\assets\backgrounds\DEFAULT">
+                    <Anchors>
+                        <Anchor point="BOTTOMLEFT" relativePoint="BOTTOMLEFT" x="0" y="0" />
+                        <Anchor point="TOPRIGHT" relativePoint="BOTTOMRIGHT" x="0" y="300" />
+                    </Anchors>
+                    <Color r="0" g="0" b="0" a="0.8" />
+                </Texture>
+            </Layer>
+        </Layers>
+        <Frames>
+            <PlayerModel name="$parentModelLeft" parentKey="ModelLeft" frameStrata="HIGH">
+                <Size y="1"/>
+                <Anchors>
+                    <Anchor point="TOPLEFT" relativePoint="TOPLEFT" x="-250" y="-300" />
+                    <Anchor point="BOTTOMRIGHT" relativePoint="BOTTOM" x="0" y="300" />
+                </Anchors>
+            </PlayerModel>
+            <PlayerModel name="$parentModelRight" parentKey="ModelRight" frameStrata="HIGH">
+                <Size y="1"/>
+                <Anchors>
+                    <Anchor point="TOPRIGHT" relativePoint="TOPRIGHT" x="250" y="-300" />
+                    <Anchor point="BOTTOMLEFT" relativePoint="BOTTOM" x="0" y="300" />
+                </Anchors>
+            </PlayerModel>
+        </Frames>
+    </Frame>
+
+    <Frame name="SVUI_AFKFrame" hidden="true">
+        <Layers>
+            <Layer level="BACKGROUND" textureSubLevel="-7">
+                <Texture file="Interface\AddOns\SVUI_!Core\assets\backgrounds\DEFAULT">
+                    <Anchors>
+                        <Anchor point="TOPLEFT" relativePoint="TOPLEFT" x="0" y="0" />
+                        <Anchor point="BOTTOMRIGHT" relativePoint="TOPRIGHT" x="0" y="-64" />
+                    </Anchors>
+                    <Color r="0" g="0" b="0" a="0.8" />
+                </Texture>
+                <Texture file="Interface\AddOns\SVUI_!Core\assets\backgrounds\DEFAULT">
+                    <Anchors>
+                        <Anchor point="BOTTOMLEFT" relativePoint="BOTTOMLEFT" x="0" y="0" />
+                        <Anchor point="TOPRIGHT" relativePoint="BOTTOMRIGHT" x="0" y="90" />
+                    </Anchors>
+                    <Color r="0" g="0" b="0" a="0.8" />
+                </Texture>
+            </Layer>
+            <Layer level="BACKGROUND">
+                <Texture parentKey="BG" file="Interface\AddOns\SVUI_!Core\assets\textures\Doodads\AFK-BG">
+                    <Size x="600" y="600"/>
+                    <Anchors>
+                        <Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMRIGHT" x="0" y="0" />
+                    </Anchors>
+                    <Color r="0" g="0" b="0" a="1" />
+                </Texture>
+            </Layer>
+        </Layers>
+        <Frames>
+            <PlayerModel name="$parentModel" parentKey="Model" frameStrata="HIGH">
+                <Size x="600" y="600"/>
+                <Anchors>
+                    <Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMRIGHT" />
+                </Anchors>
+            </PlayerModel>
+        </Frames>
+    </Frame>
+
+    <Frame name="SVUI_BoozedUpFrame" parent="UIParent" setAllPoints="true" hidden="true">
+        <Frames>
+            <PlayerModel name="$parentScreenEffect1" parentKey="ScreenEffect1" frameStrata="BACKGROUND" setAllPoints="true" />
+            <PlayerModel name="$parentScreenEffect2" parentKey="ScreenEffect2" frameStrata="BACKGROUND">
+                <Anchors>
+                    <Anchor point="BOTTOMLEFT" relativePoint="BOTTOMLEFT" x="0" y="0" />
+                </Anchors>
+            </PlayerModel>
+            <PlayerModel name="$parentScreenEffect3" parentKey="ScreenEffect3" frameStrata="BACKGROUND">
+                <Anchors>
+                    <Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMRIGHT" x="0" y="0" />
+                </Anchors>
+            </PlayerModel>
+            <Frame name="$parentYeeHaw" parentKey="YeeHaw" frameStrata="DIALOG">
+                <Size x="256" y="128"/>
+                <Anchors>
+                    <Anchor point="TOP" relativeTo="$parent" relativePoint="TOP" x="0" y="-50" />
+                </Anchors>
+                <Layers>
+                    <Layer level="ARTWORK">
+                        <Texture parentKey="tex" file="Interface\AddOns\SVUI_!Core\assets\textures\Doodads\DRUNK-PARTYTIME" setAllPoints="true" />
+                    </Layer>
+                </Layers>
+            </Frame>
+        </Frames>
+    </Frame>
+
+    <StatusBar name="SVUI_ThreatOMeter" frameStrata="DIALOG" hidden="true" />
+
+    <Frame name="SVUI_ComixFrame" frameStrata="DIALOG" hidden="true" />
+
+    <Frame name="SVUI_ComixPopup1" frameStrata="DIALOG" hidden="true">
+        <Size x="100" y="100"/>
+        <Anchors>
+            <Anchor point="CENTER" relativePoint="CENTER" x="0" y="0" />
+        </Anchors>
+        <Layers>
+            <Layer level="ARTWORK">
+                <Texture parentKey="tex" file="Interface\AddOns\SVUI_!Core\assets\textures\Doodads\COMICS-TYPE1" setAllPoints="true" />
+            </Layer>
+        </Layers>
+    </Frame>
+
+    <Frame name="SVUI_ComixPopup2" frameStrata="DIALOG" hidden="true">
+        <Size x="100" y="100"/>
+        <Anchors>
+            <Anchor point="BOTTOM" relativePoint="BOTTOM" x="0" y="100" />
+        </Anchors>
+        <Layers>
+            <Layer level="ARTWORK">
+                <Texture parentKey="tex" file="Interface\AddOns\SVUI_!Core\assets\textures\Doodads\COMICS-TYPE2" setAllPoints="true" />
+            </Layer>
+        </Layers>
+    </Frame>
+
+    <Frame name="SVUI_ComixPopup3" frameStrata="DIALOG" hidden="true">
+        <Size x="100" y="100"/>
+        <Anchors>
+            <Anchor point="CENTER" relativePoint="CENTER" x="0" y="0" />
+        </Anchors>
+        <Layers>
+            <Layer level="ARTWORK">
+                <Texture parentKey="tex" file="Interface\AddOns\SVUI_!Core\assets\textures\Doodads\COMICS-TYPE3" setAllPoints="true" />
+            </Layer>
+        </Layers>
+        <Frames>
+            <Frame name="$parentBG" parentKey="bg" frameStrata="BACKGROUND">
+                <Size x="128" y="128"/>
+                <Anchors>
+                    <Anchor point="CENTER" relativePoint="CENTER" x="0" y="0" />
+                </Anchors>
+                <Layers>
+                    <Layer level="ARTWORK">
+                        <Texture parentKey="tex" file="Interface\AddOns\SVUI_!Core\assets\textures\Doodads\COMICS-TYPE3-BG" setAllPoints="true" />
+                    </Layer>
+                </Layers>
+            </Frame>
+        </Frames>
+    </Frame>
+
+    <Frame name="SVUI_ScriptError" movable="true" hidden="true" frameStrata="DIALOG">
+        <Size x="484" y="550"/>
+        <Anchors>
+            <Anchor point="TOPLEFT" x="80" y="-80"/>
+        </Anchors>
+        <Layers>
+            <Layer level="BACKGROUND">
+                <Texture name="$parentBG" setAllPoints="true"/>
+            </Layer>
+            <Layer level="OVERLAY">
+                <Texture name="$parentTitleBG">
+                    <Anchors>
+                        <Anchor point="TOPLEFT">
+                            <Offset x="8" y="-8"/>
+                        </Anchor>
+                        <Anchor point="BOTTOMRIGHT" relativePoint="TOPRIGHT">
+                            <Offset x="-32" y="-24"/>
+                        </Anchor>
+                    </Anchors>
+                </Texture>
+                <Texture name="$parentDialogBG">
+                    <Anchors>
+                        <Anchor point="TOPLEFT">
+                            <Offset x="8" y="-32"/>
+                        </Anchor>
+                        <Anchor point="BOTTOMRIGHT">
+                            <Offset x="-32" y="32"/>
+                        </Anchor>
+                    </Anchors>
+                </Texture>
+            </Layer>
+            <Layer level="ARTWORK">
+                <FontString parentKey="Title" inherits="GameFontNormal">
+                    <Anchors>
+                        <Anchor point="TOPLEFT">
+                            <Offset x="8" y="-8"/>
+                        </Anchor>
+                        <Anchor point="TOPRIGHT">
+                            <Offset x="-32" y="-24"/>
+                        </Anchor>
+                    </Anchors>
+                </FontString>
+                <FontString parentKey="sourceLabel" font="GameFontNormalCenter">
+                    <Size x="140" y="16"/>
+                    <Anchors>
+                        <Anchor point="BOTTOMLEFT">
+                            <Offset x="104" y="8"/>
+                        </Anchor>
+                    </Anchors>
+                </FontString>
+            </Layer>
+        </Layers>
+        <Frames>
+            <ScrollFrame name="$parentDialog" parentKey="Dialog" inherits="MinimalScrollFrameTemplate">
+                <Size x="443" y="484"/>
+                <Anchors>
+                    <Anchor point="TOPLEFT">
+                        <Offset x="12" y="-30"/>
+                    </Anchor>
+                </Anchors>
+                <ScrollChild>
+                    <EditBox parentKey="Input" multiLine="true" letters="25000" autoFocus="false">
+                        <Size x="443" y="484"/>
+                        <Scripts>
+                            <OnCursorChanged function="ScrollingEdit_OnCursorChanged"/>
+                            <OnUpdate>
+                                ScrollingEdit_OnUpdate(self, elapsed, self:GetParent());
+                            </OnUpdate>
+                            <OnEditFocusGained>
+                                self:HighlightText(0);
+                            </OnEditFocusGained>
+                            <OnEscapePressed function="EditBox_ClearFocus"/>
+                        </Scripts>
+                        <FontString inherits="ChatFontNormal"/>
+                    </EditBox>
+                </ScrollChild>
+            </ScrollFrame>
+            <Button parentKey="Clear" inherits="UIPanelButtonTemplate" text="RESET">
+                <Size x="96" y="24"/>
+                <Anchors>
+                    <Anchor point="BOTTOMLEFT">
+                        <Offset x="8" y="4"/>
+                    </Anchor>
+                </Anchors>
+                <Scripts>
+                    <OnClick>
+                        local frame = _G["SVUI_ScriptErrorDialog"];
+                        frame.Input:SetText("");
+                        _G["SVUI"]:ResetErrors();
+                    </OnClick>
+                </Scripts>
+            </Button>
+            <Button parentKey="Close" inherits="UIPanelCloseButton">
+                <Anchors>
+                    <Anchor point="TOPRIGHT">
+                        <Offset x="-2" y="-2"/>
+                    </Anchor>
+                </Anchors>
+            </Button>
+        </Frames>
+        <Scripts>
+            <OnDragStart>
+                _G["SVUI_ScriptError"].moving = true;
+                _G["SVUI_ScriptError"]:StartMoving();
+            </OnDragStart>
+            <OnDragStop>
+                _G["SVUI_ScriptError"].moving = nil;
+                _G["SVUI_ScriptError"]:StopMovingOrSizing();
+            </OnDragStop>
+        </Scripts>
+    </Frame>
+
+    <Frame name="SVUI_ProfileInterface" movable="true" hidden="true" frameStrata="DIALOG">
+        <Size x="484" y="550"/>
+        <Anchors>
+            <Anchor point="TOPLEFT" x="80" y="-80"/>
+        </Anchors>
+        <Layers>
+            <Layer level="BACKGROUND">
+                <Texture name="$parentBG" setAllPoints="true"/>
+            </Layer>
+            <Layer level="OVERLAY">
+                <Texture name="$parentTitleBG">
+                    <Anchors>
+                        <Anchor point="TOPLEFT">
+                            <Offset x="8" y="-8"/>
+                        </Anchor>
+                        <Anchor point="BOTTOMRIGHT" relativePoint="TOPRIGHT">
+                            <Offset x="-32" y="-24"/>
+                        </Anchor>
+                    </Anchors>
+                </Texture>
+                <Texture name="$parentDialogBG">
+                    <Anchors>
+                        <Anchor point="TOPLEFT">
+                            <Offset x="8" y="-32"/>
+                        </Anchor>
+                        <Anchor point="BOTTOMRIGHT">
+                            <Offset x="-32" y="32"/>
+                        </Anchor>
+                    </Anchors>
+                </Texture>
+            </Layer>
+            <Layer level="ARTWORK">
+                <FontString parentKey="Title" inherits="GameFontNormal">
+                    <Anchors>
+                        <Anchor point="TOPLEFT">
+                            <Offset x="8" y="-8"/>
+                        </Anchor>
+                        <Anchor point="TOPRIGHT">
+                            <Offset x="-32" y="-24"/>
+                        </Anchor>
+                    </Anchors>
+                </FontString>
+                <FontString parentKey="sourceLabel" font="GameFontNormalCenter">
+                    <Size x="140" y="16"/>
+                    <Anchors>
+                        <Anchor point="BOTTOMLEFT">
+                            <Offset x="104" y="8"/>
+                        </Anchor>
+                    </Anchors>
+                </FontString>
+            </Layer>
+        </Layers>
+        <Frames>
+            <Frame name="$parentHelp">
+                <Size x="300" y="200"/>
+                <Anchors>
+                    <Anchor point="LEFT" relativePoint="RIGHT" x="6" y="0" />
+                </Anchors>
+                <Layers>
+                    <Layer level="OVERLAY">
+                        <FontString parentKey="Text" font="GameFontNormal">
+                            <Size x="290" y="190"/>
+                            <Anchors>
+                                <Anchor point="CENTER" x="0" y="0" />
+                            </Anchors>
+                        </FontString>
+                    </Layer>
+                </Layers>
+            </Frame>
+            <ScrollFrame name="$parentDialog" parentKey="Dialog" inherits="MinimalScrollFrameTemplate">
+                <Size x="443" y="484"/>
+                <Anchors>
+                    <Anchor point="TOPLEFT">
+                        <Offset x="12" y="-30"/>
+                    </Anchor>
+                </Anchors>
+                <ScrollChild>
+                    <EditBox parentKey="Input" multiLine="true" letters="100000" autoFocus="true">
+                        <Size x="443" y="484"/>
+                        <Scripts>
+                            <OnCursorChanged function="ScrollingEdit_OnCursorChanged"/>
+                            <OnUpdate>
+                                ScrollingEdit_OnUpdate(self, elapsed, self:GetParent());
+                            </OnUpdate>
+                            <OnEditFocusGained>
+                                self:HighlightText(0);
+                            </OnEditFocusGained>
+                            <OnEscapePressed function="EditBox_ClearFocus"/>
+                        </Scripts>
+                        <FontString inherits="ChatFontNormal"/>
+                    </EditBox>
+                </ScrollChild>
+            </ScrollFrame>
+            <Button parentKey="Export" inherits="UIPanelButtonTemplate" text="Generate Export Key">
+                <Size x="126" y="24"/>
+                <Anchors>
+                    <Anchor point="BOTTOMLEFT">
+                        <Offset x="8" y="4"/>
+                    </Anchor>
+                </Anchors>
+                <Scripts>
+                    <OnClick>
+                        _G["SVUI"]:ExportProfile();
+                    </OnClick>
+                </Scripts>
+            </Button>
+            <Button parentKey="Import" inherits="UIPanelButtonTemplate" text="Import From Key">
+                <Size x="126" y="24"/>
+                <Anchors>
+                    <Anchor point="BOTTOMLEFT">
+                        <Offset x="142" y="4"/>
+                    </Anchor>
+                </Anchors>
+                <Scripts>
+                    <OnClick>
+                        _G["SVUI"]:ImportProfile();
+                    </OnClick>
+                </Scripts>
+            </Button>
+            <Button parentKey="Clear" inherits="UIPanelButtonTemplate" text="Clear">
+                <Size x="126" y="24"/>
+                <Anchors>
+                    <Anchor point="BOTTOMLEFT">
+                        <Offset x="284" y="4"/>
+                    </Anchor>
+                </Anchors>
+                <Scripts>
+                    <OnClick>
+                        local dialog = _G["SVUI_ProfileInterfaceDialog"];
+                        if(dialog and dialog.Input) then
+                            dialog.Input:SetText('')
+                        end
+                    </OnClick>
+                </Scripts>
+            </Button>
+            <Button parentKey="Close" inherits="UIPanelCloseButton">
+                <Anchors>
+                    <Anchor point="TOPRIGHT">
+                        <Offset x="-2" y="-2"/>
+                    </Anchor>
+                </Anchors>
+            </Button>
+        </Frames>
+        <Scripts>
+            <OnDragStart>
+                _G["SVUI_ProfileInterface"].moving = true;
+                _G["SVUI_ProfileInterface"]:StartMoving();
+            </OnDragStart>
+            <OnDragStop>
+                _G["SVUI_ProfileInterface"].moving = nil;
+                _G["SVUI_ProfileInterface"]:StopMovingOrSizing();
+            </OnDragStop>
+        </Scripts>
+    </Frame>
+
+    <Frame name="SVUI_NPCFrame" hidden="true">
+        <Size x="384" y="512"/>
+        <Frames>
+            <PlayerModel name="$parentModel" parentKey="Model" frameStrata="HIGH">
+                <Size x="100" y="100"/>
+                <Anchors>
+                    <Anchor point="BOTTOM" relativeTo="$parent" relativePoint="TOPLEFT" x="40" y="-50" />
+                </Anchors>
+            </PlayerModel>
+        </Frames>
+    </Frame>
+</Ui>
diff --git a/SVUI_!Options/License.txt b/SVUI_!Options/License.txt
new file mode 100644
index 0000000..69d4d04
--- /dev/null
+++ b/SVUI_!Options/License.txt
@@ -0,0 +1,31 @@
+
+The MIT License
+
+Copyright (c) 2010, Failcoder (Steve Jackson)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy
+of this software and associated documentation files (the "Software"), to
+deal
+in the Software without restriction, including without limitation the
+rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN
+THE SOFTWARE.
diff --git a/SVUI_!Options/SVUI_!Options.lua b/SVUI_!Options/SVUI_!Options.lua
new file mode 100644
index 0000000..e843b6f
--- /dev/null
+++ b/SVUI_!Options/SVUI_!Options.lua
@@ -0,0 +1,2033 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pcall         = _G.pcall;
+local print         = _G.print;
+local ipairs        = _G.ipairs;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local rawset        = _G.rawset;
+local rawget        = _G.rawget;
+local tostring      = _G.tostring;
+local tonumber      = _G.tonumber;
+local getmetatable  = _G.getmetatable;
+local setmetatable  = _G.setmetatable;
+local table 	 =  _G.table;
+local wipe       =  _G.wipe;
+--[[ TABLE METHODS ]]--
+local tsort = table.sort;
+local IsAddOnLoaded         = _G.IsAddOnLoaded;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L;
+local _, SVUIOptions = ...;
+local SVUILib = Librarian("Registry");
+local AceGUI = LibStub("AceGUI-3.0", true);
+local AceConfig = LibStub("AceConfig-3.0");
+local AceConfigDialog = LibStub("AceConfigDialog-3.0");
+local AceVillainWidgets = AceVillainWidgets;
+local GameTooltip = GameTooltip;
+local GetNumEquipmentSets = GetNumEquipmentSets;
+local GetEquipmentSetInfo = GetEquipmentSetInfo;
+local sortingFunction = function(arg1, arg2) return arg1 < arg2 end
+local GUIWidth = SV.LowRez and 890 or 1090;
+local playerRealm = GetRealmName()
+local playerName = UnitName("player")
+local profileKey = ("%s - %s"):format(playerName, playerRealm)
+local NONE = _G.NONE;
+local GetSpellInfo = _G.GetSpellInfo;
+local collectgarbage = _G.collectgarbage;
+
+local allFilterTable, userFilterTable, tempFilterTable = {},{},{};
+local CURRENT_FILTER_TYPE = NONE;
+
+AceConfig:RegisterOptionsTable(SV.NameID, SV.Options);
+AceConfigDialog:SetDefaultSize(SV.NameID, GUIWidth, 651);
+
+SVUIOptions.FilterOptionGroups = {};
+SVUIOptions.FilterOptionSpells = {};
+--[[
+##########################################################
+INIT OPTIONS
+##########################################################
+]]--
+local function RefreshProfileOptions()
+	local hasProfile = true;
+	local currentProfile = SVUILib:CurrentProfile()
+	if(not currentProfile) then
+		hasProfile = false
+		currentProfile = profileKey
+	end
+	SV.Options.args.profiles.desc = " |cff66FF33" .. L["current"] .. currentProfile .. "|r";
+	local optionGroup = SV.Options.args.profiles.args
+
+	optionGroup.common = {
+		order = 1,
+		type = "group",
+		name = L["Profile Behavior"],
+		guiInline = true,
+		args = {
+			spacer1 = {
+				order = 1,
+				type = "description",
+				name = "|cff66FF33" .. L["current"] .. currentProfile .. "|r",
+				width = "full",
+			},
+			spacer2 = {
+				order = 2,
+				type = "description",
+				name = "",
+				width = "full",
+			},
+			dualSpec = {
+				order = 3,
+				type = "toggle",
+				name = "Dual-Spec Switching",
+				get = function() return SVUILib:CheckDualProfile() end,
+				set = function(key, value) SVUILib:ToggleDualProfile(value) end
+			},
+			mpEnable = {
+				order = 4,
+				type = "toggle",
+				name = "Enable Master Profile",
+				desc = L["Toggle the use of a master profile. You can assign any profile as a master for easy one-click installation on your other characters."],
+				get = function()
+					local mp = SVUILib:CheckMasterProfile()
+					if(type(mp) == 'string') then
+						return true
+					else
+						return false
+					end
+				end,
+				set = function(key, value)
+					if(not value) then
+						SVUILib:SetMasterProfile()
+					else
+						SVUILib:SetMasterProfile(currentProfile)
+					end
+					SV:SavedPopup()
+					RefreshProfileOptions()
+				end,
+			},
+			mpSelect = {
+				order = 5,
+				type = "select",
+				name = "Select Master Profile",
+				desc = L["Select any of your known profiles to use as the master."],
+				get = function() return SVUILib:CheckMasterProfile() end,
+				set = function(key, value) SVUILib:SetMasterProfile(value) SV:SavedPopup() RefreshProfileOptions() end,
+				values = SVUILib:GetProfiles(),
+				disabled = function()
+					local t = SVUILib:CheckMasterProfile()
+					return (not t)
+				end,
+			},
+			profileInterface = {
+				order = 6,
+				type = "execute",
+				name = L["Advanced Import/Export Tool"],
+				desc = L["If you would like to (import/export) your profile (from/to) another computer then use this advanced profile tool."],
+				func = function() SV.ProfileInterface:Toggle() end,
+			}
+		},
+	}
+
+	optionGroup.sharing = {
+		order = 2,
+		type = "group",
+		name = L["Shared Settings"],
+		guiInline = true,
+		args = SV:GenerateSharedProfileOptions(),
+	}
+	optionGroup.actions = {
+		order = 3,
+		type = "group",
+		name = L["Profile Actions"],
+		guiInline = true,
+		args = {
+			importdesc = {
+				order = 1,
+				type = "description",
+				name = function()
+					if(SVUILib:CheckDualProfile()) then
+						return L["Can not Save, Copy or Change while dual spec swapping is enabled"] .. "\n";
+					else
+						return L["import_desc"] .. "\n";
+					end
+				end,
+				width = "full"
+			},
+			spacer1 = {
+				order = 2,
+				type = "description",
+				name = "",
+				width = "full",
+			},
+			export = {
+				order = 3,
+				name = L["export"],
+				desc = L["export_sub"],
+				type = "input",
+				get = false,
+				set = function(key, value) SVUILib:CloneDatabase(value) SV:SavedPopup() RefreshProfileOptions() end,
+				disabled = function()
+					local t = SVUILib:CheckProfiles()
+					return ((not t) or SVUILib:CheckDualProfile())
+				end,
+			},
+			copy = {
+				order = 4,
+				name = L["Copy"],
+				desc = L["Copy from another profile. Further changes from other characters using this profile will not affect this one."],
+				type = "select",
+				get = function() return currentProfile end,
+				set = function(key, value) SV:CopyProfile(value) SV:SavedPopup() RefreshProfileOptions() end,
+				disabled = function()
+					local t = SVUILib:CheckProfiles()
+					return ((not t) or SVUILib:CheckDualProfile())
+				end,
+				values = SVUILib:GetProfiles(),
+			},
+			import = {
+				order = 5,
+				name = L["Share"],
+				desc = L["Share an already existing profile. Changes made by any characters using this profile will be shared."],
+				type = "select",
+				get = function() return currentProfile end,
+				set = function(key, value) SV:LinkProfile(value) SV:SavedPopup() RefreshProfileOptions() end,
+				disabled = function()
+					local t = SVUILib:CheckProfiles()
+					return ((not t) or SVUILib:CheckDualProfile())
+				end,
+				values = SVUILib:GetProfiles(),
+				width = 'fill',
+			},
+		},
+	}
+	optionGroup.resetting = {
+		order = 4,
+		type = "group",
+		name = L["Profile Reset"],
+		guiInline = true,
+		args = {
+			spacer1 = {
+				order = 1,
+				type = "description",
+				name = L["reset_desc"] .. "\n",
+				width = "full",
+			},
+			reset = {
+				order = 2,
+				type = "execute",
+				name = function() return L["reset"] .. " " .. " |cffFFFF00" .. currentProfile .. "|r" end,
+				desc = L["reset_sub"],
+				func = function() SV:StaticPopup_Show("RESET_PROFILE_PROMPT") end,
+				width = 'full'
+			},
+		}
+	}
+	optionGroup.removal = {
+		order = 5,
+		type = "group",
+		name = L["Profile Removal"],
+		guiInline = true,
+		args = {
+			spacer1 = {
+				order = 1,
+				type = "description",
+				name = L["delete_desc"] .. "\n",
+				width = "full",
+			},
+			delete = {
+				order = 2,
+				type = "select",
+				width = "full",
+				name = L["delete"],
+				desc = L["delete_sub"],
+				get = function() return " SELECT ONE" end,
+				set = function(key, value) SVUILib:Remove(value) end,
+				values = SVUILib:GetProfiles(),
+				disabled = function() local t = SVUILib:CheckProfiles() return (not t) end,
+				confirm = true,
+				confirmText = L["delete_confirm"],
+			}
+		}
+	}
+end
+
+function SVUIOptions:SetToFontConfig(font)
+	font = font or "Default";
+	AceConfigDialog:SelectGroup(SV.NameID, "Fonts", "fontGroup", font);
+end
+
+local function GetUserFilterList()
+	wipe(userFilterTable);
+	userFilterTable[""] = NONE;
+	for filter in pairs(SV.db.Filters.Custom) do
+		userFilterTable[filter] = filter
+	end
+	return userFilterTable
+end
+
+local function GetAllFilterList()
+	wipe(allFilterTable);
+	allFilterTable[""] = NONE;
+	for filter in pairs(SV.db.Filters) do
+		if(filter == 'Raid') then
+			allFilterTable[filter] = "Consolidated"
+		elseif(filter ~= 'Custom') then
+			allFilterTable[filter] = filter
+		end
+	end
+	for filter in pairs(SV.db.Filters.Custom) do
+		allFilterTable[filter] = filter
+	end
+	return allFilterTable
+end
+
+function SVUIOptions:SetFilterOptions(filterType, selectedSpell)
+	local FILTER
+	CURRENT_FILTER_TYPE = filterType
+	if(SV.db.Filters.Custom[filterType]) then
+		FILTER = SV.db.Filters.Custom[filterType]
+	else
+		FILTER = SV.db.Filters[filterType]
+	end
+	if((not filterType) or (filterType == "") or (not FILTER)) then
+		SV.Options.args.Filters.args.filterGroup = nil;
+		SV.Options.args.Filters.args.spellGroup = nil;
+		return
+	end
+	if(not self.FilterOptionGroups[filterType]) then
+		self.FilterOptionGroups[filterType] = self.FilterOptionGroups['_NEW'](filterType);
+	end
+	SV.Options.args.Filters.args.filterGroup = self.FilterOptionGroups[filterType](selectedSpell)
+	if(not self.FilterOptionSpells[filterType]) then
+		self.FilterOptionSpells[filterType] = self.FilterOptionSpells['_NEW'](filterType);
+	end
+	SV.Options.args.Filters.args.spellGroup = self.FilterOptionSpells[filterType](selectedSpell);
+	SV.Events:Trigger("AURA_FILTER_OPTIONS_CHANGED");
+	collectgarbage("collect")
+end
+
+
+function SVUIOptions:SetToFilterConfig(newFilter)
+	local filter = newFilter or "BuffWatch";
+	self:SetFilterOptions(filter);
+	_G.LibStub("AceConfigDialog-3.0"):SelectGroup(SV.NameID, "Filters");
+end
+
+local generalFonts = {
+	["default"] = {
+		order = 1,
+		name = "Default",
+		desc = "Standard font for the majority of uses."
+	},
+	["dialog"] = {
+		order = 2,
+		name = "Dialog",
+		desc = "Font used in places that story text appears. (ie.. quest text)"
+	},
+	["combat"] = {
+		order = 3,
+		name = "Combat",
+		desc = "Scrolling combat text font."
+	},
+	["alert"] = {
+		order = 4,
+		name = "Alerts",
+		desc = "Font used for on-screen message alerts."
+	},
+	["zone"] = {
+		order = 5,
+		name = "Zone Text",
+		desc = "Font used for zone names. Shown when changing zones."
+	},
+	["title"] = {
+		order = 6,
+		name = "Titles",
+		desc = "Font used to display various titles."
+	},
+	["header"] = {
+		order = 7,
+		name = "Frame Headers",
+		desc = "Font used to large names at the top of some frames."
+	},
+	["caps"] = {
+		order = 8,
+		name = "Caps",
+		desc = "Font typically used for things like tabs and fitted headers."
+	},
+};
+local numberFonts = {
+	["number"] = {
+		order = 1,
+		name = "Numbers (Regular)",
+		desc = "Font used to display most numeric values."
+	},
+	["number_big"] = {
+		order = 2,
+		name = "Numbers (Large)",
+		desc = "Font used to display larger numeric values."
+	},
+	["aura"]   = {
+		order = 3,
+		name = "Auras",
+		desc = "Aura counts and timers use this font."
+	},
+};
+local lootFonts = {
+	["lootdialog"] = {
+		order = 1,
+		name = "Loot Frame Dialog",
+		desc = "Default font used in the loot frame"
+	},
+    ["lootnumber"] = {
+		order = 2,
+		name = "Loot Frame Numbers",
+		desc = "Font used in the loot frame to display numeric values."
+	},
+	["rolldialog"] = {
+		order = 3,
+		name = "Roll Frame Dialog",
+		desc = "Default font used in the loot-roll frame"
+	},
+    ["rollnumber"] = {
+		order = 4,
+		name = "Roll Frame Numbers",
+		desc = "Font used in the loot-roll frame to display numeric values."
+	},
+};
+local miscFonts = {
+	["data"] = {
+		order = 1,
+		name = "Docked Stats",
+		desc = "Font used by the bottom and top data docks."
+	},
+	["narrator"] = {
+		order = 2,
+		name = "Narratives",
+		desc = "Font used for things like the 'Meanwhile' tag."
+	},
+	["pixel"] = {
+		order = 3,
+		name = "Pixel",
+		desc = "Tiniest fonts."
+	},
+};
+
+SV.Options.args.primary = {
+	type = "group",
+	order = 1,
+	name = L["Main"],
+	get = function(j) return SV.db[j[#j]] end,
+	set = function(j, value) SV.db[j[#j]] = value end,
+	args = {
+		introGroup1 = {
+			order = 1,
+			name = "",
+			type = "description",
+			width = "full",
+			image = function() return SV.SplashImage, 256, 128 end,
+		},
+		introGroup2 = {
+			order = 2,
+			name = L["Here are a few basic quick-change options to possibly save you some time."],
+			type = "description",
+			width = "full",
+			fontSize = "large",
+		},
+		quickGroup1 = {
+			order = 3,
+			name = "",
+			type = "group",
+			width = "full",
+			guiInline = true,
+			args = {
+				Install = {
+					order = 1,
+					width = "full",
+					type = "execute",
+					name = L["Install"],
+					desc = L["Run the installation process."],
+					func = function() SV.Setup:LoadInstaller() SV:ToggleConfig() end
+				},
+				Themes = {
+					order = 2,
+					width = "full",
+					type = "execute",
+					name = L["Themes"],
+					desc = L["Select an available theme."],
+					func = function() SV.Setup:SelectTheme() SV:ToggleConfig() end
+				},
+				Backdrops = {
+					order = 3,
+					width = "full",
+					type = "execute",
+					name = L["Backdrops"],
+					desc = L["Change all backdrop art randomly."],
+					func = function() SV.Setup:RandomBackdrops() end
+				},
+				ToggleAnchors = {
+					order = 4,
+					width = "full",
+					type = "execute",
+					name = L["Move Frames"],
+					desc = L["Unlock various elements of the UI to be repositioned."],
+					func = function() SV:MoveAnchors() end
+				},
+				ResetMoveables = {
+					order = 5,
+					width = "full",
+					type = "execute",
+					name = L["Reset SVUI Anchors"],
+					desc = L["Reset all movable frames to their original positions."],
+					func = function() SV:StaticPopup_Show("RESETLAYOUT_CHECK") end
+				},
+				ResetDraggables = {
+					order = 6,
+					width = "full",
+					type = "execute",
+					name = L["Reset Blizzard Anchors"],
+					desc = L["Reset all draggable Blizzard frames to their original positions."],
+					func = function() SV:StaticPopup_Show("RESETBLIZZARD_CHECK") end
+				},
+			},
+		},
+	}
+}
+
+SV.Options.args.Core = {
+	type = "group",
+	order = 2,
+	name = L['General Options'],
+	childGroups = "tab",
+	get = function(key) return SV.db[key[#key]] end,
+	set = function(key, value) SV.db[key[#key]] = value end,
+	args = {}
+}
+
+SV.Options.args.Core.args.mostCommon = {
+	type = "group",
+	order = 1,
+	name = "Most Common",
+	guiInline = true,
+	args = {
+		LoginMessage = {
+			order = 1,
+			type = 'toggle',
+			name = L['Login Messages'],
+			get = function(j)return SV.db.general.loginmessage end,
+			set = function(j,value)SV.db.general.loginmessage = value end
+		},
+		LoginCredits = {
+			order = 2,
+			type = 'toggle',
+			name = L['Login Credits'],
+			get = function(j)return SV.db.general.logincredits end,
+			set = function(j,value)SV.db.general.logincredits = value end
+		},
+		useDraggable = {
+			order = 3,
+			type = "toggle",
+			name = L["Enable Draggable"],
+			desc = L["Allow many default Blizzard frames to be draggable"],
+			get = function(j)return SV.db.general.useDraggable end,
+			set = function(j,value)SV.db.general.useDraggable = value; SV:StaticPopup_Show("RL_CLIENT") end
+		},
+		saveDraggable = {
+			order = 4,
+			type = "toggle",
+			name = L["Save Draggable"],
+			desc = L["Save the positions of draggable frames when they are moved. NOTE: THIS WILL OVERRIDE BLIZZARD FRAME SNAPPING!"],
+			get = function(j)return SV.db.general.saveDraggable end,
+			set = function(j,value)SV.db.general.saveDraggable = value; SV:StaticPopup_Show("RL_CLIENT") end
+		},
+		cooldownText = {
+			order = 5,
+			type = "toggle",
+			name = L['Cooldown Text'],
+			desc = L["Display cooldown text on anything with the cooldown spiral."],
+			get = function(j)return SV.db.general.cooldown end,
+			set = function(j,value)SV.db.general.cooldown = value; SV:StaticPopup_Show("RL_CLIENT")end
+		},
+		texture = {
+			order = 6,
+			type = "group",
+			name = L["Textures"],
+			guiInline = true,
+			get = function(key)
+				return SV.media.shared.background[key[#key]].file
+			end,
+			set = function(key, value)
+				SV.media.shared.background[key[#key]].file = value
+				SV:RefreshEverything(true)
+			end,
+			args = {
+				default = {
+					type = "select",
+					dialogControl = 'LSM30_Background',
+					order = 1,
+					name = L["Primary Texture"],
+					desc = L["Used on almost every frame of this UI."],
+					values = AceVillainWidgets.background
+				},
+				pattern = {
+					type = "select",
+					dialogControl = 'LSM30_Background',
+					order = 2,
+					name = L["Secondary Texture"],
+					desc = L["Used on most patterned frames."],
+					values = AceVillainWidgets.background
+				},
+				model = {
+					type = "select",
+					dialogControl = 'LSM30_Background',
+					order = 3,
+					name = L["ModelFrame Texture"],
+					desc = L["Used behind 3D model frames. (ie..Dressing Room, Character, Pet, and Mount displays)"],
+					values = AceVillainWidgets.background
+				},
+				premium = {
+					type = "select",
+					dialogControl = 'LSM30_Background',
+					order = 4,
+					name = L["Unique Texture"],
+					desc = L["Used in special areas. (ie..Glyphs BG)"],
+					values = AceVillainWidgets.background
+				},
+			}
+		},
+		colors = {
+			order = 7,
+			type = "group",
+			name = L["Colors"],
+			guiInline = true,
+			args = {
+				customClassColor = {
+					type = "toggle",
+					order = 1,
+					name = L["Use Custom Class Colors"],
+					desc = L["Use the enhanced class colors provided by SVUI"],
+					get = function(key) return SV.db.general.customClassColor end,
+					set = function(key, value) SV.db.general.customClassColor = value; SV:StaticPopup_Show("RL_CLIENT") end,
+				},
+				default = {
+					type = "color",
+					order = 2,
+					name = L["Primary Color"],
+					desc = L["Main color used by most UI elements. (ex: Backdrop Color)"],
+					hasAlpha = true,
+					get = function(key)
+						local color = SV.media.color.default
+						return color[1],color[2],color[3],color[4]
+					end,
+					set = function(key, rValue, gValue, bValue, aValue)
+						SV.media.color.default = {rValue, gValue, bValue, aValue}
+						SV:UpdateSharedMedia()
+					end,
+				},
+				secondary = {
+					type = "color",
+					order = 3,
+					name = L["Secondary Color"],
+					desc = L["Color used as contrast in multi-colored frames."],
+					hasAlpha = true,
+					get = function(key)
+						local color = SV.media.color.secondary
+						return color[1],color[2],color[3],color[4]
+					end,
+					set = function(key, rValue, gValue, bValue, aValue)
+						SV.media.color.secondary = {rValue, gValue, bValue, aValue}
+						SV:UpdateSharedMedia()
+					end,
+				},
+				special = {
+					type = "color",
+					order = 4,
+					name = L["Accent Color"],
+					desc = L["Color used in various frame accents.  (ex: Dressing Room Backdrop Color)"],
+					hasAlpha = true,
+					get = function(key)
+						local color = SV.media.color.special
+						return color[1],color[2],color[3],color[4]
+					end,
+					set = function(key, rValue, gValue, bValue, aValue)
+						SV.media.color.special = {rValue, gValue, bValue, aValue}
+						SV.media.color.specialdark = {(rValue * 0.75), (gValue * 0.75), (bValue * 0.75), aValue}
+						SV:UpdateSharedMedia()
+					end,
+				},
+				resetbutton = {
+					type = "execute",
+					order = 5,
+					name = L["Restore Defaults"],
+					func = function()
+						SV.media.color.default = {0.15, 0.15, 0.15, 1};
+						SV.media.color.secondary = {0.2, 0.2, 0.2, 1};
+						SV.media.color.special = {0.37, 0.32, 0.29, 1};
+						SV:UpdateSharedMedia()
+					end
+				}
+			}
+		},
+		loot = {
+			order = 8,
+			type = "toggle",
+			name = L['Loot Frame'],
+			desc = L['Enable/Disable the loot frame.'],
+			get = function()return SV.db.general.loot end,
+			set = function(j,value)SV.db.general.loot = value;SV:StaticPopup_Show("RL_CLIENT")end
+		},
+		lootRoll = {
+			order = 9,
+			type = "toggle",
+			name = L['Loot Roll'],
+			desc = L['Enable/Disable the loot roll frame.'],
+			get = function()return SV.db.general.lootRoll end,
+			set = function(j,value)SV.db.general.lootRoll = value;SV:StaticPopup_Show("RL_CLIENT")end
+		},
+		lootRollWidth = {
+			order = 10,
+			type = 'range',
+			width = "full",
+			name = L["Roll Frame Width"],
+			min = 100,
+			max = 328,
+			step = 1,
+			get = function()return SV.db.general.lootRollWidth end,
+			set = function(a,b) SV.db.general.lootRollWidth = b; end,
+		},
+		lootRollHeight = {
+			order = 11,
+			type = 'range',
+			width = "full",
+			name = L["Roll Frame Height"],
+			min = 14,
+			max = 58,
+			step = 1,
+			get = function()return SV.db.general.lootRollHeight end,
+			set = function(a,b) SV.db.general.lootRollHeight = b; end,
+		},
+	}
+};
+
+SV.Options.args.Core.args.Extras = {
+	type = "group",
+	order = 2,
+	name = "Extras",
+	guiInline = true,
+	get = function(a)return SV.db["Extras"][a[#a]]end,
+	set = function(a,b)SV:ChangeDBVar(b,a[#a]); end,
+	args = {
+		common = {
+			order = 1,
+			type = "group",
+			name = L["General"],
+			guiInline = true,
+			args = {
+				threatbar = {
+					order = 1,
+					type = 'toggle',
+					name = L["Threat Thermometer"],
+					desc = L["Enable/disable the custom SVUI threat meter"],
+					get = function(j)return SV.db["Extras"].threatbar end,
+					set = function(j,value)SV.db["Extras"].threatbar = value; SV:StaticPopup_Show("RL_CLIENT") end
+				},
+				woot = {
+					order = 2,
+					type = 'toggle',
+					name = L["Say Thanks"],
+					desc = L["Thank someone when they cast specific spells on you. Typically resurrections"],
+					get = function(j)return SV.db["Extras"].woot end,
+					set = function(j,value)SV.db["Extras"].woot = value;SV:ToggleReactions()end
+				},
+				pvpinterrupt = {
+					order = 3,
+					type = 'toggle',
+					name = L["Report PVP Actions"],
+					desc = L["Announce your interrupts, as well as when you have been sapped!"],
+					get = function(j)return SV.db["Extras"].pvpinterrupt end,
+					set = function(j,value)SV.db["Extras"].pvpinterrupt = value;SV:ToggleReactions()end
+				},
+				lookwhaticando = {
+					order = 4,
+					type = 'toggle',
+					name = L["Report Spells"],
+					desc = L["Announce various helpful spells cast by players in your party/raid"],
+					get = function(j)return SV.db["Extras"].lookwhaticando end,
+					set = function(j,value)SV.db["Extras"].lookwhaticando = value;SV:ToggleReactions()end
+				},
+				sharingiscaring = {
+					order = 5,
+					type = 'toggle',
+					name = L["Report Shareables"],
+					desc = L["Announce when someone in your party/raid has laid a feast or repair bot"],
+					get = function(j)return SV.db["Extras"].sharingiscaring end,
+					set = function(j,value)SV.db["Extras"].sharingiscaring = value;SV:ToggleReactions()end
+				},
+				reactionChat = {
+					order = 6,
+					type = 'toggle',
+					name = L["Report in Chat"],
+					desc = L["Announcements will be sent to group chat channels"],
+					get = function(j)return SV.db["Extras"].reactionChat end,
+					set = function(j,value)SV.db["Extras"].reactionChat = value;SV:ToggleReactions()end
+				},
+				reactionEmote = {
+					order = 7,
+					type = 'toggle',
+					name = L["Auto Emotes"],
+					desc = L["Some announcements are accompanied by player emotes."],
+					get = function(j)return SV.db["Extras"].reactionEmote end,
+					set = function(j,value)SV.db["Extras"].reactionEmote = value;SV:ToggleReactions()end
+				},
+			}
+		},
+		automations = {
+			order = 2,
+			type = "group",
+			name = L["Automations"],
+			guiInline = true,
+			args = {
+				intro = {
+					order = 1,
+					type = "description",
+					name = L["Adjust the behavior of the many automations."]
+				},
+				automationGroup1 = {
+					order = 2,
+					type = "group",
+					guiInline = true,
+					name = L["Task Minions"],
+					desc = L['Minions that can make certain tasks easier by handling them automatically.'],
+					args = {
+						mailOpener = {
+							order = 1,
+							type = 'toggle',
+							name = L["Enable Mail Helper"],
+							get = function(j) return SV.db["Extras"].mailOpener end,
+							set = function(j,value) SV.db["Extras"].mailOpener = value; SV:ToggleMailMinions() end
+						},
+						autoAcceptInvite = {
+							order = 2,
+							name = L['Accept Invites'],
+							desc = L['Automatically accept invites from guild/friends.'],
+							type = 'toggle',
+							get = function(j) return SV.db["Extras"].autoAcceptInvite end,
+							set = function(j,value) SV.db["Extras"].autoAcceptInvite = value end
+						},
+						vendorGrays = {
+							order = 3,
+							name = L['Vendor Grays'],
+							desc = L['Automatically vendor gray items when visiting a vendor.'],
+							type = 'toggle',
+							get = function(j) return SV.db["Extras"].vendorGrays end,
+							set = function(j,value) SV.db["Extras"].vendorGrays = value end
+						},
+						pvpautorelease = {
+							order = 4,
+							type = "toggle",
+							name = L['PvP Autorelease'],
+							desc = L['Automatically release body when killed inside a battleground.'],
+							get = function(j) return SV.db["Extras"].pvpautorelease end,
+							set = function(j,value) SV.db["Extras"].pvpautorelease = value; SV:StaticPopup_Show("RL_CLIENT") end
+						},
+						autorepchange = {
+							order = 5,
+							type = "toggle",
+							name = L['Track Reputation'],
+							desc = L['Automatically change your watched faction on the reputation bar to the faction you got reputation points for.'],
+							get = function(j)return SV.db["Extras"].autorepchange end,
+							set = function(j,value)SV.db["Extras"].autorepchange = value end
+						},
+						skipcinematics = {
+							order = 6,
+							type = "toggle",
+							name = L['Skip Cinematics'],
+							desc = L['Automatically skip any cinematic sequences.'],
+							get = function(j)return SV.db["Extras"].skipcinematics end,
+							set = function(j,value) SV.db["Extras"].skipcinematics = value; SV:StaticPopup_Show("RL_CLIENT") end
+						},
+						autoRepair = {
+							order = 7,
+							name = L['Auto Repair'],
+							desc = L['Automatically repair using the following method when visiting a merchant.'],
+							type = 'select',
+							values = {
+								['NONE'] = NONE,
+								['GUILD'] = GUILD,
+								['PLAYER'] = PLAYER
+							},
+							get = function(j)return SV.db["Extras"].autoRepair end,
+							set = function(j,value)SV.db["Extras"].autoRepair = value end
+						},
+					}
+				},
+				automationGroup2 = {
+					order = 3,
+					type = "group",
+					guiInline = true,
+					name = L["Looting Minions"],
+					desc = L['Minions that can make looting easier by rolling automatically.'],
+					get = function(key) return SV.db.Extras[key[#key]] end,
+					set = function(key,value) SV.db.Extras[key[#key]] = value; SV.Events:Trigger("LOOTING_UPVALUES_UPDATED"); end,
+					disabled = function() return not SV.db.general.lootRoll end,
+					args = {
+						autoRoll = {
+							order = 1,
+							name = L['Auto Greed'],
+							desc = L['Automatically select greed on loot rolls.'],
+							type = 'toggle',
+						},
+						autoRollDisenchant = {
+							order = 2,
+							name = L['Auto Disenchant'],
+							desc = L['"Auto Greed" will select disenchant (when available).'],
+							type = 'toggle',
+						},
+						autoRollMaxLevel = {
+							order = 3,
+							name = L['Only Max Level'],
+							desc = L['When set, "Auto Greed" will only operate if you are at max player level.'],
+							type = 'toggle',
+						},
+						autoRollSoulbound = {
+							order = 4,
+							name = L['Allow Soulbound'],
+							desc = L['When set, "Auto Greed" will include items that are BoP.'],
+							type = 'toggle',
+						},
+						autoRollQuality = {
+							order = 5,
+							name = L['Max Quality'],
+							desc = L['Set the highest item quality that "Auto Greed" will activate on.'],
+							type = 'select',
+							values = {
+								['2'] = ITEM_QUALITY2_DESC,
+								['3'] = ITEM_QUALITY3_DESC,
+								['4'] = ITEM_QUALITY4_DESC
+							},
+						},
+					}
+				},
+				automationGroup3 = {
+					order = 4,
+					type = "group",
+					guiInline = true,
+					name = L["Quest Minions"],
+					desc = L['Minions that can make questing easier by automatically accepting/completing quests.'],
+					args = {
+						autoquestaccept = {
+							order = 1,
+							type = "toggle",
+							name = L['Accept Quests'],
+							desc = L['Automatically accepts quests as they are presented to you.'],
+							get = function(j)return SV.db["Extras"].autoquestaccept end,
+							set = function(j,value) SV.db["Extras"].autoquestaccept = value end
+						},
+						autoquestcomplete = {
+							order = 2,
+							type = "toggle",
+							name = L['Complete Quests'],
+							desc = L['Automatically complete quests when possible.'],
+							get = function(j)return SV.db["Extras"].autoquestcomplete end,
+							set = function(j,value)SV.db["Extras"].autoquestcomplete = value end
+						},
+						autoquestreward = {
+							order = 3,
+							type = "toggle",
+							name = L['Select Quest Reward'],
+							desc = L['Automatically select the quest reward with the highest vendor sell value.'],
+							get = function(j)return SV.db["Extras"].autoquestreward end,
+							set = function(j,value)SV.db["Extras"].autoquestreward = value end
+						},
+						autodailyquests = {
+							order = 4,
+							type = "toggle",
+							name = L['Only Automate Dailies'],
+							desc = L['Force the auto accept functions to only respond to daily quests. NOTE: This does not apply to daily heroics for some reason.'],
+							get = function(j)return SV.db["Extras"].autodailyquests end,
+							set = function(j,value)SV.db["Extras"].autodailyquests = value end
+						},
+						autopvpquests = {
+							order = 5,
+							type = "toggle",
+							name = L['Accept PVP Quests'],
+							get = function(j)return SV.db["Extras"].autopvpquests end,
+							set = function(j,value)SV.db["Extras"].autopvpquests = value end
+						},
+					}
+				},
+			}
+		},
+		FunStuff = {
+			type = "group",
+			order = 12,
+			name = L["Fun Stuff"],
+			guiInline = true,
+			args = {
+				drunk = {
+					order = 1,
+					type = 'toggle',
+					name = L["Drunk Mode"],
+					get = function(j)return SV.db.FunStuff.drunk end,
+					set = function(j,value) SV.db.FunStuff.drunk = value; SV.Drunk:Toggle() end,
+				},
+				NPC = {
+					order = 2,
+					type = 'toggle',
+					width = "full",
+					name = L["Gossip/Quest/Merchant Models"],
+					get = function(j)return SV.db.FunStuff.NPC end,
+					set = function(j,value) SV.db.FunStuff.NPC = value; end,
+				},
+				comix = {
+					order = 3,
+					type = 'select',
+					name = L["Comic Popups"],
+					desc = '"All Popups" will include non-comic styles (ie.. TOASTY!)',
+					get = function(j)return SV.db.FunStuff.comix end,
+					set = function(j,value) SV.db.FunStuff.comix = value; SV.Comix:Toggle() end,
+					values = {
+						['NONE'] = NONE,
+						['1'] = 'All Popups',
+						['2'] = 'Comic Style Only',
+					}
+				},
+				afk = {
+					order = 4,
+					type = 'select',
+					name = L["AFK Screen"],
+					get = function(j)return SV.db.FunStuff.afk end,
+					set = function(j,value) SV.db.FunStuff.afk = value; SV.AFK:Toggle() end,
+					values = {
+						['NONE'] = NONE,
+						['1'] = 'Fully Enabled',
+						['2'] = 'Enabled (No Spinning)',
+					}
+				},
+				gamemenu = {
+					order = 5,
+					type = 'select',
+					name = L["Game Menu"],
+					get = function(j)return SV.db.FunStuff.gamemenu end,
+					set = function(j,value) SV.db.FunStuff.gamemenu = value; SV:StaticPopup_Show("RL_CLIENT") end,
+					values = {
+						['NONE'] = NONE,
+						['1'] = 'You + Henchman',
+						['2'] = 'You x2',
+					}
+				},
+			}
+		},
+	}
+};
+
+local function GetGearSetList()
+	local t = {["none"] = L["No Change"]}
+	for i = 1, GetNumEquipmentSets() do
+		local name = GetEquipmentSetInfo(i)
+		if name then
+			t[name] = name
+		end
+	end
+	tsort(t, sortingFunction)
+	return t
+end
+
+SV.Options.args.Core.args.Gear = {
+	order = 3,
+	type = 'group',
+	name = "Gear",
+	guiInline = true,
+	get = function(key) return SV.db.Gear[key[#key]]end,
+	set = function(key, value) SV.db.Gear[key[#key]] = value; SV:UpdateGearInfo() end,
+	args = {
+		intro = {
+			order = 1,
+			type = 'description',
+			name = function()
+				if(GetNumEquipmentSets()==0) then
+					return ("%s\n|cffFF0000Must create an equipment set to use some of these features|r"):format(L["EQUIPMENT_DESC"])
+				else
+					return L["EQUIPMENT_DESC"]
+				end
+			end
+		},
+		specialization = {
+			order = 2,
+			type = "group",
+			name = L["Specialization"],
+			guiInline = true,
+			disabled = function() return GetNumEquipmentSets() == 0 end,
+			args = {
+				enable = {
+					type = "toggle",
+					order = 1,
+					name = L["Enable"],
+					desc = L["Enable/Disable auto swapping gear sets when switching specializations."],
+					get = function(key) return SV.db.Gear.specialization.enable end,
+					set = function(key, value) SV.db.Gear.specialization.enable = value; SV:UpdateGearInfo() end
+				},
+				primary = {
+					type = "select",
+					order = 2,
+					name = L["Primary Gear Set"],
+					desc = L["Choose the equipment set to use for your primary specialization."],
+					disabled = function() return not SV.db.Gear.specialization.enable end,
+					values = GetGearSetList(),
+					get = function(e) return SV.db.Gear.specialization.primary end,
+					set = function(e,value) SV.db.Gear.specialization.primary = value; SV:UpdateGearInfo() end
+				},
+				secondary = {
+					type = "select",
+					order = 3,
+					name = L["Secondary Gear Set"],
+					desc = L["Choose the equipment set to use for your secondary specialization."],
+					disabled = function() return not SV.db.Gear.specialization.enable end,
+					values = GetGearSetList(),
+					get = function(e) return SV.db.Gear.specialization.secondary end,
+					set = function(e,value) SV.db.Gear.specialization.secondary = value; SV:UpdateGearInfo() end
+				}
+			}
+		},
+		battleground = {
+			order = 3,
+			type = "group",
+			name = L["Battleground"],
+			guiInline = true,
+			disabled = function()return GetNumEquipmentSets() == 0 end,
+			args = {
+				enable = {
+					type = "toggle",
+					order = 1,
+					name = L["Enable"],
+					desc = L["Enable/Disable auto swapping gear sets in battlegrounds."],
+					get = function(e) return SV.db.Gear.battleground.enable end,
+					set = function(e,value) SV.db.Gear.battleground.enable = value; SV:UpdateGearInfo() end
+				},
+				equipmentset = {
+					type = "select",
+					order = 2,
+					name = L["Battleground Gear Set"],
+					desc = L["Choose the equipment set to use when you enter a battleground or arena."],
+					disabled = function() return not SV.db.Gear.battleground.enable end,
+					values = GetGearSetList(),
+					get = function(e) return SV.db.Gear.battleground.equipmentset end,
+					set = function(e,value) SV.db.Gear.battleground.equipmentset = value; SV:UpdateGearInfo() end
+				}
+			}
+		},
+		intro2 = {
+			type = "description",
+			name = L["DURABILITY_DESC"],
+			order = 4
+		},
+		durability = {
+			type = "group",
+			name = DURABILITY,
+			guiInline = true,
+			order = 5,
+			get = function(e)return SV.db.Gear.durability[e[#e]]end,
+			set = function(e,value)SV.db.Gear.durability[e[#e]] = value; SV:UpdateGearInfo() end,
+			args = {
+				enable = {
+					type = "toggle",
+					order = 1,
+					name = L["Enable"],
+					desc = L["Enable/Disable the display of durability information on the character screen."]
+				},
+				onlydamaged = {
+					type = "toggle",
+					order = 2,
+					name = L["Damaged Only"],
+					desc = L["Only show durability information for items that are damaged."],
+					disabled = function()return not SV.db.Gear.durability.enable end
+				}
+			}
+		},
+		intro3 = {
+			type = "description",
+			name = L["ITEMLEVEL_DESC"],
+			order = 6
+		},
+		itemlevels = {
+			type = "group",
+			name = STAT_AVERAGE_ITEM_LEVEL,
+			guiInline = true,
+			order = 7,
+			args = {
+				characterItemLevel = {
+					type = "toggle",
+					order = 1,
+					name = L["Character Screen iLevels"],
+					desc = L["Enable/Disable the display of item levels on the character screen."],
+					get = function(e)return SV.db.Gear.labels.characterItemLevel end,
+					set = function(e,value)SV.db.Gear.labels.characterItemLevel = value; SV:UpdateGearInfo() end,
+				},
+				inventoryItemLevel = {
+					type = "toggle",
+					order = 2,
+					name = L["Inventory iLevels"],
+					desc = L["Enable/Disable the display of item levels in your bags (or bank)."],
+					get = function(e)return SV.db.Gear.labels.inventoryItemLevel end,
+					set = function(e,value)SV.db.Gear.labels.inventoryItemLevel = value; SV:UpdateGearInfo() end,
+				}
+			}
+		},
+		setNames = {
+			type = "group",
+			name = L["Set Labels"],
+			guiInline = true,
+			order = 8,
+			args = {
+				inventoryGearSet = {
+					type = "toggle",
+					order = 1,
+					name = L["Equipment Set Overlay"],
+					desc = L["Show the associated equipment sets for the items in your bags (or bank)."],
+					get = function(e)return SV.db.Gear.labels.inventoryGearSet end,
+					set = function(e,value)SV.db.Gear.labels.inventoryGearSet = value; SV:UpdateGearInfo() end,
+				}
+			}
+		}
+	}
+};
+
+SV.Options.args.Core.args.errors = {
+	order = 4,
+	type = "group",
+	name = L["Error Handling"],
+	guiInline = true,
+	args = {
+		filterErrors = {
+			order = 1,
+			name = L["Filter Errors"],
+			desc = L["Choose specific errors from the list below to hide/ignore"],
+			type = "toggle",
+			get = function(key)return SV.db.general.filterErrors end,
+			set = function(key,value)SV.db.general.filterErrors = value; SV:UpdateErrorFilters() end
+		},
+		hideErrorFrame = {
+			order = 2,
+			name = L["Combat Hide All"],
+			desc = L["Hides all errors regardless of filtering while in combat."],
+			type = "toggle",
+			disabled = function() return not SV.db.general.filterErrors end,
+			get = function(key) return SV.db.general.hideErrorFrame end,
+			set = function(key,value)SV.db.general.hideErrorFrame = value; SV:UpdateErrorFilters() end
+		},
+		filterGroup = {
+			order = 3,
+			type = "group",
+			guiInline = true,
+			name = L["Filters"],
+			disabled = function() return not SV.db.general.filterErrors end,
+			args = {}
+		},
+	}
+};
+
+SV.Options.args.Screen = {
+	type = 'group',
+	name = 'Screen',
+	order = 3,
+	get = function(a)return SV.db.screen[a[#a]] end,
+	set = function(a,b) SV.db.screen[a[#a]] = b; end,
+	args = {
+		commonGroup = {
+			order = 1,
+			type = 'group',
+			name = L['Basic Options'],
+			guiInline = true,
+			args = {
+				autoScale = {
+					order = 1,
+					name = L["Auto Scale"],
+					desc = L["Automatically scale the User Interface based on your screen resolution"],
+					type = "toggle",
+					get = function(j)return SV.db.screen.autoScale end,
+					set = function(j,value)
+						SV.db.screen.autoScale = value;
+						if(value) then
+							SV.db.screen.scaleAdjust = 0.64;
+						end
+						SV:StaticPopup_Show("RL_CLIENT")
+					end
+				},
+				multiMonitor = {
+					order = 2,
+					name = L["Multi Monitor"],
+					desc = L["Adjust UI dimensions to accomodate for multiple monitor setups"],
+					type = "toggle",
+					get = function(j)return SV.db.screen.multiMonitor end,
+					set = function(j,value) SV.db.screen.multiMonitor = value; SV:StaticPopup_Show("RL_CLIENT") end
+				},
+			}
+		},
+		advancedGroup = {
+			order = 2,
+			type = 'group',
+			name = L['Advanced Options'],
+			guiInline = true,
+			args = {
+				advanced = {
+					order = 1,
+					name = L["Enable"],
+					desc = L["These settings are for advanced users only!"],
+					type = "toggle",
+					get = function(j)return SV.db.screen.advanced end,
+					set = function(j,value) SV.db.screen.advanced = value; SV:StaticPopup_Show("RL_CLIENT"); end
+				},
+				forcedWidth = {
+					order = 2,
+					name = L["Forced Width"],
+					desc = function() return L["Setting your resolution height here will bypass all evaluated measurements. Current: "] .. SV.db.screen.forcedWidth; end,
+					type = "input",
+					disabled = function() return not SV.db.screen.advanced end,
+					get = function(key) return SV.db.screen.forcedWidth end,
+					set = function(key, value)
+						local w = tonumber(value);
+						if(not w) then
+							SV:AddonMessage(L["Value must be a number"])
+						elseif(w < 800) then
+							SV:AddonMessage(L["Less than 800 is not allowed"])
+						else
+							SV.db.screen.forcedWidth = w;
+							SV:StaticPopup_Show("RL_CLIENT");
+						end
+					end
+				},
+				forcedHeight = {
+					order = 3,
+					name = L["Forced Height"],
+					desc = function() return L["Setting your resolution height here will bypass all evaluated measurements. Current: "] .. SV.db.screen.forcedHeight; end,
+					type = "input",
+					disabled = function() return not SV.db.screen.advanced end,
+					get = function(key) return SV.db.screen.forcedHeight end,
+					set = function(key, value)
+						local h = tonumber(value);
+						if(not h) then
+							SV:AddonMessage(L["Value must be a number"])
+						elseif(h < 600) then
+							SV:AddonMessage(L["Less than 600 is not allowed"])
+						else
+							SV.db.screen.forcedHeight = h;
+							SV:StaticPopup_Show("RL_CLIENT");
+						end
+					end
+				},
+				scaleAdjust = {
+					order = 4,
+					name = L["Base Scale"],
+					desc = L["You can use this to adjust the base value applied to scale calculations."],
+					type = "range",
+					width = 'full',
+					min = 0.25,
+					max = 1,
+					step = 0.01,
+					disabled = function() return not SV.db.screen.advanced end,
+					get = function(j)return SV.db.screen.scaleAdjust end,
+					set = function(j,value)
+						SV.db.screen.scaleAdjust = value;
+						if(value ~= 0.64) then
+							SV.db.screen.autoScale = false;
+						end
+						SV:StaticPopup_Show("RL_CLIENT")
+					end
+				},
+			}
+		},
+	}
+}
+SV.Options.args.Fonts = {
+	order = 4,
+	type = "group",
+	name = L['Fonts'],
+	childGroups = "tab",
+	args = {
+		fontGroup = {
+			order = 1,
+			type = 'group',
+			name = L['Font Options'],
+			childGroups = "tree",
+			args = {}
+		}
+	}
+}
+SV.Options.args.Dock = {
+	type = "group",
+	order = 5,
+	name = SV.Dock.TitleID,
+	args = {
+	  intro = {
+			order = 1,
+			type = "description",
+			name = "Configure the various frame docks around the screen"
+		},
+		generalGroup = {
+			order = 2,
+			type = "group",
+			name = "General",
+			guiInline = true,
+			get = function(key)return SV.db.Dock[key[#key]];end,
+			set = function(key,value)
+				SV.Dock:ChangeDBVar(value,key[#key]);
+				SV.Dock:Refresh()
+			end,
+			args = {
+				bottomPanel = {
+					order = 1,
+					type = 'toggle',
+					name = L['Bottom Panel'],
+					desc = L['Display a border across the bottom of the screen.'],
+					get = function(j) return SV.db.Dock.bottomPanel end,
+					set = function(key,value) SV.Dock:ChangeDBVar(value,key[#key]); end
+				},
+				topPanel = {
+					order = 2,
+					type = 'toggle',
+					name = L['Top Panel'],
+					desc = L['Display a border across the top of the screen.'],
+					get = function(j) return SV.db.Dock.topPanel end,
+					set = function(key,value) SV.Dock:ChangeDBVar(value,key[#key]); end
+				},
+				backdrop = {
+					order = 3,
+					type = 'toggle',
+					name = L['Use Backdrops'],
+					desc = L['Display a backdrop behind dock windows.'],
+					get = function(j)return SV.db.Dock.backdrop end,
+					set = function(key,value)
+						SV.Dock:ChangeDBVar(value, key[#key]);
+						SV.Dock:UpdateDockBackdrops()
+					end
+				},
+				buttonSize = {
+					order = 4,
+					type = "range",
+					name = L["Dock Button Size"],
+					desc = L["PANEL_DESC"],
+					min = 20,
+					max = 80,
+					step = 1,
+					width = "full",
+					get = function()return SV.db.Dock.buttonSize;end,
+					set = function(key,value)
+						SV.Dock:ChangeDBVar(value,key[#key]);
+						SV.Dock:Refresh()
+					end,
+				},
+			},
+		},
+		LeftBottomGroup = {
+			order = 3,
+			type = "group",
+			name = L["Bottom Left Dock"],
+			guiInline = true,
+			args = {
+				dockLeftHeight = {
+					order = 1,
+					type = "range",
+					name = L["Height"],
+					desc = L["PANEL_DESC"],
+					min = 150,
+					max = 600,
+					step = 1,
+					get = function()return SV.db.Dock.dockLeftHeight;end,
+					set = function(key,value)
+						SV.Dock:ChangeDBVar(value,key[#key]);
+						SV.Dock:Refresh()
+						if(SV.Chat) then
+							SV.Chat:UpdateLocals()
+							SV.Chat:RefreshChatFrames(true)
+						end
+					end,
+				},
+				dockLeftWidth = {
+					order = 2,
+					type = "range",
+					name = L["Width"],
+					desc = L["PANEL_DESC"],
+					min = 150,
+					max = 700,
+					step = 1,
+					get = function()return SV.db.Dock.dockLeftWidth;end,
+					set = function(key,value)
+						SV.Dock:ChangeDBVar(value,key[#key]);
+						SV.Dock:Refresh()
+						if(SV.Chat) then
+							SV.Chat:UpdateLocals()
+							SV.Chat:RefreshChatFrames(true)
+						end
+					end,
+				},
+			}
+		},
+		RightBottomGroup = {
+			order = 4,
+			type = "group",
+			name = L["Bottom Right Dock"],
+			guiInline = true,
+			args = {
+				dockRightHeight = {
+					order = 1,
+					type = "range",
+					name = L["Height"],
+					desc = L["PANEL_DESC"],
+					min = 150,
+					max = 600,
+					step = 1,
+					get = function()return SV.db.Dock.dockRightHeight;end,
+					set = function(key,value)
+						SV.Dock:ChangeDBVar(value,key[#key]);
+						SV.Dock:Refresh()
+						if(SV.Chat) then
+							SV.Chat:UpdateLocals()
+							SV.Chat:RefreshChatFrames(true)
+						end
+					end,
+				},
+				dockRightWidth = {
+					order = 2,
+					type = "range",
+					name = L["Width"],
+					desc = L["PANEL_DESC"],
+					min = 150,
+					max = 700,
+					step = 1,
+					get = function()return SV.db.Dock.dockRightWidth;end,
+					set = function(key,value)
+						SV.Dock:ChangeDBVar(value,key[#key]);
+						SV.Dock:Refresh()
+						if(SV.Chat) then
+							SV.Chat:UpdateLocals()
+							SV.Chat:RefreshChatFrames(true)
+						end
+					end,
+				},
+			}
+		},
+		LeftTopGroup = {
+			order = 5,
+			type = "group",
+			name = L["Top Left Dock"],
+			guiInline = true,
+			args = {
+				dockTopLeftHeight = {
+					order = 1,
+					type = "range",
+					name = L["Height"],
+					desc = L["PANEL_DESC"],
+					min = 150,
+					max = 600,
+					step = 1,
+					get = function()return SV.db.Dock.dockTopLeftHeight;end,
+					set = function(key,value)
+						SV.Dock:ChangeDBVar(value,key[#key]);
+						SV.Dock:Refresh()
+						if(SV.Chat) then
+							SV.Chat:UpdateLocals()
+							SV.Chat:RefreshChatFrames(true)
+						end
+					end,
+				},
+				dockTopLeftWidth = {
+					order = 2,
+					type = "range",
+					name = L["Width"],
+					desc = L["PANEL_DESC"],
+					min = 150,
+					max = 700,
+					step = 1,
+					get = function()return SV.db.Dock.dockTopLeftWidth;end,
+					set = function(key,value)
+						SV.Dock:ChangeDBVar(value,key[#key]);
+						SV.Dock:Refresh()
+						if(SV.Chat) then
+							SV.Chat:UpdateLocals()
+							SV.Chat:RefreshChatFrames(true)
+						end
+					end,
+				},
+			}
+		},
+		RightTopGroup = {
+			order = 6,
+			type = "group",
+			name = L["Top Right Dock"],
+			guiInline = true,
+			args = {
+				dockTopRightHeight = {
+					order = 1,
+					type = "range",
+					name = L["Height"],
+					desc = L["PANEL_DESC"],
+					min = 150,
+					max = 600,
+					step = 1,
+					get = function()return SV.db.Dock.dockTopRightHeight;end,
+					set = function(key,value)
+						SV.Dock:ChangeDBVar(value,key[#key]);
+						SV.Dock:Refresh()
+						if(SV.Chat) then
+							SV.Chat:UpdateLocals()
+							SV.Chat:RefreshChatFrames(true)
+						end
+					end,
+				},
+				dockTopRightWidth = {
+					order = 2,
+					type = "range",
+					name = L["Width"],
+					desc = L["PANEL_DESC"],
+					min = 150,
+					max = 700,
+					step = 1,
+					get = function()return SV.db.Dock.dockTopRightWidth;end,
+					set = function(key,value)
+						SV.Dock:ChangeDBVar(value,key[#key]);
+						SV.Dock:Refresh()
+						if(SV.Chat) then
+							SV.Chat:UpdateLocals()
+							SV.Chat:RefreshChatFrames(true)
+						end
+					end,
+				},
+			}
+		},
+		dataGroup = {
+			order = 7,
+			type = "group",
+			name = "Reports (Data Texts)",
+			guiInline = true,
+			get = function(key)return SV.db.Reports[key[#key]];end,
+			set = function(key,value)
+				SV.Reports:ChangeDBVar(value,key[#key]);
+			end,
+			args = {
+				time24 = {
+					order = 1,
+					type = "toggle",
+					name = L["24-Hour Time"],
+					desc = L["Toggle 24-hour mode for the time datatext."],
+				},
+				localtime = {
+					order = 2,
+					type = "toggle",
+					name = L["Local Time"],
+					desc = L["If not set to true then the server time will be displayed instead."]
+				},
+				battleground = {
+					order = 3,
+					type = "toggle",
+					name = L["Battleground Texts"],
+					desc = L["When inside a battleground display personal scoreboard information on the main datatext bars."]
+				},
+				backdrop = {
+					order = 4,
+					name = "Data Backgrounds",
+					desc = L["Display background textures on docked data texts"],
+					type = "toggle",
+					set = function(key, value) SV.Reports:ChangeDBVar(value, key[#key]); SV.Reports:UpdateAllReports() end,
+				},
+				shortGold = {
+					order = 5,
+					type = "toggle",
+					name = L["Shortened Gold Text"],
+				},
+				spacer1 = {
+					order = 6,
+					name = "",
+					type = "description",
+					width = "full",
+				},
+				dockCenterWidth = {
+					order = 7,
+					type = 'range',
+					name = L['Stat Panel Width'],
+					desc = L["PANEL_DESC"],
+					min = 400,
+					max = 1800,
+					step = 1,
+					width = "full",
+					get = function()return SV.db.Dock.dockCenterWidth; end,
+					set = function(key,value)
+						SV.Dock:ChangeDBVar(value,key[#key]);
+						SV.Dock:Refresh()
+					end,
+				},
+				spacer2 = {
+					order = 8,
+					name = "",
+					type = "description",
+					width = "full",
+				},
+				buttonSize = {
+					order = 9,
+					type = "range",
+					name = L["Dock Button Size"],
+					desc = L["PANEL_DESC"],
+					min = 20,
+					max = 80,
+					step = 1,
+					width = "full",
+					get = function()return SV.db.Dock.buttonSize;end,
+					set = function(key,value)
+						SV.Dock:ChangeDBVar(value,key[#key]);
+						SV.Dock:Refresh()
+					end,
+				},
+			}
+		},
+		toolsGroup = {
+			order = 8,
+			type = "group",
+			name = L["Dock Tools"],
+			guiInline = true,
+			get = function(key) return SV.db.Dock.dockTools[key[#key]] end,
+			set = function(key,value) SV.Dock:ChangeDBVar(value, key[#key], "dockTools"); SV:StaticPopup_Show("RL_CLIENT"); end,
+			args = {
+				garrison = {
+					order = 1,
+					type = 'toggle',
+					name = L['Garrison Utility'],
+					desc = L['Left click for landing, right click to use Garrison hearth.'],
+				},
+				leader = {
+					order = 2,
+					type = 'toggle',
+					name = L['Raid Leader'],
+					desc = L['Quick launch menu of raid leader tools.'],
+				},
+				primary = {
+					order = 3,
+					type = 'toggle',
+					name = L['Primary Profession'],
+					desc = L['Quick launch of your primary profession window'],
+				},
+				secondary = {
+					order = 4,
+					type = 'toggle',
+					name = L['Secondary Profession'],
+					desc = L['Quick launch of your secondary profession window'],
+				},
+				firstAid = {
+					order = 5,
+					type = 'toggle',
+					name = L['First Aid'],
+					desc = L['Quick launch of your first aid window'],
+				},
+				cooking = {
+					order = 6,
+					type = 'toggle',
+					name = L['Cooking'],
+					desc = L['Quick launch of your cooking window'],
+				},
+				archaeology = {
+					order = 7,
+					type = 'toggle',
+					name = L['Archaeology'],
+					desc = L['Quick launch of your archaeology window'],
+				},
+				hearth = {
+					order = 8,
+					type = 'toggle',
+					name = L['Hearth Tool'],
+					desc = L['Left click to use your hearthstone, right click for various class-based options.'],
+				},
+				specswap = {
+					order = 9,
+					type = 'toggle',
+					name = L['Spec Swap'],
+					desc = L['Click to simply swap specs (out of combat).'],
+				},
+				breakstuff = {
+					order = 10,
+					type = 'toggle',
+					name = L['Break Stuff'],
+					desc = L['This tool, when available and enabled, will allow you to single click items in your bags for certain abilities. [Milling, Prospecting, Disenchanting, Lockpicking or use a Skeleton Key]'],
+				},
+				power = {
+					order = 11,
+					type = 'toggle',
+					name = L['Power Button'],
+					desc = L['This tool gives you one-click access to logging out, reloading the UI and exiting the game]'],
+				},
+			}
+		},
+		reportGroup1 = {
+			order = 9,
+			type = "group",
+			name = L["Bottom Stats: Left"],
+			guiInline = true,
+			args = {}
+		},
+		reportGroup2 = {
+			order = 10,
+			type = "group",
+			name = L["Bottom Stats: Right"],
+			guiInline = true,
+			args = {}
+		},
+		reportGroup3 = {
+			order = 11,
+			type = "group",
+			name = L["Top Stats: Left"],
+			guiInline = true,
+			args = {}
+		},
+		reportGroup4 = {
+			order = 12,
+			type = "group",
+			name = L["Top Stats: Right"],
+			guiInline = true,
+			args = {}
+		},
+	}
+}
+SV.Options.args.Filters = {
+	type = "group",
+	name = L["Aura Filters"],
+	order = 9996,
+	args = {}
+}
+
+local listIndex = 1;
+local filterGroup = SV.Options.args.Core.args.errors.args.filterGroup.args;
+for errorName, state in pairs(SV.db.general.errorFilters) do
+	filterGroup[errorName] = {
+		order = listIndex,
+		type = 'toggle',
+		name = errorName,
+		width = 'full',
+		get = function(key) return SV.db.general.errorFilters[errorName]; end,
+		set = function(key,value) SV.db.general.errorFilters[errorName] = value; SV:UpdateErrorFilters() end
+	}
+	listIndex = listIndex + 1
+end
+
+local statValues = {[""] = "None"};
+for name, _ in pairs(SV.Reports.Plugins) do
+	statValues[name] = name;
+end
+
+for panelIndex, panelPositions in pairs(SV.db.REPORT_SLOTS) do
+	local panelName = 'reportGroup' .. panelIndex;
+	local optionTable = SV.Options.args.Dock.args;
+	if(optionTable[panelName] and type(panelPositions) == "table") then
+		for i = 1, #panelPositions do
+			local slotName = 'Slot' .. i;
+			optionTable[panelName].args[slotName] = {
+				order = i,
+				type = 'select',
+				name = 'Slot '..i,
+				values = statValues,
+				get = function(key) return SV.db.REPORT_SLOTS[panelIndex][i] end,
+				set = function(key, value) SV.db.REPORT_SLOTS[panelIndex][i] = value; SV.Reports:UpdateAllReports() end
+			}
+		end
+	end
+end
+
+SV:GenerateFontOptionGroup("General", 1, "The most commonly used fonts. Changing these will require reloading the UI.", generalFonts)
+SV:GenerateFontOptionGroup("Numeric", 2, "These fonts are used for many number values.", numberFonts)
+SV:GenerateFontOptionGroup("Loot", 3, "Fonts used in loot frames.", lootFonts)
+SV:GenerateFontOptionGroup("Misc", 4, "Fonts used in various places including the docks.", miscFonts)
+
+SVUILib:LoadModuleOptions()
+RefreshProfileOptions()
+
+SVUIOptions.FilterOptionGroups['_NEW'] = function(filterType)
+	return function()
+		local RESULT, FILTER
+		if(SV.db.Filters.Custom[filterType]) then
+			FILTER = SV.db.Filters.Custom[filterType]
+		else
+			FILTER = SV.db.Filters[filterType]
+		end
+		if(FILTER) then
+			RESULT = {
+				type = "group",
+				name = filterType,
+				guiInline = true,
+				order = 4,
+				args = {
+					alertAction = {
+						order = 1,
+						name = "",
+						type = "description",
+						get = function(key) return "" end,
+					},
+					addSpell = {
+						order = 2,
+						name = L["Add Spell"],
+						desc = L["Add a spell to the filter. You can add by name, or ID (number). If the spell is in your spellbook or on an actionbar then you can drag and drop it here."],
+						type = "input",
+						get = function(key) RESULT.args.alertAction.name = ""; return "" end,
+						set = function(key, value)
+							local spellID = tonumber(value);
+							if(not spellID) then
+								spellID = select(7, GetSpellInfo(value))
+							end
+							RESULT.args.alertAction.name = "";
+							if((not spellID) or (not GetSpellInfo(spellID))) then
+								SV:AddonMessage(L["Spell Not Found"])
+								RESULT.args.alertAction.name = '|cffFF0000'..L["Spell Not Found"]..'|r';
+							elseif(not FILTER[value]) then
+								FILTER[value] = {['enable'] = true, ['id'] = spellID, ['priority'] = 0}
+								SVUIOptions:SetFilterOptions(filterType)
+								SV.Events:Trigger("AURA_FILTER_OPTIONS_CHANGED");
+							end
+						end
+					},
+					removeSpell = {
+						order = 3,
+						name = L["Remove Spell"],
+						desc = L["Remove a spell from the filter."],
+						type = "select",
+						disabled = function()
+							local EMPTY = true;
+							for g in pairs(FILTER) do
+								EMPTY = false;
+							end
+							return EMPTY
+						end,
+						values = function()
+							wipe(tempFilterTable)
+							for id, filterData in pairs(FILTER) do
+								if(type(id) == 'string' and filterData.id) then
+									local auraName = GetSpellInfo(filterData.id)
+									if(auraName) then
+										tempFilterTable[id] = auraName
+									end
+								end
+							end
+							return tempFilterTable
+						end,
+						get = function(key) return "" end,
+						set = function(key, value)
+							if(FILTER[value]) then
+								if(FILTER[value].isDefault) then
+									FILTER[value].enable = false;
+									SV:AddonMessage(L["You may not remove a spell from a default filter that is not customly added. Setting spell to false instead."])
+								else
+									FILTER[value] = nil
+								end
+							end
+							SVUIOptions:SetFilterOptions(filterType)
+							SV.Events:Trigger("AURA_FILTER_OPTIONS_CHANGED");
+						end
+					},
+				}
+			};
+		end;
+		return RESULT;
+	end;
+end;
+
+SVUIOptions.FilterOptionSpells['_NEW'] = function(filterType)
+	return function()
+		local RESULT, FILTER
+		if(SV.db.Filters.Custom[filterType]) then
+			FILTER = SV.db.Filters.Custom[filterType]
+		else
+			FILTER = SV.db.Filters[filterType]
+		end
+		if(FILTER) then
+			RESULT = {
+				type = "group",
+				name = filterType .. " - " .. L["Spells"],
+				order = 5,
+				guiInline = true,
+				args = {}
+			};
+			local hasSpells = false;
+			for id, filterData in pairs(FILTER) do
+				local auraName = GetSpellInfo(filterData.id)
+				if(auraName) then
+					RESULT.args[auraName] = {
+						name = auraName,
+						type = "toggle",
+						get = function()
+							return FILTER[id].enable
+						end,
+						set = function(key, value)
+							FILTER[id].enable = value;
+							SV.Events:Trigger("AURA_FILTER_OPTIONS_CHANGED");
+							SVUIOptions:SetFilterOptions(filterType)
+						end
+					};
+					hasSpells = true
+				end
+			end
+			if(not hasSpells) then
+				RESULT.args.alertAction = {
+					order = 1,
+					name = '|cffFF0000'..L["No Spells"]..'|r',
+					type = "description",
+					get = function(key) return "" end,
+				};
+			end
+		end
+		return RESULT;
+	end;
+end;
+
+SV.Options.args.Filters.args.createFilter = {
+	order = 1,
+	name = L["Create Filter"],
+	desc = L["Create a custom filter."],
+	type = "input",
+	get = function(key) return "" end,
+	set = function(key, value)
+		if(not value or (value and value == '')) then
+			SV:AddonMessage(L["Not a usable filter name"])
+		elseif(SV.db.Filters.Custom[value]) then
+			SV:AddonMessage(L["Filter already exists"])
+		else
+			SV.db.Filters.Custom[value] = {};
+			SVUIOptions:SetFilterOptions(value);
+		end
+	end
+};
+
+SV.Options.args.Filters.args.deleteFilter = {
+	type = "select",
+	order = 2,
+	name = L["Delete Filter"],
+	desc = L["Delete a custom filter."],
+	get = function(key) return "" end,
+	set = function(key, value)
+		SV.db.Filters.Custom[value] = nil;
+		SV.Options.args.Filters.args.filterGroup = nil
+	end,
+	values = GetUserFilterList()
+};
+
+SV.Options.args.Filters.args.selectFilter = {
+	order = 3,
+	type = "select",
+	name = L["Select Filter"],
+	get = function(key) return CURRENT_FILTER_TYPE end,
+	set = function(key, value) SVUIOptions:SetFilterOptions(value) end,
+	values = GetAllFilterList()
+};
+
+SV.OptionsLoaded = true;
diff --git a/SVUI_!Options/SVUI_!Options.toc b/SVUI_!Options/SVUI_!Options.toc
new file mode 100644
index 0000000..1f48cad
--- /dev/null
+++ b/SVUI_!Options/SVUI_!Options.toc
@@ -0,0 +1,15 @@
+## Interface: 70000
+## Author: Failcoder
+## Version: 1.3.5
+## Title: |cffFF9900SuperVillain UI: |r|cff00FF00!Options|r
+## Notes: SVUI [|cff9911FFConfig Options|r]
+## RequiredDeps: SVUI_!Core
+## LoadOnDemand: 1
+## X-Email: munglunch@gmail.com
+## X-Website: http://www.supervillainui.com
+## X-Donate: PayPal:munglunch@gmail.com
+## X-License: MIT
+## X-Category: Interface Enhancements
+## X-MKName: Options
+
+SVUI_!Options.xml
diff --git a/SVUI_!Options/SVUI_!Options.xml b/SVUI_!Options/SVUI_!Options.xml
new file mode 100644
index 0000000..326a102
--- /dev/null
+++ b/SVUI_!Options/SVUI_!Options.xml
@@ -0,0 +1,4 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+	<Script file='SVUI_!Options.lua'/>
+	<Script file='UnitFrames.lua'/>
+</Ui>
\ No newline at end of file
diff --git a/SVUI_!Options/UnitFrames.lua b/SVUI_!Options/UnitFrames.lua
new file mode 100644
index 0000000..b6d24cb
--- /dev/null
+++ b/SVUI_!Options/UnitFrames.lua
@@ -0,0 +1,5286 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pcall         = _G.pcall;
+local print         = _G.print;
+local ipairs        = _G.ipairs;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local rawset        = _G.rawset;
+local rawget        = _G.rawget;
+local tostring      = _G.tostring;
+local tonumber      = _G.tonumber;
+local getmetatable  = _G.getmetatable;
+local setmetatable  = _G.setmetatable;
+local table 	 	= _G.table;
+local string 	 	= _G.string;
+local upper 		= string.upper;
+local gsub 			= string.gsub;
+--[[ TABLE METHODS ]]--
+local tsort = table.sort;
+
+local NONE = _G.NONE;
+local GetSpellInfo = _G.GetSpellInfo;
+local collectgarbage = _G.collectgarbage;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G["SVUI"];
+local L = SV.L;
+local MOD = SV.UnitFrames;
+if(not MOD) then return end;
+local _, SVUIOptions = ...;
+local Schema = MOD.Schema;
+local ACD = LibStub("AceConfigDialog-3.0");
+local playerClass = select(2, UnitClass("player"));
+local DEFAULT_COLOR = {["r"] = 1, ["g"] = 0, ["b"] = 0};
+local STYLE_SELECT = {["coloredIcon"] = L["Colored Icon"], ["texturedIcon"] = L["Textured Icon"], [""] = NONE};
+local POSITION_SELECT = {
+	["TOPLEFT"] = "TOPLEFT",
+	["TOPRIGHT"] = "TOPRIGHT",
+	["BOTTOMLEFT"] = "BOTTOMLEFT",
+	["BOTTOMRIGHT"] = "BOTTOMRIGHT",
+	["LEFT"] = "LEFT",
+	["RIGHT"] = "RIGHT",
+	["TOP"] = "TOP",
+	["BOTTOM"] = "BOTTOM"
+};
+
+local ANCHOR_SELECT = {
+	["LEFT"] = "LEFT",
+	["RIGHT"] = "RIGHT",
+	["TOP"] = "TOP",
+	["BOTTOM"] = "BOTTOM"
+};
+
+local textStringFormats = {
+	["none"] = "None",
+	["current"] = "Current",
+	["deficit"] = "Deficit",
+	["percent"] = "Percent",
+	["curpercent"] = "Current - Percent",
+	["curmax"] = "Current - Maximum",
+	["curmax-percent"] = "Current - Maximum | %",
+};
+
+local FRAME_MAP = {
+	["player"] = "SVUI_Player",
+	["target"] = "SVUI_Target",
+	["targettarget"] = "SVUI_TargetTarget",
+	["pet"] = "SVUI_Pet",
+	["pettarget"] = "SVUI_PetTarget",
+	["focus"] = "SVUI_Focus",
+	["focustarget"] = "SVUI_FocusTarget",
+};
+
+local tempFilterTable, filterList = {}, {};
+
+if(not SV.db.Filters.PetBuffWatch) then
+	SV.db.Filters.PetBuffWatch = {}
+end
+
+if(not SV.db.Filters.BuffWatch) then
+	SV.db.Filters.BuffWatch = {}
+end
+
+local function SetWatchedBuff(stringID, id, data, enable, point, color, anyUnit)
+	if(not data[id]) then
+		data[stringID] = {["enable"] = enable, ["id"] = id, ["point"] = point, ["color"] = color, ["anyUnit"] = anyUnit}
+	else
+		data[stringID]["id"] = id;
+		data[stringID]["enable"] = enable;
+		data[stringID]["point"] = point;
+		data[stringID]["color"] = color;
+		data[stringID]["anyUnit"] = anyUnit;
+	end
+end
+
+local function UpdateBuffWatch()
+	MOD:SetUnitFrame("focus")
+	MOD:SetGroupFrame("raid")
+	MOD:SetGroupFrame("party")
+end
+
+local function UpdatePetBuffWatch()
+	MOD:SetUnitFrame("pet")
+	MOD:SetGroupFrame("raidpet")
+end
+
+local unitFonts = {
+	["unitaurabar"] = {
+		order = 1,
+		name = "Unitframe AuraBar",
+		desc = "Used on unit aurabars."
+	},
+    ["unitaura"] = {
+		order = 2,
+		name = "Unitframe Aura",
+		desc = "Used on unit frames for auras (normal scale)."
+	},
+    ["unitaurasmall"] = {
+		order = 3,
+		name = "Unitframe Aura (Small)",
+		desc = "Used on unit frames for auras (small scale)."
+	},
+    ["unitprimary"] = {
+		order = 4,
+		name = "Unitframe Values",
+		desc = "Used on all primary unit frames for health, power and misc values.\nUnits: player, pet, target, focus, boss and arena"
+	},
+    ["unitsecondary"] = {
+		order = 5,
+		name = "Unitframe Values",
+		desc = "Used on all non-primary unit frames for health, power and misc values.\nUnits: pettarget, targettarget, focustarget, party, raid, raidpet, tank and assist."
+	},
+};
+
+--[[
+##########################################################
+HELPER FUNCTIONS
+##########################################################
+]]--
+function SVUIOptions:SetSizeConfigGroup(gridMode, unitName)
+
+	local sizeGroup = {
+		order = 2,
+		guiInline = true,
+		type = "group",
+		name = L["Size Settings"],
+		args = {}
+	}
+
+	if(gridMode) then
+		sizeGroup.args = {
+			size = {
+				order = 1,
+				name = L["Grid Size"],
+				type = "range",
+				min = 10,
+				max = 100,
+				step = 1,
+				width = 'full',
+				get = function(key) return SV.db.UnitFrames[unitName].grid[key[#key]] end,
+				set = function(key, value) MOD:ChangeDBVar(value, key[#key], unitName, "grid"); MOD:SetGroupFrame(unitName) end,
+			},
+			spacer1 = {
+				order = 2,
+				name = "",
+				type = "description",
+				width = "full",
+			},
+			wrapXOffset = {
+				order = 3,
+				type = "range",
+				name = L["Horizontal Spacing"],
+				min = 0,
+				max = 50,
+				step = 1,
+				get = function(key) return SV.db.UnitFrames[unitName][key[#key]] end,
+				set = function(key, value) MOD:ChangeDBVar(value, key[#key], unitName); MOD:SetGroupFrame(unitName) end,
+			},
+			wrapYOffset = {
+				order = 4,
+				type = "range",
+				name = L["Vertical Spacing"],
+				min = 0,
+				max = 50,
+				step = 1,
+				get = function(key) return SV.db.UnitFrames[unitName][key[#key]] end,
+				set = function(key, value) MOD:ChangeDBVar(value, key[#key], unitName); MOD:SetGroupFrame(unitName) end,
+			},
+		}
+	else
+		sizeGroup.args = {
+			width = {
+				order = 1,
+				name = L["Width"],
+				type = "range",
+				min = 10,
+				max = 500,
+				step = 1,
+				width = 'full',
+				get = function(key) return SV.db.UnitFrames[unitName][key[#key]] end,
+				set = function(key, value) MOD:ChangeDBVar(value, key[#key], unitName); MOD:SetGroupFrame(unitName) end,
+			},
+			height = {
+				order = 2,
+				name = L["Height"],
+				type = "range",
+				min = 10,
+				max = 500,
+				step = 1,
+				width = 'full',
+				get = function(key) return SV.db.UnitFrames[unitName][key[#key]] end,
+				set = function(key, value) MOD:ChangeDBVar(value, key[#key], unitName); MOD:SetGroupFrame(unitName) end,
+			},
+			spacer1 = {
+				order = 3,
+				name = "",
+				type = "description",
+				width = "full",
+			},
+			wrapXOffset = {
+				order = 4,
+				type = "range",
+				name = L["Horizontal Spacing"],
+				min = 0,
+				max = 50,
+				step = 1,
+				width = 'full',
+				get = function(key) return SV.db.UnitFrames[unitName][key[#key]] end,
+				set = function(key, value) MOD:ChangeDBVar(value, key[#key], unitName); MOD:SetGroupFrame(unitName) end,
+			},
+			wrapYOffset = {
+				order = 5,
+				type = "range",
+				name = L["Vertical Spacing"],
+				min = 0,
+				max = 50,
+				step = 1,
+				width = 'full',
+				get = function(key) return SV.db.UnitFrames[unitName][key[#key]] end,
+				set = function(key, value) MOD:ChangeDBVar(value, key[#key], unitName); MOD:SetGroupFrame(unitName) end,
+			},
+		}
+	end
+
+	return sizeGroup
+end
+
+function SVUIOptions:SetCastbarConfigGroup(updateFunction, unitName, count)
+	local configTable = {
+		order = 800,
+		type = "group",
+		name = L["Castbar"],
+		get = function(key)
+			return SV.db.UnitFrames[unitName]["castbar"][key[#key]]
+		end,
+		set = function(key, value)
+			MOD:ChangeDBVar(value, key[#key], unitName, "castbar")
+			updateFunction(MOD, unitName, count)
+		end,
+		args = {
+			enable = {
+				type = "toggle",
+				order = 1,
+				name = L["Enable"]
+			},
+			commonGroup = {
+				order = 2,
+				guiInline = true,
+				type = "group",
+				name = L["Base Settings"],
+				args = {
+					forceshow = {
+						order = 1,
+						name = SHOW.." / "..HIDE,
+						type = "execute",
+						func = function()
+							local v = unitName:gsub("(.)", upper, 1)
+							v = "SVUI_"..v;
+							v = v:gsub("t(arget)", "T%1")
+							if count then
+								for w = 1, count do
+									local castbar = _G[v..w].Castbar;
+									if not castbar.oldHide then
+										castbar.oldHide = castbar.Hide;
+										castbar.Hide = castbar.Show;
+										castbar:Show()
+									else
+										castbar.Hide = castbar.oldHide;
+										castbar.oldHide = nil;
+										castbar:Hide()
+										castbar.lastUpdate = 0
+									end
+								end
+							else
+								local castbar = _G[v].Castbar;
+								if not castbar.oldHide then
+									castbar.oldHide = castbar.Hide;
+									castbar.Hide = castbar.Show;
+									castbar:Show()
+								else
+									castbar.Hide = castbar.oldHide;
+									castbar.oldHide = nil;
+									castbar:Hide()
+									castbar.lastUpdate = 0
+								end
+							end
+						end,
+					},
+					icon = {
+						order = 2,
+						name = L["Icon"],
+						type = "toggle"
+					},
+					latency = {
+						order = 3,
+						name = L["Latency"],
+						type = "toggle"
+					},
+					spark = {
+						order = 4,
+						type = "toggle",
+						name = L["Spark"]
+					},
+				}
+			},
+			sizeGroup = {
+				order = 3,
+				guiInline = true,
+				type = "group",
+				name = L["Size Settings"],
+				args = {
+					matchFrameWidth = {
+						order = 1,
+						name = L["Auto Width"],
+						desc = "Force the castbar to ALWAYS match its unitframes width.",
+						type = "toggle",
+					},
+					matchsize = {
+						order = 2,
+						type = "execute",
+						name = L["Match Frame Width"],
+						desc = "Set the castbar width to match its unitframe.",
+						func = function()
+							SV.db.UnitFrames[unitName]["castbar"]["width"] = SV.db.UnitFrames[unitName]["width"]
+							updateFunction(MOD, unitName, count)
+						end
+					},
+					width = {
+						order = 3,
+						name = L["Width"],
+						type = "range",
+						width = "full",
+						min = 50,
+						max = 600,
+						step = 1,
+						disabled = function() return SV.db.UnitFrames[unitName]["castbar"].matchFrameWidth end
+					},
+					height = {
+						order = 4,
+						name = L["Height"],
+						type = "range",
+						width = "full",
+						min = 10,
+						max = 85,
+						step = 1
+					},
+				}
+			},
+			colorGroup = {
+				order = 4,
+				type = "group",
+				guiInline = true,
+				name = L["Custom Coloring"],
+				args = {
+					useCustomColor = {
+						type = "toggle",
+						order = 1,
+						name = L["Enable"]
+					},
+					castingColor = {
+						order = 2,
+						name = L["Custom Bar Color"],
+						type = "color",
+						get = function(key)
+							local color = SV.db.UnitFrames[unitName]["castbar"]["castingColor"]
+							return color[1], color[2], color[3], color[4]
+						end,
+						set = function(key, rValue, gValue, bValue)
+							SV.db.UnitFrames[unitName]["castbar"]["castingColor"] = {rValue, gValue, bValue}
+							MOD:RefreshUnitFrames()
+						end,
+						disabled = function() return not SV.db.UnitFrames[unitName]["castbar"].useCustomColor end
+					},
+					sparkColor = {
+						order = 3,
+						name = L["Custom Spark Color"],
+						type = "color",
+						get = function(key)
+							local color = SV.db.UnitFrames[unitName]["castbar"]["sparkColor"]
+							return color[1], color[2], color[3], color[4]
+						end,
+						set = function(key, rValue, gValue, bValue)
+							SV.db.UnitFrames[unitName]["castbar"]["sparkColor"] = {rValue, gValue, bValue}
+							MOD:RefreshUnitFrames()
+						end,
+						disabled = function() return not SV.db.UnitFrames[unitName]["castbar"].useCustomColor end
+					},
+				}
+			},
+			formatGroup = {
+				order = 4,
+				guiInline = true,
+				type = "group",
+				name = L["Text Settings"],
+				args = {
+					format = {
+						order = 1,
+						type = "select",
+						name = L["Format"],
+						values = { ["CURRENTMAX"] = L["Current / Max"], ["CURRENT"] = L["Current"], ["REMAINING"] = L["Remaining"] }
+					},
+				}
+			}
+		}
+	}
+	if(unitName == "player") then
+		configTable.args.commonGroup.args.ticks = {
+			order = 6,
+			type = "toggle",
+			name = L["Ticks"],
+			desc = L["Display tick marks on the castbar."]
+		}
+		configTable.args.commonGroup.args.displayTarget = {
+			order = 7,
+			type = "toggle",
+			name = L["Display Target"],
+			desc = L["Display the target of your current cast."]
+		}
+	end
+	return configTable
+end
+
+function SVUIOptions:SetMiscConfigGroup(partyRaid, updateFunction, unitName, count)
+	local miscGroup = {
+		order = 99,
+		type = "group",
+		name = L["Misc Text"],
+		set = function(key, value)
+			MOD:ChangeDBVar(value, key[#key], unitName, "formatting");
+			local tag = ""
+			local pc = SV.db.UnitFrames[unitName]["formatting"].threat and "[threat]" or "";
+			tag = tag .. pc;
+			local ap = SV.db.UnitFrames[unitName]["formatting"].absorbs and "[absorbs]" or "";
+			tag = tag .. ap;
+			local cp = SV.db.UnitFrames[unitName]["formatting"].incoming and "[incoming]" or "";
+			tag = tag .. cp;
+
+			MOD:ChangeDBVar(tag, "tags", unitName, "misc");
+			updateFunction(MOD, unitName, count)
+		end,
+		args = {
+			incoming = {
+				order = 1,
+				name = L["Show Incoming Heals"],
+				type = "toggle",
+				get = function() return SV.db.UnitFrames[unitName]["formatting"].incoming end,
+			},
+			absorbs = {
+				order = 2,
+				name = L["Show Absorbs"],
+				type = "toggle",
+				get = function() return SV.db.UnitFrames[unitName]["formatting"].absorbs end,
+			},
+			threat = {
+				order = 3,
+				name = L["Show Threat"],
+				type = "toggle",
+				get = function() return SV.db.UnitFrames[unitName]["formatting"].threat end,
+			},
+			xOffset = {
+				order = 4,
+				type = "range",
+				width = "full",
+				name = L["Misc Text X Offset"],
+				desc = L["Offset position for text."],
+				min = -300,
+				max = 300,
+				step = 1,
+				get = function() return SV.db.UnitFrames[unitName]["formatting"].xOffset end,
+				set = function(key, value) MOD:ChangeDBVar(value, key[#key], unitName, "formatting"); end,
+			},
+			yOffset = {
+				order = 5,
+				type = "range",
+				width = "full",
+				name = L["Misc Text Y Offset"],
+				desc = L["Offset position for text."],
+				min = -300,
+				max = 300,
+				step = 1,
+				get = function() return SV.db.UnitFrames[unitName]["formatting"].yOffset end,
+				set = function(key, value) MOD:ChangeDBVar(value, key[#key], unitName, "formatting"); end,
+			},
+		}
+	}
+	return miscGroup
+end
+
+function SVUIOptions:SetHealthConfigGroup(partyRaid, updateFunction, unitName, count)
+	local healthOptions = {
+		order = 100,
+		type = "group",
+		name = L["Health"],
+		get = function(key)
+			return SV.db.UnitFrames[unitName]["health"][key[#key]]
+		end,
+		set = function(key, value)
+			MOD:ChangeDBVar(value, key[#key], unitName, "health");
+			updateFunction(MOD, unitName, count)
+		end,
+		args = {
+			commonGroup = {
+				order = 1,
+				type = "group",
+				guiInline = true,
+				name = L["Base Settings"],
+				args = {
+					position = {
+						type = "select",
+						order = 1,
+						name = L["Text Position"],
+						desc = L["Set the anchor for this bars value text"],
+						values = SV.PointIndexes
+					},
+					xOffset = {
+						order = 2,
+						type = "range",
+						name = L["Text xOffset"],
+						desc = L["Offset position for text."],
+						min = -300,
+						max = 300,
+						step = 1
+					},
+					yOffset = {
+						order = 3,
+						type = "range",
+						name = L["Text yOffset"],
+						desc = L["Offset position for text."],
+						min = -300,
+						max = 300,
+						step = 1
+					},
+					spacer1 = {
+						order = 4,
+						name = "",
+						type = "description",
+						width = "full",
+					},
+					reversed = {
+						type = "toggle",
+						order = 5,
+						name = L["Reverse Fill"],
+						desc = L["Invert this bars fill direction"]
+					},
+				}
+			},
+			formatGroup = {
+				order = 2,
+				type = "group",
+				guiInline = true,
+				name = L["Text Settings"],
+				set = function(key, value)
+					MOD:ChangeDBVar(value, key[#key], unitName, "formatting");
+					local tag = ""
+					local pc = SV.db.UnitFrames[unitName]["formatting"].health_colored and "[health:color]" or "";
+					tag = tag .. pc;
+
+					local pt = SV.db.UnitFrames[unitName]["formatting"].health_type;
+					if(pt and pt ~= "none") then
+						tag = tag .. "[health:" .. pt .. "]"
+					end
+
+					MOD:ChangeDBVar(tag, "tags", unitName, "health");
+					updateFunction(MOD, unitName, count)
+				end,
+				args = {
+					health_colored = {
+						order = 1,
+						name = L["Colored"],
+						type = "toggle",
+						get = function() return SV.db.UnitFrames[unitName]["formatting"].health_colored end,
+						desc = L["Use various name coloring methods"]
+					},
+					health_type = {
+						order = 3,
+						name = L["Text Format"],
+						type = "select",
+						get = function() return SV.db.UnitFrames[unitName]["formatting"].health_type end,
+						desc = L["TEXT_FORMAT_DESC"],
+						values = textStringFormats,
+					}
+				}
+			},
+			colorGroup = {
+				order = 3,
+				type = "group",
+				guiInline = true,
+				name = L["Color Settings"],
+				args = {
+					classColor = {
+						order = 1,
+						type = "toggle",
+						name = L["Class Health"],
+						desc = L["Color health by classcolor or reaction."],
+					},
+					valueColor = {
+						order = 2,
+						type = "toggle",
+						name = L["Health By Value"],
+						desc = L["Color health by amount remaining."],
+					},
+					classBackdrop = {
+						order = 3,
+						type = "toggle",
+						name = L["Class Backdrop"],
+						desc = L["Color the health backdrop by class or reaction."],
+					},
+					configureButton = {
+						order = 4,
+						name = L["Coloring"],
+						type = "execute",
+						width = 'full',
+						func = function() ACD:SelectGroup(SV.NameID, "UnitFrames", "commonGroup", "baseGroup", "allColorsGroup", "healthGroup") end
+					},
+				}
+			}
+		}
+	}
+	if SV.db.UnitFrames[unitName].health.orientation then
+		healthOptions.args.commonGroup.args.orientation = {
+			type = "select",
+			order = 6,
+			name = L["Orientation"],
+			desc = L["Direction the health bar moves when gaining/losing health."],
+			values = {["HORIZONTAL"] = L["Horizontal"], ["VERTICAL"] = L["Vertical"]}
+		}
+	end
+	if partyRaid then
+		healthOptions.args.commonGroup.args.frequentUpdates = {
+			type = "toggle",
+			order = 7,
+			name = L["Frequent Updates"],
+			desc = L["Rapidly update the health, uses more memory and cpu. Only recommended for healing."]
+		}
+	end
+	return healthOptions
+end
+
+function SVUIOptions:SetPowerConfigGroup(playerTarget, updateFunction, unitName, count)
+	local powerOptions = {
+		order = 200,
+		type = "group",
+		name = L["Power"],
+		get = function(key)
+			return SV.db.UnitFrames[unitName]["power"][key[#key]]
+		end,
+		set = function(key, value)
+			MOD:ChangeDBVar(value, key[#key], unitName, "power");
+			updateFunction(MOD, unitName, count)
+		end,
+		args = {
+			enable = {type = "toggle", order = 1, name = L["Power Bar Enabled"]},
+			commonGroup = {
+				order = 2,
+				type = "group",
+				guiInline = true,
+				name = L["Base Settings"],
+				args = {
+					detached = {
+						type = "toggle",
+						order = 1,
+						name = L["Detached"],
+						desc = L["Detach the power bar from the unit frame."]
+					},
+					anchor = {
+						type = "select",
+						order = 2,
+						name = L["Bar Position"],
+						desc = L["Set direction to anchor this bar"],
+						values = ANCHOR_SELECT
+					},
+					height = {
+						type = "range",
+						name = L["Height"],
+						width = 'full',
+						order = 4,
+						min = 3,
+						max = 250,
+						step = 1
+					},
+					width = {
+						type = "range",
+						name = L["Width"],
+						width = 'full',
+						order = 5,
+						min = 3,
+						max = 250,
+						step = 1
+					},
+				}
+			},
+			textGroup = {
+				order = 3,
+				type = "group",
+				guiInline = true,
+				name = L["Text Settings"],
+				args = {
+					position = {
+						type = "select",
+						order = 1,
+						name = L["Text Position"],
+						desc = L["Set the anchor for this bars value text"],
+						values = SV.PointIndexes
+					},
+					xOffset = {
+						order = 2,
+						type = "range",
+						name = L["Text xOffset"],
+						desc = L["Offset position for text."],
+						min = -300,
+						max = 300,
+						step = 1
+					},
+					yOffset = {
+						order = 3,
+						type = "range",
+						name = L["Text yOffset"],
+						desc = L["Offset position for text."],
+						min = -300,
+						max = 300,
+						step = 1
+					},
+				}
+			},
+			formatGroup = {
+				order = 4,
+				type = "group",
+				guiInline = true,
+				name = L["Text Formatting"],
+				set = function(key, value)
+					MOD:ChangeDBVar(value, key[#key], unitName, "formatting");
+					local tag = ""
+					local cp = SV.db.UnitFrames[unitName]["formatting"].power_class and "[classpower]" or "";
+					tag = tag .. cp;
+					local ap = SV.db.UnitFrames[unitName]["formatting"].power_alt and "[altpower]" or "";
+					tag = tag .. ap;
+					local pc = SV.db.UnitFrames[unitName]["formatting"].power_colored and "[power:color]" or "";
+					tag = tag .. pc;
+
+					local pt = SV.db.UnitFrames[unitName]["formatting"].power_type;
+					if(pt and pt ~= "none") then
+						tag = tag .. "[power:" .. pt .. "]"
+					end
+
+					MOD:ChangeDBVar(tag, "tags", unitName, "power");
+					updateFunction(MOD, unitName, count)
+				end,
+				args = {
+					power_colored = {
+						order = 1,
+						name = L["Colored"],
+						type = "toggle",
+						get = function() return SV.db.UnitFrames[unitName]["formatting"].power_colored end,
+						desc = L["Use various name coloring methods"]
+					},
+					power_class = {
+						order = 2,
+						name = L["Show Class Power"],
+						type = "toggle",
+						get = function() return SV.db.UnitFrames[unitName]["formatting"].power_class end,
+					},
+					power_alt = {
+						order = 3,
+						name = L["Show Alt Power"],
+						type = "toggle",
+						get = function() return SV.db.UnitFrames[unitName]["formatting"].power_alt end,
+					},
+					power_type = {
+						order = 4,
+						name = L["Text Format"],
+						type = "select",
+						get = function() return SV.db.UnitFrames[unitName]["formatting"].power_type end,
+						desc = L["TEXT_FORMAT_DESC"],
+						values = textStringFormats,
+					}
+				}
+			},
+			colorGroup = {
+				order = 5,
+				type = "group",
+				guiInline = true,
+				name = L["Color Settings"],
+				args = {
+					classColor = {
+						order = 1,
+						type = "toggle",
+						name = L["Class Power"],
+						desc = L["Color power by classcolor or reaction."],
+					},
+					configureButton = {
+						order = 2,
+						name = L["Coloring"],
+						type = "execute",
+						width = 'full',
+						func = function() ACD:SelectGroup(SV.NameID, "UnitFrames", "commonGroup", "baseGroup", "allColorsGroup", "powerGroup") end
+					},
+				}
+			}
+		}
+	}
+
+	if SV.db.UnitFrames[unitName].power.orientation then
+		powerOptions.args.commonGroup.args.orientation = {
+			type = "select",
+			order = 3,
+			name = L["Orientation"],
+			desc = L["Direction the power bar moves when gaining/losing power."],
+			values = {["HORIZONTAL"] = L["Horizontal"], ["VERTICAL"] = L["Vertical"]}
+		}
+	end
+
+	return powerOptions
+end
+
+function SVUIOptions:SetNameConfigGroup(updateFunction, unitName, count)
+	local k = {
+		order = 400,
+		type = "group",
+		name = L['Name'],
+		get = function(key)
+			return SV.db.UnitFrames[unitName]["name"][key[#key]]
+		end,
+		set = function(key, value)
+			MOD:ChangeDBVar(value, key[#key], unitName, "name");
+			updateFunction(MOD, unitName, count)
+		end,
+		disabled = function()
+			if(SV.db.UnitFrames[unitName].grid and SV.db.UnitFrames[unitName].grid.enable) then
+				return true
+			end
+			return false
+		end,
+		args = {
+			description = {
+				order = 1,
+				name = function()
+					if(SV.db.UnitFrames[unitName].grid and SV.db.UnitFrames[unitName].grid.enable) then
+						return L['Name Options Disabled While in Grid Mode']
+					end
+					return ''
+				end,
+				type = "description",
+				width = "full",
+			},
+			enable = {
+				type = "toggle",
+				order = 2,
+				name = L["Unit Name Enabled"],
+				get = function(key)
+					return SV.db.UnitFrames[unitName]["name"].tags ~= ""
+				end,
+				set = function(key, value)
+					MOD:ChangeDBVar(value, key[#key], unitName, "formatting");
+					local tag = ""
+					if(value == true) then
+						tag = SV.db.UnitFrames[unitName]["formatting"].name_colored and "[name:color]" or "";
+
+						local length = SV.db.UnitFrames[unitName]["formatting"].name_length;
+						tag = tag .. "[name:" .. length .. "]"
+						local lvl = SV.db.UnitFrames[unitName]["formatting"].smartlevel and "[smartlevel]" or "";
+						tag = tag .. lvl
+					end
+
+					MOD:ChangeDBVar(tag, "tags", unitName, "name");
+					updateFunction(MOD, unitName, count)
+				end,
+			},
+			commonGroup = {
+				order = 3,
+				type = "group",
+				guiInline = true,
+				name = L["Base Settings"],
+				args = {
+					position = {
+						type = "select",
+						order = 1,
+						name = L["Text Position"],
+						desc = L["Set the anchor for this units name text"],
+						values = SV.PointIndexes
+					},
+					xOffset = {
+						order = 2,
+						type = "range",
+						name = L["Text xOffset"],
+						desc = L["Offset position for text."],
+						min = -300,
+						max = 300,
+						step = 1
+					},
+					yOffset = {
+						order = 3,
+						type = "range",
+						name = L["Text yOffset"],
+						desc = L["Offset position for text."],
+						min = -300,
+						max = 300,
+						step = 1
+					},
+				}
+			},
+			fontGroup = {
+				order = 4,
+				type = "group",
+				guiInline = true,
+				name = L["Fonts"],
+				set = function(key, value)
+					MOD:ChangeDBVar(value, key[#key], unitName, "name");
+					MOD:RefreshAllUnitMedia()
+				end,
+				args = {
+					font = {
+						type = "select",
+						dialogControl = "LSM30_Font",
+						order = 0,
+						name = L["Default Font"],
+						desc = L["The font used to show unit names."],
+						values = AceVillainWidgets.font
+					},
+					fontOutline = {
+						order = 1,
+						name = L["Font Outline"],
+						desc = L["Set the font outline."],
+						type = "select",
+						values = {["NONE"] = L["None"], ["OUTLINE"] = "OUTLINE", ["MONOCHROMEOUTLINE"] = "MONOCROMEOUTLINE", ["THICKOUTLINE"] = "THICKOUTLINE"}
+					},
+					fontSize = {
+						order = 2,
+						name = L["Font Size"],
+						desc = L["Set the font size."],
+						type = "range",
+						min = 6,
+						max = 22,
+						step = 1
+					}
+				}
+			},
+			formatGroup = {
+				order = 5,
+				type = "group",
+				guiInline = true,
+				name = L["Text Settings"],
+				set = function(key, value)
+					MOD:ChangeDBVar(value, key[#key], unitName, "formatting");
+					local tag = ""
+					tag = SV.db.UnitFrames[unitName]["formatting"].name_colored and "[name:color]" or "";
+
+					local length = SV.db.UnitFrames[unitName]["formatting"].name_length;
+					tag = tag .. "[name:" .. length .. "]"
+					local lvl = SV.db.UnitFrames[unitName]["formatting"].smartlevel and "[smartlevel]" or "";
+					tag = tag .. lvl
+
+					MOD:ChangeDBVar(tag, "tags", unitName, "name");
+					updateFunction(MOD, unitName, count)
+				end,
+				args = {
+					name_colored = {
+						order = 1,
+						name = L["Colored"],
+						type = "toggle",
+						get = function() return SV.db.UnitFrames[unitName]["formatting"].name_colored end,
+						desc = L["Use various name coloring methods"]
+					},
+					smartlevel = {
+						order = 2,
+						name = L["Unit Level"],
+						type = "toggle",
+						get = function() return SV.db.UnitFrames[unitName]["formatting"].smartlevel end,
+						desc = L["Display the units level"]
+					},
+					name_length = {
+						order = 3,
+						name = L["Name Length"],
+						desc = L["TEXT_FORMAT_DESC"],
+						type = "range",
+						get = function() return SV.db.UnitFrames[unitName]["formatting"].name_length end,
+						min = 1,
+						max = 30,
+						step = 1
+					}
+				}
+			}
+		}
+	}
+	return k
+end
+
+local portraitStyles = {["2D"] = L["2D"], ["3D"] = L["3D"], ["3DOVERLAY"] = L["3D Overlay"]};
+
+function SVUIOptions:SetPortraitConfigGroup(updateFunction, unitName, count)
+	local k = {
+		order = 400,
+		type = "group",
+		name = L["Portrait"],
+		get = function(key)
+			return SV.db.UnitFrames[unitName]["portrait"][key[#key]]
+		end,
+		set = function(key, value)
+			MOD:ChangeDBVar(value, key[#key], unitName, "portrait")
+			updateFunction(MOD, unitName, count)
+		end,
+		args = {
+			enable = {
+				type = "toggle",
+				order = 1,
+				name = L["Unit Portrait Enabled"]
+			},
+			styleGroup = {
+				order = 2,
+				type = "group",
+				guiInline = true,
+				name = L["Base Settings"],
+				args = {
+					style = {
+						order = 1,
+						type = "select",
+						name = L["Style"],
+						desc = L["Select the display method of the portrait. NOTE: if overlay is set then only 3D will be available"],
+						values = portraitStyles
+					},
+					width = {
+						order = 2,
+						type = "range",
+						name = L["Width"],
+						min = 15,
+						max = 150,
+						step = 1,
+						disabled = function() return SV.db.UnitFrames[unitName]["portrait"].style == "3DOVERLAY" end
+					}
+				}
+			},
+			modGroup = {
+				order = 3,
+				type = "group",
+				guiInline = true,
+				name = L["3D Settings (Reload required to take affect)"],
+				disabled = function() return SV.db.UnitFrames[unitName]["portrait"].style == "2D" end,
+				args = {
+					rotation = {
+						order = 1,
+						type = "range",
+						name = L["Model Rotation"],
+						min = 0,
+						max = 360,
+						step = 1
+					},
+					camDistanceScale = {
+						order = 2,
+						type = "range",
+						name = L["Camera Distance Scale"],
+						desc = L["How far away the portrait is from the camera."],
+						min = 0.01,
+						max = 4,
+						step = 0.01
+					},
+				}
+			}
+		}
+	}
+	return k
+end
+
+function SVUIOptions:SetIconConfigGroup(updateFunction, unitName, count)
+	local iconGroup = SV.db.UnitFrames[unitName]["icons"]
+	local grouporder = 1
+	local k = {
+		order = 5000,
+		type = "group",
+		name = L["Icons"],
+		get = function(key)
+			return SV.db.UnitFrames[unitName]["icons"][key[#key]]
+		end,
+		set = function(key, value)
+			MOD:ChangeDBVar(value, key[#key], unitName, "icons")
+			updateFunction(MOD, unitName, count)
+		end,
+		args = {}
+	};
+
+	if(iconGroup["classIcon"]) then
+		k.args.classIcon = {
+			order = grouporder,
+			type = "group",
+			guiInline = true,
+			name = L["Class Icons"],
+			get = function(key)
+				return SV.db.UnitFrames[unitName]["icons"]["classIcon"][key[#key]]
+			end,
+			set = function(key, value)
+				MOD:ChangeDBVar(value, key[#key], unitName, "icons", "classIcon")
+				updateFunction(MOD, unitName, count)
+			end,
+			args = {
+				enable = {type = "toggle", order = 1, name = L["Enable"]},
+				attachTo = {type = "select", order = 2, name = L["Position"], values = SV.PointIndexes},
+				spacer = { order = 3, name = "", type = "description", width = "full"},
+				size = {type = "range", name = L["Size"], order = 3, min = 8, max = 60, step = 1},
+				xOffset = {order = 4, type = "range", name = L["xOffset"], min = -300, max = 300, step = 1},
+				yOffset = {order = 5, type = "range", name = L["yOffset"], min = -300, max = 300, step = 1}
+			}
+		}
+		grouporder = grouporder + 1
+	end
+
+	if(iconGroup["raidicon"]) then
+		k.args.raidicon = {
+			order = grouporder,
+			type = "group",
+			guiInline = true,
+			name = L["Raid Marker"],
+			get = function(key)
+				return SV.db.UnitFrames[unitName]["icons"]["raidicon"][key[#key]]
+			end,
+			set = function(key, value)
+				MOD:ChangeDBVar(value, key[#key], unitName, "icons", "raidicon")
+				updateFunction(MOD, unitName, count)
+			end,
+			args = {
+				enable = {type = "toggle", order = 1, name = L["Enable"]},
+				attachTo = {type = "select", order = 2, name = L["Position"], values = SV.PointIndexes},
+				spacer = { order = 3, name = "", type = "description", width = "full"},
+				size = {type = "range", name = L["Size"], order = 3, min = 8, max = 60, step = 1},
+				xOffset = {order = 4, type = "range", name = L["xOffset"], min = -300, max = 300, step = 1},
+				yOffset = {order = 5, type = "range", name = L["yOffset"], min = -300, max = 300, step = 1}
+			}
+		}
+		grouporder = grouporder + 1
+	end
+
+	if(iconGroup["aggroIcon"]) then
+		k.args.aggroIcon = {
+			order = grouporder,
+			type = "group",
+			guiInline = true,
+			name = L["Aggro (aka: !)"],
+			get = function(key)
+				return SV.db.UnitFrames[unitName]["icons"]["aggroIcon"][key[#key]]
+			end,
+			set = function(key, value)
+				MOD:ChangeDBVar(value, key[#key], unitName, "icons", "aggroIcon")
+				updateFunction(MOD, unitName, count)
+			end,
+			args = {
+				enable = {type = "toggle", order = 1, name = L["Enable"]},
+				attachTo = {type = "select", order = 2, name = L["Position"], values = SV.PointIndexes},
+				spacer = { order = 3, name = "", type = "description", width = "full"},
+				size = {type = "range", name = L["Size"], order = 3, min = 8, max = 60, step = 1},
+				xOffset = {order = 4, type = "range", name = L["xOffset"], min = -300, max = 300, step = 1},
+				yOffset = {order = 5, type = "range", name = L["yOffset"], min = -300, max = 300, step = 1}
+			}
+		}
+		grouporder = grouporder + 1
+	end
+
+	if(iconGroup["combatIcon"]) then
+		k.args.combatIcon = {
+			order = grouporder,
+			type = "group",
+			guiInline = true,
+			name = L["Combat"],
+			get = function(key)
+				return SV.db.UnitFrames[unitName]["icons"]["combatIcon"][key[#key]]
+			end,
+			set = function(key, value)
+				MOD:ChangeDBVar(value, key[#key], unitName, "icons", "combatIcon")
+				updateFunction(MOD, unitName, count)
+			end,
+			args = {
+				enable = {type = "toggle", order = 1, name = L["Enable"]},
+				attachTo = {type = "select", order = 2, name = L["Position"], values = SV.PointIndexes},
+				spacer = { order = 3, name = "", type = "description", width = "full"},
+				size = {type = "range", name = L["Size"], order = 3, min = 8, max = 60, step = 1},
+				xOffset = {order = 4, type = "range", name = L["xOffset"], min = -300, max = 300, step = 1},
+				yOffset = {order = 5, type = "range", name = L["yOffset"], min = -300, max = 300, step = 1}
+			}
+		}
+		grouporder = grouporder + 1
+	end
+
+	if(iconGroup["restIcon"]) then
+		k.args.restIcon = {
+			order = grouporder,
+			type = "group",
+			guiInline = true,
+			name = L["Resting"],
+			get = function(key)
+				return SV.db.UnitFrames[unitName]["icons"]["restIcon"][key[#key]]
+			end,
+			set = function(key, value)
+				MOD:ChangeDBVar(value, key[#key], unitName, "icons", "restIcon")
+				updateFunction(MOD, unitName, count)
+			end,
+			args = {
+				enable = {type = "toggle", order = 1, name = L["Enable"]},
+				attachTo = {type = "select", order = 2, name = L["Position"], values = SV.PointIndexes},
+				spacer = { order = 3, name = "", type = "description", width = "full"},
+				size = {type = "range", name = L["Size"], order = 3, min = 8, max = 60, step = 1},
+				xOffset = {order = 4, type = "range", name = L["xOffset"], min = -300, max = 300, step = 1},
+				yOffset = {order = 5, type = "range", name = L["yOffset"], min = -300, max = 300, step = 1}
+			}
+		}
+		grouporder = grouporder + 1
+	end
+
+	if(iconGroup["classicon"]) then
+		k.args.classicon = {
+			order = grouporder,
+			type = "group",
+			guiInline = true,
+			name = L["Class"],
+			get = function(key)
+				return SV.db.UnitFrames[unitName]["icons"]["classicon"][key[#key]]
+			end,
+			set = function(key, value)
+				MOD:ChangeDBVar(value, key[#key], unitName, "icons", "classicon")
+				updateFunction(MOD, unitName, count)
+			end,
+			args = {
+				enable = {type = "toggle", order = 1, name = L["Enable"]},
+				attachTo = {type = "select", order = 2, name = L["Position"], values = SV.PointIndexes},
+				spacer = { order = 3, name = "", type = "description", width = "full"},
+				size = {type = "range", name = L["Size"], order = 3, min = 8, max = 60, step = 1},
+				xOffset = {order = 4, type = "range", name = L["xOffset"], min = -300, max = 300, step = 1},
+				yOffset = {order = 5, type = "range", name = L["yOffset"], min = -300, max = 300, step = 1}
+			}
+		}
+		grouporder = grouporder + 1
+	end
+
+	if(iconGroup["eliteicon"]) then
+		k.args.eliteicon = {
+			order = grouporder,
+			type = "group",
+			guiInline = true,
+			name = L["Elite / Rare"],
+			get = function(key)
+				return SV.db.UnitFrames[unitName]["icons"]["eliteicon"][key[#key]]
+			end,
+			set = function(key, value)
+				MOD:ChangeDBVar(value, key[#key], unitName, "icons", "eliteicon")
+				updateFunction(MOD, unitName, count)
+			end,
+			args = {
+				enable = {type = "toggle", order = 1, name = L["Enable"]},
+				attachTo = {type = "select", order = 2, name = L["Position"], values = SV.PointIndexes},
+				spacer = { order = 3, name = "", type = "description", width = "full"},
+				size = {type = "range", name = L["Size"], order = 3, min = 8, max = 60, step = 1},
+				xOffset = {order = 4, type = "range", name = L["xOffset"], min = -300, max = 300, step = 1},
+				yOffset = {order = 5, type = "range", name = L["yOffset"], min = -300, max = 300, step = 1}
+			}
+		}
+		grouporder = grouporder + 1
+	end
+
+	if(iconGroup["roleIcon"]) then
+		k.args.roleIcon = {
+			order = grouporder,
+			type = "group",
+			guiInline = true,
+			name = L["Role"],
+			get = function(key)
+				return SV.db.UnitFrames[unitName]["icons"]["roleIcon"][key[#key]]
+			end,
+			set = function(key, value)
+				MOD:ChangeDBVar(value, key[#key], unitName, "icons", "roleIcon")
+				updateFunction(MOD, unitName, count)
+			end,
+			args = {
+				enable = {type = "toggle", order = 1, name = L["Enable"]},
+				attachTo = {type = "select", order = 2, name = L["Position"], values = SV.PointIndexes},
+				spacer = { order = 3, name = "", type = "description", width = "full"},
+				size = {type = "range", name = L["Size"], order = 3, min = 8, max = 60, step = 1},
+				xOffset = {order = 4, type = "range", name = L["xOffset"], min = -300, max = 300, step = 1},
+				yOffset = {order = 5, type = "range", name = L["yOffset"], min = -300, max = 300, step = 1}
+			}
+		}
+		grouporder = grouporder + 1
+	end
+
+	if(iconGroup["raidRoleIcons"]) then
+		k.args.raidRoleIcons = {
+			order = grouporder,
+			type = "group",
+			guiInline = true,
+			name = L["Leader / MasterLooter"],
+			get = function(key)
+				return SV.db.UnitFrames[unitName]["icons"]["raidRoleIcons"][key[#key]]
+			end,
+			set = function(key, value)
+				MOD:ChangeDBVar(value, key[#key], unitName, "icons", "raidRoleIcons")
+				updateFunction(MOD, unitName, count)
+			end,
+			args = {
+				enable = {type = "toggle", order = 1, name = L["Enable"]},
+				attachTo = {type = "select", order = 2, name = L["Position"], values = SV.PointIndexes},
+				spacer = { order = 3, name = "", type = "description", width = "full"},
+				size = {type = "range", name = L["Size"], order = 3, min = 8, max = 60, step = 1},
+				xOffset = {order = 4, type = "range", name = L["xOffset"], min = -300, max = 300, step = 1},
+				yOffset = {order = 5, type = "range", name = L["yOffset"], min = -300, max = 300, step = 1}
+			}
+		}
+		grouporder = grouporder + 1
+	end
+
+	return k
+end
+
+local BoolFilters = {
+	['player'] = true,
+	['pet'] = true,
+	['boss'] = true,
+	['arena'] = true,
+	['party'] = true,
+	['raid'] = true,
+	['raidpet'] = true,
+};
+
+local function setAuraFilteringOptions(configTable, unitName, auraType, updateFunction, isPlayer)
+	if BoolFilters[unitName] then
+		configTable.filterGroup = {
+			order = 20,
+			guiInline = true,
+			type = "group",
+			name = L["Aura filtering..."],
+			args = {
+				filterWhiteList = {
+					order = 1,
+					type = "toggle",
+					name = L["Only White Listed"],
+					desc = L["Only show auras that are on the whitelist."],
+					get = function(key)return SV.db.UnitFrames[unitName][auraType].filterWhiteList end,
+					set = function(key, value)
+						SV.db.UnitFrames[unitName][auraType].filterWhiteList = value;
+						if(value) then
+							SV.db.UnitFrames[unitName][auraType].filterPlayer = false;
+							SV.db.UnitFrames[unitName][auraType].filterDispellable = false;
+							SV.db.UnitFrames[unitName][auraType].filterInfinite = false;
+							SV.db.UnitFrames[unitName][auraType].filterRaid = false;
+						end
+						updateFunction(MOD, unitName)
+					end,
+				},
+				filterPlayer = {
+					order = 2,
+					type = "toggle",
+					name = L["From You"],
+					desc = L["Only show auras that were cast by you."],
+					get = function(key) return SV.db.UnitFrames[unitName][auraType].filterPlayer end,
+					set = function(key, value) SV.db.UnitFrames[unitName][auraType].filterPlayer = value; updateFunction(MOD, unitName) end,
+					disabled = function() return SV.db.UnitFrames[unitName][auraType].filterWhiteList end,
+				},
+				filterDispellable = {
+					order = 3,
+					type = "toggle",
+					name = L["You Can Remove"],
+					desc = L["Only show auras that can be removed by you. (example: Purge, Dispel)"],
+					get = function(key) return SV.db.UnitFrames[unitName][auraType].filterDispellable end,
+					set = function(key, value) SV.db.UnitFrames[unitName][auraType].filterDispellable = value; updateFunction(MOD, unitName) end,
+					disabled = function() return SV.db.UnitFrames[unitName][auraType].filterWhiteList end,
+				},
+				filterInfinite = {
+					order = 4,
+					type = "toggle",
+					name = L["No Duration"],
+					desc = L["Don't display auras that have no duration."],
+					get = function(key) return SV.db.UnitFrames[unitName][auraType].filterInfinite end,
+					set = function(key, value) SV.db.UnitFrames[unitName][auraType].filterInfinite = value; updateFunction(MOD, unitName) end,
+					disabled = function() return SV.db.UnitFrames[unitName][auraType].filterWhiteList end,
+				},
+				filterRaid = {
+					order = 5,
+					type = "toggle",
+					name = L["Consolidated Buffs"],
+					desc = L["Don't display consolidated buffs"],
+					get = function(key) return SV.db.UnitFrames[unitName][auraType].filterRaid end,
+					set = function(key, value) SV.db.UnitFrames[unitName][auraType].filterRaid = value; updateFunction(MOD, unitName) end,
+					disabled = function() return SV.db.UnitFrames[unitName][auraType].filterWhiteList end,
+				},
+			}
+		}
+	else
+		configTable.friendlyGroup = {
+			order = 20,
+			guiInline = true,
+			type = "group",
+			name = L["When the unit is friendly..."],
+			args = {
+				filterAll = {
+					order = 1,
+					type = "toggle",
+					name = L["Hide All"],
+					desc = L["Don't display any " .. auraType .. "."],
+					get = function(key) return SV.db.UnitFrames[unitName][auraType].filterAll.friendly end,
+					set = function(key, value)
+						SV.db.UnitFrames[unitName][auraType].filterAll.friendly = value;
+						if(value) then
+							SV.db.UnitFrames[unitName][auraType].filterWhiteList.friendly = false;
+							SV.db.UnitFrames[unitName][auraType].filterPlayer.friendly = false;
+							SV.db.UnitFrames[unitName][auraType].filterDispellable.friendly = false;
+							SV.db.UnitFrames[unitName][auraType].filterInfinite.friendly = false;
+							if(SV.db.UnitFrames[unitName][auraType].filterRaid) then
+								SV.db.UnitFrames[unitName][auraType].filterRaid.friendly = false;
+							end
+						end
+						updateFunction(MOD, unitName)
+					end,
+				},
+				filterWhiteList = {
+					order = 2,
+					type = "toggle",
+					name = L["Only White Listed"],
+					desc = L["Only show auras that are on the whitelist."],
+					get = function(key)return SV.db.UnitFrames[unitName][auraType].filterWhiteList.friendly end,
+					set = function(key, value)SV.db.UnitFrames[unitName][auraType].filterWhiteList.friendly = value; updateFunction(MOD, unitName) end,
+					set = function(key, value)
+						SV.db.UnitFrames[unitName][auraType].filterWhiteList.friendly = value;
+						if(value) then
+							SV.db.UnitFrames[unitName][auraType].filterPlayer.friendly = false;
+							SV.db.UnitFrames[unitName][auraType].filterDispellable.friendly = false;
+							SV.db.UnitFrames[unitName][auraType].filterInfinite.friendly = false;
+							if(SV.db.UnitFrames[unitName][auraType].filterRaid) then
+								SV.db.UnitFrames[unitName][auraType].filterRaid.friendly = false;
+							end
+						end
+						updateFunction(MOD, unitName)
+					end,
+					disabled = function()
+						return SV.db.UnitFrames[unitName][auraType].filterAll.friendly
+					end,
+				},
+				filterPlayer = {
+					order = 3,
+					type = "toggle",
+					name = L["From You"],
+					desc = L["Only show auras that were cast by you."],
+					get = function(key)return SV.db.UnitFrames[unitName][auraType].filterPlayer.friendly end,
+					set = function(key, value)SV.db.UnitFrames[unitName][auraType].filterPlayer.friendly = value; updateFunction(MOD, unitName) end,
+					disabled = function()
+						return (SV.db.UnitFrames[unitName][auraType].filterAll.friendly or SV.db.UnitFrames[unitName][auraType].filterWhiteList.friendly)
+					end,
+				},
+				filterDispellable = {
+					order = 4,
+					type = "toggle",
+					name = L["You Can Remove"],
+					desc = L["Only show auras that can be removed by you. (example: Purge, Dispel)"],
+					get = function(key)return SV.db.UnitFrames[unitName][auraType].filterDispellable.friendly end,
+					set = function(key, value)SV.db.UnitFrames[unitName][auraType].filterDispellable.friendly = value; updateFunction(MOD, unitName) end,
+					disabled = function()
+						return (SV.db.UnitFrames[unitName][auraType].filterAll.friendly or SV.db.UnitFrames[unitName][auraType].filterWhiteList.friendly)
+					end,
+				},
+				filterInfinite = {
+					order = 5,
+					type = "toggle",
+					name = L["No Duration"],
+					desc = L["Don't display auras that have no duration."],
+					get = function(key)return SV.db.UnitFrames[unitName][auraType].filterInfinite.friendly end,
+					set = function(key, value)SV.db.UnitFrames[unitName][auraType].filterInfinite.friendly = value; updateFunction(MOD, unitName) end,
+					disabled = function()
+						return (SV.db.UnitFrames[unitName][auraType].filterAll.friendly or SV.db.UnitFrames[unitName][auraType].filterWhiteList.friendly)
+					end,
+				},
+			},
+		}
+		configTable.enemyGroup = {
+			order = 21,
+			guiInline = true,
+			type = "group",
+			name = L["When the unit is hostile..."],
+			args = {
+				filterAll = {
+					order = 1,
+					type = "toggle",
+					name = L["Hide All"],
+					desc = L["Don't display any " .. auraType .. "."],
+					get = function(key)return SV.db.UnitFrames[unitName][auraType].filterAll.enemy end,
+					set = function(key, value)
+						SV.db.UnitFrames[unitName][auraType].filterAll.enemy = value;
+						if(value) then
+							SV.db.UnitFrames[unitName][auraType].filterWhiteList.enemy = false;
+							SV.db.UnitFrames[unitName][auraType].filterPlayer.enemy = false;
+							SV.db.UnitFrames[unitName][auraType].filterDispellable.enemy = false;
+							SV.db.UnitFrames[unitName][auraType].filterInfinite.enemy = false;
+							if(SV.db.UnitFrames[unitName][auraType].filterRaid) then
+								SV.db.UnitFrames[unitName][auraType].filterRaid.enemy = false;
+							end
+						end
+						updateFunction(MOD, unitName)
+					end,
+				},
+				filterWhiteList = {
+					order = 2,
+					type = "toggle",
+					name = L["Only White Listed"],
+					desc = L["Only show auras that are on the whitelist."],
+					get = function(key)return SV.db.UnitFrames[unitName][auraType].filterWhiteList.enemy end,
+					set = function(key, value)
+						SV.db.UnitFrames[unitName][auraType].filterWhiteList.enemy = value;
+						if(value) then
+							SV.db.UnitFrames[unitName][auraType].filterPlayer.enemy = false;
+							SV.db.UnitFrames[unitName][auraType].filterDispellable.enemy = false;
+							SV.db.UnitFrames[unitName][auraType].filterInfinite.enemy = false;
+							if(SV.db.UnitFrames[unitName][auraType].filterRaid) then
+								SV.db.UnitFrames[unitName][auraType].filterRaid.enemy = false;
+							end
+						end
+						updateFunction(MOD, unitName)
+					end,
+					disabled = function()
+						return SV.db.UnitFrames[unitName][auraType].filterAll.enemy
+					end,
+				},
+				filterPlayer = {
+					order = 3,
+					type = "toggle",
+					name = L["From You"],
+					desc = L["Only show auras that were cast by you."],
+					get = function(key)return SV.db.UnitFrames[unitName][auraType].filterPlayer.enemy end,
+					set = function(key, value)SV.db.UnitFrames[unitName][auraType].filterPlayer.enemy = value; updateFunction(MOD, unitName) end,
+					disabled = function()
+						return (SV.db.UnitFrames[unitName][auraType].filterAll.enemy or SV.db.UnitFrames[unitName][auraType].filterWhiteList.enemy)
+					end,
+				},
+				filterDispellable = {
+					order = 4,
+					type = "toggle",
+					name = L["You Can Remove"],
+					desc = L["Only show auras that can be removed by you. (example: Purge, Dispel)"],
+					get = function(key)return SV.db.UnitFrames[unitName][auraType].filterDispellable.enemy end,
+					set = function(key, value)SV.db.UnitFrames[unitName][auraType].filterDispellable.enemy = value; updateFunction(MOD, unitName) end,
+					disabled = function()
+						return (SV.db.UnitFrames[unitName][auraType].filterAll.enemy or SV.db.UnitFrames[unitName][auraType].filterWhiteList.enemy)
+					end,
+				},
+				filterInfinite = {
+					order = 5,
+					type = "toggle",
+					name = L["No Duration"],
+					desc = L["Don't display auras that have no duration."],
+					get = function(key)return SV.db.UnitFrames[unitName][auraType].filterInfinite.enemy end,
+					set = function(key, value)SV.db.UnitFrames[unitName][auraType].filterInfinite.enemy = value; updateFunction(MOD, unitName) end,
+					disabled = function()
+						return (SV.db.UnitFrames[unitName][auraType].filterAll.enemy or SV.db.UnitFrames[unitName][auraType].filterWhiteList.enemy)
+					end,
+				},
+			},
+		}
+
+		if(SV.db.UnitFrames[unitName][auraType].filterRaid) then
+			configTable.friendlyGroup.args.filterRaid = {
+				order = 6,
+				type = "toggle",
+				name = L["Consolidated Buffs"],
+				desc = L["Don't display consolidated buffs"],
+				get = function(key)return SV.db.UnitFrames[unitName][auraType].filterRaid.friendly end,
+				set = function(key, value)SV.db.UnitFrames[unitName][auraType].filterRaid.friendly = value; updateFunction(MOD, unitName) end,
+				disabled = function()
+					return (SV.db.UnitFrames[unitName][auraType].filterAll.friendly or SV.db.UnitFrames[unitName][auraType].filterWhiteList.friendly)
+				end,
+			};
+			configTable.enemyGroup.args.filterRaid = {
+				order = 6,
+				type = "toggle",
+				name = L["Consolidated Buffs"],
+				desc = L["Don't display consolidated buffs"],
+				get = function(key)return SV.db.UnitFrames[unitName][auraType].filterRaid.enemy end,
+				set = function(key, value)SV.db.UnitFrames[unitName][auraType].filterRaid.enemy = value; updateFunction(MOD, unitName) end,
+				disabled = function()
+					return (SV.db.UnitFrames[unitName][auraType].filterAll.enemy or SV.db.UnitFrames[unitName][auraType].filterWhiteList.enemy)
+				end,
+			};
+		end
+	end
+end
+
+function SVUIOptions:SetAuraConfigGroup(isPlayer, auraType, unused, updateFunction, unitName, count)
+	local groupOrder = auraType == "buffs" and 600 or 700
+	local groupName = auraType == "buffs" and L["Buffs"] or L["Debuffs"]
+	local attachToValue, attachToName;
+	if auraType == "buffs" then
+		attachToValue = "DEBUFFS"
+		attachToName = L["Debuffs"]
+	else
+		attachToValue = "BUFFS"
+		attachToName = L["Buffs"]
+	end
+
+	local configTable = {
+		order = groupOrder,
+		name = groupName,
+		type = "group",
+		get = function(key)
+			return SV.db.UnitFrames[unitName][auraType][key[#key]]
+		end,
+		set = function(key, value)
+			MOD:ChangeDBVar(value, key[#key], unitName, auraType)
+			updateFunction(MOD, unitName, count)
+		end,
+		args = {
+			enable = {
+				type = "toggle",
+				order = 2,
+				name = L["Enable "..groupName]
+			},
+			attachTo1 = {
+				type = "toggle",
+				order = 3,
+				name = L["Attach To"] .. " " .. L["Frame"],
+				get = function(key)
+					return SV.db.UnitFrames[unitName][auraType]["attachTo"] == "FRAME"
+				end,
+				set = function(key, value)
+					if(not value) then
+						MOD:ChangeDBVar(attachToValue, "attachTo", unitName, auraType)
+					else
+						MOD:ChangeDBVar("FRAME", "attachTo", unitName, auraType)
+					end
+					updateFunction(MOD, unitName, count)
+				end,
+			},
+			attachTo2 = {
+				type = "toggle",
+				order = 4,
+				name = L["Attach To"] .. " " .. attachToName,
+				get = function(key)
+					return SV.db.UnitFrames[unitName][auraType]["attachTo"] == attachToValue
+				end,
+				set = function(key, value)
+					if(not value) then
+						MOD:ChangeDBVar("FRAME", "attachTo", unitName, auraType)
+					else
+						MOD:ChangeDBVar(attachToValue, "attachTo", unitName, auraType)
+					end
+					updateFunction(MOD, unitName, count)
+				end,
+			},
+			spacer1 = {
+				order = 5,
+				name = "",
+				type = "description",
+				width = "full",
+			},
+			anchorPoint = {
+				type = "select",
+				order = 6,
+				name = L["Anchor Point"],
+				desc = L["What point to anchor to the frame you set to attach to."],
+				values = SV.PointIndexes
+			},
+			verticalGrowth = {
+				type = "select",
+				order = 7,
+				name = L["Vertical Growth"],
+				desc = L["The vertical direction that the auras will position themselves"],
+				values = {UP = "UP", DOWN = "DOWN"}
+			},
+			horizontalGrowth = {
+				type = "select",
+				order = 8,
+				name = L["Horizontal Growth"],
+				desc = L["The horizontal direction that the auras will position themselves"],
+				values = {LEFT = "LEFT", RIGHT = "RIGHT"}
+			},
+			spacer2 = {
+				order = 9,
+				name = "",
+				type = "description",
+				width = "full",
+			},
+			perrow = {
+				type = "range",
+				order = 10,
+				name = L["Per Row"],
+				min = 1,
+				max = 20,
+				step = 1
+			},
+			numrows = {
+				type = "range",
+				order = 11,
+				name = L["Num Rows"],
+				min = 1,
+				max = 4,
+				step = 1
+			},
+			sizeOverride = {
+				type = "range",
+				order = 12,
+				name = L["Size Override"],
+				desc = L["If not set to 0 then override the size of the aura icons (or height of aura bars)."],
+				min = 0,
+				max = 60,
+				step = 1
+			},
+			barWidthOverride = {
+				type = "range",
+				order = 13,
+				name = L["Bar Width Override"],
+				desc = L["If not set to 0 then override the width of aura bars."],
+				min = 0,
+				max = 500,
+				step = 1
+			},
+			spacer3 = {
+				order = 14,
+				name = "",
+				type = "description",
+				width = "full",
+			},
+			xOffset = {
+				order = 15,
+				type = "range",
+				name = L["xOffset"],
+				min = -60,
+				max = 60,
+				step = 1
+			},
+			yOffset = {
+				order = 16,
+				type = "range",
+				name = L["yOffset"],
+				min = -60,
+				max = 60,
+				step = 1
+			},
+			spacing = {
+				order = 17,
+				name = L["Aura Spacing"],
+				type = "range",
+				min = 0,
+				max = 20,
+				step = 1,
+				width = "fill",
+			},
+			useFilter = {
+				order = 18,
+				type = "select",
+				name = L["Custom Filter"],
+				desc = L["Select a custom filter to include."],
+				values = function()
+					filterList = {}
+					filterList[""] = NONE;
+					for n in pairs(SV.db.Filters.Custom) do
+						filterList[n] = n
+					end
+					return filterList
+				end,
+				get = function(key) return SV.db.UnitFrames[unitName][auraType].useFilter end,
+				set = function(key, value) SV.db.UnitFrames[unitName][auraType].useFilter = value; updateFunction(MOD, unitName) end,
+			},
+			spacer4 = {
+				order = 19,
+				name = "",
+				type = "description",
+				width = "full",
+			},
+		}
+	}
+
+	local unitGlobalName = FRAME_MAP[unitName];
+	if(unitGlobalName) then
+		configTable.args.showAuras = {
+			order = 0,
+			type = "execute",
+			name = L["Show Auras"],
+			func = function()
+				local unitframe = _G[unitGlobalName];
+				if unitframe.forceShowAuras then
+					unitframe.forceShowAuras = nil
+				else
+					unitframe.forceShowAuras = true
+				end
+				updateFunction(MOD, unitName, count)
+			end
+		}
+		configTable.args.showAurasSpacer = {
+			order = 1,
+			name = "",
+			type = "description",
+			width = "full",
+		}
+	end
+
+	setAuraFilteringOptions(configTable.args, unitName, auraType, updateFunction, isPlayer)
+
+	if(unitName == 'player' or unitName == 'target' or unitName == 'focus') then
+		configTable.args.barGroup = {
+			order = 20,
+			type = "group",
+			guiInline = true,
+			name = L["Bar Style "..groupName],
+			args = {
+				useBars = {
+					type = "toggle",
+					order = 1,
+					name = L["Enable"]
+				},
+				configureButton1 = {
+					order = 2,
+					name = L["Coloring"],
+					type = "execute", func = function() ACD:SelectGroup(SV.NameID, "UnitFrames", "commonGroup", "baseGroup", "allColorsGroup", "auraBars") end,
+					disabled = function() return not SV.db.UnitFrames[unitName][auraType].useBars end,
+				},
+				configureButton2 = {
+					order = 3,
+					name = L["Coloring (Specific)"],
+					type = "execute", func = function() SVUIOptions:SetToFilterConfig("AuraBars") end,
+					disabled = function() return not SV.db.UnitFrames[unitName][auraType].useBars end,
+				},
+				spacer = {
+					order = 4,
+					name = "",
+					type = "description",
+					width = "full",
+					disabled = function() return not SV.db.UnitFrames[unitName][auraType].useBars end,
+				},
+				sort = {
+					type = "select",
+					order = 5,
+					name = L["Sort Method"],
+					values = {["TIME_REMAINING"] = L["Time Remaining"], ["TIME_REMAINING_REVERSE"] = L["Time Remaining Reverse"], ["TIME_DURATION"] = L["Duration"], ["TIME_DURATION_REVERSE"] = L["Duration Reverse"], ["NAME"] = NAME, ["NONE"] = NONE},
+					disabled = function() return not SV.db.UnitFrames[unitName][auraType].useBars end,
+				},
+			}
+		}
+	end
+
+	return configTable
+end
+
+SV:GenerateFontOptionGroup("UnitFrame", 6, "Fonts used in unit frames.", unitFonts)
+
+SVUIOptions.FilterOptionGroups['AuraBars'] = function(selectedSpell)
+	if(not SV.db.Filters.AuraBars) then SV.db.Filters.AuraBars = {} end;
+
+	local RESULT = {
+		type = "group",
+		name = 'AuraBars',
+		guiInline = true,
+		order = 10,
+		args = {
+			addSpell = {
+				order = 1,
+				name = L["Add Spell"] ..  " by ID",
+				desc = L["Add a spell to the filter by ID (number). You can use wowhead.com to find the ID of your desired spell"],
+				type = "input",
+				guiInline = true,
+				get = function(key) return "" end,
+				set = function(key, value)
+					local spellID = tonumber(value);
+					if(not spellID) then
+						SV:AddonMessage(L["Value must be a number"])
+					elseif(not GetSpellInfo(spellID)) then
+						SV:AddonMessage(L["Not valid spell id"])
+					elseif not SV.db.Filters.AuraBars[value] then
+						SV.db.Filters.AuraBars[value] = false
+						MOD:SetUnitFrame("player")
+						MOD:SetUnitFrame("target")
+						MOD:SetUnitFrame("focus")
+						SVUIOptions:SetFilterOptions('AuraBars', value)
+					end
+				end
+			},
+			removeSpell = {
+				order = 2,
+				name = L["Remove Spell"],
+				desc = L["Remove a spell from the filter."],
+				type = "select",
+				guiInline = true,
+				disabled = function()
+					local EMPTY = true;
+					for g in pairs(SV.db.Filters.AuraBars) do
+						EMPTY = false;
+					end
+					return EMPTY
+				end,
+				values = function()
+					wipe(tempFilterTable)
+					for stringID,color in pairs(SV.db.Filters.AuraBars) do
+						local spellID
+						if(type(stringID) ~= 'number') then
+							spellID = tonumber(stringID)
+						else
+							spellID = stringID
+							stringID = tostring(stringID)
+						end
+						local auraName = GetSpellInfo(spellID)
+						tempFilterTable[stringID] = auraName
+						--print(stringID)print(auraName)print('-----')
+					end
+					return tempFilterTable
+				end,
+				get = function(key) return "" end,
+				set = function(key, value)
+					--print(value)
+					SV.db.Filters.AuraBars[value] = nil
+					MOD:SetUnitFrame("player")
+					MOD:SetUnitFrame("target")
+					MOD:SetUnitFrame("focus")
+					SVUIOptions:SetFilterOptions('AuraBars')
+				end
+			},
+			selectSpell = {
+				name = L["Select Spell"],
+				type = "select",
+				order = 3,
+				guiInline = true,
+				get = function(key) return selectedSpell end,
+				set = function(key, value)
+					SVUIOptions:SetFilterOptions('AuraBars', value)
+				end,
+				values = function()
+					wipe(tempFilterTable)
+					tempFilterTable[""] = NONE;
+					for stringID,color in pairs(SV.db.Filters.AuraBars) do
+						local spellID
+						if(type(stringID) ~= 'number') then
+							spellID = tonumber(stringID)
+						else
+							spellID = stringID
+							stringID = tostring(stringID)
+						end
+						local auraName = GetSpellInfo(spellID)
+						tempFilterTable[stringID] = auraName
+					end
+					return tempFilterTable
+				end
+			}
+		}
+	};
+
+	return RESULT;
+end;
+
+SVUIOptions.FilterOptionSpells['AuraBars'] = function(selectedSpell)
+	if(not SV.db.Filters.AuraBars) then SV.db.Filters.AuraBars = {} end;
+	local RESULT;
+	if(selectedSpell and (SV.db.Filters.AuraBars[selectedSpell] ~= nil)) then
+		RESULT = {
+			type = "group",
+			name = selectedSpell,
+			order = 15,
+			guiInline = true,
+			args = {
+				color = {
+					name = L["Color"],
+					type = "color",
+					order = 1,
+					get = function(key)
+						local abColor = SV.db.Filters.AuraBars[selectedSpell]
+						if type(abColor) == "boolean" then
+							return 0, 0, 0, 1
+						else
+							return abColor[1], abColor[2], abColor[3], abColor[4]
+						end
+					end,
+					set = function(key, r, g, b)
+						SV.db.Filters.AuraBars[selectedSpell] = {r, g, b}
+						MOD:SetUnitFrame("player")
+						MOD:SetUnitFrame("target")
+						MOD:SetUnitFrame("focus")
+					end
+				},
+				removeColor = {
+					type = "execute",
+					order = 2,
+					name = L["Restore Defaults"],
+					func = function(key, value)
+						SV.db.Filters.AuraBars[selectedSpell] = false;
+						MOD:SetUnitFrame("player")
+						MOD:SetUnitFrame("target")
+						MOD:SetUnitFrame("focus")
+					end
+				}
+			}
+		};
+	end
+
+	return RESULT;
+end;
+
+SVUIOptions.FilterOptionGroups['BuffWatch'] = function(selectedSpell)
+	local FILTER = SV.db.Filters.BuffWatch;
+
+	local RESULT = {
+		type = "group",
+		name = 'BuffWatch',
+		guiInline = true,
+		order = 4,
+		args = {
+			addSpellID = {
+				order = 1,
+				name = L["Add SpellID"],
+				desc = L["Add a spell to the filter."],
+				type = "input",
+				get = function(key)return""end,
+				set = function(key, value)
+					local spellID = tonumber(value);
+					if(not spellID) then
+						SV:AddonMessage(L["Value must be a number"])
+					elseif(not GetSpellInfo(spellID)) then
+						SV:AddonMessage(L["Not valid spell id"])
+					else
+						SetWatchedBuff(value, spellID, FILTER, true, "TOPRIGHT", DEFAULT_COLOR, false)
+						UpdateBuffWatch()
+						SVUIOptions:SetFilterOptions('BuffWatch', spellID)
+					end
+				end
+			},
+			removeSpellID = {
+				order = 2,
+				name = L["Remove SpellID"],
+				desc = L["Remove a spell from the filter."],
+				type = "input",
+				get = function(key)return""end,
+				set = function(key, value)
+					local spellID = tonumber(value);
+					if(not spellID) then
+						SV:AddonMessage(L["Value must be a number"])
+					elseif(not GetSpellInfo(spellID)) then
+						SV:AddonMessage(L["Not valid spell id"])
+					else
+						local temp;
+						for id, data in pairs(FILTER) do
+							if(tonumber(id) == spellID) then
+								temp = data;
+								FILTER[id] = nil
+							end
+						end
+						if temp == nil then
+							SV:AddonMessage(L["Spell not found in list."])
+						else
+							SVUIOptions:SetFilterOptions('BuffWatch')
+						end
+					end
+					UpdateBuffWatch("raid")
+					UpdateBuffWatch("party")
+					SVUIOptions:SetFilterOptions('BuffWatch')
+				end
+			},
+			selectSpell = {
+				name = L["Select Spell"],
+				type = "select",
+				order = 3,
+				values = function()
+					wipe(tempFilterTable)
+					for id, watchData in pairs(FILTER) do
+						local spellID = tonumber(id)
+						local name = GetSpellInfo(spellID)
+						if(name) then
+							tempFilterTable[spellID] = name
+						end
+					end
+					return tempFilterTable
+				end,
+				get = function(key) return selectedSpell end,
+				set = function(key, value) SVUIOptions:SetFilterOptions('BuffWatch', value) end
+			}
+		}
+	}
+	return RESULT;
+end;
+
+SVUIOptions.FilterOptionSpells['BuffWatch'] = function(selectedSpell)
+	local RESULT;
+	local FILTER = SV.db.Filters.BuffWatch;
+
+	if(selectedSpell) then
+		local registeredSpell;
+
+		for id, watchData in pairs(FILTER)do
+			if(tonumber(id) == selectedSpell) then
+				registeredSpell = id
+			end
+		end
+
+		local currentSpell = GetSpellInfo(selectedSpell)
+
+		if(currentSpell and registeredSpell) then
+
+			RESULT = {
+				name = currentSpell.." (Spell ID#: "..selectedSpell..")",
+				type = "group",
+				guiInline = true,
+				get = function(key) return FILTER[registeredSpell][key[#key]] end,
+				set = function(key, value)
+					SV.db.Filters.BuffWatch[registeredSpell][key[#key]] = value;
+					UpdateBuffWatch();
+				end,
+				order = 5,
+				args = {
+					enable = {
+						name = L["Enable"],
+						width = 'full',
+						order = 0,
+						type = "toggle"
+					},
+					displayText = {
+						name = L["Display Text"],
+						width = 'full',
+						type = "toggle",
+						order = 1,
+					},
+					anyUnit = {
+						name = L["Show Aura From Other Players"],
+						width = 'full',
+						order = 2,
+						type = "toggle"
+					},
+					onlyShowMissing = {
+						name = L["Show When Not Active"],
+						width = 'full',
+						order = 3,
+						type = "toggle",
+						disabled = function() return FILTER[registeredSpell].style == "text" end
+					},
+					point = {
+						name = L["Anchor Point"],
+						order = 4,
+						type = "select",
+						values = POSITION_SELECT
+					},
+					style = {
+						name = L["Style"],
+						order = 5,
+						type = "select",
+						values = STYLE_SELECT
+					},
+					color = {
+						name = L["Color"],
+						type = "color",
+						order = 6,
+						get = function(key)
+							local abColor = FILTER[registeredSpell][key[#key]]
+							return abColor.r,  abColor.g,  abColor.b,  abColor.a
+						end,
+						set = function(key, r, g, b)
+							local abColor = FILTER[registeredSpell][key[#key]]
+							abColor.r,  abColor.g,  abColor.b = r, g, b;
+							UpdateBuffWatch()
+						end
+					},
+					textColor = {
+						name = L["Text Color"],
+						type = "color",
+						order = 7,
+						get = function(key)
+							local abColor = FILTER[registeredSpell][key[#key]]
+							if abColor then
+								return abColor.r,  abColor.g,  abColor.b,  abColor.a
+							else
+								return 1, 1, 1, 1
+							end
+						end,
+						set = function(key, r, g, b)
+							FILTER[registeredSpell][key[#key]] = FILTER[registeredSpell][key[#key]] or {}
+							local abColor = FILTER[registeredSpell][key[#key]]
+							abColor.r,  abColor.g,  abColor.b = r, g, b;
+							UpdateBuffWatch()
+						end
+					},
+					textThreshold = {
+						name = L["Text Threshold"],
+						desc = L["At what point should the text be displayed. Set to -1 to disable."],
+						type = "range",
+						order = 8,
+						width = 'full',
+						min = -1,
+						max = 60,
+						step = 1
+					},
+					xOffset = {order = 9, type = "range", width = 'full', name = L["xOffset"], min = -75, max = 75, step = 1},
+					yOffset = {order = 10, type = "range", width = 'full', name = L["yOffset"], min = -75, max = 75, step = 1},
+				}
+			}
+		end
+	end
+	return RESULT;
+end;
+
+SVUIOptions.FilterOptionGroups['PetBuffWatch'] = function(selectedSpell)
+	local FILTER = SV.db.Filters.PetBuffWatch;
+	local RESULT = {
+		type = "group",
+		name = 'PetBuffWatch',
+		guiInline = true,
+		order = 4,
+		args = {
+			addSpellID = {
+				order = 1,
+				name = L["Add SpellID"],
+				desc = L["Add a spell to the filter."],
+				type = "input",
+				get = function(key) return "" end,
+				set = function(key, value)
+					local spellID = tonumber(value);
+					if(not spellID) then
+						SV:AddonMessage(L["Value must be a number"])
+					elseif(not GetSpellInfo(spellID)) then
+						SV:AddonMessage(L["Not valid spell id"])
+					else
+						SetWatchedBuff(value, spellID, FILTER, true, "TOPRIGHT", DEFAULT_COLOR, true)
+						UpdatePetBuffWatch()
+						SVUIOptions:SetFilterOptions('PetBuffWatch', spellID)
+					end
+				end
+			},
+			removeSpellID = {
+				order = 2,
+				name = L["Remove SpellID"],
+				desc = L["Remove a spell from the filter."],
+				type = "input",
+				get = function(key) return "" end,
+				set = function(key, value)
+					local spellID = tonumber(value);
+					if(not spellID) then
+						SV:AddonMessage(L["Value must be a number"])
+					elseif(not GetSpellInfo(spellID)) then
+						SV:AddonMessage(L["Not valid spell id"])
+					else
+						local success = false;
+						for id, data in pairs(FILTER) do
+							if(tonumber(id) == spellID) then
+								success = true;
+								data.enable = false;
+							end
+						end
+						if not success then
+							SV:AddonMessage(L["Spell not found in list."])
+						else
+							SVUIOptions:SetFilterOptions()
+						end
+					end
+					UpdatePetBuffWatch()
+					SVUIOptions:SetFilterOptions('PetBuffWatch', value)
+				end
+			},
+			selectSpell = {
+				name = L["Select Spell"],
+				type = "select",
+				order = 3,
+				values = function()
+					wipe(tempFilterTable)
+					for id, watchData in pairs(FILTER) do
+						local spellID = tonumber(id)
+						local name = GetSpellInfo(spellID)
+						if(name) then
+							tempFilterTable[spellID] = name
+						end
+					end
+					return tempFilterTable
+				end,
+				get = function(key) return selectedSpell end,
+				set = function(key, value) SVUIOptions:SetFilterOptions('PetBuffWatch', value) end
+			}
+		}
+	};
+
+	return RESULT;
+end;
+
+SVUIOptions.FilterOptionSpells['PetBuffWatch'] = function(selectedSpell)
+	local RESULT;
+	local FILTER = SV.db.Filters.PetBuffWatch;
+
+	if(selectedSpell) then
+		local registeredSpell;
+
+		for id, watchData in pairs(FILTER)do
+			if(tonumber(id) == selectedSpell) then
+				registeredSpell = id
+			end
+		end
+
+		local currentSpell = GetSpellInfo(selectedSpell)
+
+		if(currentSpell and registeredSpell) then
+
+			RESULT = {
+				name = currentSpell.." ("..selectedSpell..")",
+				type = "group",
+				get = function(key)return FILTER[registeredSpell][key[#key]] end,
+				set = function(key, value)
+					FILTER[registeredSpell][key[#key]] = value;
+					UpdatePetBuffWatch()
+				end,
+				order = 5,
+				guiInline = true,
+				args = {
+					enable = {
+						name = L["Enable"],
+						order = 0,
+						type = "toggle"
+					},
+					point = {
+						name = L["Anchor Point"],
+						order = 1,
+						type = "select",
+						values = POSITION_SELECT
+					},
+					xOffset = {order = 2, type = "range", name = L["xOffset"], min = -75, max = 75, step = 1},
+					yOffset = {order = 2, type = "range", name = L["yOffset"], min = -75, max = 75, step = 1},
+					style = {
+						name = L["Style"],
+						order = 3,
+						type = "select",
+						values = STYLE_SELECT
+
+					},
+					color = {
+						name = L["Color"],
+						type = "color",
+						order = 4,
+						get = function(key)
+							local abColor = FILTER[registeredSpell][key[#key]]
+							return abColor.r,  abColor.g,  abColor.b,  abColor.a
+						end,
+						set = function(key, r, g, b)
+							local abColor = FILTER[registeredSpell][key[#key]]
+							abColor.r,  abColor.g,  abColor.b = r, g, b;
+							UpdatePetBuffWatch()
+						end
+					},
+					displayText = {
+						name = L["Display Text"],
+						type = "toggle",
+						order = 5
+					},
+					textColor = {
+						name = L["Text Color"],
+						type = "color",
+						order = 6,
+						get = function(key)
+							local abColor = FILTER[registeredSpell][key[#key]]
+							if abColor then
+								return abColor.r,abColor.g,abColor.b,abColor.a
+							else
+								return 1,1,1,1
+							end
+						end,
+						set = function(key, r, g, b)
+							local abColor = FILTER[registeredSpell][key[#key]]
+							abColor.r,abColor.g,abColor.b = r, g, b;
+							UpdatePetBuffWatch()
+						end
+					},
+					textThreshold = {
+						name = L["Text Threshold"],
+						desc = L["At what point should the text be displayed. Set to -1 to disable."],
+						type = "range",
+						order = 6,
+						min = -1,
+						max = 60,
+						step = 1
+					},
+					anyUnit = {
+						name = L["Show Aura From Other Players"],
+						order = 7,
+						type = "toggle"
+					},
+					onlyShowMissing = {
+						name = L["Show When Not Active"],
+						order = 8,
+						type = "toggle",
+						disabled = function() return FILTER[registeredSpell].style == "text" end
+					}
+				}
+			}
+		end
+	end
+
+	return RESULT;
+end;
+
+local function GetPowerColorOptions()
+	local args = {};
+	local count = 1;
+	for power, color in next, SV.media.extended.unitframes.power do
+		args[power] = {
+			order = count,
+			name = power,
+			type = "color",
+			get = function(key)
+				local color = SV.media.extended.unitframes.power[power]
+				return color[1],color[2],color[3]
+			end,
+			set = function(key, rValue, gValue, bValue)
+				SV.media.extended.unitframes.power[power] = {rValue, gValue, bValue}
+				MOD:RefreshAllUnitMedia()
+			end,
+		};
+		count = count + 1;
+	end
+	return args;
+end;
+
+SV.Options.args[Schema] = {
+	type = "group",
+	name = Schema,
+	childGroups = "tab",
+	get = function(key)
+		return SV.db[Schema][key[#key]]
+	end,
+	set = function(key, value)
+		MOD:ChangeDBVar(value, key[#key]);
+		MOD:RefreshUnitFrames();
+	end,
+	args = {
+		commonGroup = {
+			order = 1,
+			type = 'group',
+			name = '',
+			childGroups = "tree",
+			args = {
+				baseGroup = {
+					order = 1,
+					type = "group",
+					name = L["General"],
+					args = {
+						commonGroup = {
+							order = 1,
+							type = "group",
+							guiInline = true,
+							name = L["General"],
+							args = {
+								themed = {
+									order = 1,
+									name = L["Elite Bursts"],
+									desc = L["Toggle the styled starbursts around the target frame for elites and rares"],
+									type = "toggle"
+								},
+								disableBlizzard = {
+									order = 2,
+									name = L["Disable Blizzard"],
+									desc = L["Disables the blizzard party/raid frames."],
+									type = "toggle",
+									get = function(key)
+										return SV.db[Schema].disableBlizzard
+									end,
+									set = function(key, value)
+										MOD:ChangeDBVar(value, "disableBlizzard");
+										SV:StaticPopup_Show("RL_CLIENT")
+									end
+								},
+								fastClickTarget = {
+									order = 3,
+									name = L["Fast Clicks"],
+									desc = L["Immediate mouse-click-targeting"],
+									type = "toggle"
+								},
+								debuffHighlighting = {
+									order = 4,
+									name = L["Debuff Highlight"],
+									desc = L["Color the unit if there is a debuff that can be dispelled by your class."],
+									type = "toggle"
+								},
+								xrayFocus = {
+									order = 5,
+									name = L["X-Ray Specs"],
+									desc = L["Use handy graphics to focus the current target, or clear the current focus"],
+									type = "toggle"
+								},
+								resolveBar = {
+									order = 6,
+									name = L["Resolve Meter"],
+									desc = L["A convenient meter for tanks to display their current resolve."],
+									type = "toggle",
+									set = function(key, value)
+										MOD:ChangeDBVar(value, "resolveBar");
+										SV:StaticPopup_Show("RL_CLIENT")
+									end
+								},
+								infoBackgrounds = {
+									order = 7,
+									name = L["Info Backgrounds"],
+									desc = L["Show or hide the gradient under each of the four main unitframes. (Player, Target, Pet, Target of Target)"],
+									type = "toggle"
+								},
+								spacer99 = {
+									order = 8,
+									name = "",
+									type = "description",
+									width = "full",
+								},
+								OORAlpha = {
+									order = 9,
+									name = L["Range Fading"],
+									desc = L["The transparency of units that are out of range."],
+									type = "range",
+									min = 0,
+									max = 1,
+									step = 0.01,
+									set = function(key, value)
+										MOD:ChangeDBVar(value, key[#key]);
+									end
+								},
+								groupOORAlpha = {
+									order = 10,
+									name = L["Group Range Fading"],
+									desc = L["The transparency of group units that are out of range."],
+									type = "range",
+									min = 0,
+									max = 1,
+									step = 0.01,
+									set = function(key, value)
+										MOD:ChangeDBVar(value, key[#key]);
+									end
+								},
+							}
+						},
+						backgroundGroup = {
+							order = 2,
+							type = "group",
+							guiInline = true,
+							name = "Unit Backgrounds (3D Portraits Only)",
+							get = function(key)
+								return SV.media.shared.background[key[#key]].file
+							end,
+							set = function(key, value)
+								SV.media.shared.background[key[#key]].file = value
+								SV:RefreshEverything(true)
+							end,
+							args = {
+								unitlarge = {
+									type = "select",
+									dialogControl = "LSM30_Background",
+									order = 2,
+									name = "Unit Background",
+									values = AceVillainWidgets.background,
+								},
+								unitsmall = {
+									type = "select",
+									dialogControl = "LSM30_Background",
+									order = 3,
+									name = "Small Unit Background",
+									values = AceVillainWidgets.background,
+								}
+							}
+						},
+						barGroup = {
+							order = 3,
+							type = "group",
+							guiInline = true,
+							name = L["Bars"],
+							get = function(key)
+								return SV.db[Schema][key[#key]]
+							end,
+							set = function(key, value)
+								MOD:ChangeDBVar(value, key[#key]);
+								MOD:RefreshAllUnitMedia()
+							end,
+							args = {
+								smoothbars = {
+									type = "toggle",
+									order = 1,
+									name = L["Smooth Bars"],
+									desc = L["Bars will transition smoothly."]
+								},
+								statusbar = {
+									type = "select",
+									dialogControl = "LSM30_Statusbar",
+									order = 2,
+									name = L["StatusBar Texture"],
+									desc = L["Main statusbar texture."],
+									values = AceVillainWidgets.statusbar
+								},
+								auraBarStatusbar = {
+									type = "select",
+									dialogControl = "LSM30_Statusbar",
+									order = 3,
+									name = L["AuraBar Texture"],
+									desc = L["Main statusbar texture."],
+									values = AceVillainWidgets.statusbar
+								},
+							}
+						},
+						fontGroup = {
+							order = 4,
+							type = "group",
+							guiInline = true,
+							name = L["Fonts"],
+							args = {
+								fontConfigButton = {
+									order = 1,
+									name = L["Set UnitFrame Fonts"],
+									type = "execute", func = function() SVUIOptions:SetToFontConfig("UnitFrame") end
+								},
+							}
+						},
+						allColorsGroup = {
+							order = 5,
+							type = "group",
+							guiInline = true,
+							name = L["Colors"],
+							args = {
+								healthGroup = {
+									order = 9,
+									type = "group", guiInline = true,
+									name = HEALTH,
+									args = {
+										forceHealthColor = {
+											order = 1,
+											type = "toggle",
+											name = L["Overlay Health Color"],
+											desc = L["Allow custom health colors when using portrait overlays."],
+											get = function(key)
+												return SV.db[Schema][key[#key]]
+											end,
+											set = function(key, value)
+												MOD:ChangeDBVar(value, key[#key]);
+												MOD:RefreshUnitFrames()
+											end
+										},
+										overlayAnimation = {
+											order = 2,
+											type = "toggle",
+											name = L["Overlay Animations"],
+											desc = L["Toggle health animations on portrait overlays."],
+											get = function(key)
+												return SV.db[Schema][key[#key]]
+											end,
+											set = function(key, value)
+												MOD:ChangeDBVar(value, key[#key]);
+												MOD:RefreshUnitFrames()
+											end
+										},
+										health = {
+											order = 3,
+											type = "color",
+											name = L["Health"],
+											get = function(key)
+												local color = SV.media.extended.unitframes.health
+												return color[1],color[2],color[3]
+											end,
+											set = function(key, rValue, gValue, bValue)
+												SV.media.extended.unitframes.health = {rValue, gValue, bValue}
+												MOD:RefreshAllUnitMedia()
+											end,
+										},
+										healthBackdrop = {
+											order = 4,
+											type = "color",
+											name = L["Health Backdrop"],
+											get = function(key)
+												local color = SV.media.extended.unitframes.healthBackdrop
+												return color[1],color[2],color[3]
+											end,
+											set = function(key, rValue, gValue, bValue)
+												SV.media.extended.unitframes.healthBackdrop = {rValue, gValue, bValue}
+												MOD:RefreshAllUnitMedia()
+											end,
+										},
+										tapped = {
+											order = 5,
+											type = "color",
+											name = L["Tapped"],
+											get = function(key)
+												local color = SV.media.extended.unitframes.tapped
+												return color[1],color[2],color[3]
+											end,
+											set = function(key, rValue, gValue, bValue)
+												SV.media.extended.unitframes.tapped = {rValue, gValue, bValue}
+												MOD:RefreshAllUnitMedia()
+											end,
+										},
+										disconnected = {
+											order = 6,
+											type = "color",
+											name = L["Disconnected"],
+											get = function(key)
+												local color = SV.media.extended.unitframes.disconnected
+												return color[1],color[2],color[3]
+											end,
+											set = function(key, rValue, gValue, bValue)
+												SV.media.extended.unitframes.disconnected = {rValue, gValue, bValue}
+												MOD:RefreshAllUnitMedia()
+											end,
+										}
+									}
+								},
+								powerGroup = {
+									order = 10,
+									type = "group",
+									guiInline = true,
+									name = L["Powers"],
+									args = GetPowerColorOptions()
+								},
+								castBars = {
+									order = 11,
+									type = "group",
+									guiInline = true,
+									name = L["Castbar"],
+									args = {
+										castClassColor = {
+											order = 0,
+											type = "toggle",
+											name = L["Class Castbars"],
+											desc = L["Color castbars by the class or reaction type of the unit."],
+											get = function(key)
+												return SV.db[Schema][key[#key]]
+											end,
+											set = function(key, value)
+												MOD:ChangeDBVar(value, key[#key]);
+												MOD:RefreshUnitFrames()
+											end
+										},
+										casting = {
+											order = 3,
+											name = L["Interruptable"],
+											type = "color",
+											get = function(key)
+												local color = SV.media.extended.unitframes.casting
+												return color[1],color[2],color[3]
+											end,
+											set = function(key, rValue, gValue, bValue)
+												SV.media.extended.unitframes.casting = {rValue, gValue, bValue}
+												MOD:RefreshAllUnitMedia()
+											end,
+										},
+										spark = {
+											order = 4,
+											name = "Spark Color",
+											type = "color",
+											get = function(key)
+												local color = SV.media.extended.unitframes.spark
+												return color[1],color[2],color[3]
+											end,
+											set = function(key, rValue, gValue, bValue)
+												SV.media.extended.unitframes.spark = {rValue, gValue, bValue}
+												MOD:RefreshAllUnitMedia()
+											end,
+										},
+										interrupt = {
+											order = 5,
+											name = L["Non-Interruptable"],
+											type = "color",
+											get = function(key)
+												local color = SV.media.extended.unitframes.interrupt
+												return color[1],color[2],color[3]
+											end,
+											set = function(key, rValue, gValue, bValue)
+												SV.media.extended.unitframes.interrupt = {rValue, gValue, bValue}
+												MOD:RefreshAllUnitMedia()
+											end,
+										}
+									}
+								},
+								auraBars = {
+									order = 11,
+									type = "group",
+									guiInline = true,
+									name = L["Aura Bars"],
+									args = {
+										auraBarByType = {
+											order = 1,
+											name = L["By Type"],
+											desc = L["Color aurabar debuffs by type."],
+											type = "toggle",
+											get = function(key)
+												return SV.db[Schema][key[#key]]
+											end,
+											set = function(key, value)
+												MOD:ChangeDBVar(value, key[#key]);
+												MOD:RefreshUnitFrames()
+											end
+										},
+										auraBarShield = {
+											order = 2,
+											name = L["Color Shield Buffs"],
+											desc = L["Color all buffs that reduce incoming damage."],
+											type = "toggle",
+											get = function(key)
+												return SV.db[Schema][key[#key]]
+											end,
+											set = function(key, value)
+												MOD:ChangeDBVar(value, key[#key]);
+												MOD:RefreshUnitFrames()
+											end
+										},
+										buff_bars = {
+											order = 10,
+											name = L["Buffs"],
+											type = "color",
+											get = function(key)
+												local color = SV.media.extended.unitframes.buff_bars
+												return color[1],color[2],color[3]
+											end,
+											set = function(key, rValue, gValue, bValue)
+												SV.media.extended.unitframes.buff_bars = {rValue, gValue, bValue}
+												MOD:RefreshAllUnitMedia()
+											end,
+										},
+										debuff_bars = {
+											order = 11,
+											name = L["Debuffs"],
+											type = "color",
+											get = function(key)
+												local color = SV.media.extended.unitframes.debuff_bars
+												return color[1],color[2],color[3]
+											end,
+											set = function(key, rValue, gValue, bValue)
+												SV.media.extended.unitframes.debuff_bars = {rValue, gValue, bValue}
+												MOD:RefreshAllUnitMedia()
+											end,
+										},
+										shield_bars = {
+											order = 12,
+											name = L["Shield Buffs Color"],
+											type = "color",
+											get = function(key)
+												local color = SV.media.extended.unitframes.shield_bars
+												return color[1],color[2],color[3]
+											end,
+											set = function(key, rValue, gValue, bValue)
+												SV.media.extended.unitframes.shield_bars = {rValue, gValue, bValue}
+												MOD:RefreshAllUnitMedia()
+											end,
+										}
+									}
+								},
+								predict = {
+									order = 12,
+									name = L["Heal Prediction"],
+									type = "group",
+									args = {
+										personal = {
+											order = 1,
+											name = L["Personal"],
+											type = "color",
+											hasAlpha = true,
+											get = function(key)
+												local color = SV.media.extended.unitframes.predict["personal"]
+												return color[1],color[2],color[3]
+											end,
+											set = function(key, rValue, gValue, bValue)
+												SV.media.extended.unitframes.predict["personal"] = {rValue, gValue, bValue}
+												MOD:RefreshUnitFrames()
+											end,
+										},
+										others = {
+											order = 2,
+											name = L["Others"],
+											type = "color",
+											hasAlpha = true,
+											get = function(key)
+												local color = SV.media.extended.unitframes.predict["others"]
+												return color[1],color[2],color[3]
+											end,
+											set = function(key, rValue, gValue, bValue)
+												SV.media.extended.unitframes.predict["others"] = {rValue, gValue, bValue}
+												MOD:RefreshUnitFrames()
+											end,
+										},
+										absorbs = {
+											order = 2,
+											name = L["Absorbs"],
+											type = "color",
+											hasAlpha = true,
+											get = function(key)
+												local color = SV.media.extended.unitframes.predict["absorbs"]
+												return color[1],color[2],color[3]
+											end,
+											set = function(key, rValue, gValue, bValue)
+												SV.media.extended.unitframes.predict["absorbs"] = {rValue, gValue, bValue}
+												MOD:RefreshUnitFrames()
+											end,
+										}
+									}
+								}
+							}
+						}
+					}
+				},
+				player = {
+					name = L['Player'],
+					type = 'group',
+					order = 3,
+					childGroups = "select",
+					get = function(l)return SV.db.UnitFrames['player'][l[#l]]end,
+					set = function(l,m)MOD:ChangeDBVar(m, l[#l], "player");MOD:SetUnitFrame('player')end,
+					args = {
+						enable = {
+							type = 'toggle',
+							order = 1,
+							name = L['Enable']
+						},
+						resetSettings = {
+							type = 'execute',
+							order = 2,
+							name = L['Restore Defaults'],
+							func = function(l,m)
+								MOD:ResetUnitOptions('player')
+								SV:ResetAnchors('Player Frame')
+							end
+						},
+						spacer1 = {
+							order = 3,
+							name = "",
+							type = "description",
+							width = "full",
+						},
+						spacer2 = {
+							order = 4,
+							name = "",
+							type = "description",
+							width = "full",
+						},
+						commonGroup = {
+							order = 5,
+							type = 'group',
+							name = L['General Settings'],
+							args = {
+								baseGroup = {
+									order = 1,
+									type = "group",
+									guiInline = true,
+									name = L["Base Settings"],
+									args = {
+										combatfade = {
+											order = 1,
+											name = L["Combat Fade"],
+											desc = L["Fade the unitframe when out of combat, not casting, no target exists."],
+											type = "toggle",
+											set = function(l, m)
+												MOD:ChangeDBVar(m, l[#l], "player");
+												MOD:SetUnitFrame("player")
+												if m == true then
+													SVUI_Pet:SetParent(SVUI_Player)
+												else
+													SVUI_Pet:SetParent(SVUI_UnitFrameParent)
+												end
+											end
+										},
+										predict = {
+											order = 2,
+											name = L["Heal Prediction"],
+											desc = L["Show a incomming heal prediction bar on the unitframe. Also display a slightly different colored bar for incoming overheals."],
+											type = "toggle"
+										},
+										threatEnabled = {
+											type = "toggle",
+											order = 3,
+											name = L["Show Threat"]
+										},
+										playerExpBar = {
+											order = 4,
+											name = "Playerframe Experience Bar",
+											desc = "Show player experience on power bar mouseover",
+											type = "toggle",
+											set = function(l, m)MOD:ChangeDBVar(m, l[#l], "player");SV:StaticPopup_Show("RL_CLIENT")end
+										},
+										playerRepBar = {
+											order = 5,
+											name = "Playerframe Reputation Bar",
+											desc = "Show player reputations on power bar mouseover",
+											type = "toggle",
+											set = function(l, m)MOD:ChangeDBVar(m, l[#l], "player");SV:StaticPopup_Show("RL_CLIENT")end
+										}
+									}
+								},
+								sizeGroup = {
+									order = 2,
+									guiInline = true,
+									type = "group",
+									name = L["Size Settings"],
+									args = {
+										width = {
+											order = 1,
+											name = L["Width"],
+											type = "range",
+											width = "full",
+											min = 50,
+											max = 500,
+											step = 1,
+											set = function(l, m)
+												if SV.db.UnitFrames["player"].castbar.width == SV.db.UnitFrames["player"][l[#l]] then
+													SV.db.UnitFrames["player"].castbar.width = m
+												end
+												MOD:ChangeDBVar(m, l[#l], "player");
+												MOD:SetUnitFrame("player")
+											end
+										},
+										height = {
+											order = 2,
+											name = L["Height"],
+											type = "range",
+											width = "full",
+											min = 10,
+											max = 250,
+											step = 1
+										},
+									}
+								},
+								pvpGroup = {
+									order = 3,
+									type = "group",
+									guiInline = true,
+									name = PVP,
+									get = function(l)return SV.db.UnitFrames["player"]["pvp"][l[#l]]end,
+									set = function(l, m)MOD:ChangeDBVar(m, l[#l], "player", "pvp");MOD:SetUnitFrame("player")end,
+									args = {
+										position = {
+											type = "select",
+											order = 2,
+											name = L["Position"],
+											values = {
+												TOPLEFT = "TOPLEFT",
+												LEFT = "LEFT",
+												BOTTOMLEFT = "BOTTOMLEFT",
+												RIGHT = "RIGHT",
+												TOPRIGHT = "TOPRIGHT",
+												BOTTOMRIGHT = "BOTTOMRIGHT",
+												CENTER = "CENTER",
+												TOP = "TOP",
+												BOTTOM = "BOTTOM"
+											}
+										},
+										tags = {
+											order = 100,
+											name = L["Text Format"],
+											type = "input",
+											width = "full",
+											desc = L["TEXT_FORMAT_DESC"]
+										}
+									}
+								}
+							}
+						},
+						misc = SVUIOptions:SetMiscConfigGroup(false, MOD.SetUnitFrame, "player"),
+						health = SVUIOptions:SetHealthConfigGroup(false, MOD.SetUnitFrame, "player"),
+						power = SVUIOptions:SetPowerConfigGroup(true, MOD.SetUnitFrame, "player"),
+						name = SVUIOptions:SetNameConfigGroup(MOD.SetUnitFrame, "player"),
+						portrait = SVUIOptions:SetPortraitConfigGroup(MOD.SetUnitFrame, "player"),
+						buffs = SVUIOptions:SetAuraConfigGroup(true, "buffs", false, MOD.SetUnitFrame, "player"),
+						debuffs = SVUIOptions:SetAuraConfigGroup(true, "debuffs", false, MOD.SetUnitFrame, "player"),
+						castbar = SVUIOptions:SetCastbarConfigGroup(MOD.SetUnitFrame, "player"),
+						icons = SVUIOptions:SetIconConfigGroup(MOD.SetUnitFrame, "player"),
+						classbar = {
+							order = 1000,
+							type = "group",
+							name = L["Classbar"],
+							get = function(l)return SV.db.UnitFrames["player"]["classbar"][l[#l]]end,
+							set = function(l, m)MOD:ChangeDBVar(m, l[#l], "player", "classbar");MOD:SetUnitFrame("player")end,
+							args = {
+								enable = {
+									type = "toggle",
+									order = 1,
+									name = L["Classbar Enabled"]
+								},
+								detachFromFrame = {
+									type = "toggle",
+									order = 2,
+									name = L["Detach From Frame"]
+								},
+								height = {
+									type = "range",
+									order = 4,
+									name = L["Classbar Height (Size)"],
+									min = 15,
+									max = 45,
+									step = 1
+								},
+								altRunes = {
+									type = "toggle",
+									order = 5,
+									width = 'full',
+									name = L["Use Alternate Styled Death Knight Runes"],
+									disabled = function() return playerClass ~= 'DEATHKNIGHT' end
+								},
+								altComboPoints = {
+									type = "toggle",
+									order = 6,
+									width = 'full',
+									name = L["Use Alternate Styled Rogue Combo Points"],
+									disabled = function() return playerClass ~= 'ROGUE' end
+								},
+								enableStagger = {
+									type = "toggle",
+									order = 7,
+									width = 'full',
+									name = L["Use Monk's Stagger Bar"],
+									disabled = function() return playerClass ~= 'MONK' end
+								},
+								enableAltMana = {
+									type = "toggle",
+									order = 8,
+									width = 'full',
+									name = L["Use Druid Alt-Mana Bar"],
+									disabled = function() return playerClass ~= 'DRUID' end
+								},
+								enableCat = {
+									type = "toggle",
+									order = 9,
+									width = 'full',
+									name = L["Use Druid Cat-Form Combo Points"],
+									disabled = function() return playerClass ~= 'DRUID' end
+								},
+								enableChicken = {
+									type = "toggle",
+									order = 10,
+									width = 'full',
+									name = L["Use Druid Eclipse Bar"],
+									disabled = function() return playerClass ~= 'DRUID' end
+								},
+							}
+						}
+					}
+				},
+				pet = {
+					name = L["Pet"],
+					type = "group",
+					order = 4,
+					childGroups = "select",
+					get = function(l)return SV.db.UnitFrames["pet"][l[#l]]end,
+					set = function(l, m)MOD:ChangeDBVar(m, l[#l], "pet");MOD:SetUnitFrame("pet")end,
+					args = {
+						enable = {type = "toggle", order = 1, name = L["Enable"]},
+						resetSettings = {type = "execute", order = 2, name = L["Restore Defaults"], func = function(l, m)MOD:ResetUnitOptions("pet")SV:ResetAnchors("Pet Frame")end},
+						spacer1 = {
+							order = 3,
+							name = "",
+							type = "description",
+							width = "full",
+						},
+						spacer2 = {
+							order = 4,
+							name = "",
+							type = "description",
+							width = "full",
+						},
+						commonGroup = {
+							order = 5,
+							type = "group",
+							name = L["General Settings"],
+							args = {
+								showAuras = {
+									order = 1,
+									type = "execute",
+									name = L["Show Auras"],
+									func = function()local U = SVUI_Pet;if U.forceShowAuras then U.forceShowAuras = nil else U.forceShowAuras = true end MOD:SetUnitFrame("pet")end
+								},
+								miscGroup = {
+									order = 2,
+									type = "group",
+									guiInline = true,
+									name = L["Base Settings"],
+									args = {
+										rangeCheck = {
+											order = 2,
+											name = L["Range Check"],
+											desc = L["Check if you are in range to cast spells on this specific unit."],
+											type = "toggle"
+										},
+										predict = {
+											order = 3,
+											name = L["Heal Prediction"],
+											desc = L["Show a incomming heal prediction bar on the unitframe. Also display a slightly different colored bar for incoming overheals."],
+											type = "toggle"
+										},
+										hideonnpc = {
+											type = "toggle",
+											order = 4,
+											name = L["Text Toggle On NPC"],
+											desc = L["Power text will be hidden on NPC targets, in addition the name text will be repositioned to the power texts anchor point."],
+											get = function(l)return SV.db.UnitFrames["pet"]["power"].hideonnpc end,
+											set = function(l, m)SV.db.UnitFrames["pet"]["power"].hideonnpc = m;MOD:SetUnitFrame("pet")end
+										},
+										threatEnabled = {
+											type = "toggle",
+											order = 5,
+											name = L["Show Threat"]
+										},
+									}
+								},
+								scaleGroup = {
+									order = 6,
+									type = "group",
+									guiInline = true,
+									name = L["Frame Size"],
+									args = {
+										width = {order = 1, name = L["Width"], width = "full", type = "range", min = 50, max = 500, step = 1},
+										height = {order = 2, name = L["Height"], width = "full", type = "range", min = 10, max = 250, step = 1},
+									}
+								},
+								watchGroup = {
+									order = 8,
+									type = "group",
+									guiInline = true,
+									name = L["Aura Watch"],
+									get = function(l)return SV.db.UnitFrames["pet"]["auraWatch"][l[#l]]end,
+									set = function(l, m)MOD:ChangeDBVar(m, l[#l], "pet", "auraWatch");MOD:SetUnitFrame("pet")end,
+									args = {
+										enable = {
+											type = "toggle",
+											name = L["Enable"],
+											order = 1
+										},
+										size = {
+											type = "range",
+											name = L["Size"],
+											desc = L["Size of the indicator icon."],
+											order = 2,
+											min = 4,
+											max = 15,
+											step = 1
+										}
+									}
+								},
+							},
+						},
+						misc = SVUIOptions:SetMiscConfigGroup(false, MOD.SetUnitFrame, "pet"),
+						health = SVUIOptions:SetHealthConfigGroup(false, MOD.SetUnitFrame, "pet"),
+						power = SVUIOptions:SetPowerConfigGroup(false, MOD.SetUnitFrame, "pet"),
+						portrait = SVUIOptions:SetPortraitConfigGroup(MOD.SetUnitFrame, "pet"),
+						name = SVUIOptions:SetNameConfigGroup(MOD.SetUnitFrame, "pet"),
+						buffs = SVUIOptions:SetAuraConfigGroup(true, "buffs", false, MOD.SetUnitFrame, "pet"),
+						debuffs = SVUIOptions:SetAuraConfigGroup(true, "debuffs", false, MOD.SetUnitFrame, "pet")
+					}
+				},
+				pettarget = {
+					name = L["Pet Target"],
+					type = "group",
+					order = 5,
+					childGroups = "select",
+					get = function(l)return SV.db.UnitFrames["pettarget"][l[#l]]end,
+					set = function(l, m)MOD:ChangeDBVar(m, l[#l], "pettarget");MOD:SetUnitFrame("pettarget")end,
+					args = {
+						enable = {type = "toggle", order = 1, name = L["Enable"]},
+						resetSettings = {type = "execute", order = 2, name = L["Restore Defaults"], func = function(l, m)MOD:ResetUnitOptions("pettarget")SV:ResetAnchors("PetTarget Frame")end},
+						spacer1 = {
+							order = 3,
+							name = "",
+							type = "description",
+							width = "full",
+						},
+						spacer2 = {
+							order = 4,
+							name = "",
+							type = "description",
+							width = "full",
+						},
+						commonGroup = {
+							order = 5,
+							type = "group",
+							name = L["General Settings"],
+							args = {
+								showAuras = {
+									order = 1,
+									type = "execute",
+									name = L["Show Auras"],
+									func = function()local U = SVUI_PetTarget;if U.forceShowAuras then U.forceShowAuras = nil else U.forceShowAuras = true end MOD:SetUnitFrame("pettarget")end
+								},
+								miscGroup = {
+									order = 2,
+									type = "group",
+									guiInline = true,
+									name = L["Base Settings"],
+									args = {
+										rangeCheck = {
+											order = 2,
+											name = L["Range Check"],
+											desc = L["Check if you are in range to cast spells on this specific unit."],
+											type = "toggle"
+										},
+										hideonnpc = {
+											type = "toggle",
+											order = 4,
+											name = L["Text Toggle On NPC"],
+											desc = L["Power text will be hidden on NPC targets, in addition the name text will be repositioned to the power texts anchor point."],
+											get = function(l)return SV.db.UnitFrames["pettarget"]["power"].hideonnpc end,
+											set = function(l, m)SV.db.UnitFrames["pettarget"]["power"].hideonnpc = m;MOD:SetUnitFrame("pettarget")end
+										},
+										threatEnabled = {
+											type = "toggle",
+											order = 5,
+											name = L["Show Threat"]
+										},
+									}
+								},
+								scaleGroup = {
+									order = 3,
+									type = "group",
+									guiInline = true,
+									name = L["Frame Size"],
+									args = {
+										width = {order = 1, name = L["Width"], width = "full", type = "range", min = 50, max = 500, step = 1},
+										height = {order = 2, name = L["Height"], width = "full", type = "range", min = 10, max = 250, step = 1},
+									}
+								},
+							},
+						},
+						misc = SVUIOptions:SetMiscConfigGroup(false, MOD.SetUnitFrame, "pettarget"),
+						health = SVUIOptions:SetHealthConfigGroup(false, MOD.SetUnitFrame, "pettarget"),
+						power = SVUIOptions:SetPowerConfigGroup(false, MOD.SetUnitFrame, "pettarget"),
+						name = SVUIOptions:SetNameConfigGroup(MOD.SetUnitFrame, "pettarget"),
+						buffs = SVUIOptions:SetAuraConfigGroup(false, "buffs", false, MOD.SetUnitFrame, "pettarget"),
+						debuffs = SVUIOptions:SetAuraConfigGroup(false, "debuffs", false, MOD.SetUnitFrame, "pettarget")
+					}
+				},
+				target = {
+					name = L['Target'],
+					type = 'group',
+					order = 6,
+					childGroups = "select",
+					get=function(l)return SV.db.UnitFrames['target'][l[#l]]end,
+					set=function(l,m)MOD:ChangeDBVar(m, l[#l], "target");MOD:SetUnitFrame('target')end,
+					args={
+						enable={type='toggle',order=1,name=L['Enable']},
+						resetSettings={type='execute',order=2,name=L['Restore Defaults'],func=function(l,m)MOD:ResetUnitOptions('target')SV:ResetAnchors('Target Frame')end},
+						spacer1 = {
+							order = 3,
+							name = "",
+							type = "description",
+							width = "full",
+						},
+						spacer2 = {
+							order = 4,
+							name = "",
+							type = "description",
+							width = "full",
+						},
+						commonGroup = {
+							order = 5,
+							type = 'group',
+							name = L['General Settings'],
+							args = {
+								baseGroup = {
+									order = 1,
+									type = "group",
+									guiInline = true,
+									name = L["Base Settings"],
+									args = {
+										showAuras = {
+											order = 1,
+											type = "execute",
+											name = L["Show Auras"],
+											func = function()local U = SVUI_Target;if U.forceShowAuras then U.forceShowAuras = nil else U.forceShowAuras = true end MOD:SetUnitFrame("target")end
+										},
+										predict = {
+											order = 2,
+											name = L["Heal Prediction"],
+											desc = L["Show a incomming heal prediction bar on the unitframe. Also display a slightly different colored bar for incoming overheals."],
+											type = "toggle"
+										},
+										hideonnpc = {
+											type = "toggle",
+											order = 3,
+											name = L["Text Toggle On NPC"],
+											desc = L["Power text will be hidden on NPC targets, in addition the name text will be repositioned to the power texts anchor point."],
+											get = function(l)return SV.db.UnitFrames["target"]["power"].hideonnpc end,
+											set = function(l, m)SV.db.UnitFrames["target"]["power"].hideonnpc = m;MOD:SetUnitFrame("target")end
+										},
+										threatEnabled = {
+											type = "toggle",
+											order = 4,
+											name = L["Show Threat"]
+										},
+										middleClickFocus = {
+											order = 5,
+											name = L["Middle Click - Set Focus"],
+											desc = L["Middle clicking the unit frame will cause your focus to match the unit."],
+											type = "toggle",
+											disabled = function()return IsAddOnLoaded("Clique")end
+										},
+
+									}
+								},
+								sizeGroup = {
+									order = 2,
+									guiInline = true,
+									type = "group",
+									name = L["Size Settings"],
+									args = {
+										width = {
+											order = 1,
+											name = L["Width"],
+											type = "range",
+											width = "full",
+											min = 10,
+											max = 500,
+											step = 1,
+											set = function(l, m)
+												if SV.db.UnitFrames["target"].castbar.width == SV.db.UnitFrames["target"][l[#l]] then
+													SV.db.UnitFrames["target"].castbar.width = m
+												end
+												MOD:ChangeDBVar(m, l[#l], "target");
+												MOD:SetUnitFrame("target")
+											end
+										},
+										height = {
+											order = 2,
+											name = L["Height"],
+											type = "range",
+											width = "full",
+											min = 10,
+											max = 500,
+											step = 1
+										},
+									}
+								}
+							}
+						},
+						combobar = {
+							order = 800,
+							type = "group",
+							name = L["Combobar"],
+							get = function(l)return SV.db.UnitFrames["target"]["combobar"][l[#l]]end,
+							set = function(l, m)MOD:ChangeDBVar(m, l[#l], "target", "combobar");MOD:SetUnitFrame("target")end,
+							args = {
+								enable = {
+									type = "toggle",
+									order = 1,
+									name = L["Enable"]
+								},
+								smallIcons = {
+									type = "toggle",
+									name = L["Small Points"],
+									order = 2
+								},
+								height = {
+									type = "range",
+									order = 3,
+									name = L["Height"],
+									min = 15,
+									max = 45,
+									step = 1
+								},
+								autoHide = {
+									type = "toggle",
+									name = L["Auto-Hide"],
+									order = 4
+								}
+							}
+						},
+						misc = SVUIOptions:SetMiscConfigGroup(false, MOD.SetUnitFrame, "target"),
+						health = SVUIOptions:SetHealthConfigGroup(false, MOD.SetUnitFrame, "target"),
+						power = SVUIOptions:SetPowerConfigGroup(true, MOD.SetUnitFrame, "target"),
+						name = SVUIOptions:SetNameConfigGroup(MOD.SetUnitFrame, "target"),
+						portrait = SVUIOptions:SetPortraitConfigGroup(MOD.SetUnitFrame, "target"),
+						buffs = SVUIOptions:SetAuraConfigGroup(false, "buffs", false, MOD.SetUnitFrame, "target"),
+						debuffs = SVUIOptions:SetAuraConfigGroup(false, "debuffs", false, MOD.SetUnitFrame, "target"),
+						castbar = SVUIOptions:SetCastbarConfigGroup(MOD.SetUnitFrame, "target"),
+						icons = SVUIOptions:SetIconConfigGroup(MOD.SetUnitFrame, "target")
+					}
+				},
+				targettarget = {
+					name = L['Target of Target'],
+					type = 'group',
+					order = 7,
+					childGroups = "select",
+					get = function(l)return SV.db.UnitFrames['targettarget'][l[#l]]end,
+					set = function(l,m)MOD:ChangeDBVar(m, l[#l], "targettarget");MOD:SetUnitFrame('targettarget')end,
+					args={
+						enable={type='toggle',order=1,name=L['Enable']},
+						resetSettings={type='execute',order=2,name=L['Restore Defaults'],func=function(l,m)MOD:ResetUnitOptions('targettarget')SV:ResetAnchors('TargetTarget Frame')end},
+						spacer1 = {
+							order = 3,
+							name = "",
+							type = "description",
+							width = "full",
+						},
+						spacer2 = {
+							order = 4,
+							name = "",
+							type = "description",
+							width = "full",
+						},
+						commonGroup = {
+							order = 5,
+							type = 'group',
+							name = L['General Settings'],
+							args = {
+								baseGroup = {
+									order = 1,
+									type = "group",
+									guiInline = true,
+									name = L["Base Settings"],
+									args = {
+										showAuras = {
+											order = 1,
+											type = "execute",
+											name = L["Show Auras"],
+											func = function()local U = SVUI_TargetTarget;if U.forceShowAuras then U.forceShowAuras = nil else U.forceShowAuras = true end MOD:SetUnitFrame("targettarget")end
+										},
+										spacer1 = {
+											order = 2,
+											type = "description",
+											name = "",
+										},
+										rangeCheck = {
+											order = 3,
+											name = L["Range Check"],
+											desc = L["Check if you are in range to cast spells on this specific unit."],
+											type = "toggle"
+										},
+										hideonnpc = {
+											type = "toggle",
+											order = 4,
+											name = L["Text Toggle On NPC"],
+											desc = L["Power text will be hidden on NPC targets, in addition the name text will be repositioned to the power texts anchor point."],
+											get = function(l)return SV.db.UnitFrames["target"]["power"].hideonnpc end,
+											set = function(l, m)SV.db.UnitFrames["target"]["power"].hideonnpc = m;MOD:SetUnitFrame("target")end
+										},
+										threatEnabled = {
+											type = "toggle",
+											order = 5,
+											name = L["Show Threat"]
+										}
+									}
+								},
+								sizeGroup = {
+									order = 2,
+									guiInline = true,
+									type = "group",
+									name = L["Size Settings"],
+									args = {
+										width = {
+											order = 1,
+											name = L["Width"],
+											type = "range",
+											width = "full",
+											min = 10,
+											max = 500,
+											step = 1,
+										},
+										height = {
+											order = 2,
+											name = L["Height"],
+											type = "range",
+											width = "full",
+											min = 10,
+											max = 500,
+											step = 1
+										},
+									}
+								}
+							}
+						},
+						misc = SVUIOptions:SetMiscConfigGroup(false, MOD.SetUnitFrame, "targettarget"),
+						health = SVUIOptions:SetHealthConfigGroup(false, MOD.SetUnitFrame, "targettarget"),
+						power = SVUIOptions:SetPowerConfigGroup(nil, MOD.SetUnitFrame, "targettarget"),
+						name = SVUIOptions:SetNameConfigGroup(MOD.SetUnitFrame, "targettarget"),
+						portrait = SVUIOptions:SetPortraitConfigGroup(MOD.SetUnitFrame, "targettarget"),
+						buffs = SVUIOptions:SetAuraConfigGroup(false, "buffs", false, MOD.SetUnitFrame, "targettarget"),
+						debuffs = SVUIOptions:SetAuraConfigGroup(false, "debuffs", false, MOD.SetUnitFrame, "targettarget"),
+						icons = SVUIOptions:SetIconConfigGroup(MOD.SetUnitFrame, "targettarget")
+					}
+				},
+				focus = {
+					name = L["Focus"],
+					type = "group",
+					order = 8,
+					childGroups = "select",
+					get = function(l)return SV.db.UnitFrames["focus"][l[#l]]end,
+					set = function(l, m)MOD:ChangeDBVar(m, l[#l], "focus");MOD:SetUnitFrame("focus")end,
+					args = {
+						enable = {type = "toggle", order = 1, name = L["Enable"]},
+						resetSettings = {type = "execute", order = 2, name = L["Restore Defaults"], func = function(l, m)MOD:ResetUnitOptions("focus");SV:ResetAnchors("Focus Frame")end},
+						spacer1 = {
+							order = 3,
+							name = "",
+							type = "description",
+							width = "full",
+						},
+						spacer2 = {
+							order = 4,
+							name = "",
+							type = "description",
+							width = "full",
+						},
+						commonGroup = {
+							order = 5,
+							type = "group",
+							name = L["General Settings"],
+							args = {
+								baseGroup = {
+									order = 1,
+									type = "group",
+									guiInline = true,
+									name = L["Base Settings"],
+									args = {
+										showAuras = {
+											order = 1,
+											type = "execute",
+											name = L["Show Auras"],
+											func = function()local U = SVUI_Focus;if U.forceShowAuras then U.forceShowAuras = nil else U.forceShowAuras = true end MOD:SetUnitFrame("focus")end
+										},
+										rangeCheck = {
+											order = 2,
+											name = L["Range Check"],
+											desc = L["Check if you are in range to cast spells on this specific unit."],
+											type = "toggle"
+										},
+										predict = {
+											order = 3,
+											name = L["Heal Prediction"],
+											desc = L["Show a incomming heal prediction bar on the unitframe. Also display a slightly different colored bar for incoming overheals."],
+											type = "toggle"
+										},
+										hideonnpc = {
+											type = "toggle",
+											order = 4,
+											name = L["Text Toggle On NPC"],
+											desc = L["Power text will be hidden on NPC targets, in addition the name text will be repositioned to the power texts anchor point."],
+											get = function(l)return SV.db.UnitFrames["focus"]["power"].hideonnpc end,
+											set = function(l, m)SV.db.UnitFrames["focus"]["power"].hideonnpc = m;MOD:SetUnitFrame("focus")end
+										},
+										threatEnabled = {
+											type = "toggle",
+											order = 5,
+											name = L["Show Threat"]
+										}
+									}
+								},
+								sizeGroup = {
+									order = 2,
+									guiInline = true,
+									type = "group",
+									name = L["Size Settings"],
+									args = {
+										width = {
+											order = 1,
+											name = L["Width"],
+											type = "range",
+											width = "full",
+											min = 10,
+											max = 500,
+											step = 1,
+										},
+										height = {
+											order = 2,
+											name = L["Height"],
+											type = "range",
+											width = "full",
+											min = 10,
+											max = 500,
+											step = 1
+										},
+									}
+								},
+							}
+						},
+						misc = SVUIOptions:SetMiscConfigGroup(false, MOD.SetUnitFrame, "focus"),
+						health = SVUIOptions:SetHealthConfigGroup(false, MOD.SetUnitFrame, "focus"),
+						power = SVUIOptions:SetPowerConfigGroup(nil, MOD.SetUnitFrame, "focus"),
+						name = SVUIOptions:SetNameConfigGroup(MOD.SetUnitFrame, "focus"),
+						buffs = SVUIOptions:SetAuraConfigGroup(false, "buffs", false, MOD.SetUnitFrame, "focus"),
+						debuffs = SVUIOptions:SetAuraConfigGroup(false, "debuffs", false, MOD.SetUnitFrame, "focus"),
+						castbar = SVUIOptions:SetCastbarConfigGroup(MOD.SetUnitFrame, "focus"),
+						icons = SVUIOptions:SetIconConfigGroup(MOD.SetUnitFrame, "focus")
+					}
+				},
+				focustarget = {
+					name = L["FocusTarget"],
+					type = "group",
+					order = 9,
+					childGroups = "select",
+					get = function(l)return SV.db.UnitFrames["focustarget"][l[#l]]end,
+					set = function(l, m)MOD:ChangeDBVar(m, l[#l], "focustarget");MOD:SetUnitFrame("focustarget")end,
+					args = {
+						enable = {type = "toggle", order = 1, name = L["Enable"]},
+						resetSettings = {type = "execute", order = 2, name = L["Restore Defaults"], func = function(l, m)MOD:ResetUnitOptions("focustarget")SV:ResetAnchors("FocusTarget Frame")end},
+						spacer1 = {
+							order = 3,
+							name = "",
+							type = "description",
+							width = "full",
+						},
+						spacer2 = {
+							order = 4,
+							name = "",
+							type = "description",
+							width = "full",
+						},
+						commonGroup = {
+							order = 5,
+							type = "group",
+							name = L["General Settings"],
+							args = {
+								baseGroup = {
+									order = 1,
+									type = "group",
+									guiInline = true,
+									name = L["Base Settings"],
+									args = {
+										showAuras = {
+											order = 1,
+											type = "execute",
+											name = L["Show Auras"],
+											func = function()
+												if(SVUI_FocusTarget.forceShowAuras == true) then
+													SVUI_FocusTarget.forceShowAuras = nil
+												else
+													SVUI_FocusTarget.forceShowAuras = true
+												end
+												MOD:SetUnitFrame("focustarget")
+											end
+										},
+										spacer1 = {
+											order = 2,
+											type = "description",
+											name = "",
+										},
+										rangeCheck = {order = 3, name = L["Range Check"], desc = L["Check if you are in range to cast spells on this specific unit."], type = "toggle"},
+										hideonnpc = {type = "toggle", order = 4, name = L["Text Toggle On NPC"], desc = L["Power text will be hidden on NPC targets, in addition the name text will be repositioned to the power texts anchor point."], get = function(l)return SV.db.UnitFrames["focustarget"]["power"].hideonnpc end, set = function(l, m)SV.db.UnitFrames["focustarget"]["power"].hideonnpc = m;MOD:SetUnitFrame("focustarget")end},
+										threatEnabled = {type = "toggle", order = 5, name = L["Show Threat"]}
+									}
+								},
+								sizeGroup = {
+									order = 2,
+									guiInline = true,
+									type = "group",
+									name = L["Size Settings"],
+									args = {
+										width = {
+											order = 1,
+											name = L["Width"],
+											type = "range",
+											width = "full",
+											min = 10,
+											max = 500,
+											step = 1,
+										},
+										height = {
+											order = 2,
+											name = L["Height"],
+											type = "range",
+											width = "full",
+											min = 10,
+											max = 500,
+											step = 1
+										},
+									}
+								},
+							}
+						},
+						misc = SVUIOptions:SetMiscConfigGroup(false, MOD.SetUnitFrame, "focustarget"),
+						health = SVUIOptions:SetHealthConfigGroup(false, MOD.SetUnitFrame, "focustarget"),
+						power = SVUIOptions:SetPowerConfigGroup(false, MOD.SetUnitFrame, "focustarget"),
+						name = SVUIOptions:SetNameConfigGroup(MOD.SetUnitFrame, "focustarget"),
+						buffs = SVUIOptions:SetAuraConfigGroup(false, "buffs", false, MOD.SetUnitFrame, "focustarget"),
+						debuffs = SVUIOptions:SetAuraConfigGroup(false, "debuffs", false, MOD.SetUnitFrame, "focustarget"),
+						icons = SVUIOptions:SetIconConfigGroup(MOD.SetUnitFrame, "focustarget")
+					}
+				},
+				party = {
+					name = L['Party'],
+					type = 'group',
+					order = 10,
+					childGroups = "select",
+					get = function(l) return SV.db.UnitFrames['party'][l[#l]] end,
+					set = function(l, m) MOD:ChangeDBVar(m, l[#l], "party"); MOD:SetGroupFrame('party') end,
+					args = {
+						enable = {
+							type = 'toggle',
+							order = 1,
+							name = L['Enable'],
+						},
+						configureToggle = {
+							order = 2,
+							type = 'execute',
+							name = L['Display Frames'],
+							func = function()
+								MOD:ViewGroupFrames(SVUI_Party, SVUI_Party.forceShow ~= true or nil)
+							end,
+						},
+						resetSettings = {
+							type = 'execute',
+							order = 3,
+							name = L['Restore Defaults'],
+							func = function(l, m)MOD:ResetUnitOptions('party')SV:ResetAnchors('Party Frames')end,
+						},
+						spacer1 = {
+							order = 4,
+							name = "",
+							type = "description",
+							width = "full",
+						},
+						spacer2 = {
+							order = 5,
+							name = "",
+							type = "description",
+							width = "full",
+						},
+						general = {
+							order = 6,
+							type = "group",
+							name = L["General Settings"],
+							args = {
+								commonGroup = {
+									order = 1,
+									name = L["Basic Options"],
+									type = "group",
+									guiInline = true,
+									args = {
+										rangeCheck = {
+											order = 1,
+											type = "toggle",
+											name = L["Range Check"],
+											desc = L["Check if you are in range to cast spells on this specific unit."],
+										},
+										predict = {
+											order = 2,
+											type = "toggle",
+											name = L["Heal Prediction"],
+											desc = L["Show a incomming heal prediction bar on the unitframe. Also display a slightly different colored bar for incoming overheals."],
+										},
+										threatEnabled = {
+											order = 3,
+											type = "toggle",
+											name = L["Show Threat"],
+										},
+										useFor5man = {
+											order = 4,
+											type = "toggle",
+											name = L["Raid 5 Party"],
+											desc = L["Use party frames when in a 5-man raid group"],
+											get = function(l) return SV.db.UnitFrames['party'][l[#l]] end,
+											set = function(l, m) MOD:ChangeDBVar(m, l[#l], "party"); MOD:SetGroupFrame("party"); MOD:SetGroupFrame("raid"); end,
+										},
+									}
+								},
+								layoutGroup = {
+									order = 2,
+									name = L["Layout Options"],
+									type = "group",
+									guiInline = true,
+									set = function(key, value) MOD:ChangeDBVar(value, key[#key], "party"); MOD:SetGroupFrame("party", true) end,
+									args = {
+										common = {
+											order = 1,
+											name = L["General Layout"],
+											type = "group",
+											guiInline = true,
+											args = {
+												enable = {
+													order = 1,
+													name = L["Enable Grid Mode"],
+													desc = L["Converts frames into symmetrical squares. Ideal for healers."],
+													type = "toggle",
+													get = function(key) return SV.db.UnitFrames["party"].grid.enable end,
+													set = function(key, value)
+														MOD:ChangeDBVar(value, key[#key], "party", "grid");
+														MOD:SetGroupFrame("party", true);
+														SV.Options.args.UnitFrames.args.commonGroup.args.party.args.general.args.layoutGroup.args.sizing = SVUIOptions:SetSizeConfigGroup(value, "party");
+													end,
+												},
+												invertGroupingOrder = {
+													order = 2,
+													type = "toggle",
+													name = L["Invert Grouping Order"],
+													desc = L["Enabling this inverts the grouping order."],
+													disabled = function() return not SV.db.UnitFrames["party"].customSorting end,
+												},
+											}
+										},
+										sizing = SVUIOptions:SetSizeConfigGroup(SV.db.UnitFrames.party.grid.enable, "party"),
+										sorting = {
+											order = 3,
+											name = L["Sorting"],
+											type = "group",
+											guiInline = true,
+											args = {
+												gRowCol = {
+													order = 1,
+													type = "range",
+													name = L["Groups Per Row / Column"],
+													min = 1,
+													max = 8,
+													step = 1,
+													width = 'full',
+													set = function(key, value)
+														MOD:ChangeDBVar(value, key[#key], "party");
+														MOD:SetGroupFrame("party")
+														if(_G["SVUI_Raid"] and _G["SVUI_Raid"].isForced) then
+															MOD:ViewGroupFrames(_G["SVUI_Raid"])
+															MOD:ViewGroupFrames(_G["SVUI_Raid"], true)
+														end
+													end,
+												},
+												showBy = {
+													order = 2,
+													name = L["Growth Direction"],
+													desc = L["Growth direction from the first unitframe."],
+													type = "select",
+													values = {
+														DOWN_RIGHT = format(L["%s and then %s"], L["Down"], L["Right"]),
+														DOWN_LEFT = format(L["%s and then %s"], L["Down"], L["Left"]),
+														UP_RIGHT = format(L["%s and then %s"], L["Up"], L["Right"]),
+														UP_LEFT = format(L["%s and then %s"], L["Up"], L["Left"]),
+														RIGHT_DOWN = format(L["%s and then %s"], L["Right"], L["Down"]),
+														RIGHT_UP = format(L["%s and then %s"], L["Right"], L["Up"]),
+														LEFT_DOWN = format(L["%s and then %s"], L["Left"], L["Down"]),
+														LEFT_UP = format(L["%s and then %s"], L["Left"], L["Up"]),
+													},
+												},
+												sortMethod = {
+													order = 3,
+													name = L["Group By"],
+													desc = L["Set the order that the group will sort."],
+													type = "select",
+													values = {
+														["CLASS"] = CLASS,
+														["ROLE"] = ROLE.."(Tanks, Healers, DPS)",
+														["ROLE_TDH"] = ROLE.."(Tanks, DPS, Healers)",
+														["ROLE_HDT"] = ROLE.."(Healers, DPS, Tanks)",
+														["ROLE_HTD"] = ROLE.."(Healers, Tanks, DPS)",
+														["NAME"] = NAME,
+														["MTMA"] = L["Main Tanks  /  Main Assist"],
+														["GROUP"] = GROUP,
+													},
+												},
+												sortDir = {
+													order = 4,
+													name = L["Sort Direction"],
+													desc = L["Defines the sort order of the selected sort method."],
+													type = "select",
+													values = {
+														["ASC"] = L["Ascending"],
+														["DESC"] = L["Descending"],
+													},
+												},
+											}
+										}
+									},
+								},
+							}
+						},
+						auraWatch = {
+							order = 600,
+							type = 'group',
+							name = L['Aura Watch'],
+							get = function(l)return
+							SV.db.UnitFrames['party']['auraWatch'][l[#l]]end,
+							set = function(l, m) MOD:ChangeDBVar(m, l[#l], "party", "auraWatch"); MOD:SetGroupFrame('party')end,
+							args = {
+								enable = {
+									type = 'toggle',
+									name = L['Enable'],
+									order = 1,
+								},
+								size = {
+									type = 'range',
+									name = L['Size'],
+									desc = L['Size of the indicator icon.'],
+									order = 2,
+									min = 4,
+									max = 15,
+									step = 1,
+								},
+								configureButton = {
+									type = 'execute',
+									name = L['Configure Auras'],
+									func = function()SVUIOptions:SetToFilterConfig('BuffWatch')end,
+									order = 3,
+								},
+
+							},
+						},
+						misc = SVUIOptions:SetMiscConfigGroup(true, MOD.SetGroupFrame, 'party'),
+						health = SVUIOptions:SetHealthConfigGroup(true, MOD.SetGroupFrame, 'party'),
+						power = SVUIOptions:SetPowerConfigGroup(false, MOD.SetGroupFrame, 'party'),
+						name = SVUIOptions:SetNameConfigGroup(MOD.SetGroupFrame, 'party'),
+						portrait = SVUIOptions:SetPortraitConfigGroup(MOD.SetGroupFrame, 'party'),
+						buffs = SVUIOptions:SetAuraConfigGroup(true, 'buffs', true, MOD.SetGroupFrame, 'party'),
+						debuffs = SVUIOptions:SetAuraConfigGroup(true, 'debuffs', true, MOD.SetGroupFrame, 'party'),
+						petsGroup = {
+							order = 800,
+							type = 'group',
+							name = L['Party Pets'],
+							get = function(l)return SV.db.UnitFrames['party']['petsGroup'][l[#l]]end,
+							set = function(l, m)MOD:ChangeDBVar(m, l[#l], "party", "petsGroup");MOD:SetGroupFrame('party')end,
+							args = {
+								enable = {
+									type = 'toggle',
+									name = L['Enable'],
+									order = 1,
+								},
+								width = {
+									order = 3,
+									name = L['Width'],
+									type = 'range',
+									min = 10,
+									max = 500,
+									step = 1,
+								},
+								height = {
+									order = 4,
+									name = L['Height'],
+									type = 'range',
+									min = 10,
+									max = 250,
+									step = 1,
+								},
+								anchorPoint = {
+									type = 'select',
+									order = 5,
+									name = L['Anchor Point'],
+									desc = L['What point to anchor to the frame you set to attach to.'],
+									values = {TOPLEFT='TOPLEFT',LEFT='LEFT',BOTTOMLEFT='BOTTOMLEFT',RIGHT='RIGHT',TOPRIGHT='TOPRIGHT',BOTTOMRIGHT='BOTTOMRIGHT',CENTER='CENTER',TOP='TOP',BOTTOM='BOTTOM'},
+								},
+								xOffset = {
+									order = 6,
+									type = 'range',
+									name = L['xOffset'],
+									desc = L['An X offset (in pixels) to be used when anchoring new frames.'],
+									min =  - 500,
+									max = 500,
+									step = 1,
+								},
+								yOffset = {
+									order = 7,
+									type = 'range',
+									name = L['yOffset'],
+									desc = L['An Y offset (in pixels) to be used when anchoring new frames.'],
+									min =  - 500,
+									max = 500,
+									step = 1,
+								},
+								name_length = {
+									order = 8,
+									name = L["Name Length"],
+									desc = L["TEXT_FORMAT_DESC"],
+									type = "range",
+									width = "full",
+									min = 1,
+									max = 30,
+									step = 1,
+									set = function(key, value)
+										MOD:ChangeDBVar(value, key[#key], "party", "petsGroup");
+										local tag = "[name:" .. value .. "]";
+										MOD:ChangeDBVar(tag, "tags", "party", "petsGroup");
+									end,
+								}
+							},
+						},
+						targetsGroup = {
+							order = 900,
+							type = 'group',
+							name = L['Party Targets'],
+							get = function(l)return
+							SV.db.UnitFrames['party']['targetsGroup'][l[#l]]end,
+							set = function(l, m) MOD:ChangeDBVar(m, l[#l], "party", "targetsGroup"); MOD:SetGroupFrame('party') end,
+							args = {
+								enable = {
+									type = 'toggle',
+									name = L['Enable'],
+									order = 1,
+								},
+								width = {
+									order = 3,
+									name = L['Width'],
+									type = 'range',
+									min = 10,
+									max = 500,
+									step = 1,
+								},
+								height = {
+									order = 4,
+									name = L['Height'],
+									type = 'range',
+									min = 10,
+									max = 250,
+									step = 1,
+								},
+								anchorPoint = {
+									type = 'select',
+									order = 5,
+									name = L['Anchor Point'],
+									desc = L['What point to anchor to the frame you set to attach to.'],
+									values = {TOPLEFT='TOPLEFT',LEFT='LEFT',BOTTOMLEFT='BOTTOMLEFT',RIGHT='RIGHT',TOPRIGHT='TOPRIGHT',BOTTOMRIGHT='BOTTOMRIGHT',CENTER='CENTER',TOP='TOP',BOTTOM='BOTTOM'},
+								},
+								xOffset = {
+									order = 6,
+									type = 'range',
+									name = L['xOffset'],
+									desc = L['An X offset (in pixels) to be used when anchoring new frames.'],
+									min =  - 500,
+									max = 500,
+									step = 1,
+								},
+								yOffset = {
+									order = 7,
+									type = 'range',
+									name = L['yOffset'],
+									desc = L['An Y offset (in pixels) to be used when anchoring new frames.'],
+									min =  - 500,
+									max = 500,
+									step = 1,
+								},
+								name_length = {
+									order = 8,
+									name = L["Name Length"],
+									desc = L["TEXT_FORMAT_DESC"],
+									type = "range",
+									width = "full",
+									min = 1,
+									max = 30,
+									step = 1,
+									set = function(key, value)
+										MOD:ChangeDBVar(value, key[#key], "party", "targetsGroup");
+										local tag = "[name:" .. value .. "]";
+										MOD:ChangeDBVar(tag, "tags", "party", "targetsGroup");
+									end,
+								}
+							},
+						},
+						rdebuffs = {
+							order = 700,
+							type = 'group',
+							name = L['Raid Debuffs'],
+							get = function(l)return
+							SV.db.UnitFrames['party']['rdebuffs'][l[#l]]end,
+							set = function(l, m) MOD:ChangeDBVar(m, l[#l], "party", "rdebuffs"); MOD:SetGroupFrame('party')end,
+							args = {
+								enable = {
+									type = "toggle",
+									name = L["Enable"],
+									order = 1,
+								},
+								configureToggle = {
+									order = 2,
+									type = "execute",
+									name = L["Show Indicators"],
+									func = function()
+										local toggle = (not _G["SVUI_Party"].forceShowAuras) or nil
+										MOD:ViewGroupFrames(_G["SVUI_Party"], true, toggle)
+										MOD:SetGroupFrame('party')
+									end,
+								},
+								configureButton = {
+									type = "execute",
+									name = L["Configure Filters"],
+									func = function() SVUIOptions:SetToFilterConfig("Raid") end,
+									order = 3,
+								},
+								size = {
+									type = "range",
+									name = L["Size"],
+									order = 4,
+									min = 8,
+									max = 35,
+									step = 1,
+								},
+								fontSize = {
+									type = "range",
+									name = L["Font Size"],
+									order = 5,
+									min = 7,
+									max = 22,
+									step = 1,
+								},
+								xOffset = {
+									order = 6,
+									type = "range",
+									name = L["xOffset"],
+									min =  - 300,
+									max = 300,
+									step = 1,
+								},
+								yOffset = {
+									order = 7,
+									type = "range",
+									name = L["yOffset"],
+									min =  - 300,
+									max = 300,
+									step = 1,
+								},
+							},
+						},
+						icons = SVUIOptions:SetIconConfigGroup(MOD.SetGroupFrame, 'party')
+					},
+				},
+				raid = {
+					name = "Raid",
+					type = "group",
+					order = 11,
+					childGroups = "select",
+					get = function(l) return SV.db.UnitFrames.raid[l[#l]] end,
+					set = function(l, m) MOD:ChangeDBVar(m, l[#l], "raid"); MOD:SetGroupFrame("raid") end,
+					args = {
+						enable = {
+							type = "toggle",
+							order = 1,
+							name = L["Enable"],
+						},
+						configureToggle = {
+							order = 2,
+							type = "execute",
+							name = L["Display Frames"],
+							func = function()
+								local setForced = (_G["SVUI_Raid"].forceShow ~= true) or nil;
+								MOD:ViewGroupFrames(_G["SVUI_Raid"], setForced)
+							end,
+						},
+						resetSettings = {
+							type = "execute",
+							order = 3,
+							name = L["Restore Defaults"],
+							func = function(l, m)MOD:ResetUnitOptions("raid") SV:ResetAnchors("Raid Frames") end,
+						},
+						spacer1 = {
+							order = 4,
+							name = "",
+							type = "description",
+							width = "full",
+						},
+						spacer2 = {
+							order = 5,
+							name = "",
+							type = "description",
+							width = "full",
+						},
+						general = {
+							order = 6,
+							type = "group",
+							name = L["General Settings"],
+							args = {
+								commonGroup = {
+									order = 1,
+									name = L["Basic Options"],
+									type = "group",
+									guiInline = true,
+									args = {
+										rangeCheck = {
+											order = 1,
+											type = "toggle",
+											name = L["Range Check"],
+											desc = L["Check if you are in range to cast spells on this specific unit."],
+										},
+										predict = {
+											order = 2,
+											type = "toggle",
+											name = L["Heal Prediction"],
+											desc = L["Show a incomming heal prediction bar on the unitframe. Also display a slightly different colored bar for incoming overheals."],
+										},
+										threatEnabled = {
+											order = 3,
+											type = "toggle",
+											name = L["Show Threat"],
+										},
+										useFor5man = {
+											order = 4,
+											type = "toggle",
+											name = L["Raid 5 Party"],
+											desc = L["Use party frames when in a 5-man raid group"],
+											get = function(l) return SV.db.UnitFrames.party[l[#l]] end,
+											set = function(l, m) MOD:ChangeDBVar(m, l[#l], "party"); MOD:SetGroupFrame("party"); MOD:SetGroupFrame("raid"); end,
+										},
+									}
+								},
+								layoutGroup = {
+									order = 2,
+									name = L["Layout Options"],
+									type = "group",
+									guiInline = true,
+									set = function(key, value) MOD:ChangeDBVar(value, key[#key], "raid"); MOD:SetGroupFrame("raid", true) end,
+									args = {
+										common = {
+											order = 1,
+											name = L["General Layout"],
+											type = "group",
+											guiInline = true,
+											args = {
+												enable = {
+													order = 1,
+													name = L["Enable Grid Mode"],
+													desc = L["Converts frames into symmetrical squares. Ideal for healers."],
+													type = "toggle",
+													get = function(key) return SV.db.UnitFrames.raid.grid.enable end,
+													set = function(key, value)
+														MOD:ChangeDBVar(value, key[#key], "raid", "grid");
+														MOD:SetGroupFrame("raid", true);
+														SV.Options.args.UnitFrames.args.commonGroup.args.raid.args.general.args.layoutGroup.args.sizing = SVUIOptions:SetSizeConfigGroup(value, "raid");
+													end,
+												},
+												showPlayer = {
+													order = 2,
+													type = "toggle",
+													name = L["Display Player"],
+													desc = L["When true, always show player in raid frames."],
+													get = function(l)return SV.db.UnitFrames.raid.showPlayer end,
+													set = function(l, m) MOD:ChangeDBVar(m, l[#l], "raid"); MOD:SetGroupFrame("raid", true) end,
+												},
+												invertGroupingOrder = {
+													order = 3,
+													type = "toggle",
+													name = L["Invert Grouping Order"],
+													desc = L["Enabling this inverts the grouping order when the raid is not full, this will reverse the direction it starts from."],
+													disabled = function() return not SV.db.UnitFrames.raid.customSorting end,
+												},
+											}
+										},
+										sizing = SVUIOptions:SetSizeConfigGroup(SV.db.UnitFrames.raid.grid.enable, "raid"),
+										sorting = {
+											order = 3,
+											name = L["Sorting"],
+											type = "group",
+											guiInline = true,
+											args = {
+												gRowCol = {
+													order = 1,
+													type = "range",
+													name = L["Groups Per Row / Column"],
+													min = 1,
+													max = 8,
+													step = 1,
+													width = 'full',
+													set = function(key, value)
+														MOD:ChangeDBVar(value, key[#key], "raid");
+														MOD:SetGroupFrame("raid")
+														if(_G["SVUI_Raid"] and _G["SVUI_Raid"].isForced) then
+															MOD:ViewGroupFrames(_G["SVUI_Raid"])
+															MOD:ViewGroupFrames(_G["SVUI_Raid"], true)
+														end
+													end,
+												},
+												showBy = {
+													order = 2,
+													name = L["Growth Direction"],
+													desc = L["Growth direction from the first unitframe."],
+													type = "select",
+													values = {
+														DOWN_RIGHT = format(L["%s and then %s"], L["Down"], L["Right"]),
+														DOWN_LEFT = format(L["%s and then %s"], L["Down"], L["Left"]),
+														UP_RIGHT = format(L["%s and then %s"], L["Up"], L["Right"]),
+														UP_LEFT = format(L["%s and then %s"], L["Up"], L["Left"]),
+														RIGHT_DOWN = format(L["%s and then %s"], L["Right"], L["Down"]),
+														RIGHT_UP = format(L["%s and then %s"], L["Right"], L["Up"]),
+														LEFT_DOWN = format(L["%s and then %s"], L["Left"], L["Down"]),
+														LEFT_UP = format(L["%s and then %s"], L["Left"], L["Up"]),
+													},
+												},
+												sortMethod = {
+													order = 3,
+													name = L["Group By"],
+													desc = L["Set the order that the group will sort."],
+													type = "select",
+													values = {
+														["CLASS"] = CLASS,
+														["ROLE"] = ROLE.."(Tanks, Healers, DPS)",
+														["ROLE_TDH"] = ROLE.."(Tanks, DPS, Healers)",
+														["ROLE_HDT"] = ROLE.."(Healers, DPS, Tanks)",
+														["ROLE_HTD"] = ROLE.."(Healers, Tanks, DPS)",
+														["NAME"] = NAME,
+														["MTMA"] = L["Main Tanks  /  Main Assist"],
+														["GROUP"] = GROUP,
+													},
+												},
+												sortDir = {
+													order = 4,
+													name = L["Sort Direction"],
+													desc = L["Defines the sort order of the selected sort method."],
+													type = "select",
+													values = {
+														["ASC"] = L["Ascending"],
+														["DESC"] = L["Descending"],
+													},
+												},
+												spacer3 = {
+													order = 5,
+													type = "description",
+													width = "full",
+													name = " ",
+												},
+												allowedGroup = {
+													order = 6,
+													name = L["Enabled Groups"],
+													type = "group",
+													guiInline = true,
+													args = {
+														showGroupNumber = {
+															type = "toggle",
+															order = 1,
+															name = L["Show Group Number Icons"],
+															width = 'full',
+														},
+														one = {
+															type = "toggle",
+															order = 2,
+															name = L["Group 1"],
+															get = function(key) return SV.db.UnitFrames.raid["allowedGroup"][1] end,
+															set = function(key, value)
+																SV.db.UnitFrames.raid["allowedGroup"][1] = value;
+																MOD:SetGroupFrame("raid")
+															end,
+														},
+														two = {
+															type = "toggle",
+															order = 3,
+															name = L["Group 2"],
+															get = function(key) return SV.db.UnitFrames.raid["allowedGroup"][2] end,
+															set = function(key, value)
+																SV.db.UnitFrames.raid["allowedGroup"][2] = value;
+																MOD:SetGroupFrame("raid")
+															end,
+														},
+														three = {
+															type = "toggle",
+															order = 4,
+															name = L["Group 3"],
+															get = function(key) return SV.db.UnitFrames.raid["allowedGroup"][3] end,
+															set = function(key, value)
+																SV.db.UnitFrames.raid["allowedGroup"][3] = value;
+																MOD:SetGroupFrame("raid")
+															end,
+														},
+														four = {
+															type = "toggle",
+															order = 5,
+															name = L["Group 4"],
+															get = function(key) return SV.db.UnitFrames.raid["allowedGroup"][4] end,
+															set = function(key, value)
+																SV.db.UnitFrames.raid["allowedGroup"][4] = value;
+																MOD:SetGroupFrame("raid")
+															end,
+														},
+														five = {
+															type = "toggle",
+															order = 6,
+															name = L["Group 5"],
+															get = function(key) return SV.db.UnitFrames.raid["allowedGroup"][5] end,
+															set = function(key, value)
+																SV.db.UnitFrames.raid["allowedGroup"][5] = value;
+																MOD:SetGroupFrame("raid")
+															end,
+														},
+														six = {
+															type = "toggle",
+															order = 7,
+															name = L["Group 6"],
+															get = function(key) return SV.db.UnitFrames.raid["allowedGroup"][6] end,
+															set = function(key, value)
+																SV.db.UnitFrames.raid["allowedGroup"][6] = value;
+																MOD:SetGroupFrame("raid")
+															end,
+														},
+														seven = {
+															type = "toggle",
+															order = 8,
+															name = L["Group 7"],
+															get = function(key) return SV.db.UnitFrames.raid["allowedGroup"][7] end,
+															set = function(key, value)
+																SV.db.UnitFrames.raid["allowedGroup"][7] = value;
+																MOD:SetGroupFrame("raid")
+															end,
+														},
+														eight = {
+															type = "toggle",
+															order = 9,
+															name = L["Group 8"],
+															get = function(key) return SV.db.UnitFrames.raid["allowedGroup"][8] end,
+															set = function(key, value)
+																SV.db.UnitFrames.raid["allowedGroup"][8] = value;
+																MOD:SetGroupFrame("raid")
+															end,
+														},
+													},
+												},
+											}
+										}
+									},
+								},
+							}
+						},
+						misc = SVUIOptions:SetMiscConfigGroup(true, MOD.SetGroupFrame, "raid"),
+						health = SVUIOptions:SetHealthConfigGroup(true, MOD.SetGroupFrame, "raid"),
+						power = SVUIOptions:SetPowerConfigGroup(false, MOD.SetGroupFrame, "raid"),
+						name = SVUIOptions:SetNameConfigGroup(MOD.SetGroupFrame, "raid"),
+						buffs = SVUIOptions:SetAuraConfigGroup(true, "buffs", true, MOD.SetGroupFrame, "raid"),
+						debuffs = SVUIOptions:SetAuraConfigGroup(true, "debuffs", true, MOD.SetGroupFrame, "raid"),
+						auraWatch = {
+							order = 600,
+							type = "group",
+							name = L["Aura Watch"],
+							args = {
+								enable = {
+									type = "toggle",
+									name = L["Enable"],
+									order = 1,
+									get = function(l)return SV.db.UnitFrames.raid.auraWatch.enable end,
+									set = function(l, m)MOD:ChangeDBVar(m, "enable", "raid", "auraWatch");MOD:SetGroupFrame("raid")end,
+								},
+								size = {
+									type = "range",
+									name = L["Size"],
+									desc = L["Size of the indicator icon."],
+									order = 2,
+									min = 4,
+									max = 15,
+									step = 1,
+									get = function(l)return SV.db.UnitFrames.raid.auraWatch.size end,
+									set = function(l, m)MOD:ChangeDBVar(m, "size", "raid", "auraWatch");MOD:SetGroupFrame("raid")end,
+								},
+								configureButton = {
+									type = "execute",
+									name = L["Configure Auras"],
+									func = function()SVUIOptions:SetToFilterConfig("BuffWatch")end,
+									order = 3,
+								},
+
+							},
+						},
+						rdebuffs = {
+							order = 800,
+							type = "group",
+							name = L["Raid Debuffs"],
+							get = function(l)return
+							SV.db.UnitFrames.raid["rdebuffs"][l[#l]]end,
+							set = function(l, m)MOD:ChangeDBVar(m, l[#l], "raid", "rdebuffs");MOD:SetGroupFrame("raid")end,
+							args = {
+								enable = {
+									type = "toggle",
+									name = L["Enable"],
+									order = 1,
+								},
+								configureToggle = {
+									order = 2,
+									type = "execute",
+									name = L["Show Indicators"],
+									func = function()
+										local toggle = (not _G["SVUI_Raid"].forceShowAuras) or nil
+										MOD:ViewGroupFrames(_G["SVUI_Raid"], true, toggle)
+										MOD:SetGroupFrame("raid")
+									end,
+								},
+								configureButton = {
+									type = "execute",
+									name = L["Configure Filters"],
+									func = function()SVUIOptions:SetToFilterConfig("Raid")end,
+									order = 3,
+								},
+								size = {
+									type = "range",
+									name = L["Size"],
+									order = 4,
+									min = 8,
+									max = 35,
+									step = 1,
+								},
+								fontSize = {
+									type = "range",
+									name = L["Font Size"],
+									order = 5,
+									min = 7,
+									max = 22,
+									step = 1,
+								},
+								xOffset = {
+									order = 6,
+									type = "range",
+									name = L["xOffset"],
+									min =  - 300,
+									max = 300,
+									step = 1,
+								},
+								yOffset = {
+									order = 7,
+									type = "range",
+									name = L["yOffset"],
+									min =  - 300,
+									max = 300,
+									step = 1,
+								},
+							},
+						},
+						icons = SVUIOptions:SetIconConfigGroup(MOD.SetGroupFrame, "raid"),
+					},
+				},
+				raidpet = {
+					order = 12,
+					type = 'group',
+					name = L['Raid Pets'],
+					childGroups = "select",
+					get = function(l) return SV.db.UnitFrames['raidpet'][l[#l]] end,
+					set = function(l, m) MOD:ChangeDBVar(m, l[#l], "raidpet"); MOD:SetGroupFrame('raidpet'); end,
+					args = {
+						enable = {
+							type = 'toggle',
+							order = 1,
+							name = L['Enable'],
+						},
+						configureToggle = {
+							order = 2,
+							type = 'execute',
+							name = L['Display Frames'],
+							func = function() MOD:ViewGroupFrames(SVUI_Raidpet, SVUI_Raidpet.forceShow ~= true or nil); end,
+						},
+						resetSettings = {
+							type = 'execute',
+							order = 3,
+							name = L['Restore Defaults'],
+							func = function(l, m) MOD:ResetUnitOptions('raidpet'); SV:ResetAnchors('Raid Pet Frames'); MOD:SetGroupFrame('raidpet', true); end,
+						},
+						spacer1 = {
+							order = 4,
+							name = "",
+							type = "description",
+							width = "full",
+						},
+						spacer2 = {
+							order = 5,
+							name = "",
+							type = "description",
+							width = "full",
+						},
+						general = {
+							order = 6,
+							type = "group",
+							name = L["General Settings"],
+							args = {
+								commonGroup = {
+									order = 1,
+									name = L["Basic Options"],
+									type = "group",
+									guiInline = true,
+									args = {
+										rangeCheck = {
+											order = 1,
+											type = "toggle",
+											name = L["Range Check"],
+											desc = L["Check if you are in range to cast spells on this specific unit."],
+										},
+										predict = {
+											order = 2,
+											type = "toggle",
+											name = L["Heal Prediction"],
+											desc = L["Show a incomming heal prediction bar on the unitframe. Also display a slightly different colored bar for incoming overheals."],
+										},
+										threatEnabled = {
+											order = 3,
+											type = "toggle",
+											name = L["Show Threat"],
+										},
+									}
+								},
+								layoutGroup = {
+									order = 2,
+									name = L["Layout Options"],
+									type = "group",
+									guiInline = true,
+									set = function(key, value) MOD:ChangeDBVar(value, key[#key], "raidpet"); MOD:SetGroupFrame("raidpet", true) end,
+									args = {
+										common = {
+											order = 1,
+											name = L["General Layout"],
+											type = "group",
+											guiInline = true,
+											args = {
+												enable = {
+													order = 1,
+													name = L["Enable Grid Mode"],
+													desc = L["Converts frames into symmetrical squares. Ideal for healers."],
+													type = "toggle",
+													get = function(key) return SV.db.UnitFrames["raidpet"].grid.enable end,
+													set = function(key, value)
+														MOD:ChangeDBVar(value, key[#key], "raidpet", "grid");
+														MOD:SetGroupFrame("raidpet", true);
+														SV.Options.args.UnitFrames.args.commonGroup.args.raidpet.args.general.args.layoutGroup.args.sizing = SVUIOptions:SetSizeConfigGroup(value, "raidpet");
+													end,
+												},
+												invertGroupingOrder = {
+													order = 2,
+													type = "toggle",
+													name = L["Invert Grouping Order"],
+													desc = L["Enabling this inverts the grouping order."],
+													disabled = function() return not SV.db.UnitFrames["raidpet"].customSorting end,
+												},
+											}
+										},
+										sizing = SVUIOptions:SetSizeConfigGroup(SV.db.UnitFrames.raidpet.grid.enable, "raidpet"),
+										sorting = {
+											order = 3,
+											name = L["Sorting"],
+											type = "group",
+											guiInline = true,
+											args = {
+												gRowCol = {
+													order = 1,
+													type = "range",
+													name = L["Groups Per Row / Column"],
+													min = 1,
+													max = 8,
+													step = 1,
+													width = 'full',
+													set = function(key, value)
+														MOD:ChangeDBVar(value, key[#key], "raidpet");
+														MOD:SetGroupFrame("raidpet")
+														if(_G["SVUI_Raid"] and _G["SVUI_Raid"].isForced) then
+															MOD:ViewGroupFrames(_G["SVUI_Raid"])
+															MOD:ViewGroupFrames(_G["SVUI_Raid"], true)
+														end
+													end,
+												},
+												showBy = {
+													order = 2,
+													name = L["Growth Direction"],
+													desc = L["Growth direction from the first unitframe."],
+													type = "select",
+													values = {
+														DOWN_RIGHT = format(L["%s and then %s"], L["Down"], L["Right"]),
+														DOWN_LEFT = format(L["%s and then %s"], L["Down"], L["Left"]),
+														UP_RIGHT = format(L["%s and then %s"], L["Up"], L["Right"]),
+														UP_LEFT = format(L["%s and then %s"], L["Up"], L["Left"]),
+														RIGHT_DOWN = format(L["%s and then %s"], L["Right"], L["Down"]),
+														RIGHT_UP = format(L["%s and then %s"], L["Right"], L["Up"]),
+														LEFT_DOWN = format(L["%s and then %s"], L["Left"], L["Down"]),
+														LEFT_UP = format(L["%s and then %s"], L["Left"], L["Up"]),
+													},
+												},
+												sortMethod = {
+													order = 3,
+													name = L["Group By"],
+													desc = L["Set the order that the group will sort."],
+													type = "select",
+													values = {
+														["CLASS"] = CLASS,
+														["ROLE"] = ROLE.."(Tanks, Healers, DPS)",
+														["ROLE_TDH"] = ROLE.."(Tanks, DPS, Healers)",
+														["ROLE_HDT"] = ROLE.."(Healers, DPS, Tanks)",
+														["ROLE_HTD"] = ROLE.."(Healers, Tanks, DPS)",
+														["NAME"] = NAME,
+														["MTMA"] = L["Main Tanks  /  Main Assist"],
+														["GROUP"] = GROUP,
+													},
+												},
+												sortDir = {
+													order = 4,
+													name = L["Sort Direction"],
+													desc = L["Defines the sort order of the selected sort method."],
+													type = "select",
+													values = {
+														["ASC"] = L["Ascending"],
+														["DESC"] = L["Descending"],
+													},
+												},
+											}
+										}
+									},
+								},
+							}
+						},
+						misc = SVUIOptions:SetMiscConfigGroup(true, MOD.SetGroupFrame, 'raidpet'),
+						health = SVUIOptions:SetHealthConfigGroup(true, MOD.SetGroupFrame, 'raidpet'),
+						name = SVUIOptions:SetNameConfigGroup(MOD.SetGroupFrame, 'raidpet'),
+						buffs = SVUIOptions:SetAuraConfigGroup(true, 'buffs', true, MOD.SetGroupFrame, 'raidpet'),
+						debuffs = SVUIOptions:SetAuraConfigGroup(true, 'debuffs', true, MOD.SetGroupFrame, 'raidpet'),
+						auraWatch = {
+							order = 600,
+							type = 'group',
+							name = L['Aura Watch'],
+							args = {
+								enable = {
+									type = "toggle",
+									name = L["Enable"],
+									order = 1,
+									get = function(l)return SV.db.UnitFrames["raidpet"].auraWatch.enable end,
+									set = function(l, m)MOD:ChangeDBVar(m, "enable", "raidpet", "auraWatch");MOD:SetGroupFrame('raidpet')end,
+								},
+								size = {
+									type = "range",
+									name = L["Size"],
+									desc = L["Size of the indicator icon."],
+									order = 2,
+									min = 4,
+									max = 15,
+									step = 1,
+									get = function(l)return SV.db.UnitFrames["raidpet"].auraWatch.size end,
+									set = function(l, m)MOD:ChangeDBVar(m, "size", "raidpet", "auraWatch");MOD:SetGroupFrame('raidpet')end,
+								},
+								configureButton = {
+									type = 'execute',
+									name = L['Configure Auras'],
+									func = function()SVUIOptions:SetToFilterConfig('BuffWatch')end,
+									order = 3,
+								},
+							},
+						},
+						rdebuffs = {
+							order = 700,
+							type = 'group',
+							name = L['Raid Debuffs'],
+							get = function(l)return
+							SV.db.UnitFrames['raidpet']['rdebuffs'][l[#l]]end,
+							set = function(l, m) MOD:ChangeDBVar(m, l[#l], "raidpet", "rdebuffs"); MOD:SetGroupFrame('raidpet')end,
+							args = {
+								enable = {
+									type = "toggle",
+									name = L["Enable"],
+									order = 1,
+								},
+								configureToggle = {
+									order = 2,
+									type = "execute",
+									name = L["Show Indicators"],
+									func = function()
+										local toggle = (not _G["SVUI_RaidPet"].forceShowAuras) or nil
+										MOD:ViewGroupFrames(_G["SVUI_RaidPet"], true, toggle)
+										MOD:SetGroupFrame('raidpet')
+									end,
+								},
+								configureButton = {
+									type = "execute",
+									name = L["Configure Filters"],
+									func = function() SVUIOptions:SetToFilterConfig("Raid") end,
+									order = 3,
+								},
+								size = {
+									type = "range",
+									name = L["Size"],
+									order = 4,
+									min = 8,
+									max = 35,
+									step = 1,
+								},
+								fontSize = {
+									type = "range",
+									name = L["Font Size"],
+									order = 5,
+									min = 7,
+									max = 22,
+									step = 1,
+								},
+								xOffset = {
+									order = 6,
+									type = "range",
+									name = L["xOffset"],
+									min =  - 300,
+									max = 300,
+									step = 1,
+								},
+								yOffset = {
+									order = 7,
+									type = "range",
+									name = L["yOffset"],
+									min =  - 300,
+									max = 300,
+									step = 1,
+								},
+							},
+						},
+						icons = SVUIOptions:SetIconConfigGroup(MOD.SetGroupFrame, 'raidpet'),
+					},
+				},
+				boss = {
+					name = L["Boss"],
+					type = "group",
+					order = 13,
+					childGroups = "select",
+					get = function(l)return SV.db.UnitFrames["boss"][l[#l]]end,
+					set = function(l, m)MOD:ChangeDBVar(m, l[#l], "boss");MOD:SetEnemyFrame("boss", MAX_BOSS_FRAMES)end,
+					args = {
+						enable = {type = "toggle", order = 1, name = L["Enable"]},
+						displayFrames = {type = "execute", order = 2, name = L["Display Frames"], func = function()MOD:ViewEnemyFrames("boss", MAX_BOSS_FRAMES)end},
+						resetSettings = {type = "execute", order = 3, name = L["Restore Defaults"], func = function(l, m)MOD:ResetUnitOptions("boss")SV:ResetAnchors("Boss Frames")end},
+						spacer1 = {
+							order = 4,
+							name = "",
+							type = "description",
+							width = "full",
+						},
+						spacer2 = {
+							order = 5,
+							name = "",
+							type = "description",
+							width = "full",
+						},
+						commonGroup = {
+							order = 6,
+							type = "group",
+							name = L["General Settings"],
+							args = {
+								baseGroup = {
+									order = 1,
+									type = "group",
+									guiInline = true,
+									name = L["Base Settings"],
+									args = {
+										showBy = {order = 1, name = L["Growth Direction"], type = "select", values = {["UP"] = L["Up"], ["DOWN"] = L["Down"]}},
+										spacer1 = {
+											order = 2,
+											type = "description",
+											name = "",
+										},
+										rangeCheck = {order = 3, name = L["Range Check"], desc = L["Check if you are in range to cast spells on this specific unit."], type = "toggle"},
+										hideonnpc = {type = "toggle", order = 4, name = L["Text Toggle On NPC"], desc = L["Power text will be hidden on NPC targets, in addition the name text will be repositioned to the power texts anchor point."], get = function(l)return SV.db.UnitFrames["boss"]["power"].hideonnpc end, set = function(l, m)SV.db.UnitFrames["boss"]["power"].hideonnpc = m;MOD:SetEnemyFrame("boss")end},
+										threatEnabled = {type = "toggle", order = 5, name = L["Show Threat"]}
+									}
+								},
+								sizeGroup = {
+									order = 2,
+									guiInline = true,
+									type = "group",
+									name = L["Size Settings"],
+									args = {
+										width = {
+											order = 1,
+											name = L["Width"],
+											type = "range",
+											width = "full",
+											min = 10,
+											max = 500,
+											step = 1,
+										},
+										height = {
+											order = 2,
+											name = L["Height"],
+											type = "range",
+											width = "full",
+											min = 10,
+											max = 500,
+											step = 1
+										},
+									}
+								},
+							}
+						},
+						misc = SVUIOptions:SetMiscConfigGroup(false, MOD.SetEnemyFrame, "boss", MAX_BOSS_FRAMES),
+						health = SVUIOptions:SetHealthConfigGroup(false, MOD.SetEnemyFrame, "boss", MAX_BOSS_FRAMES),
+						power = SVUIOptions:SetPowerConfigGroup(false, MOD.SetEnemyFrame, "boss", MAX_BOSS_FRAMES),
+						name = SVUIOptions:SetNameConfigGroup(MOD.SetEnemyFrame, "boss", MAX_BOSS_FRAMES),
+						portrait = SVUIOptions:SetPortraitConfigGroup(MOD.SetEnemyFrame, "boss", MAX_BOSS_FRAMES),
+						buffs = SVUIOptions:SetAuraConfigGroup(true, "buffs", false, MOD.SetEnemyFrame, "boss", MAX_BOSS_FRAMES),
+						debuffs = SVUIOptions:SetAuraConfigGroup(true, "debuffs", false, MOD.SetEnemyFrame, "boss", MAX_BOSS_FRAMES),
+						castbar = SVUIOptions:SetCastbarConfigGroup(MOD.SetEnemyFrame, "boss", MAX_BOSS_FRAMES),
+						icons = SVUIOptions:SetIconConfigGroup(MOD.SetEnemyFrame, "boss", MAX_BOSS_FRAMES)
+					}
+				},
+				arena = {
+					name = L["Arena"],
+					type = "group",
+					order = 14,
+					childGroups = "select",
+					get = function(l)return SV.db.UnitFrames["arena"][l[#l]]end,
+					set = function(l, m)MOD:ChangeDBVar(m, l[#l], "arena");MOD:SetEnemyFrame("arena", 5)end,
+					args = {
+						enable = {type = "toggle", order = 1, name = L["Enable"]},
+						displayFrames = {type = "execute", order = 2, name = L["Display Frames"], func = function()MOD:ViewEnemyFrames("arena", 5)end},
+						resetSettings = {type = "execute", order = 3, name = L["Restore Defaults"], func = function(l, m)MOD:ResetUnitOptions("arena")SV:ResetAnchors("Arena Frames")end},
+						spacer1 = {
+							order = 4,
+							name = "",
+							type = "description",
+							width = "full",
+						},
+						spacer2 = {
+							order = 5,
+							name = "",
+							type = "description",
+							width = "full",
+						},
+						commonGroup = {
+							order = 6,
+							type = "group",
+							name = L["General Settings"],
+							args = {
+								baseGroup = {
+									order = 1,
+									type = "group",
+									guiInline = true,
+									name = L["Base Settings"],
+									args = {
+										showBy = {order = 1, name = L["Growth Direction"], type = "select", values = {["UP"] = L["Up"], ["DOWN"] = L["Down"]}},
+										spacer1 = {
+											order = 2,
+											type = "description",
+											name = "",
+										},
+										predict = {order = 3, name = L["Heal Prediction"], desc = L["Show a incomming heal prediction bar on the unitframe. Also display a slightly different colored bar for incoming overheals."], type = "toggle"},
+										rangeCheck = {order = 4, name = L["Range Check"], desc = L["Check if you are in range to cast spells on this specific unit."], type = "toggle"},
+										hideonnpc = {type = "toggle", order = 5, name = L["Text Toggle On NPC"], desc = L["Power text will be hidden on NPC targets, in addition the name text will be repositioned to the power texts anchor point."], get = function(l)return SV.db.UnitFrames["arena"]["power"].hideonnpc end, set = function(l, m)SV.db.UnitFrames["arena"]["power"].hideonnpc = m;MOD:SetEnemyFrame("arena")end},
+										threatEnabled = {type = "toggle", order = 6, name = L["Show Threat"]}
+									}
+								},
+								sizeGroup = {
+									order = 2,
+									guiInline = true,
+									type = "group",
+									name = L["Size Settings"],
+									args = {
+										width = {
+											order = 1,
+											name = L["Width"],
+											type = "range",
+											width = "full",
+											min = 10,
+											max = 500,
+											step = 1,
+										},
+										height = {
+											order = 2,
+											name = L["Height"],
+											type = "range",
+											width = "full",
+											min = 10,
+											max = 500,
+											step = 1
+										},
+									}
+								},
+								pvp = {
+									order = 3,
+									guiInline = true,
+									type = "group",
+									name = L["PVP Indicators"],
+									args = {
+										enable = {
+											type = "toggle",
+											order = 1,
+											name = L["Enable"],
+											get = function(l)return SV.db.UnitFrames.arena.pvp.enable end,
+											set = function(l, m)MOD:ChangeDBVar(m, "enable", "arena", "pvp");MOD:SetEnemyFrame("arena", 5)end,
+										},
+										trinketGroup = {
+											order = 2,
+											guiInline = true,
+											type = "group",
+											name = L["Trinkets"],
+											get = function(l)return SV.db.UnitFrames.arena.pvp[l[#l]]end,
+											set = function(l, m)MOD:ChangeDBVar(m, l[#l], "arena", "pvp");MOD:SetEnemyFrame("arena", 5)end,
+											disabled = function() return not SV.db.UnitFrames.arena.pvp.enable end,
+											args = {
+												trinketPosition = {
+													type = "select",
+													order = 1,
+													name = L["Position"],
+													values = {
+														["LEFT"] = L["Left"],
+														["RIGHT"] = L["Right"]
+													}
+												},
+												trinketSize = {
+													order = 2,
+													type = "range",
+													name = L["Size"],
+													min = 10,
+													max = 60,
+													step = 1
+												},
+												trinketX = {
+													order = 3,
+													type = "range",
+													name = L["xOffset"],
+													min = -60,
+													max = 60,
+													step = 1
+												},
+												trinketY = {
+													order = 4,
+													type = "range",
+													name = L["yOffset"],
+													min = -60,
+													max = 60,
+													step = 1
+												}
+											}
+										},
+										specGroup = {
+											order = 3,
+											guiInline = true,
+											type = "group",
+											name = L["Enemy Specs"],
+											get = function(l)return SV.db.UnitFrames.arena.pvp[l[#l]]end,
+											set = function(l, m)MOD:ChangeDBVar(m, l[#l], "arena", "pvp");MOD:SetEnemyFrame("arena", 5)end,
+											disabled = function() return not SV.db.UnitFrames.arena.pvp.enable end,
+											args = {
+												specPosition = {
+													type = "select",
+													order = 1,
+													name = L["Position"],
+													values = {
+														["LEFT"] = L["Left"],
+														["RIGHT"] = L["Right"]
+													}
+												},
+												specSize = {
+													order = 2,
+													type = "range",
+													name = L["Size"],
+													min = 10,
+													max = 60,
+													step = 1
+												},
+												specX = {
+													order = 3,
+													type = "range",
+													name = L["xOffset"],
+													min = -60,
+													max = 60,
+													step = 1
+												},
+												specY = {
+													order = 4,
+													type = "range",
+													name = L["yOffset"],
+													min = -60,
+													max = 60,
+													step = 1
+												}
+											}
+										}
+									}
+								},
+							}
+						},
+						misc = SVUIOptions:SetMiscConfigGroup(false, MOD.SetEnemyFrame, "arena", 5),
+						health = SVUIOptions:SetHealthConfigGroup(false, MOD.SetEnemyFrame, "arena", 5),
+						power = SVUIOptions:SetPowerConfigGroup(false, MOD.SetEnemyFrame, "arena", 5),
+						name = SVUIOptions:SetNameConfigGroup(MOD.SetEnemyFrame, "arena", 5),
+						portrait = SVUIOptions:SetPortraitConfigGroup(MOD.SetEnemyFrame, "arena", 5),
+						buffs = SVUIOptions:SetAuraConfigGroup(false, "buffs", false, MOD.SetEnemyFrame, "arena", 5),
+						debuffs = SVUIOptions:SetAuraConfigGroup(false, "debuffs", false, MOD.SetEnemyFrame, "arena", 5),
+						castbar = SVUIOptions:SetCastbarConfigGroup(MOD.SetEnemyFrame, "arena", 5)
+					}
+				},
+				tank = {
+					name = L["Tank"],
+					type = "group",
+					order = 15,
+					childGroups = "select",
+					get = function(l)return SV.db.UnitFrames["tank"][l[#l]]end,
+					set = function(l, m)MOD:ChangeDBVar(m, l[#l], "tank");MOD:SetGroupFrame("tank")end,
+					args = {
+						enable = {type = "toggle", order = 1, name = L["Enable"]},
+						resetSettings = {type = "execute", order = 2, name = L["Restore Defaults"], func = function(l, m)MOD:ResetUnitOptions("tank")end},
+						spacer1 = {
+							order = 3,
+							name = "",
+							type = "description",
+							width = "full",
+						},
+						spacer2 = {
+							order = 4,
+							name = "",
+							type = "description",
+							width = "full",
+						},
+						commonGroup = {
+							order = 5,
+							type = "group",
+							name = L["General Layout"],
+							args = {
+								enable = {
+									order = 1,
+									name = L["Enable Grid Mode"],
+									desc = L["Converts frames into symmetrical squares. Ideal for healers."],
+									type = "toggle",
+									get = function(key) return SV.db.UnitFrames["tank"].grid.enable end,
+									set = function(key, value)
+										MOD:ChangeDBVar(value, key[#key], "tank", "grid");
+										MOD:SetGroupFrame("tank");
+										SV.Options.args.UnitFrames.args.commonGroup.args.tank.args.commonGroup.args.sizing = SVUIOptions:SetSizeConfigGroup(value, "tank");
+									end,
+								},
+								invertGroupingOrder = {
+									order = 2,
+									type = "toggle",
+									name = L["Invert Grouping Order"],
+									desc = L["Enabling this inverts the grouping order."],
+									disabled = function() return not SV.db.UnitFrames["tank"].customSorting end,
+								},
+								sizing = SVUIOptions:SetSizeConfigGroup(SV.db.UnitFrames.tank.grid.enable, "tank"),
+							}
+						},
+						name = SVUIOptions:SetNameConfigGroup(MOD.SetGroupFrame, "tank"),
+						targetsGroup = {
+							type = "group",
+							name = L["Tank Target"],
+							get = function(l)return SV.db.UnitFrames["tank"]["targetsGroup"][l[#l]]end,
+							set = function(l, m)MOD:ChangeDBVar(m, l[#l], "tank", "targetsGroup");MOD:SetGroupFrame("tank")end,
+							args = {
+								enable = {type = "toggle", name = L["Enable"], order = 1},
+								width = {order = 2, name = L["Width"], type = "range", min = 10, max = 500, step = 1},
+								height = {order = 3, name = L["Height"], type = "range", min = 10, max = 250, step = 1},
+								anchorPoint = {type = "select", order = 5, name = L["Anchor Point"], desc = L["What point to anchor to the frame you set to attach to."], values = {TOPLEFT = "TOPLEFT", LEFT = "LEFT", BOTTOMLEFT = "BOTTOMLEFT", RIGHT = "RIGHT", TOPRIGHT = "TOPRIGHT", BOTTOMRIGHT = "BOTTOMRIGHT", CENTER = "CENTER", TOP = "TOP", BOTTOM = "BOTTOM"}},
+								xOffset = {order = 6, type = "range", name = L["xOffset"], desc = L["An X offset (in pixels) to be used when anchoring new frames."], min = -500, max = 500, step = 1},
+								yOffset = {order = 7, type = "range", name = L["yOffset"], desc = L["An Y offset (in pixels) to be used when anchoring new frames."], min = -500, max = 500, step = 1}
+							}
+						}
+					}
+				},
+				assist = {
+					name = L["Assist"],
+					type = "group",
+					order = 16,
+					childGroups = "select",
+					get = function(l)return SV.db.UnitFrames["assist"][l[#l]]end,
+					set = function(l, m)MOD:ChangeDBVar(m, l[#l], "assist");MOD:SetGroupFrame("assist")end,
+					args = {
+						enable = {type = "toggle", order = 1, name = L["Enable"]},
+						resetSettings = {type = "execute", order = 2, name = L["Restore Defaults"], func = function(l, m)MOD:ResetUnitOptions("assist")end},
+						spacer1 = {
+							order = 3,
+							name = "",
+							type = "description",
+							width = "full",
+						},
+						spacer2 = {
+							order = 4,
+							name = "",
+							type = "description",
+							width = "full",
+						},
+						commonGroup = {
+							order = 5,
+							type = "group",
+							name = L["General Layout"],
+							args = {
+								enable = {
+									order = 1,
+									name = L["Enable Grid Mode"],
+									desc = L["Converts frames into symmetrical squares. Ideal for healers."],
+									type = "toggle",
+									get = function(key) return SV.db.UnitFrames["assist"].grid.enable end,
+									set = function(key, value)
+										MOD:ChangeDBVar(value, key[#key], "assist", "grid");
+										MOD:SetGroupFrame("assist");
+										SV.Options.args.UnitFrames.args.commonGroup.args.assist.args.commonGroup.args.sizing = SVUIOptions:SetSizeConfigGroup(value, "assist");
+									end,
+								},
+								invertGroupingOrder = {
+									order = 2,
+									type = "toggle",
+									name = L["Invert Grouping Order"],
+									desc = L["Enabling this inverts the grouping order."],
+									disabled = function() return not SV.db.UnitFrames["assist"].customSorting end,
+								},
+								sizing = SVUIOptions:SetSizeConfigGroup(SV.db.UnitFrames.assist.grid.enable, "assist"),
+							}
+						},
+						name = SVUIOptions:SetNameConfigGroup(MOD.SetGroupFrame, "assist"),
+						targetsGroup = {
+							type = "group",
+							name = L["Assist Target"],
+							get = function(l)return SV.db.UnitFrames["assist"]["targetsGroup"][l[#l]]end,
+							set = function(l, m)MOD:ChangeDBVar(m, l[#l], "assist", "targetsGroup");MOD:SetGroupFrame("assist")end,
+							args = {
+								enable = {type = "toggle", name = L["Enable"], order = 1},
+								width = {order = 2, name = L["Width"], type = "range", min = 10, max = 500, step = 1},
+								height = {order = 3, name = L["Height"], type = "range", min = 10, max = 250, step = 1},
+								anchorPoint = {type = "select", order = 5, name = L["Anchor Point"], desc = L["What point to anchor to the frame you set to attach to."], values = {TOPLEFT = "TOPLEFT", LEFT = "LEFT", BOTTOMLEFT = "BOTTOMLEFT", RIGHT = "RIGHT", TOPRIGHT = "TOPRIGHT", BOTTOMRIGHT = "BOTTOMRIGHT", CENTER = "CENTER", TOP = "TOP", BOTTOM = "BOTTOM"}},
+								xOffset = {order = 6, type = "range", name = L["xOffset"], desc = L["An X offset (in pixels) to be used when anchoring new frames."], min = -500, max = 500, step = 1},
+								yOffset = {order = 7, type = "range", name = L["yOffset"], desc = L["An Y offset (in pixels) to be used when anchoring new frames."], min = -500, max = 500, step = 1}
+							}
+						}
+					}
+				}
+			},
+		}
+	},
+}
diff --git a/SVUI_ActionBars/LICENSE.txt b/SVUI_ActionBars/LICENSE.txt
new file mode 100644
index 0000000..05ceba8
--- /dev/null
+++ b/SVUI_ActionBars/LICENSE.txt
@@ -0,0 +1,31 @@
+
+The MIT License
+
+Copyright (c) 2010, Failcoder (Steve Jackson)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy
+of this software and associated documentation files (the "Software"), to
+deal
+in the Software without restriction, including without limitation the
+rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/SVUI_ActionBars/Loader.lua b/SVUI_ActionBars/Loader.lua
new file mode 100644
index 0000000..3559f45
--- /dev/null
+++ b/SVUI_ActionBars/Loader.lua
@@ -0,0 +1,1190 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+
+local SV = _G["SVUI"];
+local L = SV.L;
+local MOD = SV:NewModule(...);
+local Schema = MOD.Schema;
+
+MOD.media = {}
+MOD.media.microMenuFile = [[Interface\AddOns\SVUI_ActionBars\assets\MICROMENU]];
+MOD.media.microMenuCoords = {
+  {"CharacterMicroButton",0,0.25,0,0.25},     -- MICRO-CHARACTER
+  {"SpellbookMicroButton",0.25,0.5,0,0.25},   -- MICRO-SPELLBOOK
+  {"TalentMicroButton",0.5,0.75,0,0.25},      -- MICRO-TALENTS
+  {"AchievementMicroButton",0.75,1,0,0.25},   -- MICRO-ACHIEVEMENTS
+  {"QuestLogMicroButton",0,0.25,0.25,0.5},    -- MICRO-QUESTS
+  {"GuildMicroButton",0.25,0.5,0.25,0.5},     -- MICRO-GUILD
+  {"PVPMicroButton",0.5,0.75,0.25,0.5},       -- MICRO-PVP
+  {"LFDMicroButton",0.75,1,0.25,0.5},         -- MICRO-LFD
+  {"EJMicroButton",0,0.25,0.5,0.75},          -- MICRO-ENCOUNTER
+  {"StoreMicroButton",0.25,0.5,0.5,0.75},     -- MICRO-STORE
+  {"CollectionsMicroButton",0.5,0.75,0.5,0.75},-- MICRO-COMPANION
+  {"MainMenuMicroButton",0.75,1,0.5,0.75},    -- MICRO-SYSTEM
+  {"HelpMicroButton",0,0.25,0.75,1},          -- MICRO-HELP
+}
+
+SV.defaults[Schema] = {
+	["barCount"] = 6,
+	["font"] = "SVUI Default Font",
+	["fontSize"] = 11,
+	["fontOutline"] = "OUTLINE",
+	["countFont"] = "SVUI Number Font",
+	["countFontSize"] = 11,
+	["countFontOutline"] = "OUTLINE",
+	["cooldownSize"] = 18,
+	["rightClickSelf"] = false,
+	["macrotext"] = false,
+	["hotkeytext"] = false,
+	["hotkeyAbbrev"] = true,
+	["showGrid"] = true,
+	["unc"] = {0.8, 0.1, 0.1, 0.7},
+	["unpc"] = {0.5, 0.5, 1, 0.7},
+	["keyDown"] = false,
+	["unlock"] = "SHIFT",
+	["Micro"] = {
+		["enable"] = true,
+		["mouseover"] = true,
+		["alpha"] = 1,
+		["buttonsize"] = 30,
+		["buttonspacing"] = 4,
+		["yOffset"] = 4
+	},
+	["Totem"] = {
+	    ["enable"] = true,
+	    ["showBy"] = "VERTICAL",
+	    ["sortDirection"] = "ASCENDING",
+	    ["buttonsize"] = 40,
+	    ["buttonspacing"] = 4
+	},
+	["Bar1"] = {
+		["enable"] = true,
+		["buttons"] = 12,
+		["mouseover"] = false,
+		["buttonsPerRow"] = 12,
+		["point"] = "BOTTOMLEFT",
+		["backdrop"] = false,
+		["buttonsize"] = 32,
+		["buttonspacing"] = 2,
+		["showVehicle"] = true,
+		["useCustomPaging"] = true,
+		["useCustomVisibility"] = false,
+		["customVisibility"] = "[petbattle] hide; show",
+		["customPaging"] = {
+		    ["HUNTER"]  	 = "",
+		    ["WARLOCK"] 	 = "[form:2] 10;",
+		    ["PRIEST"]  	 = "[bonusbar:1] 7;",
+		    ["PALADIN"] 	 = "",
+		    ["MAGE"]    	 = "",
+		    ["ROGUE"]   	 = "[stance:1] 7; [stance:2] 7; [stance:3] 7; [bonusbar:1] 7; [form:3] 7;",
+		    ["DRUID"]   	 = "[bonusbar:1, nostealth] 7; [bonusbar:1, stealth] 8; [bonusbar:2] 8; [bonusbar:3] 9; [bonusbar:4] 10;",
+		    ["SHAMAN"]  	 = "",
+		    ["WARRIOR"] 	 = "[bonusbar:1] 7; [bonusbar:2] 8;",
+		    ["DEATHKNIGHT"]  = "",
+		    ["MONK"]    	 = "[bonusbar:1] 7; [bonusbar:2] 8; [bonusbar:3] 9;",
+		    ["DEMONHUNTER"]  = "",
+		},
+		["alpha"] = 1
+	},
+	["Bar2"] = {
+		["enable"] = false,
+		["mouseover"] = false,
+		["buttons"] = 12,
+		["buttonsPerRow"] = 12,
+		["point"] = "BOTTOMLEFT",
+		["backdrop"] = false,
+		["buttonsize"] = 32,
+		["buttonspacing"] = 2,
+		["showVehicle"] = false,
+		["useCustomPaging"] = false,
+		["useCustomVisibility"] = false,
+		["customVisibility"] = "[petbattle] hide; show",
+		["customPaging"] = {
+		    ["HUNTER"]  	 = "",
+		    ["WARLOCK"] 	 = "",
+		    ["PRIEST"]  	 = "",
+		    ["PALADIN"] 	 = "",
+		    ["MAGE"]    	 = "",
+		    ["ROGUE"]   	 = "",
+		    ["DRUID"]   	 = "",
+		    ["SHAMAN"]  	 = "",
+		    ["WARRIOR"] 	 = "",
+		    ["DEATHKNIGHT"]  = "",
+		    ["MONK"]    	 = "",
+		    ["DEMONHUNTER"]  = "",
+		},
+		["alpha"] = 1
+	},
+	["Bar3"] = {
+		["enable"] = true,
+		["mouseover"] = false,
+		["buttons"] = 6,
+		["buttonsPerRow"] = 6,
+		["point"] = "BOTTOMLEFT",
+		["backdrop"] = false,
+		["buttonsize"] = 32,
+		["buttonspacing"] = 2,
+		["showVehicle"] = false,
+		["useCustomPaging"] = false,
+		["useCustomVisibility"] = false,
+		["customVisibility"] = "[petbattle] hide; show",
+		["customPaging"] = {
+		    ["HUNTER"]  	 = "",
+		    ["WARLOCK"] 	 = "",
+		    ["PRIEST"]  	 = "",
+		    ["PALADIN"] 	 = "",
+		    ["MAGE"]    	 = "",
+		    ["ROGUE"]   	 = "",
+		    ["DRUID"]   	 = "",
+		    ["SHAMAN"]  	 = "",
+		    ["WARRIOR"] 	 = "",
+		    ["DEATHKNIGHT"]  = "",
+		    ["MONK"]    	 = "",
+		    ["DEMONHUNTER"]  = "",
+		},
+		["alpha"] = 1
+	},
+	["Bar4"] = {
+		["enable"] = true,
+		["mouseover"] = true,
+		["buttons"] = 12,
+		["buttonsPerRow"] = 1,
+		["point"] = "TOPRIGHT",
+		["backdrop"] = false,
+		["buttonsize"] = 32,
+		["buttonspacing"] = 2,
+		["showVehicle"] = false,
+		["useCustomPaging"] = false,
+		["useCustomVisibility"] = false,
+		["customVisibility"] = "[petbattle] hide; show",
+		["customPaging"] = {
+		    ["HUNTER"]  	 = "",
+		    ["WARLOCK"] 	 = "",
+		    ["PRIEST"]  	 = "",
+		    ["PALADIN"] 	 = "",
+		    ["MAGE"]    	 = "",
+		    ["ROGUE"]   	 = "",
+		    ["DRUID"]   	 = "",
+		    ["SHAMAN"]  	 = "",
+		    ["WARRIOR"] 	 = "",
+		    ["DEATHKNIGHT"]  = "",
+		    ["MONK"]    	 = "",
+		    ["DEMONHUNTER"]  = "",
+		},
+		["alpha"] = 1
+	},
+	["Bar5"] = {
+		["enable"] = true,
+		["mouseover"] = false,
+		["buttons"] = 6,
+		["buttonsPerRow"] = 6,
+		["point"] = "BOTTOMLEFT",
+		["backdrop"] = false,
+		["buttonsize"] = 32,
+		["buttonspacing"] = 2,
+		["showVehicle"] = false,
+		["useCustomPaging"] = false,
+		["useCustomVisibility"] = false,
+		["customVisibility"] = "[petbattle] hide; show",
+		["customPaging"] = {
+		    ["HUNTER"]  	 = "",
+		    ["WARLOCK"] 	 = "",
+		    ["PRIEST"]  	 = "",
+		    ["PALADIN"] 	 = "",
+		    ["MAGE"]    	 = "",
+		    ["ROGUE"]   	 = "",
+		    ["DRUID"]   	 = "",
+		    ["SHAMAN"]  	 = "",
+		    ["WARRIOR"] 	 = "",
+		    ["DEATHKNIGHT"]  = "",
+		    ["MONK"]    	 = "",
+		    ["DEMONHUNTER"]  = "",
+		},
+		["alpha"] = 1
+	},
+	["Bar6"] = {
+		["enable"] = false,
+		["mouseover"] = false,
+		["buttons"] = 12,
+		["buttonsPerRow"] = 12,
+		["point"] = "BOTTOMLEFT",
+		["backdrop"] = false,
+		["buttonsize"] = 32,
+		["buttonspacing"] = 2,
+		["showVehicle"] = false,
+		["useCustomPaging"] = false,
+		["useCustomVisibility"] = false,
+		["customVisibility"] = "[petbattle] hide; show",
+		["customPaging"] = {
+		    ["HUNTER"]  	 = "",
+		    ["WARLOCK"] 	 = "",
+		    ["PRIEST"]  	 = "",
+		    ["PALADIN"] 	 = "",
+		    ["MAGE"]    	 = "",
+		    ["ROGUE"]   	 = "",
+		    ["DRUID"]   	 = "",
+		    ["SHAMAN"]  	 = "",
+		    ["WARRIOR"] 	 = "",
+		    ["DEATHKNIGHT"]  = "",
+		    ["MONK"]    	 = "",
+		    ["DEMONHUNTER"]  = "",
+		},
+		["alpha"] = 1
+	},
+	["Bar7"] = {
+		["enable"] = false,
+		["mouseover"] = false,
+		["buttons"] = 12,
+		["buttonsPerRow"] = 12,
+		["point"] = "BOTTOMLEFT",
+		["backdrop"] = false,
+		["buttonsize"] = 32,
+		["buttonspacing"] = 2,
+		["showVehicle"] = false,
+		["useCustomPaging"] = false,
+		["useCustomVisibility"] = false,
+		["customVisibility"] = "[petbattle] hide; show",
+		["customPaging"] = {
+		    ["HUNTER"]  	 = "",
+		    ["WARLOCK"] 	 = "",
+		    ["PRIEST"]  	 = "",
+		    ["PALADIN"] 	 = "",
+		    ["MAGE"]    	 = "",
+		    ["ROGUE"]   	 = "",
+		    ["DRUID"]   	 = "",
+		    ["SHAMAN"]  	 = "",
+		    ["WARRIOR"] 	 = "",
+		    ["DEATHKNIGHT"]  = "",
+		    ["MONK"]    	 = "",
+		    ["DEMONHUNTER"]  = "",
+		},
+		["alpha"] = 1
+	},
+	["Bar8"] = {
+		["enable"] = false,
+		["mouseover"] = false,
+		["buttons"] = 12,
+		["buttonsPerRow"] = 12,
+		["point"] = "BOTTOMLEFT",
+		["backdrop"] = false,
+		["buttonsize"] = 32,
+		["buttonspacing"] = 2,
+		["showVehicle"] = false,
+		["useCustomPaging"] = false,
+		["useCustomVisibility"] = false,
+		["customVisibility"] = "[petbattle] hide; show",
+		["customPaging"] = {
+		    ["HUNTER"]  	 = "",
+		    ["WARLOCK"] 	 = "",
+		    ["PRIEST"]  	 = "",
+		    ["PALADIN"] 	 = "",
+		    ["MAGE"]    	 = "",
+		    ["ROGUE"]   	 = "",
+		    ["DRUID"]   	 = "",
+		    ["SHAMAN"]  	 = "",
+		    ["WARRIOR"] 	 = "",
+		    ["DEATHKNIGHT"]  = "",
+		    ["MONK"]    	 = "",
+		    ["DEMONHUNTER"]  = "",
+		},
+		["alpha"] = 1
+	},
+	["Bar9"] = {
+		["enable"] = false,
+		["mouseover"] = false,
+		["buttons"] = 12,
+		["buttonsPerRow"] = 12,
+		["point"] = "BOTTOMLEFT",
+		["backdrop"] = false,
+		["buttonsize"] = 32,
+		["buttonspacing"] = 2,
+		["showVehicle"] = false,
+		["useCustomPaging"] = false,
+		["useCustomVisibility"] = false,
+		["customVisibility"] = "[petbattle] hide; show",
+		["customPaging"] = {
+		    ["HUNTER"]  	 = "",
+		    ["WARLOCK"] 	 = "",
+		    ["PRIEST"]  	 = "",
+		    ["PALADIN"] 	 = "",
+		    ["MAGE"]    	 = "",
+		    ["ROGUE"]   	 = "",
+		    ["DRUID"]   	 = "",
+		    ["SHAMAN"]  	 = "",
+		    ["WARRIOR"] 	 = "",
+		    ["DEATHKNIGHT"]  = "",
+		    ["MONK"]    	 = "",
+		    ["DEMONHUNTER"]  = "",
+		},
+		["alpha"] = 1
+	},
+	["Bar10"] = {
+		["enable"] = false,
+		["mouseover"] = false,
+		["buttons"] = 12,
+		["buttonsPerRow"] = 12,
+		["point"] = "BOTTOMLEFT",
+		["backdrop"] = false,
+		["buttonsize"] = 32,
+		["buttonspacing"] = 2,
+		["showVehicle"] = false,
+		["useCustomPaging"] = false,
+		["useCustomVisibility"] = false,
+		["customVisibility"] = "[petbattle] hide; show",
+		["customPaging"] = {
+		    ["HUNTER"]  	 = "",
+		    ["WARLOCK"] 	 = "",
+		    ["PRIEST"]  	 = "",
+		    ["PALADIN"] 	 = "",
+		    ["MAGE"]    	 = "",
+		    ["ROGUE"]   	 = "",
+		    ["DRUID"]   	 = "",
+		    ["SHAMAN"]  	 = "",
+		    ["WARRIOR"] 	 = "",
+		    ["DEATHKNIGHT"]  = "",
+		    ["MONK"]    	 = "",
+		    ["DEMONHUNTER"]  = "",
+		},
+		["alpha"] = 1
+	},
+	["Pet"] = {
+		["enable"] = true,
+		["mouseover"] = false,
+		["buttons"] = NUM_PET_ACTION_SLOTS,
+		["buttonsPerRow"] = NUM_PET_ACTION_SLOTS,
+		["point"] = "TOPLEFT",
+		["backdrop"] = false,
+		["buttonsize"] = 24,
+		["buttonspacing"] = 3,
+		["useCustomVisibility"] = false,
+		["customVisibility"] = "[petbattle] hide; [pet, novehicleui, nooverridebar, nopossessbar] show; hide",
+		["alpha"] = 1
+	},
+	["Stance"] = {
+		["enable"] = true,
+		["style"] = "darkenInactive",
+		["mouseover"] = false,
+		["buttons"] = NUM_STANCE_SLOTS,
+		["buttonsPerRow"] = NUM_STANCE_SLOTS,
+		["point"] = "BOTTOMLEFT",
+		["backdrop"] = false,
+		["buttonsize"] = 24,
+		["buttonspacing"] = 5,
+		["useCustomVisibility"] = false,
+		["customVisibility"] = "[petbattle] hide; show",
+		["alpha"] = 1
+	}
+};
+
+function MOD:LoadOptions()
+	local count = SV.db.ActionBars.barCount or 6
+	local POSITION_VALUES = {
+		["TOPLEFT"] = "TOPLEFT",
+		["TOPRIGHT"] = "TOPRIGHT",
+		["BOTTOMLEFT"] = "BOTTOMLEFT",
+		["BOTTOMRIGHT"] = "BOTTOMRIGHT",
+	}
+
+	SV.Options.args.primary.args.quickGroup1.args.toggleKeybind = {
+		order = 5,
+		width = "full",
+		type = "execute",
+		name = L["Keybind Mode"],
+		func = function()
+			MOD:ToggleKeyBindingMode()
+			SV:ToggleConfig()
+			GameTooltip:Hide()
+		end
+	};
+
+	SV.Options.args[Schema] = {
+		type = "group",
+		name = Schema,
+		childGroups = "tab",
+		get = function(key)
+			return SV.db[Schema][key[#key]]
+		end,
+		set = function(key, value)
+			MOD:ChangeDBVar(value, key[#key]);
+			MOD:RefreshActionBars()
+		end,
+		args = {
+			barGroup = {
+				order = 3,
+				type = "group",
+				name = L["Bar Options"],
+				childGroups = "tree",
+				args = {
+					commonGroup = {
+						order = 1,
+						type = "group",
+						name = L["General Settings"],
+						args = {
+							hotkeytext = {
+								type = "toggle",
+								name = L["Keybind Text"],
+								desc = L["Display bind names on action buttons."],
+								order = 1
+							},
+							keyDown = {
+								type = "toggle",
+								name = L["Key Down"],
+								desc = OPTION_TOOLTIP_ACTION_BUTTON_USE_KEY_DOWN,
+								order = 2
+							},
+							unlock = {
+								type = "select",
+								name = PICKUP_ACTION_KEY_TEXT,
+								desc = L["The button you must hold down in order to drag an ability to another action button."],
+								order = 3,
+								values = {
+									["SHIFT"] = SHIFT_KEY,
+									["ALT"] = ALT_KEY,
+									["CTRL"] = CTRL_KEY
+								}
+							},
+							macrotext = {
+								type = "toggle",
+								name = L["Macro Text"],
+								desc = L["Display macro names on action buttons."],
+								order = 4
+							},
+							rightClickSelf = {
+								type = "toggle",
+								name = L["Self Cast"],
+								desc = L["Right-click any action button to self cast"],
+								order = 5
+							},
+							showGrid = {
+								type = "toggle",
+								name = ALWAYS_SHOW_MULTIBARS_TEXT,
+								desc = OPTION_TOOLTIP_ALWAYS_SHOW_MULTIBARS,
+								order = 6
+							},
+							unc = {
+								type = "color",
+								order = 7,
+								name = L["Out of Range"],
+								desc = L["Color of the actionbutton when out of range."],
+								hasAlpha = true,
+								get = function(key) return unpack(SV.db[Schema][key[#key]]) end,
+								set = function(key, rValue, gValue, bValue, aValue)
+									SV.db[Schema][key[#key]][1] = rValue
+									SV.db[Schema][key[#key]][2] = gValue
+									SV.db[Schema][key[#key]][3] = bValue
+									SV.db[Schema][key[#key]][4] = aValue
+									MOD:RefreshActionBars()
+								end,
+							},
+							unpc = {
+								type = "color",
+								order = 8,
+								name = L["Out of Power"],
+								desc = L["Color of the actionbutton when out of power (Mana, Rage, Focus, Holy Power)."],
+								hasAlpha = true,
+								get = function(key) return unpack(SV.db[Schema][key[#key]]) end,
+								set = function(key, rValue, gValue, bValue, aValue)
+									SV.db[Schema][key[#key]][1] = rValue
+									SV.db[Schema][key[#key]][2] = gValue
+									SV.db[Schema][key[#key]][3] = bValue
+									SV.db[Schema][key[#key]][4] = aValue
+									MOD:RefreshActionBars()
+								end,
+							},
+							barCount = {
+								order = 9,
+								type = "range",
+								width = 'full',
+								name = L["Total Bars"],
+								desc = L["The count of available bars."],
+								min = 6,
+								max = 10,
+								step = 1,
+								get = function(e)return SV.db[Schema][e[#e]]end,
+								set = function(e, f)SV.db[Schema][e[#e]] = f;SV:StaticPopup_Show("RL_CLIENT")end
+							},
+							cooldownSize = {
+								order = 10,
+								width = "full",
+								name = L["Cooldown Font Size"],
+								type = "range",
+								min = 6,
+								max = 22,
+								step = 1
+							},
+
+						}
+					},
+					Pet = {
+						order = (count + 2),
+						name = L["Pet Bar"],
+						type = "group",
+						guiInline = false,
+						get = function(e)return SV.db[Schema]["Pet"][e[#e]]end,
+						set = function(key, value)
+							MOD:ChangeDBVar(value, key[#key], "Pet");
+							MOD:RefreshBar("Pet")
+						end,
+						args = {
+							enable = {
+								order = 1,
+								width = 'full',
+								type = "toggle",
+								name = L["Enable"]
+							},
+							backdrop = {
+								order = 2,
+								name = L["Background"],
+								type = "toggle",
+								disabled = function()return not SV.db[Schema]["Pet"].enable end,
+							},
+							mouseover = {
+								order = 3,
+								name = L["Mouse Over"],
+								desc = L["The frame is not shown unless you mouse over the frame."],
+								type = "toggle",
+								disabled = function()return not SV.db[Schema]["Pet"].enable end,
+							},
+							restorePosition = {
+								order = 4,
+								type = "execute",
+								name = L["Restore Bar"],
+								desc = L["Restore the actionbars default settings"],
+								func = function()
+									SV:ResetData("ActionBars", "Pet")
+									SV:ResetAnchors("Pet Bar")
+									MOD:RefreshBar("Pet")
+								end,
+								disabled = function()return not SV.db[Schema]["Pet"].enable end,
+							},
+							adjustGroup = {
+								name = L["Bar Adjustments"],
+								type = "group",
+								order = 5,
+								guiInline = true,
+								disabled = function()return not SV.db[Schema]["Pet"].enable end,
+								args = {
+									point = {
+										order = 1,
+										type = "select",
+										name = L["Anchor Point"],
+										desc = L["The first button anchors itself to this point on the bar."],
+										values = POSITION_VALUES
+									},
+									buttons = {
+										order = 2,
+										type = "range",
+										name = L["Buttons"],
+										desc = L["The amount of buttons to display."],
+										min = 1,
+										max = NUM_PET_ACTION_SLOTS,
+										step = 1
+									},
+									buttonsPerRow = {
+										order = 3,
+										type = "range",
+										name = L["Buttons Per Row"],
+										desc = L["The amount of buttons to display per row."],
+										min = 1,
+										max = NUM_PET_ACTION_SLOTS,
+										step = 1
+									},
+									buttonsize = {
+										order = 4,
+										type = "range",
+										name = L["Button Size"],
+										desc = L["The size of the action buttons."],
+										min = 15,
+										max = 60,
+										step = 1,
+									},
+									buttonspacing = {
+										order = 5,
+										type = "range",
+										name = L["Button Spacing"],
+										desc = L["The spacing between buttons."],
+										min = 1,
+										max = 10,
+										step = 1,
+									},
+									alpha = {
+										order = 6,
+										type = "range",
+										name = L["Alpha"],
+										isPercent = true,
+										min = 0,
+										max = 1,
+										step = 0.01
+									},
+								}
+							},
+							customGroup = {
+								name = L["Visibility Options"],
+								type = "group",
+								order = 6,
+								guiInline = true,
+								args = {
+									useCustomVisibility = {
+										order = 1,
+										type = "toggle",
+										name = L["Enable"],
+										desc = L["Allow the use of custom paging for this bar"],
+										get = function()return SV.db[Schema]["Pet"].useCustomVisibility end,
+										set = function(e,f)
+											SV.db[Schema]["Pet"].useCustomVisibility = f;
+											MOD:RefreshBar("Pet")
+										end
+									},
+									resetVisibility = {
+										order = 2,
+										type = "execute",
+										name = L["Restore Defaults"],
+										desc = L["Restore default visibility attributes for this bar"],
+										func = function()
+											SV:ResetData("ActionBars", "Pet", "customVisibility")
+											MOD:RefreshBar("Pet")
+										end
+									},
+									customVisibility = {
+										order = 3,
+										type = "input",
+										width = "full",
+										name = L["Visibility"],
+										desc = L["|cffFF0000ADVANCED:|r Set the visibility attributes for this bar"],
+										get = function(e)return SV.db[Schema]["Pet"].customVisibility end,
+										set = function(e,f)
+											SV.db[Schema]["Pet"].customVisibility = f;
+											MOD:RefreshBar("Pet")
+										end,
+										disabled = function()return not SV.db[Schema]["Pet"].useCustomVisibility end,
+									},
+								}
+							}
+						}
+					},
+					Stance = {
+						order = (count + 3),
+						name = L["Stance Bar"],
+						type = "group",
+						guiInline = false,
+						get = function(e)return SV.db[Schema]["Stance"][e[#e]]end,
+						set = function(key, value)
+							MOD:ChangeDBVar(value, key[#key], "Stance");
+							MOD:RefreshBar("Stance")
+						end,
+						args = {
+							enable = {
+								order = 1,
+								width = 'full',
+								type = "toggle",
+								name = L["Enable"]
+							},
+							backdrop = {
+								order = 2,
+								name = L["Background"],
+								type = "toggle",
+								disabled = function()return not SV.db[Schema]["Stance"].enable end,
+							},
+							mouseover = {
+								order = 3,
+								name = L["Mouse Over"],
+								desc = L["The frame is not shown unless you mouse over the frame."],
+								type = "toggle",
+								disabled = function()return not SV.db[Schema]["Stance"].enable end,
+							},
+							restorePosition = {
+								order = 4,
+								type = "execute",
+								name = L["Restore Bar"],
+								desc = L["Restore the actionbars default settings"],
+								func = function()
+									SVUILib:SetDefault("ActionBars","Stance")
+									SV:ResetAnchors("Stance Bar")
+									MOD:RefreshBar("Stance")
+								end,
+								disabled = function()return not SV.db[Schema]["Stance"].enable end,
+							},
+							adjustGroup = {
+								name = L["Bar Adjustments"],
+								type = "group",
+								order = 5,
+								guiInline = true,
+								disabled = function()return not SV.db[Schema]["Stance"].enable end,
+								args = {
+									point = {
+										order = 1,
+										type = "select",
+										name = L["Anchor Point"],
+										desc = L["The first button anchors itself to this point on the bar."],
+										values = POSITION_VALUES
+									},
+									buttons = {
+										order = 2,
+										type = "range",
+										name = L["Buttons"],
+										desc = L["The amount of buttons to display."],
+										min = 1,
+										max = NUM_STANCE_SLOTS,
+										step = 1
+									},
+									buttonsPerRow = {
+										order = 3,
+										type = "range",
+										name = L["Buttons Per Row"],
+										desc = L["The amount of buttons to display per row."],
+										min = 1,
+										max = NUM_STANCE_SLOTS,
+										step = 1
+									},
+									buttonsize = {
+										order = 4,
+										type = "range",
+										name = L["Button Size"],
+										desc = L["The size of the action buttons."],
+										min = 15,
+										max = 60,
+										step = 1
+									},
+									buttonspacing = {
+										order = 5,
+										type = "range",
+										name = L["Button Spacing"],
+										desc = L["The spacing between buttons."],
+										min = 1,
+										max = 10,
+										step = 1
+									},
+									alpha = {
+										order = 6,
+										type = "range",
+										name = L["Alpha"],
+										isPercent = true,
+										min = 0,
+										max = 1,
+										step = 0.01
+									},
+								}
+							},
+							customGroup = {
+								name = L["Visibility Options"],
+								type = "group",
+								order = 6,
+								guiInline = true,
+								disabled = function()return not SV.db[Schema]["Stance"].enable end,
+								args = {
+									style = {
+										order = 1,
+										type = "select",
+										name = L["Style"],
+										desc = L["This setting will be updated upon changing stances."],
+										values = {
+											["darkenInactive"] = L["Darken Inactive"],
+											["classic"] = L["Classic"]
+										}
+									},
+									spacer1 = {
+										order = 2,
+										type = "description",
+										name = "",
+									},
+									spacer2 = {
+										order = 3,
+										type = "description",
+										name = "",
+									},
+									useCustomVisibility = {
+										order = 4,
+										type = "toggle",
+										name = L["Enable"],
+										desc = L["Allow the use of custom paging for this bar"],
+										get = function()return SV.db[Schema]["Stance"].useCustomVisibility end,
+										set = function(e,f)
+											SV.db[Schema]["Stance"].useCustomVisibility = f;
+											MOD:RefreshBar("Stance")
+										end
+									},
+									resetVisibility = {
+										order = 5,
+										type = "execute",
+										name = L["Restore Defaults"],
+										desc = L["Restore default visibility attributes for this bar"],
+										func = function()
+											SV:ResetData("ActionBars", "Stance", "customVisibility")
+											MOD:RefreshBar("Stance")
+										end
+									},
+									customVisibility = {
+										order = 6,
+										type = "input",
+										width = "full",
+										name = L["Visibility"],
+										desc = L["|cffFF0000ADVANCED:|r Set the visibility attributes for this bar"],
+										get = function(e)return SV.db[Schema]["Stance"].customVisibility end,
+										set = function(e,f)
+											SV.db[Schema]["Stance"].customVisibility = f;
+											MOD:RefreshBar("Stance")
+										end,
+										disabled = function()return not SV.db[Schema]["Stance"].useCustomVisibility end,
+									},
+								}
+							}
+						}
+					},
+					Totem = {
+						order = (count + 4),
+						name = L["Totem Bar"],
+						type = "group",
+						guiInline = false,
+						get = function(key)
+							return SV.db[Schema]["Totem"][key[#key]]
+						end,
+						set = function(key, value)
+							MOD:ChangeDBVar(value, key[#key], "Totem");
+							SV:StaticPopup_Show("RL_CLIENT")
+						end,
+						args = {
+							enable = {
+								order = 1,
+								type = "toggle",
+								name = L["Enable"],
+								width = 'full',
+								set = function(key, value)
+									MOD:ChangeDBVar(value, key[#key], "Totem");
+									SV:StaticPopup_Show("RL_CLIENT")
+								end,
+							},
+							buttonsize = {
+								order = 2,
+								type = "range",
+								name = L["Button Size"],
+								desc = L["The size of the action buttons."],
+								min = 15,
+								max = 60,
+								step = 1,
+								disabled = function()return not SV.db[Schema]["Totem"].enable end,
+							},
+							buttonspacing = {
+								order = 3,
+								type = "range",
+								name = L["Button Spacing"],
+								desc = L["The spacing between buttons."],
+								min = 1,
+								max = 10,
+								step = 1,
+								disabled = function()return not SV.db[Schema]["Totem"].enable end,
+							},
+							sortDirection = {
+								order = 4,
+								type = 'select',
+								name = L["Sort Order"],
+								values = {
+									['ASCENDING'] = L['Ascending'],
+									['DESCENDING'] = L['Descending']
+								},
+								disabled = function()return not SV.db[Schema]["Totem"].enable end,
+							},
+							showBy = {
+								order = 5,
+								type = 'select',
+								name = L["Bar Direction"],
+								values = {
+									['VERTICAL'] = L['Vertical'],
+									['HORIZONTAL'] = L['Horizontal']
+								},
+								disabled = function()return not SV.db[Schema]["Totem"].enable end,
+							},
+						}
+					},
+					Micro = {
+						order = (count + 5),
+						name = L["Micro Menu"],
+						type = "group",
+						guiInline = false,
+
+						get = function(key)
+							return SV.db[Schema]["Micro"][key[#key]]
+						end,
+						set = function(key, value)
+							MOD:ChangeDBVar(value, key[#key], "Micro");
+							MOD:UpdateMicroButtons()
+						end,
+						args = {
+							enable = {
+								order = 1,
+								type = "toggle",
+								width = 'full',
+								name = L["Enable"],
+								set = function(key, value)
+									MOD:ChangeDBVar(value, key[#key], "Micro");
+									SV:StaticPopup_Show("RL_CLIENT")
+								end,
+							},
+							mouseover = {
+								order = 2,
+								name = L["Mouse Over"],
+								desc = L["The frame is not shown unless you mouse over the frame."],
+								disabled = function()return not SV.db[Schema]["Micro"].enable end,
+								type = "toggle"
+							},
+							buttonsize = {
+								order = 3,
+								type = "range",
+								name = L["Button Size"],
+								desc = L["The size of the action buttons."],
+								min = 15,
+								max = 60,
+								step = 1,
+								disabled = function()return not SV.db[Schema]["Micro"].enable end,
+							},
+							buttonspacing = {
+								order = 4,
+								type = "range",
+								name = L["Button Spacing"],
+								desc = L["The spacing between buttons."],
+								min = 1,
+								max = 10,
+								step = 1,
+								disabled = function()return not SV.db[Schema]["Micro"].enable end,
+							},
+						}
+					},
+				}
+			}
+		}
+	}
+
+	for barNumber = 1, count do
+		local barKey = L["Bar"] .. barNumber;
+		local barTitle = L["Bar"] .. " " .. barNumber;
+		SV.Options.args[Schema].args.barGroup.args[barKey] = {
+			order = (barNumber + 1),
+			name = barTitle,
+			type = "group",
+			guiInline = false,
+			get = function(key)
+				return SV.db[Schema][barKey][key[#key]]
+			end,
+			set = function(key, value)
+				MOD:ChangeDBVar(value, key[#key], barKey);
+				MOD:RefreshBar(barKey)
+			end,
+			args = {
+				enable = {
+					order = 1,
+					type = "toggle",
+					width = 'full',
+					name = L["Enable"],
+				},
+				backdrop = {
+					order = 2,
+					name = L["Background"],
+					type = "toggle",
+					disabled = function()return not SV.db[Schema][barKey].enable end,
+				},
+				mouseover = {
+					order = 3,
+					name = L["Mouse Over"],
+					desc = L["The frame is not shown unless you mouse over the frame."],
+					type = "toggle",
+					disabled = function()return not SV.db[Schema][barKey].enable end,
+				},
+				showVehicle = {
+					order = 4,
+					type = "toggle",
+					name = L["Vehicle Bar"],
+					desc = L["Assign " .. barTitle .. " as the location for the vehicle bar. NOTE: Only one bar can have this assigned."],
+					get = function()return SV.db[Schema][barKey].showVehicle end,
+					set = function(e, f)
+						SV.db[Schema][barKey].showVehicle = f;
+						for z = 1, count do
+							if(z ~= barNumber) then
+								SV.db[Schema][L["Bar"] .. z].showVehicle = false;
+							end
+						end
+						MOD:UpdateBarPagingDefaults();
+						MOD:RefreshActionBars();
+						--SV:StaticPopup_Show("RL_CLIENT");
+					end
+				},
+				restorePosition = {
+					order = 5,
+					type = "execute",
+					name = L["Restore Bar"],
+					desc = L["Restore the actionbars default settings"],
+					func = function()
+						SV:ResetData("ActionBars", barKey)
+						SV:ResetAnchors(barKey)
+						MOD:RefreshBar(barKey)
+					end,
+					disabled = function()return not SV.db[Schema][barKey].enable end,
+				},
+				adjustGroup = {
+					name = L["Bar Adjustments"],
+					type = "group",
+					order = 6,
+					guiInline = true,
+					disabled = function()return not SV.db[Schema][barKey].enable end,
+					args = {
+						point = {
+							order = 1,
+							type = "select",
+							name = L["Anchor Point"],
+							desc = L["The first button anchors itself to this point on the bar."],
+							values = POSITION_VALUES
+						},
+						buttons = {
+							order = 2,
+							type = "range",
+							name = L["Buttons"],
+							desc = L["The amount of buttons to display."],
+							min = 1,
+							max = NUM_ACTIONBAR_BUTTONS,
+							step = 1
+						},
+						buttonsPerRow = {
+							order = 3,
+							type = "range",
+							name = L["Buttons Per Row"],
+							desc = L["The amount of buttons to display per row."],
+							min = 1,
+							max = NUM_ACTIONBAR_BUTTONS,
+							step = 1
+						},
+						buttonsize = {
+							type = "range",
+							name = L["Button Size"],
+							desc = L["The size of the action buttons."],
+							min = 15,
+							max = 60,
+							step = 1,
+							order = 4
+						},
+						buttonspacing = {
+							type = "range",
+							name = L["Button Spacing"],
+							desc = L["The spacing between buttons."],
+							min = 1,
+							max = 10,
+							step = 1,
+							order = 5
+						},
+						alpha = {
+							order = 6,
+							type = "range",
+							name = L["Alpha"],
+							isPercent = true,
+							min = 0,
+							max = 1,
+							step = 0.01
+						},
+					}
+				},
+				pagingGroup = {
+					name = L["Bar Paging"],
+					type = "group",
+					order = 7,
+					guiInline = true,
+					disabled = function()return not SV.db[Schema][barKey].enable end,
+					args = {
+						useCustomPaging = {
+							order = 1,
+							type = "toggle",
+							name = L["Custom Paging"],
+							desc = L["Allow the use of custom paging for this bar"],
+							get = function()return SV.db[Schema][barKey].useCustomPaging end,
+							set = function(e, f)
+								SV.db[Schema][barKey].useCustomPaging = f;
+								MOD:UpdateBarPagingDefaults();
+								MOD:RefreshBar(barKey)
+							end
+						},
+						resetStates = {
+							order = 2,
+							type = "execute",
+							name = L["Restore Defaults"],
+							desc = L["Restore default paging conditions for this bar"],
+							func = function()
+								SV:ResetData("ActionBars", barKey, "customPaging")
+								MOD:UpdateBarPagingDefaults();
+								MOD:RefreshBar(barKey)
+							end
+						},
+						customPaging = {
+							order = 3,
+							type = "input",
+							width = "full",
+							name = L["Paging Conditions"],
+							desc = L["|cffFF0000ADVANCED:|r Set the paging conditions for this bar"],
+							get = function(e)return SV.db[Schema][barKey].customPaging[SV.class] end,
+							set = function(e, f)
+								SV.db[Schema][barKey].customPaging[SV.class] = f;
+								MOD:UpdateBarPagingDefaults();
+								MOD:RefreshBar(barKey)
+							end,
+							disabled = function()return not SV.db[Schema][barKey].useCustomPaging end,
+						},
+					}
+				},
+				visibilityGroup = {
+					name = L["Bar Visibility"],
+					type = "group",
+					order = 8,
+					guiInline = true,
+					disabled = function()return not SV.db[Schema][barKey].enable end,
+					args = {
+						useCustomVisibility = {
+							order = 1,
+							type = "toggle",
+							name = L["Custom Visibility"],
+							desc = L["Allow the use of custom visibility for this bar"],
+							get = function()return SV.db[Schema][barKey].useCustomVisibility end,
+							set = function(e, f)
+								SV.db[Schema][barKey].useCustomVisibility = f;
+								MOD:UpdateBarPagingDefaults();
+								MOD:RefreshBar(barKey)
+							end
+						},
+						resetVisibility = {
+							order = 2,
+							type = "execute",
+							name = L["Restore Defaults"],
+							desc = L["Restore default visibility conditions for this bar"],
+							func = function()
+								--SV:ResetData("ActionBars", barKey, "customVisibility")
+								SV.db[Schema][barKey].customVisibility = SV.defaults[Schema][barKey].customVisibility;
+								MOD:UpdateBarPagingDefaults();
+								MOD:RefreshBar(barKey)
+							end
+						},
+						customVisibility = {
+							order = 3,
+							type = "input",
+							width = "full",
+							name = L["Visibility Conditions"],
+							desc = L["|cffFF0000ADVANCED:|r Set the visibility conditions for this bar"],
+							get = function(e)return SV.db[Schema][barKey].customVisibility end,
+							set = function(e, f)
+								SV.db[Schema][barKey].customVisibility = f;
+								MOD:UpdateBarPagingDefaults();
+								MOD:RefreshBar(barKey)
+							end,
+							disabled = function()return not SV.db[Schema][barKey].useCustomVisibility end,
+						},
+
+					}
+				}
+			}
+		}
+	end
+end
\ No newline at end of file
diff --git a/SVUI_ActionBars/SVUI_ActionBars.lua b/SVUI_ActionBars/SVUI_ActionBars.lua
new file mode 100644
index 0000000..30a6e94
--- /dev/null
+++ b/SVUI_ActionBars/SVUI_ActionBars.lua
@@ -0,0 +1,1632 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack            = _G.unpack;
+local select            = _G.select;
+local assert            = _G.assert;
+local type              = _G.type;
+local error             = _G.error;
+local pcall             = _G.pcall;
+local print             = _G.print;
+local ipairs            = _G.ipairs;
+local pairs             = _G.pairs;
+local next              = _G.next;
+local tostring          = _G.tostring;
+local tonumber          = _G.tonumber;
+local collectgarbage    = _G.collectgarbage;
+local string 	= _G.string;
+local math 		= _G.math;
+--[[ STRING METHODS ]]--
+local find, format, split = string.find, string.format, string.split;
+local gsub = string.gsub;
+--[[ MATH METHODS ]]--
+local ceil = math.ceil;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MODULE_NAME, MODULE_OBJ = ...;
+local MOD = SV.ActionBars;
+if(not MOD) then MOD = MODULE_OBJ end;
+local LibStub = _G.LibStub;
+if(not LibStub) then return end;
+local LSM = LibStub("LibSharedMedia-3.0");
+local LibAB = LibStub("LibActionButton-1.0");
+local Masque = LibStub("Masque", true);
+local DEFAULT_MAIN_ANCHOR = _G["SVUI_DockBottomCenter"];
+MOD.ButtonCache = {};
+MOD.MainAnchor = CreateFrame("Frame", "SVUI_ActionBarMainAnchor");
+MOD.AltVehicleBar = false;
+--[[
+##########################################################
+LOCAL VARS
+##########################################################
+]]--
+local maxFlyoutCount = 0
+local SetSpellFlyoutHook
+local NewFrame = CreateFrame
+local NewHook = hooksecurefunc
+local NUM_ACTIONBAR_BUTTONS = NUM_ACTIONBAR_BUTTONS;
+local SEQUENCE_PATTERN = '%s [bar:%d] %d;';
+local BASE_PAGING = '[form,noform] 0; [shapeshift] 13; ';
+local SHOW_VEHICLE_PATTERN = '[vehicleui,mod:alt,mod:ctrl] %d; [possessbar] %d; [overridebar] %d; ';
+local PAGE_SHOW_VEHICLE = ' ';
+local PAGE_HIDE_VEHICLE = '[vehicleui] hide; [possessbar] hide; [overridebar] hide; ';
+--[[
+	Quick explaination of what Im doing with all of these locals...
+	What I have done is set local variables for every database value
+	that the module can read efficiently. The function "UpdateLocals"
+	is used to refresh these any time a change is made to configs
+	and once when the mod is loaded.
+]]--
+local TOTAL_BARS = 6;
+local SELF_CASTING = false;
+--[[
+##########################################################
+LOCAL FUNCTIONS
+##########################################################
+]]--
+local function NewActionBar(barName)
+	local bar = CreateFrame("Frame", barName, UIParent, "SecureHandlerStateTemplate")
+	if Masque then
+	    bar.MasqueGroup = Masque:Group(MODULE_NAME, barName)
+	end
+	bar.buttons = {}
+	bar.conditions = ""
+	bar.config = {
+		outOfRangeColoring = "button",
+		tooltip = "enable",
+		showGrid = true,
+		colors = {
+			range = {0.8, 0.1, 0.1},
+			mana = {0.5, 0.5, 1.0},
+			hp = {0.5, 0.5, 1.0}
+		},
+		hideElements = {
+			macro = false,
+			hotkey = false,
+			equipped = false
+		},
+		keyBoundTarget = false,
+		clickOnDown = false
+	}
+	return bar
+end
+
+local function NewActionButton(parent, index, name)
+	return LibAB:CreateButton(index, name, parent, nil)
+end
+
+local Bar_OnEnter = function(self)
+	if(self._fade) then
+		for i=1, self.maxButtons do
+			self.buttons[i].cooldown:SetSwipeColor(0, 0, 0, 1)
+			self.buttons[i].cooldown:SetDrawBling(true)
+		end
+		self:FadeIn(0.2, self:GetAlpha(), self._alpha)
+	end
+end
+
+local Bar_OnLeave = function(self)
+	if(self._fade) then
+		for i=1, self.maxButtons do
+			self.buttons[i].cooldown:SetSwipeColor(0, 0, 0, 0)
+			self.buttons[i].cooldown:SetDrawBling(false)
+		end
+		self:FadeOut(1, self:GetAlpha(), 0)
+	end
+end
+
+function MOD:FixKeybindText(button)
+	local hotkey = _G[button:GetName()..'HotKey']
+	local hotkeyText = hotkey:GetText()
+	if hotkeyText then
+		hotkeyText = hotkeyText:gsub('SHIFT%-', "S")
+		hotkeyText = hotkeyText:gsub('ALT%-',  "A")
+		hotkeyText = hotkeyText:gsub('CTRL%-',  "C")
+		hotkeyText = hotkeyText:gsub('BUTTON',  "B")
+		hotkeyText = hotkeyText:gsub('MOUSEWHEELUP', "WU")
+		hotkeyText = hotkeyText:gsub('MOUSEWHEELDOWN', "WD")
+		hotkeyText = hotkeyText:gsub('NUMPAD',  "N")
+		hotkeyText = hotkeyText:gsub('PAGEUP', "PgU")
+		hotkeyText = hotkeyText:gsub('PAGEDOWN', "PgD")
+		hotkeyText = hotkeyText:gsub('SPACE', "SP")
+		hotkeyText = hotkeyText:gsub('INSERT', "INS")
+		hotkeyText = hotkeyText:gsub('HOME', "HM")
+		hotkeyText = hotkeyText:gsub('DELETE', "DEL")
+		hotkeyText = hotkeyText:gsub('NMULTIPLY', "N*")
+		hotkeyText = hotkeyText:gsub('NMINUS', "N-")
+		hotkeyText = hotkeyText:gsub('NPLUS', "N+")
+		hotkey:SetText(hotkeyText)
+	end
+	hotkey:ClearAllPoints()
+	hotkey:SetAllPoints()
+end
+
+local function Pinpoint(parent)
+    local centerX,centerY = parent:GetCenter()
+    local screenWidth = GetScreenWidth()
+    local screenHeight = GetScreenHeight()
+    local result;
+    if not centerX or not centerY then
+        return "CENTER"
+    end
+    local heightTop = screenHeight * 0.75;
+    local heightBottom = screenHeight * 0.25;
+    local widthLeft = screenWidth * 0.25;
+    local widthRight = screenWidth * 0.75;
+    if(((centerX > widthLeft) and (centerX < widthRight)) and (centerY > heightTop)) then
+        result="TOP"
+    elseif((centerX < widthLeft) and (centerY > heightTop)) then
+        result="TOPLEFT"
+    elseif((centerX > widthRight) and (centerY > heightTop)) then
+        result="TOPRIGHT"
+    elseif(((centerX > widthLeft) and (centerX < widthRight)) and centerY < heightBottom) then
+        result="BOTTOM"
+    elseif((centerX < widthLeft) and (centerY < heightBottom)) then
+        result="BOTTOMLEFT"
+    elseif((centerX > widthRight) and (centerY < heightBottom)) then
+        result="BOTTOMRIGHT"
+    elseif((centerX < widthLeft) and (centerY > heightBottom) and (centerY < heightTop)) then
+        result="LEFT"
+    elseif((centerX > widthRight) and (centerY < heightTop) and (centerY > heightBottom)) then
+        result="RIGHT"
+    else
+        result="CENTER"
+    end
+    return result
+end
+
+local function SaveActionButton(button, noStyle)
+	local name = button:GetName()
+	local cooldown = _G[name.."Cooldown"]
+	cooldown.SizeOverride = SV.db.ActionBars.cooldownSize
+	-- cooldown:SetSwipeColor(0, 0, 0, 0)
+	-- cooldown:SetDrawBling(false)
+	if(not button.cooldown) then
+		button.cooldown = cooldown;
+	end
+	MOD:FixKeybindText(button)
+	MOD.ButtonCache[button] = true
+	if(not noStyle) then
+		button:SetStyle("ActionSlot", true)
+		button:SetCheckedTexture("")
+	end
+end
+
+local function SetFlyoutButton(button)
+	if not button or not button.FlyoutArrow or not button.FlyoutArrow:IsShown() or not button.FlyoutBorder then return end
+	local LOCKDOWN = InCombatLockdown()
+	button.FlyoutBorder:SetAlpha(0)
+	button.FlyoutBorderShadow:SetAlpha(0)
+	SpellFlyoutHorizontalBackground:SetAlpha(0)
+	SpellFlyoutVerticalBackground:SetAlpha(0)
+	SpellFlyoutBackgroundEnd:SetAlpha(0)
+	for i = 1, GetNumFlyouts()do
+		local id = GetFlyoutID(i)
+		local _, _, max, check = GetFlyoutInfo(id)
+		if check then
+			maxFlyoutCount = max;
+			break
+		end
+	end
+	local offset = 0;
+	if SpellFlyout:IsShown() and SpellFlyout:GetParent() == button or GetMouseFocus() == button then offset = 5 else offset = 2 end
+	if button:GetParent() and button:GetParent():GetParent() and button:GetParent():GetParent():GetName() and button:GetParent():GetParent():GetName() == "SpellBookSpellIconsFrame" then return end
+	if button:GetParent() then
+		local point = Pinpoint(button:GetParent())
+		if point:find("RIGHT") then
+			button.FlyoutArrow:ClearAllPoints()
+			button.FlyoutArrow:SetPoint("LEFT", button, "LEFT", -offset, 0)
+			SetClampedTextureRotation(button.FlyoutArrow, 270)
+			if not LOCKDOWN then
+				button:SetAttribute("flyoutDirection", "LEFT")
+			end
+		elseif point:find("LEFT") then
+			button.FlyoutArrow:ClearAllPoints()
+			button.FlyoutArrow:SetPoint("RIGHT", button, "RIGHT", offset, 0)
+			SetClampedTextureRotation(button.FlyoutArrow, 90)
+			if not LOCKDOWN then
+				button:SetAttribute("flyoutDirection", "RIGHT")
+			end
+		elseif point:find("TOP") then
+			button.FlyoutArrow:ClearAllPoints()
+			button.FlyoutArrow:SetPoint("BOTTOM", button, "BOTTOM", 0, -offset)
+			SetClampedTextureRotation(button.FlyoutArrow, 180)
+			if not LOCKDOWN then
+				button:SetAttribute("flyoutDirection", "DOWN")
+			end
+		elseif point == "CENTER" or point:find("BOTTOM") then
+			button.FlyoutArrow:ClearAllPoints()
+			button.FlyoutArrow:SetPoint("TOP", button, "TOP", 0, offset)
+			SetClampedTextureRotation(button.FlyoutArrow, 0)
+			if not LOCKDOWN then
+				button:SetAttribute("flyoutDirection", "UP")
+			end
+		end
+	end
+end
+
+local function ModifyActionButton(button, noStyle)
+	local name = button:GetName()
+	if(not name) then return; end
+	local icon = _G[name.."Icon"]
+	local count = _G[name.."Count"]
+	local flash = _G[name.."Flash"]
+	local hotkey = _G[name.."HotKey"]
+	local border = _G[name.."Border"]
+	local normal = _G[name.."NormalTexture"]
+	local cooldown = _G[name.."Cooldown"]
+	local buttonTex = button:GetNormalTexture()
+	local shine = _G[name.."Shine"]
+	local highlight = button:GetHighlightTexture()
+	local pushed = button:GetPushedTexture()
+	local checked = button:GetCheckedTexture()
+	if cooldown then
+		cooldown.SizeOverride = SV.db.ActionBars.cooldownSize
+		--cooldown:SetAlpha(0)
+	end
+
+	if(not noStyle) then
+		if highlight then
+			highlight:SetColorTexture(1,1,1,.2)
+		end
+		if pushed then
+			pushed:SetColorTexture(0,0,0,.4)
+		end
+		if checked then
+			checked:SetColorTexture(1,1,1,.2)
+		end
+		if flash then
+			flash:SetTexture("")
+		end
+		if normal then
+			normal:SetTexture("")
+			normal:Hide()
+			normal:SetAlpha(0)
+		end
+		if buttonTex then
+			buttonTex:SetTexture("")
+			buttonTex:Hide()
+			buttonTex:SetAlpha(0)
+		end
+		if border then border:Die()end
+		if icon then
+			icon:SetTexCoord(.1,.9,.1,.9)
+			icon:InsetPoints(name)
+		end
+		if shine then shine:SetAllPoints()end
+	end
+
+	if count then
+		count:ClearAllPoints()
+		count:SetPoint("BOTTOMRIGHT",1,1)
+		count:SetShadowOffset(1,-1)
+		SV:FontManager(count, "number")
+	end
+
+	if SV.db.ActionBars.hotkeytext then
+		hotkey:ClearAllPoints()
+		hotkey:SetAllPoints()
+		hotkey:SetFontObject(SVUI_Font_Default)
+		hotkey:SetJustifyH("RIGHT")
+    	hotkey:SetJustifyV("TOP")
+		hotkey:SetShadowOffset(1,-1)
+	end
+
+	button.FlyoutUpdateFunc = SetFlyoutButton;
+	MOD:FixKeybindText(button)
+end
+
+do
+	local SpellFlyoutButton_OnEnter = function(self)
+		local parent = self:GetParent()
+		local anchor = select(2, parent:GetPoint())
+		if not MOD.ButtonCache[anchor] then return end
+		local anchorParent = anchor:GetParent()
+		if anchorParent._fade then
+			local alpha = anchorParent._alpha
+			local actual = anchorParent:GetAlpha()
+			anchorParent:FadeIn(0.2, actual, alpha)
+		end
+	end
+
+	local SpellFlyoutButton_OnLeave = function(self)
+		local parent = self:GetParent()
+		local anchor = select(2, parent:GetPoint())
+		if not MOD.ButtonCache[anchor] then return end
+		local anchorParent = anchor:GetParent()
+		if anchorParent._fade then
+			local actual = anchorParent:GetAlpha()
+			anchorParent:FadeOut(1, actual, 0)
+		end
+	end
+
+	local SpellFlyout_OnEnter = function(self)
+		local anchor = select(2,self:GetPoint())
+		if not MOD.ButtonCache[anchor] then return end
+		local anchorParent = anchor:GetParent()
+		if anchorParent._fade then
+			Bar_OnEnter(anchorParent)
+		end
+	end
+
+	local SpellFlyout_OnLeave = function(self)
+		local anchor = select(2, self:GetPoint())
+		if not MOD.ButtonCache[anchor] then return end
+		local anchorParent=anchor:GetParent()
+		if anchorParent._fade then
+			Bar_OnLeave(anchorParent)
+		end
+	end
+
+	local SpellFlyout_OnShow = function()
+		for i=1,maxFlyoutCount do
+			local name = ("SpellFlyoutButton%s"):format(i)
+			local button = _G[name]
+			if(button) then
+				ModifyActionButton(button)
+				SaveActionButton(button)
+
+				button:HookScript('OnEnter', SpellFlyoutButton_OnEnter)
+
+				button:HookScript('OnLeave', SpellFlyoutButton_OnLeave)
+			end
+		end
+		SpellFlyout:HookScript('OnEnter', SpellFlyout_OnEnter)
+		SpellFlyout:HookScript('OnLeave', SpellFlyout_OnLeave)
+	end
+
+	local QualifyFlyouts = function()
+		if InCombatLockdown() then return end
+		for button,_ in pairs(MOD.ButtonCache)do
+			if(button and button.FlyoutArrow) then
+				SetFlyoutButton(button)
+			end
+		end
+	end
+
+	function SetSpellFlyoutHook()
+		SpellFlyout:HookScript("OnShow",SpellFlyout_OnShow);
+		SV.Timers:ExecuteTimer(QualifyFlyouts, 5)
+	end
+end
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+function MOD:UpdateBarBindings(pet, stance)
+	if stance == true then
+		local bar = _G["SVUI_StanceBar"]
+		local bindText = bar.binding
+
+	  	for i=1,NUM_STANCE_SLOTS do
+	  		local name = ("SVUI_StanceBarButton%s"):format(i)
+	  		local hkname = ("SVUI_StanceBarButton%sHotKey"):format(i)
+			local hotkey = _G[hkname]
+		    if SV.db.ActionBars.hotkeytext then
+		    	local key = bindText:format(i);
+		    	local binding = GetBindingKey(key)
+		      	hotkey:Show()
+		      	hotkey:SetText(binding)
+		      	MOD:FixKeybindText(_G[name])
+		    else
+		      	hotkey:Hide()
+		    end
+	  	end
+  	end
+  	if pet == true then
+  		local bar = _G["SVUI_PetActionBar"]
+		local bindText = bar.binding
+
+	  	for i=1,NUM_PET_ACTION_SLOTS do
+	  		local name = ("PetActionButton%s"):format(i)
+	  		local hkname = ("PetActionButton%sHotKey"):format(i)
+			local hotkey = _G[hkname]
+		    if SV.db.ActionBars.hotkeytext then
+		      	local key = bindText:format(i);
+		    	local binding = GetBindingKey(key)
+		      	hotkey:Show()
+		      	hotkey:SetText(binding)
+		      	MOD:FixKeybindText(_G[name])
+		    else
+	    		hotkey:Hide()
+	    	end
+	  	end
+	end
+end
+
+function MOD:UpdateAllBindings(event)
+	if event == "UPDATE_BINDINGS" then
+		MOD:UpdateBarBindings(true,true)
+	end
+	MOD:UnregisterEvent("PLAYER_REGEN_DISABLED")
+	if InCombatLockdown() then return end
+	for i = 1, TOTAL_BARS do
+		local barName = ("SVUI_ActionBar%d"):format(i)
+		local bar = _G[barName]
+		if(bar and bar.buttons) then
+			local thisBinding = bar.binding
+
+			ClearOverrideBindings(bar)
+
+			for k = 1,#bar.buttons do
+				local binding = thisBinding:format(k);
+				local btn = ("%sButton%d"):format(barName, k);
+				for x = 1,select('#',GetBindingKey(binding)) do
+					local key = select(x, GetBindingKey(binding))
+					if (key and key ~= "") then
+						SetOverrideBindingClick(bar, false, key, btn)
+					end
+				end
+			end
+		end
+	end
+end
+
+function MOD:SetBarConfigData(bar)
+	local db = SV.db.ActionBars
+	local thisBinding = bar.binding;
+	local buttonList = bar.buttons;
+	local config = bar.config
+	config.hideElements.macro = (not db.macrotext);
+	config.hideElements.hotkey = (not db.hotkeytext);
+	config.showGrid = db.showGrid;
+	config.clickOnDown = db.keyDown;
+	config.colors.range = db.unc
+	config.colors.mana = db.unpc
+	config.colors.hp = db.unpc
+	SetModifiedClick("PICKUPACTION", db.unlock)
+	for i,button in pairs(buttonList)do
+		if thisBinding then
+			config.keyBoundTarget = thisBinding:format(i)
+		end
+		button.keyBoundTarget = config.keyBoundTarget;
+		button.postKeybind = self.FixKeybindText;
+		button:SetAttribute("buttonlock",true)
+		button:SetAttribute("checkselfcast",true)
+		button:SetAttribute("checkfocuscast",true)
+		button:UpdateConfig(config)
+	end
+end
+
+function MOD:UpdateBarPagingDefaults()
+	PAGE_SHOW_VEHICLE = SHOW_VEHICLE_PATTERN:format(GetVehicleBarIndex(), GetVehicleBarIndex(), GetOverrideBarIndex());
+	self.AltVehicleBar = false;
+
+	for i=2, TOTAL_BARS do
+		local id = ("Bar%d"):format(i);
+		local bar = _G["SVUI_Action" .. id];
+		if(bar) then
+			local parse = '';
+			if(SV.db.ActionBars[id].showVehicle and (not self.AltVehicleBar)) then
+				parse = PAGE_SHOW_VEHICLE;
+				self.AltVehicleBar = bar;
+			else
+				parse = PAGE_HIDE_VEHICLE;
+			end
+
+			if(SV.db.ActionBars[id].useCustomPaging) then
+				parse = parse .. SV.db.ActionBars[id].customPaging[SV.class];
+			end
+
+			bar.conditions = parse;
+			--print('Bar '..i..': '..bar.conditions);
+		end
+	end
+
+	local mainbar = _G["SVUI_ActionBar1"];
+	if(mainbar) then
+		local mainbar_parse = BASE_PAGING;
+
+		if(SV.db.ActionBars.Bar1.showVehicle or (not self.AltVehicleBar)) then
+			mainbar_parse = mainbar_parse .. " " .. PAGE_SHOW_VEHICLE;
+		else
+			mainbar_parse = mainbar_parse .. " " .. PAGE_HIDE_VEHICLE;
+		end
+
+		for i=2, TOTAL_BARS do
+			mainbar_parse = SEQUENCE_PATTERN:format(mainbar_parse, i, i)
+		end
+
+		if SV.db.ActionBars.Bar1.useCustomPaging then
+			mainbar_parse = mainbar_parse .. " " .. SV.db.ActionBars.Bar1.customPaging[SV.class];
+		end
+		--print(mainbar_parse)
+		mainbar.conditions = mainbar_parse;
+	end
+
+	if((not SV.db.ActionBars.enable or InCombatLockdown()) or not self.isInitialized) then return end
+	local Bar2Option = InterfaceOptionsActionBarsPanelBottomRight
+	local Bar3Option = InterfaceOptionsActionBarsPanelBottomLeft
+	local Bar4Option = InterfaceOptionsActionBarsPanelRightTwo
+	local Bar5Option = InterfaceOptionsActionBarsPanelRight
+
+	if (SV.db.ActionBars.Bar2.enable and not Bar2Option:GetChecked()) or (not SV.db.ActionBars.Bar2.enable and Bar2Option:GetChecked())  then
+		Bar2Option:Click()
+	end
+
+	if (SV.db.ActionBars.Bar3.enable and not Bar3Option:GetChecked()) or (not SV.db.ActionBars.Bar3.enable and Bar3Option:GetChecked())  then
+		Bar3Option:Click()
+	end
+
+	if not SV.db.ActionBars.Bar5.enable and not SV.db.ActionBars.Bar4.enable then
+		if Bar4Option:GetChecked() then
+			Bar4Option:Click()
+		end
+
+		if Bar5Option:GetChecked() then
+			Bar5Option:Click()
+		end
+	elseif not SV.db.ActionBars.Bar5.enable then
+		if not Bar5Option:GetChecked() then
+			Bar5Option:Click()
+		end
+
+		if not Bar4Option:GetChecked() then
+			Bar4Option:Click()
+		end
+	elseif (SV.db.ActionBars.Bar4.enable and not Bar4Option:GetChecked()) or (not SV.db.ActionBars.Bar4.enable and Bar4Option:GetChecked()) then
+		Bar4Option:Click()
+	elseif (SV.db.ActionBars.Bar5.enable and not Bar5Option:GetChecked()) or (not SV.db.ActionBars.Bar5.enable and Bar5Option:GetChecked()) then
+		Bar5Option:Click()
+	end
+end
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+function MOD:RefreshMainAnchor()
+	if(InCombatLockdown()) then self:RegisterEvent("PLAYER_REGEN_ENABLED"); return end
+	local newAnchor = DEFAULT_MAIN_ANCHOR
+	for i = 1, TOTAL_BARS do
+		id = ("Bar%d"):format(i);
+		bar = _G[("SVUI_Action%s"):format(id)];
+		if((i < 3) or (i > 5)) then
+			local enabled = SV.db.ActionBars[id].enable;
+			if(bar and enabled) then
+				newAnchor = bar
+			end
+		end
+	end
+	self.MainAnchor:ClearAllPoints()
+	self.MainAnchor:SetAllPoints(newAnchor)
+end
+
+do
+	local Button_OnEnter = function(self)
+		local parent = self:GetParent()
+		if parent and parent._fade then
+			Bar_OnEnter(parent)
+		end
+	end
+
+	local Button_OnLeave = function(self)
+		GameTooltip:Hide()
+		local parent = self:GetParent()
+		if parent and parent._fade then
+			Bar_OnLeave(parent)
+		end
+	end
+
+	local function _refreshButtons(bar, id, max, space, cols, totalButtons, size, point)
+		if InCombatLockdown() then return end
+		if not bar then return end
+		local hideByScale = id == "Pet" and true or false;
+		local isStance = id == "Stance" and true or false;
+		local button,lastButton,lastRow;
+
+		for i=1, max do
+			button = bar.buttons[i]
+			lastButton = bar.buttons[i - 1]
+			lastRow = bar.buttons[i - cols]
+			button:SetParent(bar)
+			button:ClearAllPoints()
+			button:SetSize(size, size)
+			button:SetAttribute("showgrid",1)
+
+			if(SELF_CASTING) then
+				button:SetAttribute("unit2", "player")
+			end
+
+			if(not button._hookFade) then
+				button:HookScript('OnEnter', Button_OnEnter)
+				button:HookScript('OnLeave', Button_OnLeave)
+				button._hookFade = true;
+			end
+
+			local x,y,anchor1,anchor2;
+
+			if(i == 1) then
+				x, y = 0, 0
+				if(point:find("BOTTOM")) then
+					y = space
+				elseif(point:find("TOP")) then
+					y = -space
+				end
+				if(point:find("RIGHT")) then
+					x = -space
+				elseif(point:find("LEFT")) then
+					x = space
+				end
+				button:SetPoint(point,bar,point,x,y)
+			elseif((i - 1) % cols == 0) then
+				x, y = 0, -space
+				anchor1, anchor2 = "TOP", "BOTTOM"
+		      	if(point:find("BOTTOM")) then
+		        	y = space;
+		        	anchor1 = "BOTTOM"
+		        	anchor2 = "TOP"
+		      	end
+				button:SetPoint(anchor1,lastRow,anchor2,x,y)
+			else
+				x, y = space, 0
+		      	anchor1, anchor2 = "LEFT", "RIGHT";
+		      	if(point:find("RIGHT")) then
+		        	x = -space;
+		        	anchor1 = "RIGHT"
+		        	anchor2 = "LEFT"
+		      	end
+				button:SetPoint(anchor1,lastButton,anchor2,x,y)
+			end
+
+			if(i > totalButtons) then
+				if hideByScale then
+					button:SetScale(0.000001)
+	      			button:SetAlpha(0)
+				else
+					button:Hide()
+				end
+				if button.cooldown then
+					button.cooldown:SetSwipeColor(0, 0, 0, 0)
+					button.cooldown:SetDrawBling(false)
+				end
+			else
+				if hideByScale then
+					button:SetScale(1)
+	      			button:SetAlpha(1)
+				else
+					button:Show()
+				end
+				if button.cooldown then
+					button.cooldown:SetSwipeColor(0, 0, 0, 1)
+					button.cooldown:SetDrawBling(true)
+				end
+			end
+			local hasMasque = false;
+			if bar.MasqueGroup then
+			    bar.MasqueGroup:AddButton(button)
+			    hasMasque = true
+			end
+			if (not isStance or (isStance and not button.FlyoutUpdateFunc)) then
+	      		ModifyActionButton(button, hasMasque);
+	      		SaveActionButton(button, hasMasque);
+	    	end
+		end
+
+		if(bar._fade) then Bar_OnLeave(bar) end
+	end
+
+	local function _getPage(bar, defaultPage, condition)
+		local page = SV.db.ActionBars[bar].customPaging[SV.class]
+		if not condition then condition = '' end
+		if not page then page = '' end
+		if page then
+			condition = condition.." "..page
+		end
+		condition = condition.." "..defaultPage
+		return condition
+	end
+
+	function MOD:RefreshBar(id)
+		if(InCombatLockdown()) then return end
+
+		local bar
+		local isPet, isStance = false, false
+		local db = SV.db.ActionBars[id]
+
+		if(id == "Pet") then
+			bar = _G["SVUI_PetActionBar"]
+			isPet = true
+		elseif(id == "Stance") then
+			bar = _G["SVUI_StanceBar"]
+			isStance = true
+		else
+			bar = _G[("SVUI_Action%s"):format(id)]
+		end
+
+		if(not bar or not db) then return end
+
+		local space = db.buttonspacing;
+		local cols = db.buttonsPerRow;
+		local size = db.buttonsize;
+		local point = db.point;
+		local barVisibility = db.customVisibility;
+		local totalButtons = db.buttons;
+		local max = (isStance and GetNumShapeshiftForms()) or (isPet and 10) or NUM_ACTIONBAR_BUTTONS;
+		local rows = ceil(totalButtons  /  cols);
+
+		if max < cols then cols = max end
+		if rows < 1 then rows = 1 end
+		bar.maxButtons = max;
+		bar:SetWidth(space  +  (size  *  cols)  +  ((space  *  (cols - 1))  +  space));
+		bar:SetHeight((space  +  (size  *  rows))  +  ((space  *  (rows - 1))  +  space));
+		bar.backdrop:ClearAllPoints()
+	  	bar.backdrop:SetAllPoints()
+		bar._fade = db.mouseover;
+		bar._alpha = db.alpha;
+
+		if db.backdrop == true then
+			bar.backdrop:Show()
+		else
+			bar.backdrop:Hide()
+		end
+
+		bar:SetScript('OnEnter', Bar_OnEnter)
+		bar:SetScript('OnLeave', Bar_OnLeave)
+
+		if(db.mouseover == true) then
+			bar:SetAlpha(0)
+			bar._fade = true
+		else
+			bar:SetAlpha(db.alpha)
+			bar._fade = false
+		end
+
+		_refreshButtons(bar, id, max, space, cols, totalButtons, size, point);
+		self:RefreshMainAnchor()
+
+		if(isPet or isStance) then
+			if db.enable then
+				bar:SetScale(1)
+				bar:SetAlpha(db.alpha)
+				if(db.mouseover == true) then
+					bar:SetAlpha(0)
+				else
+					bar:SetAlpha(db.alpha)
+				end
+				RegisterStateDriver(bar, "visibility", barVisibility)
+			else
+				bar:SetScale(0.000001)
+				bar:SetAlpha(0)
+				UnregisterStateDriver(bar, "visibility")
+			end
+			--RegisterStateDriver(bar, "show", barVisibility)
+		else
+			local p,c = bar.page, bar.conditions
+		  	local page = _getPage(id, p, c)
+			if c:find("[form, noform]") then
+				bar:SetAttribute("hasTempBar", true)
+				local newCondition = c:gsub(" %[form, noform%] 0; ", "");
+				bar:SetAttribute("newCondition", newCondition)
+			else
+				bar:SetAttribute("hasTempBar", false)
+			end
+
+			RegisterStateDriver(bar, "page", page)
+			if not bar.ready then
+				bar.ready = true;
+				self:RefreshBar(id)
+				return
+			end
+
+			if db.enable == true then
+				bar:Show()
+				RegisterStateDriver(bar, "visibility", barVisibility)
+			else
+				bar:Hide()
+				UnregisterStateDriver(bar, "visibility")
+			end
+
+			local moverName = ("SVUI_Action%d_MOVE"):format(id);
+			if(_G[moverName]) then
+				_G[moverName].snapOffset = (space * 0.5)
+			end
+		end
+	end
+end
+
+function MOD:RefreshActionBars()
+	if(InCombatLockdown()) then self:RegisterEvent("PLAYER_REGEN_ENABLED"); return end
+	self:UpdateBarPagingDefaults()
+	for button, _ in pairs(self.ButtonCache)do
+		if button then
+			ModifyActionButton(button)
+			SaveActionButton(button)
+			if(button.FlyoutArrow) then
+				SetFlyoutButton(button)
+			end
+		else
+			self.ButtonCache[button] = nil
+		end
+	end
+
+	local id, bar
+	for i = 1, TOTAL_BARS do
+		id = ("Bar%d"):format(i);
+		bar = _G[("SVUI_Action%s"):format(id)];
+		self:RefreshBar(id);
+		self:SetBarConfigData(bar);
+	end
+
+	self:RefreshBar("Pet")
+	self:RefreshBar("Stance")
+	self:UpdateBarBindings(true, true)
+
+	collectgarbage("collect");
+end
+
+local function UpdateAltVehicleBindings()
+	if(InCombatLockdown() or (not MOD.AltVehicleBar)) then return end
+	local bar = MOD.AltVehicleBar;
+	if(bar and bar.buttons) then
+		ClearOverrideBindings(bar);
+		local enabled = (HasOverrideActionBar() or HasVehicleActionBar());
+		if(enabled) then
+			local binding = bar.binding;
+			for k = 1, #bar.buttons do
+				local bindString = binding:format(k);
+				local clickBind = ("SVUI_ActionBar1Button%d"):format(k);
+				for x = 1, select('#', GetBindingKey(bindString)) do
+					local key = select(x, GetBindingKey(bindString));
+					if (key and key ~= "") then
+						print(clickBind)
+						SetOverrideBindingClick(bar, true, key, clickBind);
+					end
+				end
+			end
+		end
+	end
+end
+
+local function SetStanceBarButtons()
+	local maxForms = GetNumShapeshiftForms();
+	local currentForm = GetShapeshiftForm();
+	local maxButtons = NUM_STANCE_SLOTS;
+	local texture, name, isActive, isCastable, _;
+	for i = 1, maxButtons do
+		local button = _G["SVUI_StanceBarButton"..i]
+		local icon = _G["SVUI_StanceBarButton"..i.."Icon"]
+		if i <= maxForms then
+			texture, name, isActive, isCastable = GetShapeshiftFormInfo(i)
+			if texture == "Interface\\Icons\\Spell_Nature_WispSplode" and SV.db.ActionBars.Stance.style == "darkenInactive" then
+				_, _, texture = GetSpellInfo(name)
+			end
+
+			icon:SetTexture(texture)
+
+			if(button.cooldown) then
+				if texture then
+					button.cooldown:SetAlpha(1)
+					button.cooldown:SetSwipeColor(0, 0, 0, 1)
+					button.cooldown:SetDrawBling(true)
+				else
+					button.cooldown:SetAlpha(0)
+					button.cooldown:SetSwipeColor(0, 0, 0, 0)
+					button.cooldown:SetDrawBling(false)
+				end
+			end
+
+			if isActive then
+				StanceBarFrame.lastSelected = button:GetID()
+
+				if maxForms > 1 then
+					if button.checked then button.checked:SetColorTexture(0, 0.5, 0, 0.2) end
+					button:SetBackdropBorderColor(0.4, 0.8, 0)
+				end
+				icon:SetVertexColor(1, 1, 1)
+				button:SetChecked(true)
+			else
+				if maxForms > 1 and currentForm > 0 then
+					button:SetBackdropBorderColor(0, 0, 0)
+					if button.checked then
+						button.checked:SetAlpha(1)
+					end
+					if SV.db.ActionBars.Stance.style == "darkenInactive" then
+						icon:SetVertexColor(0.25, 0.25, 0.25)
+					else
+						icon:SetVertexColor(1, 1, 1)
+					end
+				end
+
+				button:SetChecked(false)
+			end
+			if isCastable then
+				icon:SetDesaturated(false)
+				button:SetAlpha(1)
+			else
+				icon:SetDesaturated(true)
+				button:SetAlpha(0.4)
+			end
+		end
+	end
+end
+
+function MOD:UpdateUniqueBars()
+	local bar = MOD.AltVehicleBar or _G["SVUI_ActionBar1"];
+	local barID = bar.dataID;
+	local space = SV.db.ActionBars[barID].buttonspacing
+	local total = SV.db.ActionBars[barID].buttons;
+	local rows = SV.db.ActionBars[barID].buttonsPerRow;
+	local size = SV.db.ActionBars[barID].buttonsize
+	local point = SV.db.ActionBars[barID].point;
+	local columns = ceil(total / rows);
+
+	if (HasOverrideActionBar() or HasVehicleActionBar()) and total == 12 then
+		bar.backdrop:ClearAllPoints()
+		bar.backdrop:SetPoint(SV.db.ActionBars[barID].point, bar, SV.db.ActionBars[barID].point)
+		bar.backdrop:SetWidth(space + ((size * rows) + (space * (rows - 1)) + space))
+		bar.backdrop:SetHeight(space + ((size * columns) + (space * (columns - 1)) + space))
+		bar.backdrop:SetFrameLevel(0);
+	else
+		bar.backdrop:SetAllPoints()
+		bar.backdrop:SetFrameLevel(0);
+	end
+
+	MOD:RefreshBar(barID);
+	--UpdateAltVehicleBindings();
+	SetStanceBarButtons();
+end
+--[[
+##########################################################
+HOOKED / REGISTERED FUNCTIONS
+##########################################################
+]]--
+local SVUIOptionsPanel_OnEvent = function()
+	InterfaceOptionsActionBarsPanelBottomRight.Text:SetText((L['Remove Bar %d Action Page']):format(2))
+	InterfaceOptionsActionBarsPanelBottomLeft.Text:SetText((L['Remove Bar %d Action Page']):format(3))
+	InterfaceOptionsActionBarsPanelRightTwo.Text:SetText((L['Remove Bar %d Action Page']):format(4))
+	InterfaceOptionsActionBarsPanelRight.Text:SetText((L['Remove Bar %d Action Page']):format(5))
+	InterfaceOptionsActionBarsPanelBottomRight:SetScript('OnEnter',nil)
+	InterfaceOptionsActionBarsPanelBottomLeft:SetScript('OnEnter',nil)
+	InterfaceOptionsActionBarsPanelRightTwo:SetScript('OnEnter',nil)
+	InterfaceOptionsActionBarsPanelRight:SetScript('OnEnter',nil)
+end
+
+local SVUIButton_ShowOverlayGlow = function(self)
+	if not self.overlay then return end
+	local size = self:GetWidth() / 3;
+	self.overlay:WrapPoints(self, size)
+end
+
+local ResetAllBindings = function(self)
+	if InCombatLockdown() then return end
+
+	local bar
+	for i = 1, TOTAL_BARS do
+		bar = _G[("SVUI_ActionBar%d"):format(i)]
+		if(bar) then
+			ClearOverrideBindings(bar)
+		end
+	end
+
+	ClearOverrideBindings(_G["SVUI_PetActionBar"])
+	ClearOverrideBindings(_G["SVUI_StanceBar"])
+
+	self:RegisterEvent("PLAYER_REGEN_DISABLED", "UpdateAllBindings")
+end
+--[[
+##########################################################
+BAR CREATION
+##########################################################
+]]--
+local CreateActionBars, CreateStanceBar, CreatePetBar;
+local barBindingIndex = {
+	"ACTIONBUTTON%d",
+	"MULTIACTIONBAR2BUTTON%d",
+	"MULTIACTIONBAR1BUTTON%d",
+	"MULTIACTIONBAR4BUTTON%d",
+	"MULTIACTIONBAR3BUTTON%d",
+	"SVUIACTIONBAR6BUTTON%d",
+	"SVUIACTIONBAR7BUTTON%d",
+	"SVUIACTIONBAR8BUTTON%d",
+	"SVUIACTIONBAR9BUTTON%d",
+	"SVUIACTIONBAR10BUTTON%d"
+}
+local barPageIndex = {1, 5, 6, 4, 3, 2, 7, 8, 9, 10}
+
+CreateActionBars = function(self)
+	for i = 1, TOTAL_BARS do
+		local barID = ("Bar%d"):format(i)
+		local barName = ("SVUI_Action%s"):format(barID)
+		local buttonMax = NUM_ACTIONBAR_BUTTONS
+		local space = SV.db.ActionBars["Bar"..i].buttonspacing;
+		local enabled = SV.db.ActionBars["Bar"..i].enable;
+		if(i == 1) then space = (space + 6) end
+
+		local thisBar = NewActionBar(barName)
+		thisBar.dataID = barID;
+		thisBar.binding = barBindingIndex[i];
+		thisBar.page = barPageIndex[i];
+
+		if(i == 3) then
+			thisBar:SetPoint("BOTTOMLEFT", _G["SVUI_ActionBar1"], "BOTTOMRIGHT", space, 0)
+		elseif(i == 4) then
+			thisBar:SetPoint("RIGHT", SV.Screen, "RIGHT", -space, 0)
+		elseif(i == 5) then
+			thisBar:SetPoint("BOTTOMRIGHT", _G["SVUI_ActionBar1"], "BOTTOMLEFT", -space, 0)
+		else
+			local nextGap = (i == 2) and -space or space
+			thisBar:SetPoint("BOTTOM", DEFAULT_MAIN_ANCHOR, "TOP", 0, nextGap)
+			DEFAULT_MAIN_ANCHOR = thisBar
+			if(enabled) then
+				self.MainAnchor:ClearAllPoints()
+				self.MainAnchor:SetAllPoints(thisBar)
+			end
+		end
+
+		local bg = CreateFrame("Frame", nil, thisBar)
+		bg:SetAllPoints()
+		bg:SetFrameLevel(0)
+		thisBar:SetFrameLevel(5)
+		bg:SetStyle("Frame", "Transparent")
+		bg:SetPanelColor("dark")
+		thisBar.backdrop = bg
+
+		for k = 1, buttonMax do
+			local buttonName = ("%sButton%d"):format(barName, k)
+			thisBar.buttons[k] = NewActionButton(thisBar, k, buttonName)
+			thisBar.buttons[k]:SetState(0, "action", k)
+			for x = 1, 14 do
+				local calc = (x - 1)  *  buttonMax  +  k;
+				thisBar.buttons[k]:SetState(x, "action", calc)
+			end
+			if k == 12 then
+				thisBar.buttons[k]:SetState(12, "custom", {
+					func = function(...)
+						if UnitExists("vehicle") then
+							VehicleExit()
+						else
+							PetDismiss()
+						end
+					end,
+					texture = "Interface\\Vehicles\\UI-Vehicles-Button-Exit-Down",
+					tooltip = LEAVE_VEHICLE
+				});
+			end
+		end
+
+		self:SetBarConfigData(thisBar)
+
+		if i == 1 then
+			thisBar:SetAttribute("hasTempBar", true)
+		else
+			thisBar:SetAttribute("hasTempBar", false)
+		end
+
+		thisBar:SetAttribute("_onstate-page", [[
+			if HasTempShapeshiftActionBar() and self:GetAttribute("hasTempBar") then
+				newstate = GetTempShapeshiftBarIndex() or newstate
+			end
+
+			if newstate ~= 0 then
+				self:SetAttribute("state", newstate)
+				control:ChildUpdate("state", newstate)
+			else
+				local newCondition = self:GetAttribute("newCondition")
+				if newCondition then
+					newstate = SecureCmdOptionParse(newCondition)
+					self:SetAttribute("state", newstate)
+					control:ChildUpdate("state", newstate)
+				end
+			end
+		]])
+
+		self:RefreshBar(barID)
+		SV:NewAnchor(thisBar, L[barID])
+	end
+end
+
+do
+	local function UpdateShapeshiftForms(self, event)
+	  if InCombatLockdown() or not _G["SVUI_StanceBar"] then return end
+
+	  local stanceBar = _G["SVUI_StanceBar"];
+
+	  for i = 1, #stanceBar.buttons do
+		stanceBar.buttons[i]:Hide()
+	  end
+
+	  local ready = false;
+	  local maxForms = GetNumShapeshiftForms()
+
+	  for i = 1, NUM_STANCE_SLOTS do
+		if(not stanceBar.buttons[i]) then
+		  stanceBar.buttons[i] = CreateFrame("CheckButton", format("SVUI_StanceBarButton%d", i), stanceBar, "StanceButtonTemplate")
+		  stanceBar.buttons[i]:SetID(i)
+		  ready = true
+		end
+		if(i <= maxForms) then
+		  stanceBar.buttons[i]:Show()
+		else
+		  stanceBar.buttons[i]:Hide()
+		end
+	  end
+
+	  MOD:RefreshBar("Stance")
+
+	  SetStanceBarButtons()
+	  if not C_PetBattles.IsInBattle() or ready then
+		if maxForms == 0 then
+		  UnregisterStateDriver(stanceBar, "show")
+		  stanceBar:Hide()
+		else
+		  stanceBar:Show()
+		  RegisterStateDriver(stanceBar, "show", "[petbattle] hide;show")
+		end
+	  end
+	end
+
+	local function UpdateShapeshiftCD()
+	  local maxForms = GetNumShapeshiftForms()
+	  for i = 1, NUM_STANCE_SLOTS do
+		if i  <= maxForms then
+		  local cooldown = _G["SVUI_StanceBarButton"..i.."Cooldown"]
+		  local start, duration, enable = GetShapeshiftFormCooldown(i)
+		  CooldownFrame_Set(cooldown, start, duration, enable)
+		end
+	  end
+	end
+
+	CreateStanceBar = function(self)
+	  local barID = "Stance";
+	  local maxForms = GetNumShapeshiftForms();
+	  local stanceBar = NewActionBar("SVUI_StanceBar")
+	  stanceBar.binding = "CLICK SVUI_StanceBarButton%d:LeftButton"
+
+	  stanceBar:SetPoint("BOTTOMRIGHT", self.MainAnchor, "TOPRIGHT", 0, 2);
+	  stanceBar:SetFrameLevel(5);
+
+	  local bg = CreateFrame("Frame", nil, stanceBar)
+	  bg:SetAllPoints();
+	  bg:SetFrameLevel(0);
+	  bg:SetStyle("Frame", "Transparent")
+	  bg:SetPanelColor("dark")
+	  stanceBar.backdrop = bg;
+
+	  for i = 1, NUM_STANCE_SLOTS do
+		stanceBar.buttons[i] = _G["SVUI_StanceBarButton"..i]
+	  end
+
+	  stanceBar:SetAttribute("_onstate-show", [[
+		if newstate == "hide" then
+		  self:Hide();
+		else
+		  self:Show();
+		end
+	  ]]);
+
+	  self:RegisterEvent("UPDATE_SHAPESHIFT_FORMS", UpdateShapeshiftForms)
+	  self:RegisterEvent("UPDATE_SHAPESHIFT_COOLDOWN", UpdateShapeshiftCD)
+	  self:RegisterEvent("UPDATE_SHAPESHIFT_USABLE", SetStanceBarButtons)
+	  self:RegisterEvent("UPDATE_SHAPESHIFT_FORM", SetStanceBarButtons)
+	  UpdateShapeshiftForms()
+	  stanceBar.snapOffset = -3
+	  SV:NewAnchor(stanceBar, L["Stance Bar"])
+	  self:RefreshBar("Stance")
+	  SetStanceBarButtons()
+	  self:UpdateBarBindings(false, true)
+	end
+end
+
+do
+	local PET_RESTRICTIONS = { ["PET_ACTION_FOLLOW"] = true, };
+	local RefreshPet = function(self, event, unit)
+		if(event == "UNIT_AURA" and ((not unit) or (unit ~= "pet"))) then return end
+		for i = 1, NUM_PET_ACTION_SLOTS, 1 do
+			local name = "PetActionButton"..i;
+			local button = _G[name]
+			local icon = _G[name.."Icon"]
+
+			local actionName, subtext, actionIcon, isToken, isActive, autoCastAllowed, autoCastEnabled = GetPetActionInfo(i)
+			local restrictedAction = PET_RESTRICTIONS[actionName];
+
+			if(not isToken) then
+				icon:SetTexture(actionIcon)
+				button.tooltipName = actionName
+			else
+				icon:SetTexture(_G[actionIcon])
+				button.tooltipName = _G[actionName]
+			end
+
+			button.isToken = isToken;
+			button.tooltipSubtext = subtext;
+
+			if(isActive and (not restrictedAction)) then
+				button:SetChecked(true)
+				button:SetBackdropBorderColor(0.4, 0.8, 0)
+				if(IsPetAttackAction(i)) then PetActionButton_StartFlash(button) end
+			else
+				button:SetChecked(false)
+				button:SetBackdropBorderColor(0, 0, 0)
+				if(IsPetAttackAction(i)) then PetActionButton_StopFlash(button) end
+			end
+
+			local auto = _G[name.."AutoCastable"]
+			if(autoCastAllowed and auto) then auto:Show() else auto:Hide() end
+			local shine = _G[name.."Shine"]
+			if(autoCastEnabled and shine) then AutoCastShine_AutoCastStart(shine) else AutoCastShine_AutoCastStop(shine) end
+
+			button:SetAlpha(1)
+
+			if actionIcon then
+				icon:Show()
+				if GetPetActionSlotUsable(i) then SetDesaturation(icon, nil) else SetDesaturation(icon, 1) end
+				if(button.cooldown) then
+					button.cooldown:SetAlpha(1)
+					button.cooldown:SetSwipeColor(0, 0, 0, 1)
+					button.cooldown:SetDrawBling(true)
+				end
+
+				if((not PetHasActionBar()) and (not restrictedAction)) then
+					PetActionButton_StopFlash(button)
+					SetDesaturation(icon, 1)
+					button:SetChecked(false)
+				end
+			else
+				icon:Hide()
+				if(button.cooldown) then
+					button.cooldown:SetAlpha(0)
+					button.cooldown:SetSwipeColor(0, 0, 0, 0)
+					button.cooldown:SetDrawBling(false)
+				end
+			end
+
+			button:GetCheckedTexture():SetAlpha(0.5)
+		end
+	end
+
+	CreatePetBar = function(self)
+		local barID = "Pet";
+		local petBar = NewActionBar("SVUI_PetActionBar")
+		petBar.binding = "BONUSACTIONBUTTON%d"
+
+		petBar:SetPoint("BOTTOMLEFT", self.MainAnchor, "TOPLEFT", 0, 2);
+		petBar:SetFrameLevel(5);
+		local bg = CreateFrame("Frame", nil, petBar)
+		bg:SetAllPoints();
+		bg:SetFrameLevel(0);
+		bg:SetStyle("Frame", "Transparent")
+		bg:SetPanelColor("dark")
+		petBar.backdrop = bg;
+		for i = 1, NUM_PET_ACTION_SLOTS do
+			petBar.buttons[i] = _G["PetActionButton"..i]
+		end
+		petBar:SetAttribute("_onstate-show", [[ if newstate == "hide" then self:Hide(); else self:Show(); end ]]);
+
+		PetActionBarFrame.showgrid = 1;
+		PetActionBar_ShowGrid();
+
+		self:RefreshBar("Pet")
+		self:UpdateBarBindings(true, false)
+
+		self:RegisterEvent("SPELLS_CHANGED", RefreshPet)
+		self:RegisterEvent("PLAYER_CONTROL_GAINED", RefreshPet)
+		self:RegisterEvent("PLAYER_ENTERING_WORLD", RefreshPet)
+		self:RegisterEvent("PLAYER_CONTROL_LOST", RefreshPet)
+		self:RegisterEvent("PET_BAR_UPDATE", RefreshPet)
+		self:RegisterEvent("UNIT_PET", RefreshPet)
+		self:RegisterEvent("UNIT_FLAGS", RefreshPet)
+		self:RegisterEvent("UNIT_AURA", RefreshPet)
+		self:RegisterEvent("PLAYER_FARSIGHT_FOCUS_CHANGED", RefreshPet)
+		self:RegisterEvent("PET_BAR_UPDATE_COOLDOWN", PetActionBar_UpdateCooldowns)
+
+		SV:NewAnchor(petBar, L["Pet Bar"])
+	end
+end
+
+local CreateExtraBar = function(self)
+	local specialBar = CreateFrame("Frame", "SVUI_SpecialAbility", SV.Screen)
+	specialBar:SetPoint("BOTTOM", SV.Screen, "BOTTOM", 0, 360)
+	specialBar:SetSize(ExtraActionBarFrame:GetSize())
+	ExtraActionBarFrame:SetParent(specialBar)
+	ExtraActionBarFrame:ClearAllPoints()
+	ExtraActionBarFrame:SetPoint("CENTER", specialBar, "CENTER")
+	ExtraActionBarFrame.ignoreFramePositionManager = true;
+	local max = ExtraActionBarFrame:GetNumChildren()
+	for i = 1, max do
+		local name = ("ExtraActionButton%d"):format(i)
+		local icon = ("%sIcon"):format(name)
+		local cool = ("%sCooldown"):format(name)
+		local button = _G[name]
+		if(button) then
+			button.noResize = true;
+			button.pushed = true;
+			button.checked = true;
+			ModifyActionButton(button)
+			_G[icon]:SetDrawLayer("ARTWORK")
+			_G[cool]:InsetPoints()
+			local checkedTexture = button:CreateTexture(nil, "OVERLAY")
+			checkedTexture:SetColorTexture(0.9, 0.8, 0.1, 0.3)
+			checkedTexture:InsetPoints()
+			button:SetCheckedTexture(checkedTexture)
+		end
+	end
+	if HasExtraActionBar()then
+		ExtraActionBarFrame:Show()
+	end
+	SV:NewAnchor(specialBar, L["Extra Action Button"])
+end
+--[[
+##########################################################
+DEFAULT REMOVAL
+##########################################################
+]]--
+local function RemoveDefaults()
+	if(InCombatLockdown()) then
+		MOD:RegisterEvent("PLAYER_REGEN_ENABLED")
+		return
+	end
+	local removalManager = CreateFrame("Frame")
+	removalManager:Hide()
+	MultiBarBottomLeft:SetParent(removalManager)
+	MultiBarBottomRight:SetParent(removalManager)
+	MultiBarLeft:SetParent(removalManager)
+	MultiBarRight:SetParent(removalManager)
+
+	for i = 1, 12 do
+		local ab = _G[("ActionButton%d"):format(i)]
+		ab:Hide()
+		ab:UnregisterAllEvents()
+		ab:SetAttribute("statehidden", true)
+		local mbl = _G[("MultiBarLeftButton%d"):format(i)]
+		mbl:Hide()
+		mbl:UnregisterAllEvents()
+		mbl:SetAttribute("statehidden", true)
+		local mbr = _G[("MultiBarRightButton%d"):format(i)]
+		mbr:Hide()
+		mbr:UnregisterAllEvents()
+		mbr:SetAttribute("statehidden", true)
+		local mbbl = _G[("MultiBarBottomLeftButton%d"):format(i)]
+		mbbl:Hide()
+		mbbl:UnregisterAllEvents()
+		mbbl:SetAttribute("statehidden", true)
+		local mbbr = _G[("MultiBarBottomRightButton%d"):format(i)]
+		mbbr:Hide()
+		mbbr:UnregisterAllEvents()
+		mbbr:SetAttribute("statehidden", true)
+		local mca = _G[("MultiCastActionButton%d"):format(i)]
+		mca:Hide()
+		mca:UnregisterAllEvents()
+		mca:SetAttribute("statehidden", true)
+		local vb = _G[("VehicleMenuBarActionButton%d"):format(i)]
+		if(vb) then
+			vb:Hide()
+			vb:UnregisterAllEvents()
+			vb:SetAttribute("statehidden", true)
+		end
+		local ob = _G[("OverrideActionBarButton%d"):format(i)]
+		if(ob) then
+			ob:Hide()
+			ob:UnregisterAllEvents()
+			ob:SetAttribute("statehidden", true)
+		end
+	end
+
+	ActionBarController:UnregisterAllEvents()
+	ActionBarController:RegisterEvent("UPDATE_EXTRA_ACTIONBAR")
+
+	MainMenuBar:EnableMouse(false)
+	MainMenuBar:SetAlpha(0)
+	MainMenuExpBar:UnregisterAllEvents()
+	MainMenuExpBar:Hide()
+	MainMenuExpBar:SetParent(removalManager)
+	local maxChildren = MainMenuBar:GetNumChildren();
+	for i = 1, maxChildren do
+		local child = select(i, MainMenuBar:GetChildren())
+		if child then
+			child:UnregisterAllEvents()
+			child:Hide()
+			child:SetParent(removalManager)
+		end
+	end
+	ReputationWatchBar:UnregisterAllEvents()
+	ReputationWatchBar:Hide()
+	ReputationWatchBar:SetParent(removalManager)
+	MainMenuBarArtFrame:UnregisterEvent("ACTIONBAR_PAGE_CHANGED")
+	MainMenuBarArtFrame:UnregisterEvent("ADDON_LOADED")
+	MainMenuBarArtFrame:Hide()
+	MainMenuBarArtFrame:SetParent(removalManager)
+	StanceBarFrame:UnregisterAllEvents()
+	StanceBarFrame:Hide()
+	StanceBarFrame:SetParent(removalManager)
+	OverrideActionBar:UnregisterAllEvents()
+	OverrideActionBar:Hide()
+	OverrideActionBar:SetParent(removalManager)
+	PossessBarFrame:UnregisterAllEvents()
+	PossessBarFrame:Hide()
+	PossessBarFrame:SetParent(removalManager)
+	PetActionBarFrame:UnregisterAllEvents()
+	PetActionBarFrame:Hide()
+	PetActionBarFrame:SetParent(removalManager)
+	MultiCastActionBarFrame:UnregisterAllEvents()
+	MultiCastActionBarFrame:Hide()
+	MultiCastActionBarFrame:SetParent(removalManager)
+
+	-- IconIntroTracker:UnregisterAllEvents()
+	-- IconIntroTracker:Hide()
+	-- IconIntroTracker:SetParent(removalManager)
+
+	--InterfaceOptionsCombatPanelActionButtonUseKeyDown:SetScale(0.0001)
+	--InterfaceOptionsCombatPanelActionButtonUseKeyDown:SetAlpha(0)
+	InterfaceOptionsActionBarsPanelAlwaysShowActionBars:EnableMouse(false)
+	InterfaceOptionsActionBarsPanelPickupActionKeyDropDownButton:SetScale(0.0001)
+	InterfaceOptionsActionBarsPanelLockActionBars:SetScale(0.0001)
+	InterfaceOptionsActionBarsPanelAlwaysShowActionBars:SetAlpha(0)
+	InterfaceOptionsActionBarsPanelPickupActionKeyDropDownButton:SetAlpha(0)
+	InterfaceOptionsActionBarsPanelLockActionBars:SetAlpha(0)
+	InterfaceOptionsActionBarsPanelPickupActionKeyDropDown:SetAlpha(0)
+	InterfaceOptionsActionBarsPanelPickupActionKeyDropDown:SetScale(0.00001)
+	--InterfaceOptionsStatusTextPanelXP:SetAlpha(0)
+	--InterfaceOptionsStatusTextPanelXP:SetScale(0.00001)
+
+	if PlayerTalentFrame then
+		PlayerTalentFrame:UnregisterEvent("ACTIVE_TALENT_GROUP_CHANGED")
+	else
+		hooksecurefunc("TalentFrame_LoadUI", function() PlayerTalentFrame:UnregisterEvent("ACTIVE_TALENT_GROUP_CHANGED") end)
+	end
+
+	MOD.DefaultsRemoved = true
+end
+
+local function pushSpellToActionBar(self,spellID,slotIndex,slotPos)
+	local slotParent = _G["SVUI_Bar1Button"..slotPos];
+	if(not slotParent) then return end
+	local _, _, icon = GetSpellInfo(spellID);
+	local freeIcon;
+
+	for a,b in pairs(self.iconList) do
+		if b.isFree then
+			freeIcon = b;
+		end
+	end
+
+	if not freeIcon then -- Make a new one
+		freeIcon = CreateFrame("FRAME", self:GetName().."Icon"..(#self.iconList+1), UIParent, "IconIntroTemplate");
+		self.iconList[#self.iconList+1] = freeIcon;
+	end
+
+	freeIcon.icon.icon:SetTexture(icon);
+	freeIcon.icon.slot = slotIndex;
+	freeIcon:ClearAllPoints();
+	freeIcon:SetPoint("CENTER", slotParent, 0, 0);
+	freeIcon:SetFrameLevel(slotParent:GetFrameLevel() + 1);
+	freeIcon.icon.flyin:Play(1);
+	freeIcon.isFree = false;
+
+	if not HasAction(slotPos) then
+		PickupSpell(spellID)
+		PlaceAction(slotPos)
+	end
+end
+
+IconIntroTracker_OnEvent = function(self, event, ...)
+  if event == "SPELL_PUSHED_TO_ACTIONBAR" or event == "COMBAT_LOG_EVENT_UNFILTERED" then
+		if InCombatLockdown() then
+			self.queue=self.queue or {};
+			local queueCount = #self.queue + 1;
+			local spellID, slotIndex, slotPos = ...;
+			self.queue[queueCount]={spellID,slotIndex,slotPos};
+			self:RegisterEvent("PLAYER_REGEN_ENABLED")
+		else
+			pushSpellToActionBar(self,...)
+		end
+	elseif event == "PLAYER_REGEN_ENABLED" then
+		local queueCount = #self.queue;
+		for i=1, queueCount do
+			pushSpellToActionBar(self, unpack(self.queue[i]))
+			self.queue[i]=nil;
+		end
+		self:UnregisterEvent("PLAYER_REGEN_ENABLED")
+    end
+end
+
+function MOD:PLAYER_REGEN_ENABLED()
+	self:UnregisterEvent("PLAYER_REGEN_ENABLED")
+	if(not MOD.DefaultsRemoved) then
+		RemoveDefaults()
+	end
+	self:RefreshActionBars()
+end
+
+local function UpdateActionBarOptions()
+	if InCombatLockdown() or not SV.db.ActionBars.IsLoaded then return end
+	if (SV.db.ActionBars.Bar2.enable ~= InterfaceOptionsActionBarsPanelBottomRight:GetChecked()) then
+		InterfaceOptionsActionBarsPanelBottomRight:Click()
+	end
+	if (SV.db.ActionBars.Bar3.enable ~= InterfaceOptionsActionBarsPanelRightTwo:GetChecked()) then
+		InterfaceOptionsActionBarsPanelRightTwo:Click()
+	end
+	if (SV.db.ActionBars.Bar4.enable ~= InterfaceOptionsActionBarsPanelRight:GetChecked()) then
+		InterfaceOptionsActionBarsPanelRight:Click()
+	end
+	if (SV.db.ActionBars.Bar5.enable ~= InterfaceOptionsActionBarsPanelBottomLeft:GetChecked()) then
+		InterfaceOptionsActionBarsPanelBottomLeft:Click()
+	end
+  	MOD:RefreshBar("Bar1")
+	MOD:RefreshBar("Bar6")
+end
+--[[
+##########################################################
+BUILD FUNCTION / UPDATE
+##########################################################
+]]--
+function MOD:UpdateLocals()
+	local db = SV.db.ActionBars
+	if not db then return end
+
+	TOTAL_BARS = db.barCount
+	SELF_CASTING = db.rightClickSelf
+end
+
+function MOD:ReLoad()
+	self:RefreshActionBars();
+end
+
+function MOD:Load()
+	RemoveDefaults();
+	self.MainAnchor:ClearAllPoints()
+	self.MainAnchor:SetAllPoints(DEFAULT_MAIN_ANCHOR)
+	self.MainAnchor:SetParent(SV.Screen)
+	self:UpdateLocals()
+
+	self:UpdateBarPagingDefaults()
+
+	CreateActionBars(self)
+	CreateStanceBar(self)
+	CreatePetBar(self)
+	CreateExtraBar(self)
+	self:InitializeMicroBar()
+	self:InitializeZoneButton()
+	self:InitializeTotemBar()
+
+	self:LoadKeyBinder()
+
+	self:RegisterEvent("UPDATE_BINDINGS", "UpdateAllBindings")
+	self:RegisterEvent("PET_BATTLE_CLOSE", "UpdateAllBindings")
+	self:RegisterEvent("PET_BATTLE_OPENING_DONE", ResetAllBindings)
+	self:RegisterEvent("UPDATE_VEHICLE_ACTIONBAR", "UpdateUniqueBars")
+	self:RegisterEvent("UPDATE_OVERRIDE_ACTIONBAR", "UpdateUniqueBars")
+	self:RegisterEvent("ACTIONBAR_PAGE_CHANGED", "UpdateUniqueBars")
+	if C_PetBattles.IsInBattle()then
+		ResetAllBindings(self)
+	else
+		self:UpdateAllBindings()
+	end
+	NewHook("BlizzardOptionsPanel_OnEvent", SVUIOptionsPanel_OnEvent)
+	NewHook("ActionButton_ShowOverlayGlow", SVUIButton_ShowOverlayGlow)
+	if not GetCVarBool("lockActionBars") then SetCVar("lockActionBars", 1) end
+	SetSpellFlyoutHook()
+
+	self.IsLoaded = true
+
+	SV.SystemAlert["BAR6_CONFIRMATION"] = {
+		text = L["Enabling / Disabling Bar #6 will toggle a paging option from your main actionbar to prevent duplicating bars, are you sure you want to do this?"],
+		button1 = YES,
+		button2 = NO,
+		OnAccept = function(a)
+			if SV.db.ActionBars["BAR6"].enable ~= true then
+				SV.db.ActionBars.Bar6.enable = true;
+				UpdateActionBarOptions()
+			else
+				SV.db.ActionBars.Bar6.enable = false;
+				UpdateActionBarOptions()
+			end
+		end,
+		OnCancel = SV.fubar,
+		timeout = 0,
+		whileDead = 1,
+		state1 = 1
+	};
+end
diff --git a/SVUI_ActionBars/SVUI_ActionBars.toc b/SVUI_ActionBars/SVUI_ActionBars.toc
new file mode 100644
index 0000000..73e506d
--- /dev/null
+++ b/SVUI_ActionBars/SVUI_ActionBars.toc
@@ -0,0 +1,16 @@
+## Interface: 70000
+## Author: Failcoder
+## Version: 1.3.5
+## Title: |cffFF9900SuperVillain UI: |r|cffFFEF00Action Bars|r
+## Notes: Action Bar Plugin for [|cff9911FFSVUI|r].
+## OptionalDeps: LibSharedMedia-3.0, LibActionButton-1.0
+## RequiredDeps: SVUI_!Core
+## X-SVUIName: ActionBars
+## X-SVUISchema: ActionBars
+## X-Embeds: LibActionButton-1.0
+## X-Email: munglunch@gmail.com
+## X-Website: http://www.supervillainui.com
+## X-Donate: PayPal:munglunch@gmail.com
+## X-License: MIT
+
+SVUI_ActionBars.xml
diff --git a/SVUI_ActionBars/SVUI_ActionBars.xml b/SVUI_ActionBars/SVUI_ActionBars.xml
new file mode 100644
index 0000000..c222230
--- /dev/null
+++ b/SVUI_ActionBars/SVUI_ActionBars.xml
@@ -0,0 +1,16 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+	<Script file="Loader.lua"/>
+
+	<Frame name="SVUI_DraenorButtonHolder" parent="UIParent" hidden="true">
+        <Size x="50" y="50"/>
+        <Anchors>
+            <Anchor point="BOTTOM" x="0" y="275"/>
+        </Anchors>
+    </Frame>
+	<Include file="libs\_load.xml"/>
+	<Script file="SVUI_ActionBars.lua"/>
+	<Script file="components\keybind.lua"/>
+	<Script file="components\micro.lua"/>
+	<Script file="components\zone.lua"/>
+	<Script file="components\totem.lua"/>
+</Ui>
\ No newline at end of file
diff --git a/SVUI_ActionBars/assets/MICROMENU.blp b/SVUI_ActionBars/assets/MICROMENU.blp
new file mode 100644
index 0000000..088fe01
Binary files /dev/null and b/SVUI_ActionBars/assets/MICROMENU.blp differ
diff --git a/SVUI_ActionBars/components/keybind.lua b/SVUI_ActionBars/components/keybind.lua
new file mode 100644
index 0000000..d688c5d
--- /dev/null
+++ b/SVUI_ActionBars/components/keybind.lua
@@ -0,0 +1,550 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local select  = _G.select;
+local pairs   = _G.pairs;
+local ipairs  = _G.ipairs;
+local type    = _G.type;
+local string  = _G.string;
+local math    = _G.math;
+local table   = _G.table;
+--[[ STRING METHODS ]]--
+local format, find = string.format, string.find;
+--[[ MATH METHODS ]]--
+local floor = math.floor;
+local tonumber = tonumber;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L;
+local MOD = SV.ActionBars;
+
+local RefreshBindings
+local NewFrame = CreateFrame;
+local NewHook = hooksecurefunc;
+
+local Binder = NewFrame("Frame", nil, UIParent);
+--[[
+##########################################################
+BINDING UPDATES
+##########################################################
+]]--
+do
+  --[[ HANDLERS ]]--
+  local GameTooltip_OnHide = function(self)
+    self:SetOwner(Binder, "ANCHOR_TOP")
+    self:SetPoint("BOTTOM", Binder, "TOP", 0, 1)
+    self:AddLine(Binder.button.name, 1, 1, 1)
+    Binder.button.bindings = {GetBindingKey(Binder.button.bindstring)}
+    local count = #Binder.button.bindings
+    if(count == 0) then
+      self:AddLine(L["No bindings set."], .6, .6, .6)
+    else
+      self:AddDoubleLine(L["Binding"], L["Key"], .6, .6, .6, .6, .6, .6)
+      for i = 1, count do
+        self:AddDoubleLine(i, Binder.button.bindings[i])
+      end
+    end
+    self:Show()
+    self:SetScript("OnHide", nil)
+  end
+  --[[ END OF HANDLERS ]]--
+
+  function RefreshBindings(bindTarget, bindType)
+    if(not Binder.active or InCombatLockdown()) then return end
+    Binder.button = bindTarget;
+    Binder.spellmacro = bindType;
+    Binder:ClearAllPoints()
+    Binder:SetAllPoints(bindTarget)
+    Binder:Show()
+    ShoppingTooltip1:Hide()
+    if(bindTarget.FlyoutArrow and bindTarget.FlyoutArrow:IsShown()) then
+      Binder:EnableMouse(false)
+    elseif(not Binder:IsMouseEnabled()) then
+      Binder:EnableMouse(true)
+    end
+    local keyBindID, keyBindName, keyBindString;
+    if bindType == "FLYOUT" then
+      keyBindName = GetSpellInfo(bindTarget.spellID);
+      keyBindString = ("SPELL %s"):format(keyBindName);
+      Binder.button.name = keyBindName
+      Binder.button.bindstring = keyBindString;
+      GameTooltip:AddLine(L["Trigger"])
+      GameTooltip:Show()
+      GameTooltip:SetScript("OnHide", GameTooltip_OnHide)
+    elseif bindType == "SPELL" then
+      keyBindID = SpellBook_GetSpellBookSlot(bindTarget)
+      keyBindName = GetSpellBookItemName(keyBindID, SpellBookFrame.bookType);
+      keyBindString = ("SPELL %s"):format(keyBindName);
+      Binder.button.id = keyBindID
+      Binder.button.name = keyBindName
+      Binder.button.bindstring = keyBindString;
+      GameTooltip:AddLine(L["Trigger"])
+      GameTooltip:Show()
+      GameTooltip:SetScript("OnHide", GameTooltip_OnHide)
+    elseif bindType == "MACRO" then
+      keyBindID = bindTarget:GetID()
+      if(floor(.5  +  select(2, MacroFrameTab1Text:GetTextColor())  *  10)  /  10 == .8) then
+        keyBindID = keyBindID  +  36
+      end
+      keyBindName = GetMacroInfo(keyBindID)
+      keyBindString = ("MACRO %s"):format(keyBindName);
+      Binder.button.id = keyBindID
+      Binder.button.name = keyBindName
+      Binder.button.bindstring = keyBindString;
+      Binder.button.bindings = {GetBindingKey(keyBindString)}
+      GameTooltip:SetOwner(Binder, "ANCHOR_TOP")
+      GameTooltip:SetPoint("BOTTOM", Binder, "TOP", 0, 1)
+      GameTooltip:AddLine(keyBindName, 1, 1, 1)
+      if #Binder.button.bindings == 0 then
+        GameTooltip:AddLine(L["No bindings set."], .6, .6, .6)
+      else
+        GameTooltip:AddDoubleLine(L["Binding"], L["Key"], .6, .6, .6, .6, .6, .6)
+        for i = 1, #Binder.button.bindings do
+          local lineName = ("%s%d"):format(L["Binding"], i)
+          GameTooltip:AddDoubleLine(lineName, Binder.button.bindings[i], 1, 1, 1)
+        end
+      end
+      GameTooltip:Show()
+    elseif bindType == "STANCE" or bindType == "PET" then
+      keyBindID = tonumber(bindTarget:GetID())
+      keyBindName = bindTarget:GetName()
+      if(not keyBindName) then return end
+      if ((not keyBindID) or (keyBindID < 1) or (keyBindID > (bindType == "STANCE" and 10 or 12))) then
+        keyBindString = ("CLICK %s: LeftButton"):format(keyBindName);
+      else
+        local tmpStr = bindType == "STANCE" and "StanceButton" or "BONUSACTIONBUTTON"
+        keyBindString = ("%s%d"):format(tmpStr, keyBindID);
+      end
+      Binder.button.id = keyBindID
+      Binder.button.name = keyBindName
+      Binder.button.bindstring = keyBindString
+      GameTooltip:AddLine(L["Trigger"])
+      GameTooltip:Show()
+      GameTooltip:SetScript("OnHide", GameTooltip_OnHide)
+    else
+      keyBindID = tonumber(bindTarget.action)
+      keyBindName = bindTarget:GetName()
+      if(not keyBindName) then return end
+      if(not bindTarget.keyBoundTarget and ((not keyBindID) or (keyBindID < 1) or (keyBindID > 132))) then
+        keyBindString = ("CLICK %s: LeftButton"):format(keyBindName);
+      elseif(bindTarget.keyBoundTarget) then
+        keyBindString = bindTarget.keyBoundTarget
+      else
+        local slotID = 1 + (keyBindID - 1) % 12;
+        if((keyBindID < 25) or (keyBindID > 72)) then
+          keyBindString = ("ACTIONBUTTON%s"):format(slotID);
+        elseif((keyBindID < 73) and (keyBindID > 60)) then
+          keyBindString = ("MULTIACTIONBAR1BUTTON%s"):format(slotID);
+        elseif(keyBindID < 61 and keyBindID > 48) then
+          keyBindString = ("MULTIACTIONBAR2BUTTON%s"):format(slotID);
+        elseif(keyBindID < 49 and keyBindID > 36) then
+          keyBindString = ("MULTIACTIONBAR4BUTTON%s"):format(slotID);
+        elseif(keyBindID < 37 and keyBindID > 24) then
+          keyBindString = ("MULTIACTIONBAR3BUTTON%s"):format(slotID);
+        end
+      end
+      Binder.button.action = keyBindID
+      Binder.button.name = keyBindName
+      Binder.button.bindstring = keyBindString
+      GameTooltip:AddLine(L["Trigger"])
+      GameTooltip:Show()
+      GameTooltip:SetScript("OnHide", GameTooltip_OnHide)
+    end
+  end
+end
+--[[
+##########################################################
+PACKAGE MOD
+##########################################################
+]]--
+function MOD:ToggleKeyBindingMode(deactivate, saveRequested)
+  if not deactivate then
+    Binder.active = true;
+    SV:StaticPopupSpecial_Show(SVUI_KeyBindPopup)
+    MOD:RegisterEvent('PLAYER_REGEN_DISABLED', 'ToggleKeyBindingMode', true, false)
+  else
+    if saveRequested then
+      SaveBindings(GetCurrentBindingSet())
+      SV:AddonMessage(L["Binding Changes Stored"])
+    else
+      LoadBindings(GetCurrentBindingSet())
+      SV:AddonMessage(L["Binding Changes Discarded"])
+    end
+    Binder.active = false;
+    Binder:ClearAllPoints()
+    Binder:Hide()
+    GameTooltip:Hide()
+    MOD:UnregisterEvent("PLAYER_REGEN_DISABLED")
+    SV:StaticPopupSpecial_Hide(SVUI_KeyBindPopup)
+    MOD.bindingsChanged = false
+  end
+end
+
+local blockedButtons = { LSHIFT = true, RSHIFT = true, LCTRL = true, RCTRL = true, LALT = true, RALT = true, UNKNOWN = true, LeftButton = true}
+
+--[[ HANDLERS ]]--
+local tipTimeLapse = 0;
+local GameTooltip_OnUpdate = function(self, elapsed)
+  tipTimeLapse = (tipTimeLapse + elapsed);
+  if tipTimeLapse < .2 then
+    return
+  else
+    tipTimeLapse = 0
+  end
+  if(not self.comparing and IsModifiedClick("COMPAREITEMS")) then
+    GameTooltip_ShowCompareItem(self)
+    self.comparing = true
+  elseif(self.comparing and not IsModifiedClick("COMPAREITEMS")) then
+    for _,tip in pairs(self.shoppingTooltips)do
+      tip:Hide()
+    end
+    self.comparing = false
+  end
+end
+
+local GameTooltip_OnHide = function(self)
+  for _, tip in pairs(self.shoppingTooltips)do
+    tip:Hide()
+  end
+end
+
+local GameTooltip_OnHide = function(self)
+  for _, tip in pairs(self.shoppingTooltips)do
+    tip:Hide()
+  end
+end
+
+local SpellButton_OnEnter = function(self)
+  RefreshBindings(self, "SPELL")
+end
+
+local Button_Proxy = function(self)
+  RefreshBindings(self)
+end
+local Stance_Proxy = function(self)
+  RefreshBindings(self,"STANCE")
+end
+local Pet_Proxy = function(self)
+  RefreshBindings(self,"PET")
+end
+local Flyout_Proxy = function(self)
+  RefreshBindings(self,"FLYOUT")
+end
+local Macro_Proxy = function(self)
+  RefreshBindings(self, "MACRO")
+end
+
+local BinderButton_OnEnter = function(self)
+  local parent = self.button:GetParent()
+  if parent and parent._fade then
+    parent:FadeIn(0.2, parent:GetAlpha(), parent._alpha)
+  end
+end
+
+local BinderButton_OnLeave = function(self)
+  local parent = self.button:GetParent()
+  self:ClearAllPoints()
+  self:Hide()
+  GameTooltip:Hide()
+  if parent and parent._fade then
+    parent:FadeOut(1, parent:GetAlpha(), 0)
+  end
+end
+
+local Binder_OnBinding = function(self, event)
+  MOD.bindingsChanged = true;
+  if(event == "ESCAPE" or event == "RightButton") then
+    local count = #Binder.button.bindings
+    for i=1, count do
+      SetBinding(Binder.button.bindings[i])
+    end
+    local prefix = L["All keybindings cleared for |cff00ff00%s|r."]
+    local strMsg = prefix:format(Binder.button.name)
+    SV:AddonMessage(strMsg)
+    RefreshBindings(Binder.button, Binder.spellmacro)
+    if(Binder.spellmacro ~= "MACRO") then
+      GameTooltip:Hide()
+    end
+    return
+  end
+
+  if(blockedButtons[event]) then return end
+  if(event == "MiddleButton") then
+    event = "BUTTON3"
+  end
+  if(event:find('Button%d')) then
+    event = event:upper()
+  end
+
+  local altText = IsAltKeyDown() and "ALT-" or "";
+  local ctrlText = IsControlKeyDown() and "CTRL-" or "";
+  local shiftText = IsShiftKeyDown() and "SHIFT-" or "";
+  local strBind = ("%s%s%s%s"):format(altText, ctrlText, shiftText, event)
+
+  if(not Binder.spellmacro or Binder.spellmacro == "PET" or Binder.spellmacro == "STANCE" or Binder.spellmacro == "FLYOUT") then
+    SetBinding(strBind, Binder.button.bindstring)
+  else
+    local strMacro = ("%s %s"):format(Binder.spellmacro, Binder.button.name)
+    SetBinding(strBind, strMacro)
+  end
+
+  local glue = L[" |cff00ff00bound to |r"]
+  local addMsg = ("%s%s%s."):format(strBind, glue, Binder.button.name)
+  SV:AddonMessage(addMsg)
+  RefreshBindings(Binder.button, Binder.spellmacro)
+
+  if Binder.spellmacro ~= "MACRO" then
+    GameTooltip:Hide()
+  end
+end
+
+local BinderButton_OnMouseWheel = function(self, delta)
+  if delta > 0 then
+    Binder_OnBinding(self, "MOUSEWHEELUP")
+  else
+    Binder_OnBinding(self, "MOUSEWHEELDOWN")
+  end
+end
+
+local SetBindingMacro = function(self, arg)
+  if(arg == "Blizzard_MacroUI") then
+    for i=1,36 do
+      local btnName = ("MacroButton%d"):format(i)
+      local btn = _G[btnName]
+      btn:HookScript("OnEnter", MacroBinding_OnEnter)
+    end
+  end
+end
+
+local Check_OnShow = function(self)
+  self:SetChecked(GetCurrentBindingSet() == 2)
+end
+
+local Check_OnEnter = function(self)
+  GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
+  GameTooltip:SetText(CHARACTER_SPECIFIC_KEYBINDING_TOOLTIP, nil, nil, nil, nil, 1)
+end
+
+local Check_OnClick = function(self)
+  if(MOD.bindingsChanged) then
+    SV:StaticPopup_Show("CONFIRM_LOSE_BINDING_CHANGES")
+  else
+    if SVUI_KeyBindPopupCheckButton:GetChecked() then
+      LoadBindings(2)
+      SaveBindings(2)
+    else
+      LoadBindings(1)
+      SaveBindings(1)
+    end
+  end
+end
+
+local Save_OnClick = function(self)
+  MOD:ToggleKeyBindingMode(true, true)
+end
+
+local Discard_OnClick = function(self)
+  MOD:ToggleKeyBindingMode(true, false)
+end
+--[[ END OF HANDLERS ]]--
+
+local function SetBindingButton(button, force)
+  local click1 = StanceButton1:GetScript("OnClick")
+  local click2 = PetActionButton1:GetScript("OnClick")
+  local click3 = SecureActionButton_OnClick;
+  local button_OnClick = button:GetScript("OnClick")
+  if button_OnClick == click3 or force then
+    button:HookScript("OnEnter", Button_Proxy)
+  elseif button_OnClick == click1 then
+    button:HookScript("OnEnter", Stance_Proxy)
+  elseif button_OnClick == click2 then
+    button:HookScript("OnEnter", Pet_Proxy)
+  end
+end
+
+local function RefreshAllFlyouts()
+  local count = GetNumFlyouts()
+  for i = 1, count do
+    local id = GetFlyoutID(i)
+    local _,_,numSlots,isKnown = GetFlyoutInfo(id)
+    if isKnown then
+      for x = 1, numSlots do
+        local btnName = ("SpellFlyoutButton%d"):format(x)
+        local btn = _G[btnName]
+        if(SpellFlyout:IsShown() and btn and btn:IsShown()) then
+          if(not btn.hookedFlyout) then
+            btn:HookScript("OnEnter", Flyout_Proxy)
+            btn.hookedFlyout = true
+          end
+        end
+      end
+    end
+  end
+end
+
+function MOD:LoadKeyBinder()
+  self:RefreshActionBars()
+  -- Binder:SetParent(SV.Screen)
+  Binder:SetFrameStrata("DIALOG")
+  Binder:SetFrameLevel(99)
+  Binder:EnableMouse(true)
+  Binder:EnableKeyboard(true)
+  Binder:EnableMouseWheel(true)
+  Binder.texture = Binder:CreateTexture()
+  Binder.texture:SetAllPoints(Binder)
+  Binder.texture:SetColorTexture(0, 0, 0, .25)
+  Binder:Hide()
+
+  GameTooltip:HookScript("OnUpdate", GameTooltip_OnUpdate)
+  NewHook(GameTooltip, "Hide", GameTooltip_OnHide)
+
+  Binder:SetScript("OnEnter", BinderButton_OnEnter)
+  Binder:SetScript("OnLeave", BinderButton_OnLeave)
+  Binder:SetScript("OnKeyUp", Binder_OnBinding)
+  Binder:SetScript("OnMouseUp", Binder_OnBinding)
+  Binder:SetScript("OnMouseWheel", BinderButton_OnMouseWheel)
+
+  local OBJECT = EnumerateFrames()
+  while OBJECT do
+    if(OBJECT.IsProtected and OBJECT:IsProtected() and OBJECT.GetObjectType and OBJECT:GetObjectType() == "CheckButton" and OBJECT.GetScript) then
+      SetBindingButton(OBJECT)
+    end
+    OBJECT = EnumerateFrames(OBJECT)
+  end
+
+  for OBJECT, _ in pairs(self.ButtonCache)do
+    if(OBJECT.IsProtected and OBJECT:IsProtected() and OBJECT.GetObjectType and OBJECT:GetObjectType() == "CheckButton" and OBJECT.GetScript) then
+      SetBindingButton(OBJECT, true)
+    end
+  end
+
+  for i = 1, 12 do
+    local btnName = ("SpellButton%d"):format(i)
+    local spellButton = _G[btnName]
+    spellButton:HookScript("OnEnter", SpellButton_OnEnter)
+  end
+
+  if not IsAddOnLoaded("Blizzard_MacroUI")then
+    NewHook("LoadAddOn", SetBindingMacro)
+  else
+    for i=1,36 do
+      local btnName = ("MacroButton%d"):format(i)
+      local btn = _G[btnName]
+      btn:HookScript("OnEnter", Macro_Proxy)
+    end
+  end
+
+  NewHook("ActionButton_UpdateFlyout", RefreshAllFlyouts)
+  RefreshAllFlyouts()
+
+  local pop = NewFrame("Frame", "SVUI_KeyBindPopup", UIParent)
+  pop:SetFrameStrata("DIALOG")
+  pop:SetToplevel(true)
+  pop:EnableMouse(true)
+  pop:SetMovable(true)
+  pop:SetFrameLevel(99)
+  pop:SetClampedToScreen(true)
+  pop:SetWidth(360)
+  pop:SetHeight(130)
+  pop:SetStyle("!_Frame", "Transparent")
+  pop:Hide()
+
+  local moveHandle = NewFrame("Button", nil, pop)
+  moveHandle:SetStyle("!_Frame", "Button", true)
+  moveHandle:SetWidth(100)
+  moveHandle:SetHeight(25)
+  moveHandle:SetPoint("CENTER", pop, "TOP")
+  moveHandle:SetFrameLevel(moveHandle:GetFrameLevel() + 2)
+  moveHandle:EnableMouse(true)
+  moveHandle:RegisterForClicks("AnyUp", "AnyDown")
+  local onMouseDown = function() pop:StartMoving() end
+  moveHandle:SetScript("OnMouseDown", onMouseDown)
+  local onMouseUp = function() pop:StopMovingOrSizing() end
+  moveHandle:SetScript("OnMouseUp", onMouseUp)
+
+  local moveText = moveHandle:CreateFontString("OVERLAY")
+  moveText:SetFontObject(SVUI_Font_Default)
+  moveText:SetPoint("CENTER", moveHandle, "CENTER")
+  moveText:SetText("Key Binds")
+
+  local moveDesc = pop:CreateFontString("ARTWORK")
+  moveDesc:SetFontObject("GameFontHighlight")
+  moveDesc:SetJustifyV("TOP")
+  moveDesc:SetJustifyH("LEFT")
+  moveDesc:SetPoint("TOPLEFT", 18, -32)
+  moveDesc:SetPoint("BOTTOMRIGHT", -18, 48)
+  moveDesc:SetText(L["Hover your mouse over any actionbutton or spellbook button to bind it. Press the escape key or right click to clear the current actionbutton's keybinding."])
+
+  local checkButton = NewFrame("CheckButton", "SVUI_KeyBindPopupCheckButton", pop, "OptionsCheckButtonTemplate")
+  checkButton:SetStyle("CheckButton")
+  _G["SVUI_KeyBindPopupCheckButtonText"]:SetText(CHARACTER_SPECIFIC_KEYBINDINGS)
+  checkButton:SetScript("OnShow", Check_OnShow)
+  checkButton:SetScript("OnClick", Check_OnClick)
+  checkButton:SetScript("OnEnter", Check_OnEnter)
+  checkButton:SetScript("OnLeave", GameTooltip_Hide)
+
+  local saveButton = NewFrame("Button", "SVUI_KeyBindPopupSaveButton", pop, "OptionsButtonTemplate")
+  saveButton:SetWidth(150)
+  saveButton:SetStyle("Button")
+  _G["SVUI_KeyBindPopupSaveButtonText"]:SetText(L["Save"])
+  saveButton:SetScript("OnClick", Save_OnClick)
+
+  local discardButton = NewFrame("Button", "SVUI_KeyBindPopupDiscardButton", pop, "OptionsButtonTemplate")
+  discardButton:SetWidth(150)
+  discardButton:SetStyle("Button")
+  _G["SVUI_KeyBindPopupDiscardButtonText"]:SetText(L["Discard"])
+  discardButton:SetScript("OnClick", Discard_OnClick)
+
+  checkButton:SetPoint("BOTTOMLEFT", discardButton, "TOPLEFT", 0, 2)
+  saveButton:SetPoint("BOTTOMRIGHT", -14, 10)
+  discardButton:SetPoint("BOTTOMLEFT", 14, 10)
+
+  SV:AddSlashCommand("kb", "Toggle Key Binding Mode", MOD.ToggleKeyBindingMode);
+  SV:AddSlashCommand("bind", "Toggle Key Binding Mode", MOD.ToggleKeyBindingMode);
+
+  SV.SystemAlert["KEYBIND_MODE"] = {
+    text = L["Hover your mouse over any actionbutton or spellbook button to bind it. Press the escape key or right click to clear the current actionbutton's keybinding."],
+    button1 = L["Save"],
+    button2 = L["Discard"],
+    OnAccept = function() MOD:ToggleKeyBindingMode(true, true) end,
+    OnCancel = function() MOD:ToggleKeyBindingMode(true, false) end,
+    timeout = 0,
+    whileDead = 1,
+    hideOnEscape = false
+  };
+  SV.SystemAlert["CONFIRM_LOSE_BINDING_CHANGES"] = {
+    text = CONFIRM_LOSE_BINDING_CHANGES,
+    button1 = OKAY,
+    button2 = CANCEL,
+    OnAccept = function(a)
+      if checkButton:GetChecked() then
+        LoadBindings(2)
+        SaveBindings(2)
+      else
+        LoadBindings(1)
+        SaveBindings(1)
+      end
+      MOD.bindingsChanged = nil
+    end,
+    OnCancel = function(a)
+      if checkButton:GetChecked()then
+        checkButton:SetChecked(false)
+      else
+        checkButton:SetChecked(true)
+      end
+    end,
+    timeout = 0,
+    whileDead = 1,
+    state1 = 1
+  };
+end
\ No newline at end of file
diff --git a/SVUI_ActionBars/components/micro.lua b/SVUI_ActionBars/components/micro.lua
new file mode 100644
index 0000000..0aea9dc
--- /dev/null
+++ b/SVUI_ActionBars/components/micro.lua
@@ -0,0 +1,197 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local string 	= _G.string;
+local math 		= _G.math;
+--[[ STRING METHODS ]]--
+local find, format, split = string.find, string.format, string.split;
+local gsub = string.gsub;
+--[[ MATH METHODS ]]--
+local ceil = math.ceil;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L;
+local MOD = SV.ActionBars;
+--[[
+##########################################################
+LOCAL VARS
+##########################################################
+]]--
+local NewFrame = CreateFrame
+local NewHook = hooksecurefunc
+--[[
+##########################################################
+LOCAL FUNCTIONS
+##########################################################
+]]--
+local function RefreshMicrobar()
+	if not SVUI_MicroBar then return end
+	local lastParent = SVUI_MicroBar;
+	local buttonSize =  SV.db.ActionBars.Micro.buttonsize or 30;
+	local spacing =  SV.db.ActionBars.Micro.buttonspacing or 1;
+	local barWidth = (buttonSize + spacing) * 13;
+	SVUI_MicroBar_MOVE:SetSize(barWidth, buttonSize)
+	SVUI_MicroBar:SetAllPoints(SVUI_MicroBar_MOVE)
+	for i=1,13 do
+		local data = MOD.media.microMenuCoords[i]
+		local button = _G[data[1]]
+		if(button) then
+			button:ClearAllPoints()
+			button:SetSize(buttonSize, buttonSize + 28)
+			button._fade = SV.db.ActionBars.Micro.mouseover
+			if lastParent == SVUI_MicroBar then
+				button:SetPoint("BOTTOMLEFT", lastParent, "BOTTOMLEFT", 0, 0)
+			else
+				button:SetPoint("BOTTOMLEFT", lastParent, "BOTTOMRIGHT", spacing, 0)
+			end
+			lastParent = button;
+			button:Show()
+		end
+	end
+end
+
+local SVUIMicroButton_SetNormal = function()
+	local level = MainMenuMicroButton:GetFrameLevel()
+	if(level > 0) then
+		MainMenuMicroButton:SetFrameLevel(level - 1)
+	else
+		MainMenuMicroButton:SetFrameLevel(0)
+	end
+	MainMenuMicroButton:SetFrameStrata("BACKGROUND")
+	MainMenuMicroButton.overlay:SetFrameLevel(level + 1)
+	MainMenuMicroButton.overlay:SetFrameStrata("HIGH")
+	MainMenuBarPerformanceBar:Hide()
+	HelpMicroButton:Show()
+end
+
+local SVUIMicroButtonsParent = function(self)
+	if self ~= SVUI_MicroBar then
+		self = SVUI_MicroBar
+	end
+	for i=1,13 do
+		local data = MOD.media.microMenuCoords[i]
+		if(data) then
+			local mButton = _G[data[1]]
+			if(mButton) then mButton:SetParent(SVUI_MicroBar) end
+		end
+	end
+end
+
+local MicroButton_OnEnter = function(self)
+	if(self._fade) then
+		SVUI_MicroBar:FadeIn(0.2,SVUI_MicroBar:GetAlpha(),1)
+	end
+	if InCombatLockdown()then return end
+	self.overlay:SetPanelColor("highlight")
+	self.overlay.icon:SetGradient("VERTICAL", 0.75, 0.75, 0.75, 1, 1, 1)
+end
+
+local MicroButton_OnLeave = function(self)
+	if(self._fade) then
+		SVUI_MicroBar:FadeOut(1,SVUI_MicroBar:GetAlpha(),0)
+	end
+	if InCombatLockdown()then return end
+	self.overlay:SetPanelColor("default")
+	self.overlay.icon:SetGradient("VERTICAL", 0.5, 0.53, 0.55, 0.8, 0.8, 1)
+end
+--[[
+##########################################################
+BAR CREATION
+##########################################################
+]]--
+function MOD:UpdateMicroButtons()
+	if(not SV.db.ActionBars.Micro.mouseover) then
+		SVUI_MicroBar:SetAlpha(1)
+	else
+		SVUI_MicroBar:SetAlpha(0)
+	end
+	GuildMicroButtonTabard:ClearAllPoints();
+	GuildMicroButtonTabard:Hide();
+	RefreshMicrobar()
+end
+
+function MOD:InitializeMicroBar()
+	if(not SV.db.ActionBars.Micro.enable) then return end
+	local buttonSize = SV.db.ActionBars.Micro.buttonsize or 30;
+	local spacing =  SV.db.ActionBars.Micro.buttonspacing or 1;
+	local barWidth = (buttonSize + spacing) * 13;
+	local barHeight = (buttonSize + 6);
+	local microBar = NewFrame('Frame', 'SVUI_MicroBar', UIParent)
+	microBar:SetSize(barWidth, barHeight)
+	microBar:SetFrameStrata("HIGH")
+	microBar:SetFrameLevel(0)
+	microBar:SetPoint('BOTTOMLEFT', SV.Dock.TopLeft.Bar.ToolBar, 'BOTTOMRIGHT', 4, 0)
+	SV:ManageVisibility(microBar)
+
+	for i=1,13 do
+		local data = MOD.media.microMenuCoords[i]
+		if(data) then
+			local button = _G[data[1]]
+			if(button) then
+				button:SetParent(SVUI_MicroBar)
+				button:SetSize(buttonSize, buttonSize + 28)
+				button.Flash:SetTexture("")
+				if button.SetPushedTexture then
+					button:SetPushedTexture("")
+				end
+				if button.SetNormalTexture then
+					button:SetNormalTexture("")
+				end
+				if button.SetDisabledTexture then
+					button:SetDisabledTexture("")
+				end
+				if button.SetHighlightTexture then
+					button:SetHighlightTexture("")
+				end
+				button:RemoveTextures()
+
+				local buttonMask = NewFrame("Frame",nil,button)
+				buttonMask:SetPoint("TOPLEFT",button,"TOPLEFT",0,-28)
+				buttonMask:SetPoint("BOTTOMRIGHT",button,"BOTTOMRIGHT",0,0)
+				buttonMask:SetStyle("DockButton")
+				buttonMask:SetPanelColor()
+				buttonMask.icon = buttonMask:CreateTexture(nil,"OVERLAY",nil,2)
+				buttonMask.icon:InsetPoints(buttonMask,2,2)
+				buttonMask.icon:SetTexture(MOD.media.microMenuFile)
+				buttonMask.icon:SetTexCoord(data[2],data[3],data[4],data[5])
+				buttonMask.icon:SetGradient("VERTICAL", 0.5, 0.53, 0.55, 0.8, 0.8, 1)
+				button.overlay = buttonMask;
+				button._fade = SV.db.ActionBars.Micro.mouseover
+				button:HookScript('OnEnter', MicroButton_OnEnter)
+				button:HookScript('OnLeave', MicroButton_OnLeave)
+				button:Show()
+			end
+		end
+	end
+
+	MicroButtonPortrait:ClearAllPoints()
+	MicroButtonPortrait:Hide()
+	MainMenuBarPerformanceBar:ClearAllPoints()
+	MainMenuBarPerformanceBar:Hide()
+
+	NewHook('MainMenuMicroButton_SetNormal', SVUIMicroButton_SetNormal)
+	NewHook('UpdateMicroButtonsParent', SVUIMicroButtonsParent)
+	NewHook('MoveMicroButtons', RefreshMicrobar)
+	NewHook('UpdateMicroButtons', MOD.UpdateMicroButtons)
+
+	SVUIMicroButtonsParent(microBar)
+	SVUIMicroButton_SetNormal()
+
+	SV:NewAnchor(microBar, L["Micro Bar"])
+
+	RefreshMicrobar()
+	SVUI_MicroBar:SetAlpha(0)
+end
\ No newline at end of file
diff --git a/SVUI_ActionBars/components/totem.lua b/SVUI_ActionBars/components/totem.lua
new file mode 100644
index 0000000..c26aa4b
--- /dev/null
+++ b/SVUI_ActionBars/components/totem.lua
@@ -0,0 +1,195 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local ipairs 	= _G.ipairs;
+local type 		= _G.type;
+local math 		= _G.math;
+local cos, deg, rad, sin = math.cos, math.deg, math.rad, math.sin;
+local hooksecurefunc = _G.hooksecurefunc;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L;
+local MOD = SV.ActionBars;
+--[[
+##########################################################
+LOCALS
+##########################################################
+]]--
+local PlayerClass = select(2, UnitClass('player'))
+local TOTEM_PRIORITIES = STANDARD_TOTEM_PRIORITIES;
+local MOVER_NAME = L["Totem Bar"];
+if(PlayerClass == "SHAMAN") then
+	TOTEM_PRIORITIES = SHAMAN_TOTEM_PRIORITIES
+elseif(PlayerClass == "DEATHKNIGHT") then
+	MOVER_NAME = L["Ghoul Bar"]
+elseif(PlayerClass == "DRUID") then
+	MOVER_NAME = L["Mushroom Bar"]
+end
+--[[
+##########################################################
+TOTEMS
+##########################################################
+]]--
+local Totems = CreateFrame("Frame", "SVUI_TotemBar", UIParent);
+
+function Totems:Refresh()
+	for i = 1, MAX_TOTEMS do
+		local slot = TOTEM_PRIORITIES[i]
+		local haveTotem, name, start, duration, icon = GetTotemInfo(slot)
+		local svuitotem = _G["SVUI_TotemBarTotem"..slot]
+		if(haveTotem) then
+			svuitotem:Show()
+			svuitotem.Icon:SetTexture(icon)
+			CooldownFrame_Set(svuitotem.CD, start, duration, 1)
+			local blizztotem = _G["TotemFrameTotem"..slot]
+			local tslot = blizztotem.slot
+			if(tslot and tslot > 0) then
+				local anchor = _G["SVUI_TotemBarTotem"..tslot]
+				blizztotem:ClearAllPoints()
+				blizztotem:SetAllPoints(anchor)
+				blizztotem:SetFrameStrata(anchor:GetFrameStrata())
+				blizztotem:SetFrameLevel(anchor:GetFrameLevel() + 99)
+			end
+		else
+			svuitotem:Hide()
+		end
+	end
+end
+
+function Totems:Update()
+	local settings = SV.db.ActionBars.Totem;
+	local totemSize = settings.buttonsize;
+	local totemSpace = settings.buttonspacing;
+	local totemGrowth = settings.showBy;
+	local totemSort = settings.sortDirection;
+
+	for i = 1, MAX_TOTEMS do
+		local button = self[i]
+		if(button) then
+			local lastButton = self[i - 1]
+			button:SetSize(totemSize, totemSize)
+			button:ClearAllPoints()
+			if(totemGrowth == "HORIZONTAL" and totemSort == "ASCENDING") then
+				if(i == 1) then
+					button:SetPoint("LEFT", self, "LEFT", totemSpace, 0)
+				elseif lastButton then
+					button:SetPoint("LEFT", lastButton, "RIGHT", totemSpace, 0)
+				end
+			elseif(totemGrowth == "VERTICAL" and totemSort == "ASCENDING") then
+				if(i == 1) then
+					button:SetPoint("TOP", self, "TOP", 0, -totemSpace)
+				elseif lastButton then
+					button:SetPoint("TOP", lastButton, "BOTTOM", 0, -totemSpace)
+				end
+			elseif(totemGrowth == "HORIZONTAL" and totemSort == "DESCENDING") then
+				if(i == 1) then
+					button:SetPoint("RIGHT", self, "RIGHT", -totemSpace, 0)
+				elseif lastButton then
+					button:SetPoint("RIGHT", lastButton, "LEFT", -totemSpace, 0)
+				end
+			else
+				if(i == 1) then
+					button:SetPoint("BOTTOM", self, "BOTTOM", 0, totemSpace)
+				elseif lastButton then
+					button:SetPoint("BOTTOM", lastButton, "TOP", 0, totemSpace)
+				end
+			end
+		end
+	end
+
+	local calcWidth, calcHeight;
+	if(totemGrowth == "HORIZONTAL") then
+		calcWidth = ((totemSize * MAX_TOTEMS) + (totemSpace * MAX_TOTEMS) + totemSpace);
+		calcHeight = (totemSize + (totemSpace * 2));
+	else
+		calcWidth = (totemSize + (totemSpace * 2));
+		calcHeight = ((totemSize * MAX_TOTEMS) + (totemSpace * MAX_TOTEMS) + totemSpace);
+	end
+
+	self:SetSize(calcWidth, calcHeight);
+	self:Refresh()
+end
+
+local Totems_OnEnter = function(self)
+	if(not self:IsVisible()) then return end
+	GameTooltip:SetOwner(self, 'ANCHOR_BOTTOMRIGHT')
+	GameTooltip:SetTotem(self:GetID())
+end
+
+local Totems_OnLeave = function()
+	GameTooltip:Hide()
+end
+
+local Totems_OnEvent = function(self, event, ...)
+	self:Refresh()
+end
+
+local _hook_TotemFrame_OnUpdate = function()
+	for i=1, MAX_TOTEMS do
+		local slot = TOTEM_PRIORITIES[i]
+		local blizztotem = _G["TotemFrameTotem"..slot]
+		local tslot = blizztotem.slot
+		if(tslot and tslot > 0) then
+			local anchor = _G["SVUI_TotemBarTotem"..tslot]
+			blizztotem:ClearAllPoints()
+			blizztotem:SetAllPoints(anchor)
+			blizztotem:SetFrameStrata(anchor:GetFrameStrata())
+			blizztotem:SetFrameLevel(anchor:GetFrameLevel() + 99)
+		end
+	end
+end
+
+function MOD:InitializeTotemBar()
+	if(not SV.db.ActionBars.Totem.enable) then return; end
+
+	local xOffset = SV.db.Dock.dockLeftWidth + 12
+
+	Totems:SetPoint("BOTTOMLEFT", SV.Screen, "BOTTOMLEFT", xOffset, 40)
+
+	for i = 1, MAX_TOTEMS do
+		local slot = TOTEM_PRIORITIES[i]
+		local totem = CreateFrame("Button", "SVUI_TotemBarTotem"..slot, Totems)
+		totem:SetFrameStrata("BACKGROUND")
+		totem:SetID(slot)
+		totem:SetStyle("Frame", "Icon")
+		totem:Hide()
+
+		totem.Icon = totem:CreateTexture(nil, "ARTWORK")
+		totem.Icon:InsetPoints()
+		totem.Icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+		totem.CD = CreateFrame("Cooldown", "SVUI_TotemBarTotem"..slot.."Cooldown", totem, "CooldownFrameTemplate")
+		totem.CD:SetReverse(true)
+
+		totem.Anchor = CreateFrame("Frame", nil, totem)
+		totem.Anchor:SetAllPoints()
+
+		Totems[i] = totem
+	end
+
+	Totems:Show()
+	TotemFrame:Show()
+	TotemFrame.Hide = TotemFrame.Show
+	_G.TotemFrame_AdjustPetFrame = SV.fubar
+	hooksecurefunc("TotemFrame_Update", _hook_TotemFrame_OnUpdate)
+
+	Totems:RegisterEvent("PLAYER_TOTEM_UPDATE")
+	Totems:RegisterEvent("PLAYER_ENTERING_WORLD")
+	Totems:SetScript("OnEvent", Totems_OnEvent)
+
+	Totems:Update()
+
+	SV:NewAnchor(Totems, MOVER_NAME)
+end
diff --git a/SVUI_ActionBars/components/zone.lua b/SVUI_ActionBars/components/zone.lua
new file mode 100644
index 0000000..86d82c0
--- /dev/null
+++ b/SVUI_ActionBars/components/zone.lua
@@ -0,0 +1,310 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local string 	= _G.string;
+local math 		= _G.math;
+--[[ STRING METHODS ]]--
+local find, format, split = string.find, string.format, string.split;
+local gsub = string.gsub;
+--[[ MATH METHODS ]]--
+local ceil = math.ceil;
+--BLIZZARD API
+local PickupSpell       = _G.PickupSpell;
+local GetSpellInfo      = _G.GetSpellInfo;
+local GetSpellCharges   = _G.GetSpellCharges;
+local GetSpellCooldown  = _G.GetSpellCooldown;
+local GetTime           = _G.GetTime;
+local SpellHasRange     = _G.SpellHasRange;
+local GetBindingKey     = _G.GetBindingKey;
+local GetBindingText    = _G.GetBindingText;
+local CreateFrame       = _G.CreateFrame;
+local InCombatLockdown  = _G.InCombatLockdown;
+local GameTooltip       = _G.GameTooltip;
+local hooksecurefunc    = _G.hooksecurefunc;
+local IsAltKeyDown      = _G.IsAltKeyDown;
+local IsShiftKeyDown    = _G.IsShiftKeyDown;
+local IsControlKeyDown  = _G.IsControlKeyDown;
+local IsModifiedClick   = _G.IsModifiedClick;
+local RegisterStateDriver = _G.RegisterStateDriver;
+local RANGE_INDICATOR   = _G.RANGE_INDICATOR;
+local CooldownFrame_Set = _G.CooldownFrame_Set;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L;
+local MOD = SV.ActionBars;
+
+local NO_ART = SV.NoTexture;
+--[[
+##########################################################
+DRAENOR ZONE BUTTON INTERNALS
+##########################################################
+]]--
+local DraenorButton_OnDrag = function(self)
+	if(self.spellID) then
+		PickupSpell(DraenorZoneAbilitySpellID);
+	end
+end
+
+local DraenorButton_OnEvent = function(self, event)
+	if(event == "SPELLS_CHANGED") then
+		if(not self.baseName) then
+			self.baseName = GetSpellInfo(DraenorZoneAbilitySpellID);
+		end
+		self:UpdateCooldown()
+	elseif(event == 'PLAYER_REGEN_ENABLED') then
+		self:SetAttribute('spell', self.attribute)
+		self:UnregisterEvent(event)
+		self:UpdateCooldown()
+	elseif(event == 'UPDATE_BINDINGS') then
+		if(self:IsShown()) then
+			self:SetUsage()
+			self:SetAttribute('binding', GetTime())
+		end
+	else
+		self:Update()
+	end
+
+	if(not self.baseName) then
+		return;
+	end
+
+	local lastState = self.BuffSeen;
+	self.BuffSeen = HasDraenorZoneAbility();
+	local spellName, _, texture, _, _, _, spellID = GetSpellInfo(self.baseName);
+
+	if(self.BuffSeen) then
+		if(not HasDraenorZoneSpellOnBar(self)) then
+			self:SetUsage(spellID, spellName, texture);
+		else
+			self:ClearUsage();
+		end
+	else
+		DraenorZoneAbilityFrame.CurrentTexture = texture;
+		self:ClearUsage();
+	end
+
+	-- if(lastState ~= self.BuffSeen) then
+	-- 	UIParent_ManageFramePositions();
+	-- 	ActionBarController_UpdateAll(true);
+	-- end
+end
+
+local DraenorButtonUpdate = function(self)
+	if (not self.baseName) then
+		return;
+	end
+	local name, _, tex, _, _, _, spellID = GetSpellInfo(self.baseName);
+
+	DraenorZoneAbilityFrame.CurrentTexture = tex;
+	DraenorZoneAbilityFrame.CurrentSpell = name;
+
+	self.Icon:SetTexture(tex);
+	self.Artwork:SetTexture(DRAENOR_ZONE_SPELL_ABILITY_TEXTURES_BASE[spellID])
+
+	local charges, maxCharges, chargeStart, chargeDuration = GetSpellCharges(spellID);
+	local usesCharges = false;
+	if(self.Count) then
+		if(maxCharges and maxCharges > 1) then
+			self.Count:SetText(charges);
+			usesCharges = true;
+		else
+			self.Count:SetText("");
+		end
+	end
+
+	local start, duration, enable = GetSpellCooldown(name);
+
+	if(usesCharges and charges < maxCharges) then
+		CooldownFrame_Set(self.Cooldown, chargeStart, chargeDuration, enable, charges, maxCharges);
+	elseif(start) then
+		CooldownFrame_Set(self.Cooldown, start, duration, enable);
+	end
+
+	self.spellName = name;
+	self.spellID = spellID;
+end
+--[[
+##########################################################
+ZONE BUTTON CONSTRUCT
+##########################################################
+]]--
+local UpdateSpellCooldown = function(self)
+    if(self:IsShown() and self.spellName) then
+        local start, duration, enable = GetSpellCooldown(self.spellName)
+        if((start and start > 0) and (duration and duration > 0)) then
+            self.Cooldown:SetCooldown(start, duration)
+            self.Cooldown:Show()
+        else
+            self.Cooldown:Hide()
+        end
+    end
+end
+
+local SpellButton_OnEnter = function(self)
+    if(self.spellID) then
+        GameTooltip:SetOwner(self, 'ANCHOR_LEFT')
+        GameTooltip:SetSpellByID(self.spellID)
+    end
+end
+
+local ButtonSpell_OnEvent = function(self, event)
+    if(event == 'PLAYER_REGEN_ENABLED') then
+        self:SetAttribute('spell', self.attribute)
+        self:UnregisterEvent(event)
+        self:UpdateCooldown()
+    elseif(event == 'UPDATE_BINDINGS') then
+        if(self:IsShown()) then
+            self:SetUsage()
+            self:SetAttribute('binding', GetTime())
+        end
+    else
+        self:Update()
+    end
+end
+
+local SetButtonSpell = function(self, spellID, spellName, texture)
+    if(spellID and spellName) then
+        if(spellID == self.spellID and self:IsShown()) then
+            return false
+        end
+
+        self.Icon:SetTexture(texture)
+        self.spellID = spellID
+        self.spellName = spellName
+    end
+
+    local HotKey = self.HotKey
+    local key = GetBindingKey('SVUI_DRAENORZONE')
+    if(key) then
+        HotKey:SetText(GetBindingText(key, 1))
+        HotKey:Show()
+    elseif(self.spellName and SpellHasRange(self.spellName)) then
+        HotKey:SetText(RANGE_INDICATOR)
+        HotKey:Show()
+    else
+        HotKey:Hide()
+    end
+
+    if(InCombatLockdown()) then
+        self.attribute = self.spellName
+        self:RegisterEvent('PLAYER_REGEN_ENABLED')
+    else
+        self:SetAttribute('spell', self.spellName)
+        self:UpdateCooldown()
+    end
+
+    self:FadeIn()
+end
+
+local ClearButtonSpell = function(self)
+    self:FadeOut()
+    if(InCombatLockdown()) then
+        self.attribute = nil;
+        self:RegisterEvent('PLAYER_REGEN_ENABLED');
+    else
+        self:SetAttribute('spell', nil);
+    end
+end
+--[[
+##########################################################
+PACKAGE CALL
+##########################################################
+]]--
+function MOD:InitializeZoneButton()
+if(not DraenorZoneAbilityFrame) then return end;
+	local size = SVUI_DraenorButtonHolder:GetHeight()
+    local draenor = CreateFrame('Button', "SVUI_DraenorZoneAbility", UIParent, 'SecureActionButtonTemplate, SecureHandlerStateTemplate, SecureHandlerAttributeTemplate');
+    draenor:SetSize(size,size);
+    draenor:SetPoint("CENTER", SVUI_DraenorButtonHolder, "CENTER", 0, 0);
+    draenor:SetAlpha(0);
+    draenor:SetStyle("!_ActionSlot");
+
+    draenor.SetUsage = SetButtonSpell;
+    draenor.ClearUsage = ClearButtonSpell;
+    draenor.UpdateCooldown = UpdateSpellCooldown;
+    draenor.Update = DraenorButtonUpdate
+
+    local texture = DraenorZoneAbilityFrame.SpellButton.Style:GetTexture();
+    if(SV.Allegiance == 'Horde') then
+        texture = "Interface\\ExtraButton\\GarrZoneAbility-BarracksHorde";
+    end
+
+    local Artwork = draenor.Panel:CreateTexture('$parentArtwork', 'BACKGROUND')
+    Artwork:SetPoint('CENTER', -2, 2)
+    Artwork:SetSize(size * 4.2, size * 2.1)
+    Artwork:SetTexture(texture)
+    draenor.Artwork = Artwork
+
+    local Icon = draenor:CreateTexture('$parentIcon', 'BACKGROUND')
+    Icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+    Icon:SetAllPoints()
+    draenor.Icon = Icon
+
+    local HotKey = draenor:CreateFontString('$parentHotKey', nil, 'NumberFontNormal')
+    HotKey:SetPoint('BOTTOMRIGHT', -5, 5)
+    draenor.HotKey = HotKey
+
+    local Cooldown = CreateFrame('Cooldown', '$parentCooldown', draenor, 'CooldownFrameTemplate')
+    Cooldown:ClearAllPoints()
+    Cooldown:SetPoint('TOPRIGHT', -2, -3)
+    Cooldown:SetPoint('BOTTOMLEFT', 2, 1)
+    Cooldown:Hide()
+    draenor.Cooldown = Cooldown
+
+    RegisterStateDriver(draenor, 'visible', '[petbattle] hide; show')
+    draenor:SetAttribute('type', 'spell');
+    draenor:SetAttribute('_onattributechanged', [[
+        if(name == 'spell') then
+            if(value and not self:IsShown()) then
+                self:Show()
+            elseif(not value) then
+                self:Hide()
+            end
+        elseif(name == 'state-visible') then
+            if(value == 'show') then
+                self:CallMethod('Update')
+            else
+                self:Hide()
+            end
+        end
+
+        if(self:IsShown() and (name == 'item' or name == 'binding')) then
+			self:ClearBindings()
+			local key = GetBindingKey('SVUI_DRAENORZONE')
+			if(key) then
+				self:SetBindingClick(1, key, self, 'LeftButton')
+			end
+		end
+    ]]);
+
+  draenor:SetScript('OnEnter', SpellButton_OnEnter);
+  draenor:SetScript('OnLeave', GameTooltip_Hide);
+	draenor:RegisterForDrag("LeftButton");
+	draenor:SetScript('OnDragStart', DraenorButton_OnDrag);
+
+	draenor:RegisterUnitEvent("UNIT_AURA", "player");
+	draenor:RegisterEvent("SPELL_UPDATE_COOLDOWN");
+	draenor:RegisterEvent("SPELL_UPDATE_USABLE");
+	draenor:RegisterEvent("SPELL_UPDATE_CHARGES");
+	draenor:RegisterEvent("SPELLS_CHANGED");
+	draenor:RegisterEvent("ACTIONBAR_SLOT_CHANGED");
+	draenor:RegisterEvent("UPDATE_BINDINGS");
+    draenor:SetScript('OnEvent', DraenorButton_OnEvent);
+
+    SV:NewAnchor(draenor, L["Zone Ability Button"]);
+
+	DraenorZoneAbilityFrame:UnregisterAllEvents()
+end
diff --git a/SVUI_ActionBars/libs/CallbackHandler-1.0/CallbackHandler-1.0.lua b/SVUI_ActionBars/libs/CallbackHandler-1.0/CallbackHandler-1.0.lua
new file mode 100644
index 0000000..a127301
--- /dev/null
+++ b/SVUI_ActionBars/libs/CallbackHandler-1.0/CallbackHandler-1.0.lua
@@ -0,0 +1,240 @@
+--[[ $Id: CallbackHandler-1.0.lua 965 2010-08-09 00:47:52Z mikk $ ]]
+local MAJOR, MINOR = "CallbackHandler-1.0", 6
+local CallbackHandler = LibStub:NewLibrary(MAJOR, MINOR)
+
+if not CallbackHandler then return end -- No upgrade needed
+
+local meta = {__index = function(tbl, key) tbl[key] = {} return tbl[key] end}
+
+-- Lua APIs
+local tconcat = table.concat
+local assert, error, loadstring = assert, error, loadstring
+local setmetatable, rawset, rawget = setmetatable, rawset, rawget
+local next, select, pairs, type, tostring = next, select, pairs, type, tostring
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: geterrorhandler
+
+local xpcall = xpcall
+
+local function errorhandler(err)
+	return geterrorhandler()(err)
+end
+
+local function CreateDispatcher(argCount)
+	local code = [[
+	local next, xpcall, eh = ...
+
+	local method, ARGS
+	local function call() method(ARGS) end
+
+	local function dispatch(handlers, ...)
+		local index
+		index, method = next(handlers)
+		if not method then return end
+		local OLD_ARGS = ARGS
+		ARGS = ...
+		repeat
+			xpcall(call, eh)
+			index, method = next(handlers, index)
+		until not method
+		ARGS = OLD_ARGS
+	end
+
+	return dispatch
+	]]
+
+	local ARGS, OLD_ARGS = {}, {}
+	for i = 1, argCount do ARGS[i], OLD_ARGS[i] = "arg"..i, "old_arg"..i end
+	code = code:gsub("OLD_ARGS", tconcat(OLD_ARGS, ", ")):gsub("ARGS", tconcat(ARGS, ", "))
+	return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(next, xpcall, errorhandler)
+end
+
+local Dispatchers = setmetatable({}, {__index=function(self, argCount)
+	local dispatcher = CreateDispatcher(argCount)
+	rawset(self, argCount, dispatcher)
+	return dispatcher
+end})
+
+--------------------------------------------------------------------------
+-- CallbackHandler:New
+--
+--   target            - target object to embed public APIs in
+--   RegisterName      - name of the callback registration API, default "RegisterCallback"
+--   UnregisterName    - name of the callback unregistration API, default "UnregisterCallback"
+--   UnregisterAllName - name of the API to unregister all callbacks, default "UnregisterAllCallbacks". false == don't publish this API.
+
+function CallbackHandler:New(target, RegisterName, UnregisterName, UnregisterAllName, OnUsed, OnUnused)
+	-- TODO: Remove this after beta has gone out
+	assert(not OnUsed and not OnUnused, "ACE-80: OnUsed/OnUnused are deprecated. Callbacks are now done to registry.OnUsed and registry.OnUnused")
+
+	RegisterName = RegisterName or "RegisterCallback"
+	UnregisterName = UnregisterName or "UnregisterCallback"
+	if UnregisterAllName==nil then	-- false is used to indicate "don't want this method"
+		UnregisterAllName = "UnregisterAllCallbacks"
+	end
+
+	-- we declare all objects and exported APIs inside this closure to quickly gain access
+	-- to e.g. function names, the "target" parameter, etc
+
+
+	-- Create the registry object
+	local events = setmetatable({}, meta)
+	local registry = { recurse=0, events=events }
+
+	-- registry:Fire() - fires the given event/message into the registry
+	function registry:Fire(eventname, ...)
+		if not rawget(events, eventname) or not next(events[eventname]) then return end
+		local oldrecurse = registry.recurse
+		registry.recurse = oldrecurse + 1
+
+		Dispatchers[select('#', ...) + 1](events[eventname], eventname, ...)
+
+		registry.recurse = oldrecurse
+
+		if registry.insertQueue and oldrecurse==0 then
+			-- Something in one of our callbacks wanted to register more callbacks; they got queued
+			for eventname,callbacks in pairs(registry.insertQueue) do
+				local first = not rawget(events, eventname) or not next(events[eventname])	-- test for empty before. not test for one member after. that one member may have been overwritten.
+				for self,func in pairs(callbacks) do
+					events[eventname][self] = func
+					-- fire OnUsed callback?
+					if first and registry.OnUsed then
+						registry.OnUsed(registry, target, eventname)
+						first = nil
+					end
+				end
+			end
+			registry.insertQueue = nil
+		end
+	end
+
+	-- Registration of a callback, handles:
+	--   self["method"], leads to self["method"](self, ...)
+	--   self with function ref, leads to functionref(...)
+	--   "addonId" (instead of self) with function ref, leads to functionref(...)
+	-- all with an optional arg, which, if present, gets passed as first argument (after self if present)
+	target[RegisterName] = function(self, eventname, method, ... --[[actually just a single arg]])
+		if type(eventname) ~= "string" then
+			error("Usage: "..RegisterName.."(eventname, method[, arg]): 'eventname' - string expected.", 2)
+		end
+
+		method = method or eventname
+
+		local first = not rawget(events, eventname) or not next(events[eventname])	-- test for empty before. not test for one member after. that one member may have been overwritten.
+
+		if type(method) ~= "string" and type(method) ~= "function" then
+			error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - string or function expected.", 2)
+		end
+
+		local regfunc
+
+		if type(method) == "string" then
+			-- self["method"] calling style
+			if type(self) ~= "table" then
+				error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): self was not a table?", 2)
+			elseif self==target then
+				error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): do not use Library:"..RegisterName.."(), use your own 'self'", 2)
+			elseif type(self[method]) ~= "function" then
+				error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - method '"..tostring(method).."' not found on self.", 2)
+			end
+
+			if select("#",...)>=1 then	-- this is not the same as testing for arg==nil!
+				local arg=select(1,...)
+				regfunc = function(...) self[method](self,arg,...) end
+			else
+				regfunc = function(...) self[method](self,...) end
+			end
+		else
+			-- function ref with self=object or self="addonId" or self=thread
+			if type(self)~="table" and type(self)~="string" and type(self)~="thread" then
+				error("Usage: "..RegisterName.."(self or \"addonId\", eventname, method): 'self or addonId': table or string or thread expected.", 2)
+			end
+
+			if select("#",...)>=1 then	-- this is not the same as testing for arg==nil!
+				local arg=select(1,...)
+				regfunc = function(...) method(arg,...) end
+			else
+				regfunc = method
+			end
+		end
+
+
+		if events[eventname][self] or registry.recurse<1 then
+		-- if registry.recurse<1 then
+			-- we're overwriting an existing entry, or not currently recursing. just set it.
+			events[eventname][self] = regfunc
+			-- fire OnUsed callback?
+			if registry.OnUsed and first then
+				registry.OnUsed(registry, target, eventname)
+			end
+		else
+			-- we're currently processing a callback in this registry, so delay the registration of this new entry!
+			-- yes, we're a bit wasteful on garbage, but this is a fringe case, so we're picking low implementation overhead over garbage efficiency
+			registry.insertQueue = registry.insertQueue or setmetatable({},meta)
+			registry.insertQueue[eventname][self] = regfunc
+		end
+	end
+
+	-- Unregister a callback
+	target[UnregisterName] = function(self, eventname)
+		if not self or self==target then
+			error("Usage: "..UnregisterName.."(eventname): bad 'self'", 2)
+		end
+		if type(eventname) ~= "string" then
+			error("Usage: "..UnregisterName.."(eventname): 'eventname' - string expected.", 2)
+		end
+		if rawget(events, eventname) and events[eventname][self] then
+			events[eventname][self] = nil
+			-- Fire OnUnused callback?
+			if registry.OnUnused and not next(events[eventname]) then
+				registry.OnUnused(registry, target, eventname)
+			end
+		end
+		if registry.insertQueue and rawget(registry.insertQueue, eventname) and registry.insertQueue[eventname][self] then
+			registry.insertQueue[eventname][self] = nil
+		end
+	end
+
+	-- OPTIONAL: Unregister all callbacks for given selfs/addonIds
+	if UnregisterAllName then
+		target[UnregisterAllName] = function(...)
+			if select("#",...)<1 then
+				error("Usage: "..UnregisterAllName.."([whatFor]): missing 'self' or \"addonId\" to unregister events for.", 2)
+			end
+			if select("#",...)==1 and ...==target then
+				error("Usage: "..UnregisterAllName.."([whatFor]): supply a meaningful 'self' or \"addonId\"", 2)
+			end
+
+
+			for i=1,select("#",...) do
+				local self = select(i,...)
+				if registry.insertQueue then
+					for eventname, callbacks in pairs(registry.insertQueue) do
+						if callbacks[self] then
+							callbacks[self] = nil
+						end
+					end
+				end
+				for eventname, callbacks in pairs(events) do
+					if callbacks[self] then
+						callbacks[self] = nil
+						-- Fire OnUnused callback?
+						if registry.OnUnused and not next(callbacks) then
+							registry.OnUnused(registry, target, eventname)
+						end
+					end
+				end
+			end
+		end
+	end
+
+	return registry
+end
+
+
+-- CallbackHandler purposefully does NOT do explicit embedding. Nor does it
+-- try to upgrade old implicit embeds since the system is selfcontained and
+-- relies on closures to work.
+
diff --git a/SVUI_ActionBars/libs/LibActionButton-1.0/LibActionButton-1.0.lua b/SVUI_ActionBars/libs/LibActionButton-1.0/LibActionButton-1.0.lua
new file mode 100644
index 0000000..6a1d6eb
--- /dev/null
+++ b/SVUI_ActionBars/libs/LibActionButton-1.0/LibActionButton-1.0.lua
@@ -0,0 +1,1624 @@
+--[[
+Copyright (c) 2010-2014, Hendrik "nevcairiel" Leppkes <h.leppkes@gmail.com>
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+    * Neither the name of the developer nor the names of its contributors
+      may be used to endorse or promote products derived from this software without
+      specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+]]
+local MAJOR_VERSION = "LibActionButton-1.0"
+local MINOR_VERSION = 57
+
+if not LibStub then error(MAJOR_VERSION .. " requires LibStub.") end
+local lib, oldversion = LibStub:NewLibrary(MAJOR_VERSION, MINOR_VERSION)
+if not lib then return end
+
+-- Lua functions
+local _G = _G
+local type, error, tostring, tonumber, assert, select = type, error, tostring, tonumber, assert, select
+local setmetatable, wipe, unpack, pairs, next = setmetatable, wipe, unpack, pairs, next
+local str_match, format, tinsert, tremove = string.match, format, tinsert, tremove
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- Note: No WoW API function get upvalued to allow proper interaction with any addons that try to hook them.
+-- GLOBALS: LibStub, CreateFrame, InCombatLockdown, ClearCursor, GetCursorInfo, GameTooltip, GameTooltip_SetDefaultAnchor
+-- GLOBALS: GetBindingKey, GetBindingText, SetBinding, SetBindingClick, GetCVar, GetMacroInfo
+-- GLOBALS: PickupAction, PickupItem, PickupMacro, PickupPetAction, PickupSpell, PickupCompanion, PickupEquipmentSet
+-- GLOBALS: CooldownFrame_Set, UIParent, IsSpellOverlayed, SpellFlyout, GetMouseFocus, SetClampedTextureRotation
+-- GLOBALS: GetActionInfo, GetActionTexture, HasAction, GetActionText, GetActionCount, GetActionCooldown, IsAttackAction
+-- GLOBALS: IsAutoRepeatAction, IsEquippedAction, IsCurrentAction, IsConsumableAction, IsUsableAction, IsStackableAction, IsActionInRange
+-- GLOBALS: GetSpellLink, GetMacroSpell, GetSpellTexture, GetSpellCount, GetSpellCooldown, IsAttackSpell, IsCurrentSpell
+-- GLOBALS: FindSpellBookSlotBySpellID, IsUsableSpell, IsConsumableSpell, IsSpellInRange, IsAutoRepeatSpell
+-- GLOBALS: GetItemIcon, GetItemCount, GetItemCooldown, IsEquippedItem, IsCurrentItem, IsUsableItem, IsConsumableItem, IsItemInRange
+-- GLOBALS: GetActionCharges, IsItemAction, GetSpellCharges
+-- GLOBALS: RANGE_INDICATOR, ATTACK_BUTTON_FLASH_TIME, TOOLTIP_UPDATE_TIME
+
+local KeyBound = LibStub("LibKeyBound-1.0", true)
+local CBH = LibStub("CallbackHandler-1.0")
+
+lib.eventFrame = lib.eventFrame or CreateFrame("Frame")
+lib.eventFrame:UnregisterAllEvents()
+
+lib.buttonRegistry = lib.buttonRegistry or {}
+lib.activeButtons = lib.activeButtons or {}
+lib.actionButtons = lib.actionButtons or {}
+lib.nonActionButtons = lib.nonActionButtons or {}
+
+lib.ChargeCooldowns = lib.ChargeCooldowns or {}
+lib.NumChargeCooldowns = lib.NumChargeCooldowns or 0
+
+lib.unusedOverlayGlows = lib.unusedOverlayGlows or {}
+lib.numOverlays = lib.numOverlays or 0
+
+lib.ACTION_HIGHLIGHT_MARKS = lib.ACTION_HIGHLIGHT_MARKS or setmetatable({}, { __index = ACTION_HIGHLIGHT_MARKS })
+
+lib.callbacks = lib.callbacks or CBH:New(lib)
+
+local Generic = CreateFrame("CheckButton")
+local Generic_MT = {__index = Generic}
+
+local Action = setmetatable({}, {__index = Generic})
+local Action_MT = {__index = Action}
+
+local PetAction = setmetatable({}, {__index = Generic})
+local PetAction_MT = {__index = PetAction}
+
+local Spell = setmetatable({}, {__index = Generic})
+local Spell_MT = {__index = Spell}
+
+local Item = setmetatable({}, {__index = Generic})
+local Item_MT = {__index = Item}
+
+local Macro = setmetatable({}, {__index = Generic})
+local Macro_MT = {__index = Macro}
+
+local Custom = setmetatable({}, {__index = Generic})
+local Custom_MT = {__index = Custom}
+
+local type_meta_map = {
+	empty  = Generic_MT,
+	action = Action_MT,
+	--pet    = PetAction_MT,
+	spell  = Spell_MT,
+	item   = Item_MT,
+	macro  = Macro_MT,
+	custom = Custom_MT
+}
+
+local ButtonRegistry, ActiveButtons, ActionButtons, NonActionButtons = lib.buttonRegistry, lib.activeButtons, lib.actionButtons, lib.nonActionButtons
+
+local Update, UpdateButtonState, UpdateUsable, UpdateCount, UpdateCooldown, UpdateTooltip, UpdateNewAction
+local StartFlash, StopFlash, UpdateFlash, UpdateHotkeys, UpdateRangeTimer, UpdateOverlayGlow
+local UpdateFlyout, ShowGrid, HideGrid, UpdateGrid, SetupSecureSnippets, WrapOnClick
+local ShowOverlayGlow, HideOverlayGlow, GetOverlayGlow, OverlayGlowAnimOutFinished
+local HookCooldown
+
+local InitializeEventHandler, OnEvent, ForAllButtons, OnUpdate
+
+local DefaultConfig = {
+	outOfRangeColoring = "button",
+	tooltip = "enabled",
+	showGrid = false,
+	colors = {
+		range = { 0.8, 0.1, 0.1 },
+		mana = { 0.5, 0.5, 1.0 }
+	},
+	hideElements = {
+		macro = false,
+		hotkey = false,
+		equipped = false,
+	},
+	keyBoundTarget = false,
+	clickOnDown = false,
+	flyoutDirection = "UP",
+}
+
+--- Create a new action button.
+-- @param id Internal id of the button (not used by LibActionButton-1.0, only for tracking inside the calling addon)
+-- @param name Name of the button frame to be created (not used by LibActionButton-1.0 aside from naming the frame)
+-- @param header Header that drives these action buttons (if any)
+function lib:CreateButton(id, name, header, config)
+	if type(name) ~= "string" then
+		error("Usage: CreateButton(id, name. header): Buttons must have a valid name!", 2)
+	end
+	if not header then
+		error("Usage: CreateButton(id, name, header): Buttons without a secure header are not yet supported!", 2)
+	end
+
+	if not KeyBound then
+		KeyBound = LibStub("LibKeyBound-1.0", true)
+	end
+
+	local button = setmetatable(CreateFrame("CheckButton", name, header, "SecureActionButtonTemplate, ActionButtonTemplate"), Generic_MT)
+	button:RegisterForDrag("LeftButton", "RightButton")
+	button:RegisterForClicks("AnyUp")
+
+	-- Frame Scripts
+	button:SetScript("OnEnter", Generic.OnEnter)
+	button:SetScript("OnLeave", Generic.OnLeave)
+	button:SetScript("PreClick", Generic.PreClick)
+	button:SetScript("PostClick", Generic.PostClick)
+
+	button.id = id
+	button.header = header
+	-- Mapping of state -> action
+	button.state_types = {}
+	button.state_actions = {}
+
+	-- Store the LAB Version that created this button for debugging
+	button.__LAB_Version = MINOR_VERSION
+
+	-- just in case we're not run by a header, default to state 0
+	button:SetAttribute("state", 0)
+
+	SetupSecureSnippets(button)
+	WrapOnClick(button)
+
+	-- adjust hotkey style for better readability
+	button.HotKey:SetFont(button.HotKey:GetFont(), 13, "OUTLINE")
+	button.HotKey:SetVertexColor(0.75, 0.75, 0.75)
+
+	-- adjust count/stack size
+	button.Count:SetFont(button.Count:GetFont(), 16, "OUTLINE")
+
+	-- hook Cooldown stuff for alpha fix in 6.0
+	HookCooldown(button)
+
+	-- Store the button in the registry, needed for event and OnUpdate handling
+	if not next(ButtonRegistry) then
+		InitializeEventHandler()
+	end
+	ButtonRegistry[button] = true
+
+	button:UpdateConfig(config)
+
+	-- run an initial update
+	button:UpdateAction()
+	UpdateHotkeys(button)
+
+	-- somewhat of a hack for the Flyout buttons to not error.
+	button.action = 0
+
+	lib.callbacks:Fire("OnButtonCreated", button)
+
+	return button
+end
+
+function SetupSecureSnippets(button)
+	button:SetAttribute("_custom", Custom.RunCustom)
+	-- secure UpdateState(self, state)
+	-- update the type and action of the button based on the state
+	button:SetAttribute("UpdateState", [[
+		local state = ...
+		self:SetAttribute("state", state)
+		local type, action = (self:GetAttribute(format("labtype-%s", state)) or "empty"), self:GetAttribute(format("labaction-%s", state))
+
+		self:SetAttribute("type", type)
+		if type ~= "empty" and type ~= "custom" then
+			local action_field = (type == "pet") and "action" or type
+			self:SetAttribute(action_field, action)
+			self:SetAttribute("action_field", action_field)
+		end
+		local onStateChanged = self:GetAttribute("OnStateChanged")
+		if onStateChanged then
+			self:Run(onStateChanged, state, type, action)
+		end
+	]])
+
+	-- this function is invoked by the header when the state changes
+	button:SetAttribute("_childupdate-state", [[
+		self:RunAttribute("UpdateState", message)
+		self:CallMethod("UpdateAction")
+	]])
+
+	-- secure PickupButton(self, kind, value, ...)
+	-- utility function to place a object on the cursor
+	button:SetAttribute("PickupButton", [[
+		local kind, value = ...
+		if kind == "empty" then
+			return "clear"
+		elseif kind == "action" or kind == "pet" then
+			local actionType = (kind == "pet") and "petaction" or kind
+			return actionType, value
+		elseif kind == "spell" or kind == "item" or kind == "macro" then
+			return "clear", kind, value
+		else
+			print("LibActionButton-1.0: Unknown type: " .. tostring(kind))
+			return false
+		end
+	]])
+
+	button:SetAttribute("OnDragStart", [[
+		if (self:GetAttribute("buttonlock") and not IsModifiedClick("PICKUPACTION")) or self:GetAttribute("LABdisableDragNDrop") then return false end
+		local state = self:GetAttribute("state")
+		local type = self:GetAttribute("type")
+		-- if the button is empty, we can't drag anything off it
+		if type == "empty" or type == "custom" then
+			return false
+		end
+		-- Get the value for the action attribute
+		local action_field = self:GetAttribute("action_field")
+		local action = self:GetAttribute(action_field)
+
+		-- non-action fields need to change their type to empty
+		if type ~= "action" and type ~= "pet" then
+			self:SetAttribute(format("labtype-%s", state), "empty")
+			self:SetAttribute(format("labaction-%s", state), nil)
+			-- update internal state
+			self:RunAttribute("UpdateState", state)
+			-- send a notification to the insecure code
+			self:CallMethod("ButtonContentsChanged", state, "empty", nil)
+		end
+		-- return the button contents for pickup
+		return self:RunAttribute("PickupButton", type, action)
+	]])
+
+	button:SetAttribute("OnReceiveDrag", [[
+		if self:GetAttribute("LABdisableDragNDrop") then return false end
+		local kind, value, subtype, extra = ...
+		if not kind or not value then return false end
+		local state = self:GetAttribute("state")
+		local buttonType, buttonAction = self:GetAttribute("type"), nil
+		if buttonType == "custom" then return false end
+		-- action buttons can do their magic themself
+		-- for all other buttons, we'll need to update the content now
+		if buttonType ~= "action" and buttonType ~= "pet" then
+			-- with "spell" types, the 4th value contains the actual spell id
+			if kind == "spell" then
+				if extra then
+					value = extra
+				else
+					print("no spell id?", ...)
+				end
+			elseif kind == "item" and value then
+				value = format("item:%d", value)
+			end
+
+			-- Get the action that was on the button before
+			if buttonType ~= "empty" then
+				buttonAction = self:GetAttribute(self:GetAttribute("action_field"))
+			end
+
+			-- TODO: validate what kind of action is being fed in here
+			-- We can only use a handful of the possible things on the cursor
+			-- return false for all those we can't put on buttons
+
+			self:SetAttribute(format("labtype-%s", state), kind)
+			self:SetAttribute(format("labaction-%s", state), value)
+			-- update internal state
+			self:RunAttribute("UpdateState", state)
+			-- send a notification to the insecure code
+			self:CallMethod("ButtonContentsChanged", state, kind, value)
+		else
+			-- get the action for (pet-)action buttons
+			buttonAction = self:GetAttribute("action")
+		end
+		return self:RunAttribute("PickupButton", buttonType, buttonAction)
+	]])
+
+	button:SetScript("OnDragStart", nil)
+	-- Wrapped OnDragStart(self, button, kind, value, ...)
+	button.header:WrapScript(button, "OnDragStart", [[
+		return self:RunAttribute("OnDragStart")
+	]])
+	-- Wrap twice, because the post-script is not run when the pre-script causes a pickup (doh)
+	-- we also need some phony message, or it won't work =/
+	button.header:WrapScript(button, "OnDragStart", [[
+		return "message", "update"
+	]], [[
+		self:RunAttribute("UpdateState", self:GetAttribute("state"))
+	]])
+
+	button:SetScript("OnReceiveDrag", nil)
+	-- Wrapped OnReceiveDrag(self, button, kind, value, ...)
+	button.header:WrapScript(button, "OnReceiveDrag", [[
+		return self:RunAttribute("OnReceiveDrag", kind, value, ...)
+	]])
+	-- Wrap twice, because the post-script is not run when the pre-script causes a pickup (doh)
+	-- we also need some phony message, or it won't work =/
+	button.header:WrapScript(button, "OnReceiveDrag", [[
+		return "message", "update"
+	]], [[
+		self:RunAttribute("UpdateState", self:GetAttribute("state"))
+	]])
+end
+
+function WrapOnClick(button)
+	-- Wrap OnClick, to catch changes to actions that are applied with a click on the button.
+	button.header:WrapScript(button, "OnClick", [[
+		if self:GetAttribute("type") == "action" then
+			local type, action = GetActionInfo(self:GetAttribute("action"))
+			return nil, format("%s|%s", tostring(type), tostring(action))
+		end
+	]], [[
+		local type, action = GetActionInfo(self:GetAttribute("action"))
+		if message ~= format("%s|%s", tostring(type), tostring(action)) then
+			self:RunAttribute("UpdateState", self:GetAttribute("state"))
+		end
+	]])
+end
+
+-----------------------------------------------------------
+--- utility
+
+function lib:GetAllButtons()
+	local buttons = {}
+	for button in next, ButtonRegistry do
+		buttons[button] = true
+	end
+	return buttons
+end
+
+function Generic:ClearSetPoint(...)
+	self:ClearAllPoints()
+	self:SetPoint(...)
+end
+
+function Generic:NewHeader(header)
+	self.header = header
+	self:SetParent(header)
+	SetupSecureSnippets(self)
+	WrapOnClick(self)
+end
+
+
+-----------------------------------------------------------
+--- state management
+
+function Generic:ClearStates()
+	for state in pairs(self.state_types) do
+		self:SetAttribute(format("labtype-%s", state), nil)
+		self:SetAttribute(format("labaction-%s", state), nil)
+	end
+	wipe(self.state_types)
+	wipe(self.state_actions)
+end
+
+function Generic:SetState(state, kind, action)
+	if not state then state = self:GetAttribute("state") end
+	state = tostring(state)
+	-- we allow a nil kind for setting a empty state
+	if not kind then kind = "empty" end
+	if not type_meta_map[kind] then
+		error("SetStateAction: unknown action type: " .. tostring(kind), 2)
+	end
+	if kind ~= "empty" and action == nil then
+		error("SetStateAction: an action is required for non-empty states", 2)
+	end
+	if kind ~= "custom" and action ~= nil and type(action) ~= "number" and type(action) ~= "string" or (kind == "custom" and type(action) ~= "table") then
+		error("SetStateAction: invalid action data type, only strings and numbers allowed", 2)
+	end
+
+	if kind == "item" then
+		if tonumber(action) then
+			action = format("item:%s", action)
+		else
+			local itemString = str_match(action, "^|c%x+|H(item[%d:]+)|h%[")
+			if itemString then
+				action = itemString
+			end
+		end
+	end
+
+	self.state_types[state] = kind
+	self.state_actions[state] = action
+	self:UpdateState(state)
+end
+
+function Generic:UpdateState(state)
+	if not state then state = self:GetAttribute("state") end
+	state = tostring(state)
+	self:SetAttribute(format("labtype-%s", state), self.state_types[state])
+	self:SetAttribute(format("labaction-%s", state), self.state_actions[state])
+	if state ~= tostring(self:GetAttribute("state")) then return end
+	if self.header then
+		self.header:SetFrameRef("updateButton", self)
+		self.header:Execute([[
+			local frame = self:GetFrameRef("updateButton")
+			control:RunFor(frame, frame:GetAttribute("UpdateState"), frame:GetAttribute("state"))
+		]])
+	else
+	-- TODO
+	end
+	self:UpdateAction()
+end
+
+function Generic:GetAction(state)
+	if not state then state = self:GetAttribute("state") end
+	state = tostring(state)
+	return self.state_types[state] or "empty", self.state_actions[state]
+end
+
+function Generic:UpdateAllStates()
+	for state in pairs(self.state_types) do
+		self:UpdateState(state)
+	end
+end
+
+function Generic:ButtonContentsChanged(state, kind, value)
+	state = tostring(state)
+	self.state_types[state] = kind or "empty"
+	self.state_actions[state] = value
+	lib.callbacks:Fire("OnButtonContentsChanged", self, state, self.state_types[state], self.state_actions[state])
+	self:UpdateAction(self)
+end
+
+function Generic:DisableDragNDrop(flag)
+	if InCombatLockdown() then
+		error("LibActionButton-1.0: You can only toggle DragNDrop out of combat!", 2)
+	end
+	if flag then
+		self:SetAttribute("LABdisableDragNDrop", true)
+	else
+		self:SetAttribute("LABdisableDragNDrop", nil)
+	end
+end
+
+function Generic:AddToButtonFacade(group)
+	if type(group) ~= "table" or type(group.AddButton) ~= "function" then
+		error("LibActionButton-1.0:AddToButtonFacade: You need to supply a proper group to use!", 2)
+	end
+	group:AddButton(self)
+	self.LBFSkinned = true
+end
+
+function Generic:AddToMasque(group)
+	if type(group) ~= "table" or type(group.AddButton) ~= "function" then
+		error("LibActionButton-1.0:AddToMasque: You need to supply a proper group to use!", 2)
+	end
+	group:AddButton(self)
+	self.MasqueSkinned = true
+end
+
+function Generic:UpdateAlpha()
+	UpdateCooldown(self)
+end
+
+-----------------------------------------------------------
+--- frame scripts
+
+-- copied (and adjusted) from SecureHandlers.lua
+local function PickupAny(kind, target, detail, ...)
+	if kind == "clear" then
+		ClearCursor()
+		kind, target, detail = target, detail, ...
+	end
+
+	if kind == 'action' then
+		PickupAction(target)
+	elseif kind == 'item' then
+		PickupItem(target)
+	elseif kind == 'macro' then
+		PickupMacro(target)
+	elseif kind == 'petaction' then
+		PickupPetAction(target)
+	elseif kind == 'spell' then
+		PickupSpell(target)
+	elseif kind == 'companion' then
+		PickupCompanion(target, detail)
+	elseif kind == 'equipmentset' then
+		PickupEquipmentSet(target)
+	end
+end
+
+function Generic:OnEnter()
+	if self.config.tooltip ~= "disabled" and (self.config.tooltip ~= "nocombat" or not InCombatLockdown()) then
+		UpdateTooltip(self)
+	end
+	if KeyBound then
+		KeyBound:Set(self)
+	end
+
+	if self._state_type == "action" and self.NewActionTexture then
+		lib.ACTION_HIGHLIGHT_MARKS[self._state_action] = false
+		UpdateNewAction(self)
+	end
+end
+
+function Generic:OnLeave()
+	GameTooltip:Hide()
+end
+
+-- Insecure drag handler to allow clicking on the button with an action on the cursor
+-- to place it on the button. Like action buttons work.
+function Generic:PreClick()
+	if self._state_type == "action" or self._state_type == "pet"
+	   or InCombatLockdown() or self:GetAttribute("LABdisableDragNDrop")
+	then
+		return
+	end
+	-- check if there is actually something on the cursor
+	local kind, value, subtype = GetCursorInfo()
+	if not (kind and value) then return end
+	self._old_type = self._state_type
+	if self._state_type and self._state_type ~= "empty" then
+		self._old_type = self._state_type
+		self:SetAttribute("type", "empty")
+		--self:SetState(nil, "empty", nil)
+	end
+	self._receiving_drag = true
+end
+
+local function formatHelper(input)
+	if type(input) == "string" then
+		return format("%q", input)
+	else
+		return tostring(input)
+	end
+end
+
+function Generic:PostClick()
+	UpdateButtonState(self)
+	if self._receiving_drag and not InCombatLockdown() then
+		if self._old_type then
+			self:SetAttribute("type", self._old_type)
+			self._old_type = nil
+		end
+		local oldType, oldAction = self._state_type, self._state_action
+		local kind, data, subtype, extra = GetCursorInfo()
+		self.header:SetFrameRef("updateButton", self)
+		self.header:Execute(format([[
+			local frame = self:GetFrameRef("updateButton")
+			control:RunFor(frame, frame:GetAttribute("OnReceiveDrag"), %s, %s, %s, %s)
+			control:RunFor(frame, frame:GetAttribute("UpdateState"), %s)
+		]], formatHelper(kind), formatHelper(data), formatHelper(subtype), formatHelper(extra), formatHelper(self:GetAttribute("state"))))
+		PickupAny("clear", oldType, oldAction)
+	end
+	self._receiving_drag = nil
+end
+
+-----------------------------------------------------------
+--- configuration
+
+local function merge(target, source, default)
+	for k,v in pairs(default) do
+		if type(v) ~= "table" then
+			if source and source[k] ~= nil then
+				target[k] = source[k]
+			else
+				target[k] = v
+			end
+		else
+			if type(target[k]) ~= "table" then target[k] = {} else wipe(target[k]) end
+			merge(target[k], type(source) == "table" and source[k], v)
+		end
+	end
+	return target
+end
+
+function Generic:UpdateConfig(config)
+	if config and type(config) ~= "table" then
+		error("LibActionButton-1.0: UpdateConfig requires a valid configuration!", 2)
+	end
+	local oldconfig = self.config
+	if not self.config then self.config = {} end
+	-- merge the two configs
+	merge(self.config, config, DefaultConfig)
+
+	if self.config.outOfRangeColoring == "button" or (oldconfig and oldconfig.outOfRangeColoring == "button") then
+		UpdateUsable(self)
+	end
+	if self.config.outOfRangeColoring == "hotkey" then
+		self.outOfRange = nil
+	elseif oldconfig and oldconfig.outOfRangeColoring == "hotkey" then
+		self.HotKey:SetVertexColor(0.75, 0.75, 0.75)
+	end
+
+	if self.config.hideElements.macro then
+		self.Name:Hide()
+	else
+		self.Name:Show()
+	end
+
+	self:SetAttribute("flyoutDirection", self.config.flyoutDirection)
+
+	UpdateHotkeys(self)
+	UpdateGrid(self)
+	Update(self)
+	self:RegisterForClicks(self.config.clickOnDown and "AnyDown" or "AnyUp")
+end
+
+-----------------------------------------------------------
+--- event handler
+
+function ForAllButtons(method, onlyWithAction)
+	assert(type(method) == "function")
+	for button in next, (onlyWithAction and ActiveButtons or ButtonRegistry) do
+		method(button)
+	end
+end
+
+function InitializeEventHandler()
+	lib.eventFrame:SetScript("OnEvent", OnEvent)
+	lib.eventFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
+	lib.eventFrame:RegisterEvent("ACTIONBAR_SHOWGRID")
+	lib.eventFrame:RegisterEvent("ACTIONBAR_HIDEGRID")
+	--lib.eventFrame:RegisterEvent("ACTIONBAR_PAGE_CHANGED")
+	--lib.eventFrame:RegisterEvent("UPDATE_BONUS_ACTIONBAR")
+	lib.eventFrame:RegisterEvent("ACTIONBAR_SLOT_CHANGED")
+	lib.eventFrame:RegisterEvent("UPDATE_BINDINGS")
+	lib.eventFrame:RegisterEvent("UPDATE_SHAPESHIFT_FORM")
+	lib.eventFrame:RegisterEvent("UPDATE_VEHICLE_ACTIONBAR")
+
+	lib.eventFrame:RegisterEvent("ACTIONBAR_UPDATE_STATE")
+	lib.eventFrame:RegisterEvent("ACTIONBAR_UPDATE_USABLE")
+	lib.eventFrame:RegisterEvent("ACTIONBAR_UPDATE_COOLDOWN")
+	lib.eventFrame:RegisterEvent("PLAYER_TARGET_CHANGED")
+	lib.eventFrame:RegisterEvent("TRADE_SKILL_SHOW")
+	lib.eventFrame:RegisterEvent("TRADE_SKILL_CLOSE")
+	lib.eventFrame:RegisterEvent("ARCHAEOLOGY_CLOSED")
+	lib.eventFrame:RegisterEvent("PLAYER_ENTER_COMBAT")
+	lib.eventFrame:RegisterEvent("PLAYER_LEAVE_COMBAT")
+	lib.eventFrame:RegisterEvent("START_AUTOREPEAT_SPELL")
+	lib.eventFrame:RegisterEvent("STOP_AUTOREPEAT_SPELL")
+	lib.eventFrame:RegisterEvent("UNIT_ENTERED_VEHICLE")
+	lib.eventFrame:RegisterEvent("UNIT_EXITED_VEHICLE")
+	lib.eventFrame:RegisterEvent("COMPANION_UPDATE")
+	lib.eventFrame:RegisterEvent("UNIT_INVENTORY_CHANGED")
+	lib.eventFrame:RegisterEvent("LEARNED_SPELL_IN_TAB")
+	lib.eventFrame:RegisterEvent("PET_STABLE_UPDATE")
+	lib.eventFrame:RegisterEvent("PET_STABLE_SHOW")
+	lib.eventFrame:RegisterEvent("SPELL_ACTIVATION_OVERLAY_GLOW_SHOW")
+	lib.eventFrame:RegisterEvent("SPELL_ACTIVATION_OVERLAY_GLOW_HIDE")
+	lib.eventFrame:RegisterEvent("SPELL_UPDATE_CHARGES")
+	lib.eventFrame:RegisterEvent("UPDATE_SUMMONPETS_ACTION")
+
+	-- With those two, do we still need the ACTIONBAR equivalents of them?
+	lib.eventFrame:RegisterEvent("SPELL_UPDATE_COOLDOWN")
+	lib.eventFrame:RegisterEvent("SPELL_UPDATE_USABLE")
+	lib.eventFrame:RegisterEvent("PLAYER_EQUIPMENT_CHANGED")
+
+	lib.eventFrame:RegisterEvent("LOSS_OF_CONTROL_ADDED")
+	lib.eventFrame:RegisterEvent("LOSS_OF_CONTROL_UPDATE")
+
+	lib.eventFrame:Show()
+	lib.eventFrame:SetScript("OnUpdate", OnUpdate)
+end
+
+function OnEvent(frame, event, arg1, ...)
+	if (event == "UNIT_INVENTORY_CHANGED" and arg1 == "player") or event == "LEARNED_SPELL_IN_TAB" then
+		local tooltipOwner = GameTooltip:GetOwner()
+		if ButtonRegistry[tooltipOwner] then
+			tooltipOwner:SetTooltip()
+		end
+	elseif event == "ACTIONBAR_SLOT_CHANGED" then
+		for button in next, ButtonRegistry do
+			if button._state_type == "action" and (arg1 == 0 or arg1 == tonumber(button._state_action)) then
+				Update(button)
+			end
+		end
+	elseif event == "PLAYER_ENTERING_WORLD" or event == "UPDATE_SHAPESHIFT_FORM" or event == "UPDATE_VEHICLE_ACTIONBAR" then
+		ForAllButtons(Update)
+	elseif event == "ACTIONBAR_PAGE_CHANGED" or event == "UPDATE_BONUS_ACTIONBAR" then
+		-- TODO: Are these even needed?
+	elseif event == "ACTIONBAR_SHOWGRID" then
+		ShowGrid()
+	elseif event == "ACTIONBAR_HIDEGRID" then
+		HideGrid()
+	elseif event == "UPDATE_BINDINGS" then
+		ForAllButtons(UpdateHotkeys)
+	elseif event == "PLAYER_TARGET_CHANGED" then
+		UpdateRangeTimer()
+	elseif (event == "ACTIONBAR_UPDATE_STATE") or
+		((event == "UNIT_ENTERED_VEHICLE" or event == "UNIT_EXITED_VEHICLE") and (arg1 == "player")) or
+		((event == "COMPANION_UPDATE") and (arg1 == "MOUNT")) then
+		ForAllButtons(UpdateButtonState, true)
+	elseif event == "ACTIONBAR_UPDATE_USABLE" then
+		for button in next, ActionButtons do
+			UpdateUsable(button)
+		end
+	elseif event == "SPELL_UPDATE_USABLE" then
+		for button in next, NonActionButtons do
+			UpdateUsable(button)
+		end
+	elseif event == "ACTIONBAR_UPDATE_COOLDOWN" then
+		for button in next, ActionButtons do
+			UpdateCooldown(button)
+			if GameTooltip:GetOwner() == button then
+				UpdateTooltip(button)
+			end
+		end
+	elseif event == "SPELL_UPDATE_COOLDOWN" then
+		for button in next, NonActionButtons do
+			UpdateCooldown(button)
+			if GameTooltip:GetOwner() == button then
+				UpdateTooltip(button)
+			end
+		end
+	elseif event == "LOSS_OF_CONTROL_ADDED" then
+		for button in next, ActiveButtons do
+			UpdateCooldown(button)
+			if GameTooltip:GetOwner() == button then
+				UpdateTooltip(button)
+			end
+		end
+	elseif event == "LOSS_OF_CONTROL_UPDATE" then
+		for button in next, ActiveButtons do
+			UpdateCooldown(button)
+		end
+	elseif event == "TRADE_SKILL_SHOW" or event == "TRADE_SKILL_CLOSE"  or event == "ARCHAEOLOGY_CLOSED" then
+		ForAllButtons(UpdateButtonState, true)
+	elseif event == "PLAYER_ENTER_COMBAT" then
+		for button in next, ActiveButtons do
+			if button:IsAttack() then
+				StartFlash(button)
+			end
+		end
+	elseif event == "PLAYER_LEAVE_COMBAT" then
+		for button in next, ActiveButtons do
+			if button:IsAttack() then
+				StopFlash(button)
+			end
+		end
+	elseif event == "START_AUTOREPEAT_SPELL" then
+		for button in next, ActiveButtons do
+			if button:IsAutoRepeat() then
+				StartFlash(button)
+			end
+		end
+	elseif event == "STOP_AUTOREPEAT_SPELL" then
+		for button in next, ActiveButtons do
+			if button.flashing == 1 and not button:IsAttack() then
+				StopFlash(button)
+			end
+		end
+	elseif event == "PET_STABLE_UPDATE" or event == "PET_STABLE_SHOW" then
+		ForAllButtons(Update)
+	elseif event == "SPELL_ACTIVATION_OVERLAY_GLOW_SHOW" then
+		for button in next, ActiveButtons do
+			local spellId = button:GetSpellId()
+			if spellId and spellId == arg1 then
+				ShowOverlayGlow(button)
+			else
+				if button._state_type == "action" then
+					local actionType, id = GetActionInfo(button._state_action)
+					if actionType == "flyout" and FlyoutHasSpell(id, arg1) then
+						ShowOverlayGlow(button)
+					end
+				end
+			end
+		end
+	elseif event == "SPELL_ACTIVATION_OVERLAY_GLOW_HIDE" then
+		for button in next, ActiveButtons do
+			local spellId = button:GetSpellId()
+			if spellId and spellId == arg1 then
+				HideOverlayGlow(button)
+			else
+				if button._state_type == "action" then
+					local actionType, id = GetActionInfo(button._state_action)
+					if actionType == "flyout" and FlyoutHasSpell(id, arg1) then
+						HideOverlayGlow(button)
+					end
+				end
+			end
+		end
+	elseif event == "PLAYER_EQUIPMENT_CHANGED" then
+		for button in next, ActiveButtons do
+			if button._state_type == "item" then
+				Update(button)
+			end
+		end
+	elseif event == "SPELL_UPDATE_CHARGES" then
+		ForAllButtons(UpdateCount, true)
+	elseif event == "UPDATE_SUMMONPETS_ACTION" then
+		for button in next, ActiveButtons do
+			if button._state_type == "action" then
+				local actionType, id = GetActionInfo(button._state_action)
+				if actionType == "summonpet" then
+					local texture = GetActionTexture(button._state_action)
+					if texture then
+						button.icon:SetTexture(texture)
+					end
+				end
+			end
+		end
+	end
+end
+
+local flashTime = 0
+local rangeTimer = -1
+function OnUpdate(_, elapsed)
+	flashTime = flashTime - elapsed
+	rangeTimer = rangeTimer - elapsed
+	-- Run the loop only when there is something to update
+	if rangeTimer <= 0 or flashTime <= 0 then
+		for button in next, ActiveButtons do
+			-- Flashing
+			if button.flashing == 1 and flashTime <= 0 then
+				if button.Flash:IsShown() then
+					button.Flash:Hide()
+				else
+					button.Flash:Show()
+				end
+			end
+
+			-- Range
+			if rangeTimer <= 0 then
+				local inRange = button:IsInRange()
+				local oldRange = button.outOfRange
+				button.outOfRange = (inRange == false)
+				if oldRange ~= button.outOfRange then
+					if button.config.outOfRangeColoring == "button" then
+						UpdateUsable(button)
+					elseif button.config.outOfRangeColoring == "hotkey" then
+						local hotkey = button.HotKey
+						if hotkey:GetText() == RANGE_INDICATOR then
+							if inRange == false then
+								hotkey:Show()
+							else
+								hotkey:Hide()
+							end
+						end
+						if inRange == false then
+							hotkey:SetVertexColor(unpack(button.config.colors.range))
+						else
+							hotkey:SetVertexColor(0.75, 0.75, 0.75)
+						end
+					end
+				end
+			end
+		end
+
+		-- Update values
+		if flashTime <= 0 then
+			flashTime = flashTime + ATTACK_BUTTON_FLASH_TIME
+		end
+		if rangeTimer <= 0 then
+			rangeTimer = TOOLTIP_UPDATE_TIME
+		end
+	end
+end
+
+local gridCounter = 0
+function ShowGrid()
+	gridCounter = gridCounter + 1
+	if gridCounter >= 1 then
+		for button in next, ButtonRegistry do
+			if button:IsShown() then
+				button:SetAlpha(1.0)
+			end
+		end
+	end
+end
+
+function HideGrid()
+	if gridCounter > 0 then
+		gridCounter = gridCounter - 1
+	end
+	if gridCounter == 0 then
+		for button in next, ButtonRegistry do
+			if button:IsShown() and not button:HasAction() and not button.config.showGrid then
+				button:SetAlpha(0.0)
+			end
+		end
+	end
+end
+
+function UpdateGrid(self)
+	if self.config.showGrid then
+		self:SetAlpha(1.0)
+	elseif gridCounter == 0 and self:IsShown() and not self:HasAction() then
+		self:SetAlpha(0.0)
+	end
+end
+
+-----------------------------------------------------------
+--- KeyBound integration
+
+function Generic:GetBindingAction()
+	return self.config.keyBoundTarget or "CLICK "..self:GetName()..":LeftButton"
+end
+
+function Generic:GetHotkey()
+	local name = "CLICK "..self:GetName()..":LeftButton"
+	local key = GetBindingKey(self.config.keyBoundTarget or name)
+	if not key and self.config.keyBoundTarget then
+		key = GetBindingKey(name)
+	end
+	if key then
+		return KeyBound and KeyBound:ToShortKey(key) or key
+	end
+end
+
+local function getKeys(binding, keys)
+	keys = keys or ""
+	for i = 1, select("#", GetBindingKey(binding)) do
+		local hotKey = select(i, GetBindingKey(binding))
+		if keys ~= "" then
+			keys = keys .. ", "
+		end
+		keys = keys .. GetBindingText(hotKey, "KEY_")
+	end
+	return keys
+end
+
+function Generic:GetBindings()
+	local keys, binding
+
+	if self.config.keyBoundTarget then
+		keys = getKeys(self.config.keyBoundTarget)
+	end
+
+	keys = getKeys("CLICK "..self:GetName()..":LeftButton")
+
+	return keys
+end
+
+function Generic:SetKey(key)
+	if self.config.keyBoundTarget then
+		SetBinding(key, self.config.keyBoundTarget)
+	else
+		SetBindingClick(key, self:GetName(), "LeftButton")
+	end
+	lib.callbacks:Fire("OnKeybindingChanged", self, key)
+end
+
+local function clearBindings(binding)
+	while GetBindingKey(binding) do
+		SetBinding(GetBindingKey(binding), nil)
+	end
+end
+
+function Generic:ClearBindings()
+	if self.config.keyBoundTarget then
+		clearBindings(self.config.keyBoundTarget)
+	end
+	clearBindings("CLICK "..self:GetName()..":LeftButton")
+	lib.callbacks:Fire("OnKeybindingChanged", self, nil)
+end
+
+-----------------------------------------------------------
+--- button management
+
+function Generic:UpdateAction(force)
+	local type, action = self:GetAction()
+	if force or type ~= self._state_type or action ~= self._state_action then
+		-- type changed, update the metatable
+		if force or self._state_type ~= type then
+			local meta = type_meta_map[type] or type_meta_map.empty
+			setmetatable(self, meta)
+			self._state_type = type
+		end
+		self._state_action = action
+		Update(self)
+	end
+end
+
+function Update(self)
+	if self:HasAction() then
+		ActiveButtons[self] = true
+		if self._state_type == "action" then
+			ActionButtons[self] = true
+			NonActionButtons[self] = nil
+		else
+			ActionButtons[self] = nil
+			NonActionButtons[self] = true
+		end
+		self:SetAlpha(1.0)
+		UpdateButtonState(self)
+		UpdateUsable(self)
+		UpdateCooldown(self)
+		UpdateFlash(self)
+	else
+		ActiveButtons[self] = nil
+		ActionButtons[self] = nil
+		NonActionButtons[self] = nil
+		if gridCounter == 0 and not self.config.showGrid then
+			self:SetAlpha(0.0)
+		end
+		self.cooldown:Hide()
+		self:SetChecked(false)
+		if self.chargeCooldown then
+			EndChargeCooldown(self.chargeCooldown)
+		end
+	end
+
+	-- Add a green border if button is an equipped item
+	if self:IsEquipped() and not self.config.hideElements.equipped then
+		self.Border:SetVertexColor(0, 1.0, 0, 0.35)
+		self.Border:Show()
+	else
+		self.Border:Hide()
+	end
+
+	-- Update Action Text
+	if not self:IsConsumableOrStackable() then
+		self.Name:SetText(self:GetActionText())
+	else
+		self.Name:SetText("")
+	end
+
+	-- Update icon and hotkey
+	local texture = self:GetTexture()
+	if texture then
+		self.icon:SetTexture(texture)
+		self.icon:Show()
+		self.rangeTimer = - 1
+		self:SetNormalTexture("Interface\\Buttons\\UI-Quickslot2")
+		if not self.LBFSkinned and not self.MasqueSkinned then
+			self.NormalTexture:SetTexCoord(0, 0, 0, 0)
+		end
+	else
+		self.icon:Hide()
+		self.cooldown:Hide()
+		self.rangeTimer = nil
+		self:SetNormalTexture("Interface\\Buttons\\UI-Quickslot")
+		if self.HotKey:GetText() == RANGE_INDICATOR then
+			self.HotKey:Hide()
+		else
+			self.HotKey:SetVertexColor(0.75, 0.75, 0.75)
+		end
+		if not self.LBFSkinned and not self.MasqueSkinned then
+			self.NormalTexture:SetTexCoord(-0.15, 1.15, -0.15, 1.17)
+		end
+	end
+
+	self:UpdateLocal()
+
+	UpdateCount(self)
+
+	UpdateFlyout(self)
+
+	UpdateOverlayGlow(self)
+
+	UpdateNewAction(self)
+
+	if GameTooltip:GetOwner() == self then
+		UpdateTooltip(self)
+	end
+
+	-- this could've been a spec change, need to call OnStateChanged for action buttons, if present
+	if not InCombatLockdown() and self._state_type == "action" then
+		local onStateChanged = self:GetAttribute("OnStateChanged")
+		if onStateChanged then
+			self.header:SetFrameRef("updateButton", self)
+			self.header:Execute(([[
+				local frame = self:GetFrameRef("updateButton")
+				control:RunFor(frame, frame:GetAttribute("OnStateChanged"), %s, %s, %s)
+			]]):format(formatHelper(self:GetAttribute("state")), formatHelper(self._state_type), formatHelper(self._state_action)))
+		end
+	end
+	lib.callbacks:Fire("OnButtonUpdate", self)
+end
+
+function Generic:UpdateLocal()
+-- dummy function the other button types can override for special updating
+end
+
+function UpdateButtonState(self)
+	if self:IsCurrentlyActive() or self:IsAutoRepeat() then
+		self:SetChecked(true)
+	else
+		self:SetChecked(false)
+	end
+	lib.callbacks:Fire("OnButtonState", self)
+end
+
+function UpdateUsable(self)
+	-- TODO: make the colors configurable
+	-- TODO: allow disabling of the whole recoloring
+	if self.config.outOfRangeColoring == "button" and self.outOfRange then
+		self.icon:SetVertexColor(unpack(self.config.colors.range))
+	else
+		local isUsable, notEnoughMana = self:IsUsable()
+		if isUsable then
+			self.icon:SetVertexColor(1.0, 1.0, 1.0)
+			--self.NormalTexture:SetVertexColor(1.0, 1.0, 1.0)
+		elseif notEnoughMana then
+			self.icon:SetVertexColor(unpack(self.config.colors.mana))
+			--self.NormalTexture:SetVertexColor(0.5, 0.5, 1.0)
+		else
+			self.icon:SetVertexColor(0.4, 0.4, 0.4)
+			--self.NormalTexture:SetVertexColor(1.0, 1.0, 1.0)
+		end
+	end
+	lib.callbacks:Fire("OnButtonUsable", self)
+end
+
+function UpdateCount(self)
+	if not self:HasAction() then
+		self.Count:SetText("")
+		return
+	end
+	if self:IsConsumableOrStackable() then
+		local count = self:GetCount()
+		if count > (self.maxDisplayCount or 9999) then
+			self.Count:SetText("*")
+		else
+			self.Count:SetText(count)
+		end
+	else
+		local charges, maxCharges, chargeStart, chargeDuration = self:GetCharges()
+		if charges and maxCharges and maxCharges > 0 then
+			self.Count:SetText(charges)
+		else
+			self.Count:SetText("")
+		end
+	end
+end
+
+local function SetCooldownHook(cooldown, ...)
+	local effectiveAlpha = cooldown:GetEffectiveAlpha()
+	local start, duration = ...
+
+	if start ~= 0 or duration ~= 0 then
+		-- update swipe alpha
+		cooldown.__metaLAB.SetSwipeColor(cooldown, cooldown.__SwipeR, cooldown.__SwipeG, cooldown.__SwipeB, cooldown.__SwipeA * effectiveAlpha)
+
+		-- only draw bling and edge if alpha is over 50%
+		cooldown:SetDrawBling(effectiveAlpha > 0.5)
+		if effectiveAlpha < 0.5 then
+			cooldown:SetDrawEdge(false)
+		end
+
+		-- ensure the swipe isn't drawn on fully faded bars
+		if effectiveAlpha <= 0.0 then
+			cooldown:SetDrawSwipe(false)
+		end
+	end
+
+	return cooldown.__metaLAB.SetCooldown(cooldown, ...)
+end
+
+local function SetSwipeColorHook(cooldown, r, g, b, a)
+	local effectiveAlpha = cooldown:GetEffectiveAlpha()
+	cooldown.__SwipeR, cooldown.__SwipeG, cooldown.__SwipeB, cooldown.__SwipeA = r, g, b, (a or 1)
+	return cooldown.__metaLAB.SetSwipeColor(cooldown, r, g, b, a * effectiveAlpha)
+end
+
+function HookCooldown(button)
+	if not button.cooldown.__metaLAB then
+		button.cooldown.__metaLAB = getmetatable(button.cooldown).__index
+		button.cooldown.__SwipeR, button.cooldown.__SwipeG, button.cooldown.__SwipeB, button.cooldown.__SwipeA = 0, 0, 0, 0.8
+
+		button.cooldown.SetCooldown = SetCooldownHook
+		button.cooldown.SetSwipeColor = SetSwipeColorHook
+	end
+end
+
+function EndChargeCooldown(self)
+	self:Hide()
+	self:SetParent(UIParent)
+	self.parent.chargeCooldown = nil
+	self.parent = nil
+	tinsert(lib.ChargeCooldowns, self)
+end
+
+local function StartChargeCooldown(parent, chargeStart, chargeDuration)
+	if not parent.chargeCooldown then
+		local cooldown = tremove(lib.ChargeCooldowns)
+		if not cooldown then
+			lib.NumChargeCooldowns = lib.NumChargeCooldowns + 1
+			cooldown = CreateFrame("Cooldown", "LAB10ChargeCooldown"..lib.NumChargeCooldowns, parent, "CooldownFrameTemplate");
+			cooldown:SetScript("OnCooldownDone", EndChargeCooldown)
+			cooldown:SetHideCountdownNumbers(true)
+			cooldown:SetDrawEdge(true)
+			cooldown:SetDrawSwipe(false)
+		end
+		cooldown:SetParent(parent)
+		cooldown:SetAllPoints(parent)
+		cooldown:SetFrameStrata("TOOLTIP")
+		cooldown:Show()
+		parent.chargeCooldown = cooldown
+		cooldown.parent = parent
+	end
+	parent.chargeCooldown:SetCooldown(chargeStart, chargeDuration)
+	if not chargeStart or chargeStart == 0 then
+		EndChargeCooldown(parent.chargeCooldown)
+	end
+end
+
+function OnCooldownDone(self)
+	self:SetScript("OnCooldownDone", nil)
+	UpdateCooldown(self:GetParent())
+end
+
+function UpdateCooldown(self)
+	local locStart, locDuration = self:GetLossOfControlCooldown()
+	local start, duration, enable = self:GetCooldown()
+	local charges, maxCharges, chargeStart, chargeDuration = self:GetCharges()
+
+	if (locStart + locDuration) > (start + duration) then
+		if self.cooldown.currentCooldownType ~= COOLDOWN_TYPE_LOSS_OF_CONTROL then
+			self.cooldown:SetEdgeTexture("Interface\\Cooldown\\edge-LoC")
+			self.cooldown:SetHideCountdownNumbers(true)
+			self.cooldown.currentCooldownType = COOLDOWN_TYPE_LOSS_OF_CONTROL
+			self.cooldown:SetSwipeColor(0.17, 0, 0, 0.8)
+		end
+		CooldownFrame_Set(self.cooldown, locStart, locDuration, 1, nil, nil, true)
+	else
+		if self.cooldown.currentCooldownType ~= COOLDOWN_TYPE_NORMAL then
+			self.cooldown:SetEdgeTexture("Interface\\Cooldown\\edge")
+			self.cooldown:SetHideCountdownNumbers(false)
+			self.cooldown.currentCooldownType = COOLDOWN_TYPE_NORMAL
+			self.cooldown:SetSwipeColor(0, 0, 0, 0.8)
+		end
+		if locStart > 0 then
+			self.cooldown:SetScript("OnCooldownDone", OnCooldownDone)
+		end
+		if charges and maxCharges and maxCharges > 0 and charges < maxCharges then
+			StartChargeCooldown(self, chargeStart, chargeDuration)
+		elseif self.chargeCooldown then
+			EndChargeCooldown(self.chargeCooldown)
+		end
+		CooldownFrame_Set(self.cooldown, start, duration, enable, charges, maxCharges)
+	end
+end
+
+function StartFlash(self)
+	self.flashing = 1
+	flashTime = 0
+	UpdateButtonState(self)
+end
+
+function StopFlash(self)
+	self.flashing = 0
+	self.Flash:Hide()
+	UpdateButtonState(self)
+end
+
+function UpdateFlash(self)
+	if (self:IsAttack() and self:IsCurrentlyActive()) or self:IsAutoRepeat() then
+		StartFlash(self)
+	else
+		StopFlash(self)
+	end
+end
+
+function UpdateTooltip(self)
+	if (GetCVar("UberTooltips") == "1") then
+		GameTooltip_SetDefaultAnchor(GameTooltip, self);
+	else
+		GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
+	end
+	if self:SetTooltip() then
+		self.UpdateTooltip = UpdateTooltip
+	else
+		self.UpdateTooltip = nil
+	end
+end
+
+function UpdateHotkeys(self)
+	local key = self:GetHotkey()
+	if not key or key == "" or self.config.hideElements.hotkey then
+		self.HotKey:SetText(RANGE_INDICATOR)
+		self.HotKey:SetPoint("TOPLEFT", self, "TOPLEFT", 1, - 2)
+		self.HotKey:Hide()
+	else
+		self.HotKey:SetText(key)
+		self.HotKey:SetPoint("TOPLEFT", self, "TOPLEFT", - 2, - 2)
+		self.HotKey:Show()
+	end
+
+	if self.postKeybind then
+		self.postKeybind(nil, self)
+	end
+end
+
+local function OverlayGlow_OnHide(self)
+	if self.animOut:IsPlaying() then
+		self.animOut:Stop()
+		OverlayGlowAnimOutFinished(self.animOut)
+	end
+end
+
+function GetOverlayGlow()
+	local overlay = tremove(lib.unusedOverlayGlows);
+	if not overlay then
+		lib.numOverlays = lib.numOverlays + 1
+		overlay = CreateFrame("Frame", "LAB10ActionButtonOverlay"..lib.numOverlays, UIParent, "ActionBarButtonSpellActivationAlert")
+		overlay.animOut:SetScript("OnFinished", OverlayGlowAnimOutFinished)
+		overlay:SetScript("OnHide", OverlayGlow_OnHide)
+	end
+	return overlay
+end
+
+function ShowOverlayGlow(self)
+	if self.overlay then
+		if self.overlay.animOut:IsPlaying() then
+			self.overlay.animOut:Stop()
+			self.overlay.animIn:Play()
+		end
+	else
+		self.overlay = GetOverlayGlow()
+		local frameWidth, frameHeight = self:GetSize()
+		self.overlay:SetParent(self)
+		self.overlay:ClearAllPoints()
+		--Make the height/width available before the next frame:
+		self.overlay:SetSize(frameWidth * 1.4, frameHeight * 1.4)
+		self.overlay:SetPoint("TOPLEFT", self, "TOPLEFT", -frameWidth * 0.2, frameHeight * 0.2)
+		self.overlay:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", frameWidth * 0.2, -frameHeight * 0.2)
+		self.overlay.animIn:Play()
+	end
+end
+
+function HideOverlayGlow(self)
+	if self.overlay then
+		if self.overlay.animIn:IsPlaying() then
+			self.overlay.animIn:Stop()
+		end
+		if self:IsVisible() then
+			self.overlay.animOut:Play()
+		else
+			OverlayGlowAnimOutFinished(self.overlay.animOut)
+		end
+	end
+end
+
+function OverlayGlowAnimOutFinished(animGroup)
+	local overlay = animGroup:GetParent()
+	local actionButton = overlay:GetParent()
+	overlay:Hide()
+	tinsert(lib.unusedOverlayGlows, overlay)
+	actionButton.overlay = nil
+end
+
+function UpdateOverlayGlow(self)
+	local spellId = self:GetSpellId()
+	if spellId and IsSpellOverlayed(spellId) then
+		ShowOverlayGlow(self)
+	else
+		HideOverlayGlow(self)
+	end
+end
+
+hooksecurefunc("MarkNewActionHighlight", function(action, flag)
+	lib.ACTION_HIGHLIGHT_MARKS[action] = flag
+	for button in next, ButtonRegistry do
+		if button._state_type == "action" and action == tonumber(button._state_action) then
+			UpdateNewAction(button)
+		end
+	end
+end)
+
+function UpdateNewAction(self)
+	-- special handling for "New Action" markers
+	if self.NewActionTexture then
+		if self._state_type == "action" and lib.ACTION_HIGHLIGHT_MARKS[self._state_action] then
+			self.NewActionTexture:Show()
+		else
+			self.NewActionTexture:Hide()
+		end
+	end
+end
+
+-- Hook UpdateFlyout so we can use the blizzy templates
+hooksecurefunc("ActionButton_UpdateFlyout", function(self, ...)
+	if ButtonRegistry[self] then
+		UpdateFlyout(self)
+	end
+end)
+
+function UpdateFlyout(self)
+	-- disabled FlyoutBorder/BorderShadow, those are not handled by LBF and look terrible
+	self.FlyoutBorder:Hide()
+	self.FlyoutBorderShadow:Hide()
+	if self._state_type == "action" then
+		-- based on ActionButton_UpdateFlyout in ActionButton.lua
+		local actionType = GetActionInfo(self._state_action)
+		if actionType == "flyout" then
+			-- Update border and determine arrow position
+			local arrowDistance
+			if (SpellFlyout and SpellFlyout:IsShown() and SpellFlyout:GetParent() == self) or GetMouseFocus() == self then
+				arrowDistance = 5
+			else
+				arrowDistance = 2
+			end
+
+			-- Update arrow
+			self.FlyoutArrow:Show()
+			self.FlyoutArrow:ClearAllPoints()
+			local direction = self:GetAttribute("flyoutDirection");
+			if direction == "LEFT" then
+				self.FlyoutArrow:SetPoint("LEFT", self, "LEFT", -arrowDistance, 0)
+				SetClampedTextureRotation(self.FlyoutArrow, 270)
+			elseif direction == "RIGHT" then
+				self.FlyoutArrow:SetPoint("RIGHT", self, "RIGHT", arrowDistance, 0)
+				SetClampedTextureRotation(self.FlyoutArrow, 90)
+			elseif direction == "DOWN" then
+				self.FlyoutArrow:SetPoint("BOTTOM", self, "BOTTOM", 0, -arrowDistance)
+				SetClampedTextureRotation(self.FlyoutArrow, 180)
+			else
+				self.FlyoutArrow:SetPoint("TOP", self, "TOP", 0, arrowDistance)
+				SetClampedTextureRotation(self.FlyoutArrow, 0)
+			end
+
+			-- return here, otherwise flyout is hidden
+			return
+		end
+	end
+	self.FlyoutArrow:Hide()
+end
+
+function UpdateRangeTimer()
+	rangeTimer = -1
+end
+
+local function GetSpellIdByName(spellName)
+	if not spellName then return end
+	local spellLink = GetSpellLink(spellName)
+	if spellLink then
+		return tonumber(spellLink:match("spell:(%d+)"))
+	end
+	return nil
+end
+
+-----------------------------------------------------------
+--- WoW API mapping
+--- Generic Button
+Generic.HasAction               = function(self) return nil end
+Generic.GetActionText           = function(self) return "" end
+Generic.GetTexture              = function(self) return nil end
+Generic.GetCharges              = function(self) return nil end
+Generic.GetCount                = function(self) return 0 end
+Generic.GetCooldown             = function(self) return 0, 0, 0 end
+Generic.IsAttack                = function(self) return nil end
+Generic.IsEquipped              = function(self) return nil end
+Generic.IsCurrentlyActive       = function(self) return nil end
+Generic.IsAutoRepeat            = function(self) return nil end
+Generic.IsUsable                = function(self) return nil end
+Generic.IsConsumableOrStackable = function(self) return nil end
+Generic.IsUnitInRange           = function(self, unit) return nil end
+Generic.IsInRange               = function(self)
+	local unit = self:GetAttribute("unit")
+	if unit == "player" then
+		unit = nil
+	end
+	local val = self:IsUnitInRange(unit)
+	-- map 1/0 to true false, since the return values are inconsistent between actions and spells
+	if val == 1 then val = true elseif val == 0 then val = false end
+	return val
+end
+Generic.SetTooltip              = function(self) return nil end
+Generic.GetSpellId              = function(self) return nil end
+Generic.GetLossOfControlCooldown = function(self) return 0, 0 end
+
+-----------------------------------------------------------
+--- Action Button
+Action.HasAction               = function(self) return HasAction(self._state_action) end
+Action.GetActionText           = function(self) return GetActionText(self._state_action) end
+Action.GetTexture              = function(self) return GetActionTexture(self._state_action) end
+Action.GetCharges              = function(self) return GetActionCharges(self._state_action) end
+Action.GetCount                = function(self) return GetActionCount(self._state_action) end
+Action.GetCooldown             = function(self) return GetActionCooldown(self._state_action) end
+Action.IsAttack                = function(self) return IsAttackAction(self._state_action) end
+Action.IsEquipped              = function(self) return IsEquippedAction(self._state_action) end
+Action.IsCurrentlyActive       = function(self) return IsCurrentAction(self._state_action) end
+Action.IsAutoRepeat            = function(self) return IsAutoRepeatAction(self._state_action) end
+Action.IsUsable                = function(self) return IsUsableAction(self._state_action) end
+Action.IsConsumableOrStackable = function(self) return IsConsumableAction(self._state_action) or IsStackableAction(self._state_action) or (not IsItemAction(self._state_action) and GetActionCount(self._state_action) > 0) end
+Action.IsUnitInRange           = function(self, unit) return IsActionInRange(self._state_action, unit) end
+Action.SetTooltip              = function(self) return GameTooltip:SetAction(self._state_action) end
+Action.GetSpellId              = function(self)
+	local actionType, id, subType = GetActionInfo(self._state_action)
+	if actionType == "spell" then
+		return id
+	elseif actionType == "macro" then
+		local _, _, spellId = GetMacroSpell(id)
+		return spellId
+	end
+end
+Action.GetLossOfControlCooldown = function(self) return GetActionLossOfControlCooldown(self._state_action) end
+
+-----------------------------------------------------------
+--- Spell Button
+Spell.HasAction               = function(self) return true end
+Spell.GetActionText           = function(self) return "" end
+Spell.GetTexture              = function(self) return GetSpellTexture(self._state_action) end
+Spell.GetCharges              = function(self) return GetSpellCharges(self._state_action) end
+Spell.GetCount                = function(self) return GetSpellCount(self._state_action) end
+Spell.GetCooldown             = function(self) return GetSpellCooldown(self._state_action) end
+Spell.IsAttack                = function(self) return IsAttackSpell(FindSpellBookSlotBySpellID(self._state_action), "spell") end -- needs spell book id as of 4.0.1.13066
+Spell.IsEquipped              = function(self) return nil end
+Spell.IsCurrentlyActive       = function(self) return IsCurrentSpell(self._state_action) end
+Spell.IsAutoRepeat            = function(self) return IsAutoRepeatSpell(FindSpellBookSlotBySpellID(self._state_action), "spell") end -- needs spell book id as of 4.0.1.13066
+Spell.IsUsable                = function(self) return IsUsableSpell(self._state_action) end
+Spell.IsConsumableOrStackable = function(self) return IsConsumableSpell(self._state_action) end
+Spell.IsUnitInRange           = function(self, unit) return IsSpellInRange(FindSpellBookSlotBySpellID(self._state_action), "spell", unit) end -- needs spell book id as of 4.0.1.13066
+Spell.SetTooltip              = function(self) return GameTooltip:SetSpellByID(self._state_action) end
+Spell.GetSpellId              = function(self) return self._state_action end
+
+-----------------------------------------------------------
+--- Item Button
+local function getItemId(input)
+	return input:match("^item:(%d+)")
+end
+
+Item.HasAction               = function(self) return true end
+Item.GetActionText           = function(self) return "" end
+Item.GetTexture              = function(self) return GetItemIcon(self._state_action) end
+Item.GetCharges              = function(self) return nil end
+Item.GetCount                = function(self) return GetItemCount(self._state_action, nil, true) end
+Item.GetCooldown             = function(self) return GetItemCooldown(getItemId(self._state_action)) end
+Item.IsAttack                = function(self) return nil end
+Item.IsEquipped              = function(self) return IsEquippedItem(self._state_action) end
+Item.IsCurrentlyActive       = function(self) return IsCurrentItem(self._state_action) end
+Item.IsAutoRepeat            = function(self) return nil end
+Item.IsUsable                = function(self) return IsUsableItem(self._state_action) end
+Item.IsConsumableOrStackable = function(self) return IsConsumableItem(self._state_action) end
+Item.IsUnitInRange           = function(self, unit) return IsItemInRange(self._state_action, unit) end
+Item.SetTooltip              = function(self) return GameTooltip:SetHyperlink(self._state_action) end
+Item.GetSpellId              = function(self) return nil end
+
+-----------------------------------------------------------
+--- Macro Button
+-- TODO: map results of GetMacroSpell/GetMacroItem to proper results
+Macro.HasAction               = function(self) return true end
+Macro.GetActionText           = function(self) return (GetMacroInfo(self._state_action)) end
+Macro.GetTexture              = function(self) return (select(2, GetMacroInfo(self._state_action))) end
+Macro.GetCharges              = function(self) return nil end
+Macro.GetCount                = function(self) return 0 end
+Macro.GetCooldown             = function(self) return 0, 0, 0 end
+Macro.IsAttack                = function(self) return nil end
+Macro.IsEquipped              = function(self) return nil end
+Macro.IsCurrentlyActive       = function(self) return nil end
+Macro.IsAutoRepeat            = function(self) return nil end
+Macro.IsUsable                = function(self) return nil end
+Macro.IsConsumableOrStackable = function(self) return nil end
+Macro.IsUnitInRange           = function(self, unit) return nil end
+Macro.SetTooltip              = function(self) return nil end
+Macro.GetSpellId              = function(self) return nil end
+
+-----------------------------------------------------------
+--- Custom Button
+Custom.HasAction               = function(self) return true end
+Custom.GetActionText           = function(self) return "" end
+Custom.GetTexture              = function(self) return self._state_action.texture end
+Custom.GetCharges              = function(self) return nil end
+Custom.GetCount                = function(self) return 0 end
+Custom.GetCooldown             = function(self) return 0, 0, 0 end
+Custom.IsAttack                = function(self) return nil end
+Custom.IsEquipped              = function(self) return nil end
+Custom.IsCurrentlyActive       = function(self) return nil end
+Custom.IsAutoRepeat            = function(self) return nil end
+Custom.IsUsable                = function(self) return true end
+Custom.IsConsumableOrStackable = function(self) return nil end
+Custom.IsUnitInRange           = function(self, unit) return nil end
+Custom.SetTooltip              = function(self) return GameTooltip:SetText(self._state_action.tooltip) end
+Custom.GetSpellId              = function(self) return nil end
+Custom.RunCustom               = function(self, unit, button) return self._state_action.func(self, unit, button) end
+
+-----------------------------------------------------------
+--- Update old Buttons
+if oldversion and next(lib.buttonRegistry) then
+	InitializeEventHandler()
+	for button in next, lib.buttonRegistry do
+		-- this refreshes the metatable on the button
+		Generic.UpdateAction(button, true)
+		SetupSecureSnippets(button)
+		if oldversion < 12 then
+			WrapOnClick(button)
+		end
+		if oldversion < 23 then
+			if button.overlay then
+				button.overlay:Hide()
+				ActionButton_HideOverlayGlow(button)
+				button.overlay = nil
+				UpdateOverlayGlow(button)
+			end
+		end
+	end
+end
diff --git a/SVUI_ActionBars/libs/LibStub/LibStub.lua b/SVUI_ActionBars/libs/LibStub/LibStub.lua
new file mode 100644
index 0000000..ade16d8
--- /dev/null
+++ b/SVUI_ActionBars/libs/LibStub/LibStub.lua
@@ -0,0 +1,31 @@
+-- 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 _G = getfenv(0)
+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
diff --git a/SVUI_ActionBars/libs/_load.xml b/SVUI_ActionBars/libs/_load.xml
new file mode 100644
index 0000000..2c06c97
--- /dev/null
+++ b/SVUI_ActionBars/libs/_load.xml
@@ -0,0 +1,5 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+	<Script file="LibStub\LibStub.lua"/>
+    <Script file="CallbackHandler-1.0\CallbackHandler-1.0.lua"/>
+    <Script file="LibActionButton-1.0\LibActionButton-1.0.lua"/>
+</Ui>
\ No newline at end of file
diff --git a/SVUI_Auras/LICENSE.txt b/SVUI_Auras/LICENSE.txt
new file mode 100644
index 0000000..05ceba8
--- /dev/null
+++ b/SVUI_Auras/LICENSE.txt
@@ -0,0 +1,31 @@
+
+The MIT License
+
+Copyright (c) 2010, Failcoder (Steve Jackson)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy
+of this software and associated documentation files (the "Software"), to
+deal
+in the Software without restriction, including without limitation the
+rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/SVUI_Auras/Loader.lua b/SVUI_Auras/Loader.lua
new file mode 100644
index 0000000..0ed37ce
--- /dev/null
+++ b/SVUI_Auras/Loader.lua
@@ -0,0 +1,317 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+
+local SV = _G["SVUI"];
+local L = SV.L
+local MOD = SV:NewModule(...);
+local Schema = MOD.Schema;
+
+MOD.media = {}
+MOD.media.hyperAuraIcons = {
+	[[Interface\Addons\SVUI_Auras\assets\AURA-STATS]],
+	[[Interface\Addons\SVUI_Auras\assets\AURA-HEART]],
+	[[Interface\Addons\SVUI_Auras\assets\AURA-POWER]],
+	[[Interface\Addons\SVUI_Auras\assets\AURA-HASTE]],
+	[[Interface\Addons\SVUI_Auras\assets\AURA-SPELL]],
+	[[Interface\Addons\SVUI_Auras\assets\AURA-CRIT]],
+	[[Interface\Addons\SVUI_Auras\assets\AURA-MASTERY]],
+	[[Interface\Addons\SVUI_Auras\assets\AURA-MULTISTRIKE]],
+	[[Interface\Addons\SVUI_Auras\assets\AURA-VERSATILITY]]
+};
+
+-- local GENERAL_PROCS = {10060,119032,121557,6346,114255};
+-- local DISC_PROCS = {81700,109964,81782,33206};
+-- local HOLY_PROCS = {20711,47788,63735};
+-- local SHADOW_PROCS = {47585,15286,132573,158831};
+
+SV.defaults.Filters["Procs"] = {};
+
+SV.defaults[Schema] = {
+	["aurasEnabled"] = true,
+	["hyperBuffsEnabled"] = true,
+	["hyperBuffsFiltered"] = true,
+	["font"] = "SVUI Number Font",
+	["fontSize"] = 12,
+	["fontOutline"] = "THINOUTLINE",
+	["countOffsetV"] = 0,
+	["countOffsetH"] = 0,
+	["timeOffsetV"] = -4,
+	["timeOffsetH"] = 0,
+	["fadeBy"] = 5,
+	["procsEnabled"] = true,
+	["procSize"] = 40,
+	["buffs"] = {
+		["showBy"] = "LEFT_DOWN",
+		["wrapAfter"] = 12,
+		["maxWraps"] = 3,
+		["wrapXOffset"] = 6,
+		["wrapYOffset"] = 16,
+		["sortMethod"] = "TIME",
+		["sortDir"] = "-",
+		["isolate"] = 1,
+		["size"] = 32,
+	},
+	["debuffs"] = {
+		["showBy"] = "LEFT_DOWN",
+		["wrapAfter"] = 12,
+		["maxWraps"] = 1,
+		["wrapXOffset"] = 6,
+		["wrapYOffset"] = 16,
+		["sortMethod"] = "TIME",
+		["sortDir"] = "-",
+		["isolate"] = 1,
+		["size"] = 32,
+	},
+};
+
+local auraOptionsTemplate = {
+	scaleGroup = {
+		order = 1,
+		guiInline = true,
+		type = "group",
+		name = L["Scale Options"],
+		args = {
+			size = {
+				type = "range",
+				name = L["Size"],
+				desc = L["Set the size of the individual auras."],
+				min = 16,
+				max = 60,
+				step = 2,
+				order = 1
+			},
+			wrapXOffset = {
+				order = 2,
+				type = "range",
+				name = L["Horizontal Spacing"],
+				min = 0,
+				max = 50,
+				step = 1
+			},
+			wrapYOffset = {
+				order = 3,
+				type = "range",
+				name = L["Vertical Spacing"],
+				min = 0,
+				max = 50,
+				step = 1
+			},
+		}
+	},
+	layoutGroup = {
+		order = 2,
+		guiInline = true,
+		type = "group",
+		name = L["Directional Options"],
+		args = {
+			showBy = {
+				type = "select",
+				order = 1,
+				name = L["Growth Direction"],
+				desc = L["The direction the auras will grow and then the direction they will grow after they reach the wrap after limit."],
+				values = {
+					DOWN_RIGHT = format(L["%s and then %s"], L["Down"], L["Right"]),
+					DOWN_LEFT = format(L["%s and then %s"], L["Down"], L["Left"]),
+					UP_RIGHT = format(L["%s and then %s"], L["Up"], L["Right"]),
+					UP_LEFT = format(L["%s and then %s"], L["Up"], L["Left"]),
+					RIGHT_DOWN = format(L["%s and then %s"], L["Right"], L["Down"]),
+					RIGHT_UP = format(L["%s and then %s"], L["Right"], L["Up"]),
+					LEFT_DOWN = format(L["%s and then %s"], L["Left"], L["Down"]),
+					LEFT_UP = format(L["%s and then %s"], L["Left"], L["Up"])
+				}
+			},
+			wrapAfter = {
+				type = "range",
+				order = 2,
+				name = L["Wrap After"],
+				desc = L["Begin a new row or column after this many auras."],
+				min = 1,
+				max = 32,
+				step = 1
+			},
+			maxWraps = {
+				name = L["Max Wraps"],
+				order = 3,
+				desc = L["Limit the number of rows or columns."],
+				type = "range",
+				min = 1,
+				max = 32,
+				step = 1
+			},
+		}
+	},
+	sortGroup = {
+		order = 1,
+		guiInline = true,
+		type = "group",
+		name = L["Sorting Options"],
+		args = {
+			sortMethod = {
+				order = 1,
+				name = L["Sort Method"],
+				desc = L["Defines how the group is sorted."],
+				type = "select",
+				values = {
+					["INDEX"] = L["Index"],
+					["TIME"] = L["Time"],
+					["NAME"] = L["Name"]
+				}
+			},
+			sortDir = {
+				order = 2,
+				name = L["Sort Direction"],
+				desc = L["Defines the sort order of the selected sort method."],
+				type = "select",
+				values = {
+					["+"] = L["Ascending"],
+					["-"] = L["Descending"]
+				}
+			},
+			isolate = {
+				order = 3,
+				name = L["Seperate"],
+				desc = L["Indicate whether buffs you cast yourself should be separated before or after."],
+				type = "select",
+				values = {
+					[-1] = L["Other's First"],
+					[0] = L["No Sorting"],
+					[1] = L["Your Auras First"]
+				}
+			}
+		}
+	},
+}
+
+function MOD:LoadOptions()
+	SV.Options.args[Schema] = {
+		type = "group",
+		name = Schema,
+		childGroups = "tab",
+		get = function(a)return SV.db[Schema][a[#a]] end,
+		set = function(a,b)
+			MOD:ChangeDBVar(b,a[#a]);
+			MOD:UpdateAuraHeader(SVUI_PlayerBuffs, "buffs")
+			MOD:UpdateAuraHeader(SVUI_PlayerDebuffs, "debuffs")
+		end,
+		args = {
+			intro = {
+				order = 1,
+				width = 'full',
+				type = "description",
+				name = L["AURAS_DESC"]
+			},
+			aurasEnabled = {
+				order = 2,
+				type = "toggle",
+				name = L["Auras Enabled"],
+				get = function(a) return SV.db[Schema].aurasEnabled end,
+				set = function(a,b)SV.db[Schema].aurasEnabled = b;SV:StaticPopup_Show("RL_CLIENT") end
+			},
+			hyperBuffsEnabled = {
+				order = 3,
+				type = "toggle",
+				name = L["Hyper Auras Enabled"],
+				get = function(a)return SV.db[Schema].hyperBuffsEnabled end,
+				set = function(a,b)SV.db[Schema].hyperBuffsEnabled = b;SV:StaticPopup_Show("RL_CLIENT")end
+			},
+			hyperBuffsFiltered = {
+				order = 4,
+				type = "toggle",
+				name = L["Hyper Auras Filtered"],
+				get = function(a)return SV.db[Schema].hyperBuffsFiltered end,
+				set = function(a,b)SV.db[Schema].hyperBuffsFiltered = b;SV:StaticPopup_Show("RL_CLIENT")end
+			},
+			procsEnabled = {
+				order = 5,
+				type = "toggle",
+				name = L["Proc Watch Enabled"],
+				get = function(a) return SV.db[Schema].procsEnabled end,
+				set = function(a,b)SV.db[Schema].procsEnabled = b;SV:StaticPopup_Show("RL_CLIENT") end
+			},
+			auraGroups = {
+				order = 6,
+				type = "group",
+				name = L["Options"],
+				childGroups = "tree",
+				disabled = function() return not SV.db[Schema].aurasEnabled end,
+				args = {
+					common = {
+						order = 10,
+						type = "group",
+						name = L["General"],
+						args = {
+							fadeBy = {
+								type = "range",
+								name = L["Fade Threshold"],
+								desc = L["Threshold before text changes red, goes into decimal form, and the icon will fade. Set to -1 to disable."],
+								min = -1,
+								max = 30,
+								step = 1,
+								order = 1
+							},
+							timeOffsetH = {
+								order = 2,
+								name = L["Time xOffset"],
+								type = "range",
+								min = -60,
+								max = 60,
+								step = 1
+							},
+							timeOffsetV = {
+								order = 3,
+								name = L["Time yOffset"],
+								type = "range",
+								min = -60,
+								max = 60,
+								step = 1
+							},
+							countOffsetH = {
+								order = 4,
+								name = L["Count xOffset"],
+								type = "range",
+								min = -60,
+								max = 60,
+								step = 1
+							},
+							countOffsetV = {
+								order = 5,
+								name = L["Count yOffset"],
+								type = "range",
+								min = -60,
+								max = 60,
+								step = 1
+							}
+						}
+					},
+					buffs = {
+						order = 30,
+						type = "group",
+						name = L["Buffs"],
+						get = function(b)return SV.db[Schema].buffs[b[#b]]end,
+						set = function(a,b)MOD:ChangeDBVar(b,a[#a],"buffs");MOD:UpdateAuraHeader(SVUI_PlayerBuffs, "buffs")end,
+						args = auraOptionsTemplate
+					},
+					debuffs = {
+						order = 40,
+						type = "group",
+						name = L["Debuffs"],
+						get = function(b)return SV.db[Schema].debuffs[b[#b]]end,
+						set = function(a,b)MOD:ChangeDBVar(b,a[#a],"debuffs");MOD:UpdateAuraHeader(SVUI_PlayerDebuffs, "debuffs")end,
+						args = auraOptionsTemplate
+					}
+				}
+			},
+		}
+	}
+end
diff --git a/SVUI_Auras/SVUI_Auras.lua b/SVUI_Auras/SVUI_Auras.lua
new file mode 100644
index 0000000..28884d8
--- /dev/null
+++ b/SVUI_Auras/SVUI_Auras.lua
@@ -0,0 +1,641 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack    = _G.unpack;
+local select    = _G.select;
+local pairs     = _G.pairs;
+local ipairs    = _G.ipairs;
+local type      = _G.type;
+local error     = _G.error;
+local pcall     = _G.pcall;
+local tostring  = _G.tostring;
+local tonumber  = _G.tonumber;
+local string 	= _G.string;
+local math 		= _G.math;
+local table 	= _G.table;
+--[[ STRING METHODS ]]--
+local format = string.format;
+--[[ MATH METHODS ]]--
+local abs, ceil, floor, round = math.abs, math.ceil, math.floor, math.round;
+--[[ TABLE METHODS ]]--
+local tremove, twipe = table.remove, table.wipe;
+--BLIZZARD API
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+local GameTooltip           = _G.GameTooltip;
+local ReloadUI              = _G.ReloadUI;
+local hooksecurefunc        = _G.hooksecurefunc;
+local GetTime               = _G.GetTime;
+local UnitName              = _G.UnitName;
+local UnitAura              = _G.UnitAura;
+local UnitBuff              = _G.UnitBuff;
+local UnitStat              = _G.UnitStat;
+local UnitLevel             = _G.UnitLevel;
+local UnitClass             = _G.UnitClass;
+--local NUM_LE_RAID_BUFF_TYPES = _G.NUM_LE_RAID_BUFF_TYPES;
+local RAID_CLASS_COLORS     = _G.RAID_CLASS_COLORS;
+local CUSTOM_CLASS_COLORS   = _G.CUSTOM_CLASS_COLORS;
+local GetItemQualityColor   = _G.GetItemQualityColor;
+local GetInventoryItemQuality   = _G.GetInventoryItemQuality;
+local GetInventoryItemTexture   = _G.GetInventoryItemTexture;
+local GetWeaponEnchantInfo  = _G.GetWeaponEnchantInfo;
+local RegisterStateDriver   = _G.RegisterStateDriver;
+local UnregisterStateDriver = _G.UnregisterStateDriver;
+local RegisterAttributeDriver   = _G.RegisterAttributeDriver;
+local GetRaidBuffTrayAuraInfo 	= _G.GetRaidBuffTrayAuraInfo;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local MOD = SV.Auras;
+if(not MOD) then return end;
+
+MOD.Holder = CreateFrame("Frame", "SVUI_AurasAnchor", UIParent)
+MOD.HyperBuffFrame = CreateFrame('Frame', 'SVUI_ConsolidatedBuffs', UIParent)
+--[[
+##########################################################
+LOCAL VARS
+##########################################################
+]]--
+local HOLDER_OFFSET = -8;
+local AURA_FADE_TIME = 5;
+local DIRECTION_TO_POINT = {
+	DOWN_RIGHT = "TOPLEFT",
+	DOWN_LEFT = "TOPRIGHT",
+	UP_RIGHT = "BOTTOMLEFT",
+	UP_LEFT = "BOTTOMRIGHT",
+	RIGHT_DOWN = "TOPLEFT",
+	RIGHT_UP = "BOTTOMLEFT",
+	LEFT_DOWN = "TOPRIGHT",
+	LEFT_UP = "BOTTOMRIGHT",
+};
+local DIRECTION_TO_HORIZONTAL_SPACING_MULTIPLIER = {
+	DOWN_RIGHT = 1,
+	DOWN_LEFT = -1,
+	UP_RIGHT = 1,
+	UP_LEFT = -1,
+	RIGHT_DOWN = 1,
+	RIGHT_UP = 1,
+	LEFT_DOWN = -1,
+	LEFT_UP = -1,
+};
+local DIRECTION_TO_VERTICAL_SPACING_MULTIPLIER = {
+	DOWN_RIGHT = -1,
+	DOWN_LEFT = -1,
+	UP_RIGHT = 1,
+	UP_LEFT = 1,
+	RIGHT_DOWN = -1,
+	RIGHT_UP = 1,
+	LEFT_DOWN = -1,
+	LEFT_UP = 1,
+};
+local IS_HORIZONTAL_GROWTH = {
+	RIGHT_DOWN = true,
+	RIGHT_UP = true,
+	LEFT_DOWN = true,
+	LEFT_UP = true,
+};
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+do
+	local RefreshAuraTime = function(self, elapsed)
+		if(self.offset) then
+			local expiration = select(self.offset, GetWeaponEnchantInfo())
+			if expiration then
+				self.timeLeft = expiration / 1e3
+			else
+				self.timeLeft = 0
+			end
+		else
+			self.timeLeft = self.timeLeft - elapsed
+		end
+
+		if(self.nextUpdate > 0) then
+			self.nextUpdate = self.nextUpdate - elapsed;
+			return
+		end
+
+		local expires = self.timeLeft
+		local calc = 0;
+		local remaining = 0;
+		if expires < 60 then
+			if expires >= AURA_FADE_TIME then
+				remaining = floor(expires)
+				self.nextUpdate = 0.51
+				self.time:SetFormattedText("|cffffff00%d|r", remaining)
+			else
+				remaining = expires
+				self.nextUpdate = 0.051
+				self.time:SetFormattedText("|cffff0000%.1f|r", remaining)
+			end
+		elseif expires < 3600 then
+			remaining = ceil(expires / 60);
+			calc = floor((expires / 60) + .5);
+			self.nextUpdate = calc > 1 and ((expires - calc) * 29.5) or (expires - 59.5);
+			self.time:SetFormattedText("|cffffffff%dm|r", remaining)
+		elseif expires < 86400 then
+			remaining = ceil(expires / 3600);
+			calc = floor((expires / 3600) + .5);
+			self.nextUpdate = calc > 1 and ((expires - calc) * 1799.5) or (expires - 3570);
+			self.time:SetFormattedText("|cff66ffff%dh|r", remaining)
+		else
+			remaining = ceil(expires / 86400);
+			calc = floor((expires / 86400) + .5);
+			self.nextUpdate = calc > 1 and ((expires - calc) * 43199.5) or (expires - 86400);
+			self.time:SetFormattedText("|cff6666ff%dd|r", remaining)
+		end
+
+		if(self.timeLeft > AURA_FADE_TIME) then
+			SV.Animate:StopFlash(self)
+		else
+			SV.Animate:Flash(self, 1)
+		end
+	end
+
+	local Aura_OnAttributeChanged = function(self, attribute, auraIndex)
+		if(attribute == "index") then
+			local filter = self:GetParent():GetAttribute("filter")
+			local unit = self:GetParent():GetAttribute("unit")
+			local name, _, icon, count, dispelType, val, expires, caster = UnitAura(unit, auraIndex, filter)
+			if name then
+				if val > 0 and expires then
+					local timeLeft = expires - GetTime()
+					if(not self.timeLeft) then
+						self.timeLeft = timeLeft;
+						self:SetScript("OnUpdate", RefreshAuraTime)
+					else
+						self.timeLeft = timeLeft
+					end
+					self.nextUpdate = -1;
+					RefreshAuraTime(self, 0)
+				else
+					self.timeLeft = nil;
+					self.time:SetText("")
+					self:SetScript("OnUpdate", nil)
+				end
+				if count > 1 then
+					self.count:SetText(count)
+				else
+					self.count:SetText("")
+				end
+				if filter == "HARMFUL" then
+					local color = DebuffTypeColor[dispelType or ""]
+					self:SetBackdropBorderColor(color.r, color.g, color.b)
+				else
+					self:SetBackdropBorderColor(0, 0, 0);
+				end
+				self.texture:SetTexture(icon)
+				self.offset = nil
+			end
+		elseif(attribute == "target-slot") then
+			local quality = GetInventoryItemQuality("player", auraIndex)
+			local tex = GetInventoryItemTexture("player", auraIndex)
+			self.texture:SetTexture(tex)
+			local offset = 2;
+			local enchantIndex = self:GetName():sub(-1)
+			if(enchantIndex:match("2")) then
+				offset = 5
+			end
+
+			if(quality) then
+				self:SetBackdropBorderColor(GetItemQualityColor(quality))
+			end
+
+			local enchantInfo = select(offset, GetWeaponEnchantInfo())
+			if(enchantInfo) then
+				self.offset = offset;
+				self:SetScript("OnUpdate", RefreshAuraTime)
+				self.nextUpdate = -1;
+				RefreshAuraTime(self, 0)
+			else
+				self.timeLeft = nil;
+				self.offset = nil;
+				self:SetScript("OnUpdate", nil)
+				self.time:SetText("")
+				self:SetAlpha(0)
+			end
+		end
+	end
+
+	function MOD:CreateIcon(aura, has_attrib)
+		aura:SetBackdrop({
+			bgFile = [[Interface\BUTTONS\WHITE8X8]],
+			tile = false,
+			tileSize = 0,
+			edgeFile = [[Interface\BUTTONS\WHITE8X8]],
+			edgeSize = 2,
+			insets = {
+				left = 0,
+				right = 0,
+				top = 0,
+				bottom = 0
+			}
+		 })
+	 	aura:SetBackdropColor(0, 0, 0)
+	 	aura:SetBackdropBorderColor(0, 0, 0)
+
+		aura.texture = aura:CreateTexture(nil, "BORDER")
+		aura.texture:InsetPoints(aura, 2, 2)
+		aura.texture:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+
+		aura.count = aura:CreateFontString(nil, "ARTWORK")
+		aura.count:SetPoint("BOTTOMRIGHT", (-1 + SV.db.Auras.countOffsetH), (1 + SV.db.Auras.countOffsetV))
+		aura.count:SetFontObject(SVUI_Font_Aura)
+
+		aura.time = aura:CreateFontString(nil, "ARTWORK")
+		aura.time:SetPoint("TOP", aura, "BOTTOM", 1 + SV.db.Auras.timeOffsetH, 0 + SV.db.Auras.timeOffsetV)
+		aura.time:SetFontObject(SVUI_Font_Aura)
+
+		aura.highlight = aura:CreateTexture(nil, "HIGHLIGHT")
+		aura.highlight:SetTexture(SV.media.statusbar.default)
+		aura.highlight:SetVertexColor(1, 1, 1, 0.45)
+		aura.highlight:InsetPoints(aura, 2, 2)
+
+		SV.Animate:Flash(aura)
+		aura:SetScript("OnAttributeChanged", Aura_OnAttributeChanged)
+	end
+end
+
+do
+	local ConsolidatedBuff_OnUpdate = function(self, current)
+		local expires = (self.expiration - current);
+		self.expiration = expires;
+		self.bar:SetValue(expires)
+		if self.nextUpdate > 0 then
+			self.nextUpdate = self.nextUpdate - current;
+			return
+		end
+		if self.expiration <= 0 then
+			self:SetScript("OnUpdate", nil)
+			return
+		end
+
+		local calc = 0;
+		if expires < 60 then
+			if expires >= AURA_FADE_TIME then
+				self.nextUpdate = 0.51;
+			else
+				self.nextUpdate = 0.051;
+			end
+		elseif expires < 3600 then
+			calc = floor((expires / 60) + .5);
+			self.nextUpdate = calc > 1 and ((expires - calc) * 29.5) or (expires - 59.5);
+		elseif expires < 86400 then
+			calc = floor((expires / 3600) + .5);
+			self.nextUpdate = calc > 1 and ((expires - calc) * 1799.5) or (expires - 3570);
+		else
+			calc = floor((expires / 86400) + .5);
+			self.nextUpdate = calc > 1 and ((expires - calc) * 43199.5) or (expires - 86400);
+		end
+	end
+
+	local UpdateConsolidatedReminder = function(self, event, arg)
+		if(event == "UNIT_AURA" and arg ~= "player") then return end
+		for i = 1, NUM_LE_RAID_BUFF_TYPES do
+			local name, _, duration, expiration, spellId, slot, caster, classFileName, unitName;
+			name, _, _, duration, expiration, spellId, slot = GetRaidBuffTrayAuraInfo(i)
+
+			--[[ EXPERIMENTAL ]]--
+			if(name) then
+				_, _, _, _, _, _, _, caster = UnitBuff('player', name)
+			elseif(slot) then
+				name, _, _, _, _, _, _, caster = UnitBuff('player', slot)
+			end
+			local buff = MOD.HyperBuffFrame[i]
+			--[[ ____________ ]]--
+
+			if name then
+				if(caster) then
+					_,classFileName = UnitClass(caster)
+					unitName = UnitName(caster)
+					if(classFileName and RAID_CLASS_COLORS[classFileName]) then
+						local hex = RAID_CLASS_COLORS[classFileName].colorStr
+						buff.casterTip = ("|c%s%s|r"):format(hex, unitName)
+					else
+						buff.casterTip = unitName
+					end
+				end
+				local timeLeft = expiration - GetTime()
+
+				buff.expiration = timeLeft;
+				buff.duration = duration;
+				buff.spellName = name;
+				buff.nextUpdate = 0;
+				buff:SetAlpha(1)
+				buff.empty:SetAlpha(1)
+				if(duration > 0 and timeLeft > 0) then
+					buff:SetAlpha(1)
+					buff:SetScript("OnUpdate", ConsolidatedBuff_OnUpdate)
+					buff.bar:SetMinMaxValues(0, duration)
+					buff.bar:SetValue(timeLeft)
+				else
+					buff:SetScript("OnUpdate", nil)
+					buff.bar:SetMinMaxValues(0, 1)
+					buff.bar:SetValue(1)
+				end
+			else
+				buff.spellName = nil;
+				buff.casterTip = nil;
+				buff.bar:SetValue(0)
+				buff:SetAlpha(0.1)
+				buff.empty:SetAlpha(0)
+				buff:SetScript("OnUpdate", nil)
+			end
+		end
+	end
+
+	local function PlayerRoleChanged()
+		if(SV.db.Auras.hyperBuffsEnabled) then
+			MOD:Update_ConsolidatedBuffsSettings()
+		end
+	end
+
+	function MOD:ToggleConsolidatedBuffs()
+		if(SV.db.Auras.hyperBuffsEnabled) then
+			local maxShown = #MOD.media.hyperAuraIcons - 1
+			local CB_HEIGHT = Minimap:GetHeight()
+			local CB_WIDTH = (CB_HEIGHT / maxShown) + 4
+			--print("ToggleConsolidatedBuffs "..CB_WIDTH)
+			MOD.Holder:SetSize(CB_WIDTH, CB_HEIGHT)
+			MOD.HyperBuffFrame:Show()
+			BuffFrame:RegisterUnitEvent("UNIT_AURA", "player")
+			MOD:RegisterEvent("UNIT_AURA", UpdateConsolidatedReminder)
+			MOD:RegisterEvent("GROUP_ROSTER_UPDATE", UpdateConsolidatedReminder)
+			MOD:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED", UpdateConsolidatedReminder)
+			UpdateConsolidatedReminder()
+		else
+			MOD.HyperBuffFrame:Hide()
+			BuffFrame:UnregisterEvent("UNIT_AURA")
+			MOD:UnregisterEvent("UNIT_AURA")
+			MOD:UnregisterEvent("GROUP_ROSTER_UPDATE")
+			MOD:UnregisterEvent("PLAYER_SPECIALIZATION_CHANGED")
+		end
+	end
+end
+
+do
+	local AuraButton_OnEnter = function(self)
+		GameTooltip:Hide()
+		GameTooltip:SetOwner(self, "ANCHOR_BOTTOMLEFT", -3, self:GetHeight() + 2)
+		GameTooltip:ClearLines()
+		local parent = self:GetParent()
+		local id = parent:GetID()
+		if parent.spellName then
+			GameTooltip:SetUnitConsolidatedBuff("player", id)
+			if parent.casterTip then
+				GameTooltip:AddDoubleLine("|cff00FFFFCast By:|r", parent.casterTip)
+			end
+		end
+		GameTooltip:AddDoubleLine("|cff00FFFFBuff Type:|r", _G[("RAID_BUFF_%d"):format(id)])
+		GameTooltip:Show()
+	end
+
+	local AuraButton_OnLeave = function(self)
+		GameTooltip:Hide()
+	end
+
+	function MOD:Update_ConsolidatedBuffsSettings(event)
+		MOD.HyperBuffFrame:SetAllPoints(MOD.Holder)
+		local hideIndex;
+		if(SV.db.Auras.hyperBuffsFiltered) then
+			if SV.SpecificClassRole == 'CASTER' then
+				hideIndex = 3
+			else
+				hideIndex = 5
+			end
+		end
+		local lastGoodFrame
+		local maxShown = #MOD.media.hyperAuraIcons - 1
+		local CB_HEIGHT = Minimap:GetHeight() - 50
+		local buffSize = (CB_HEIGHT / maxShown) - 1
+
+		for i=1, NUM_LE_RAID_BUFF_TYPES do
+			local buff = MOD.HyperBuffFrame[i]
+			local lastIndex = (i - 1)
+			if(buff) then
+				buff:ClearAllPoints()
+
+				if i==1 then
+					buff:SetPoint("TOP", MOD.HyperBuffFrame, "TOP", 0, 0)
+					lastGoodFrame = buff
+				else
+					buff:SetPoint("TOP", lastGoodFrame, "BOTTOM", 0, -4)
+				end
+
+				if(hideIndex and i == hideIndex) then
+					buff:Hide()
+				else
+					buff:Show()
+					lastGoodFrame = buff
+				end
+
+				buff:SetSize(buffSize,buffSize)
+
+				local tip = _G[("ConsolidatedBuffsTooltipBuff%d"):format(i)]
+				tip:ClearAllPoints()
+				tip:SetAllPoints(MOD.HyperBuffFrame[i])
+				tip:SetParent(MOD.HyperBuffFrame[i])
+				tip:SetAlpha(0)
+				tip:SetScript("OnEnter",AuraButton_OnEnter)
+				tip:SetScript("OnLeave",AuraButton_OnLeave)
+			end
+		end
+		if not event then
+			MOD:ToggleConsolidatedBuffs()
+		end
+	end
+end
+
+function MOD:UpdateAuraHeader(auraHeader, auraType)
+	if(InCombatLockdown() or not auraHeader) then return end
+
+	local db = SV.db.Auras[auraType]
+	local showBy = db.showBy
+
+	if(auraType == "buffs") then
+		auraHeader:SetAttribute("consolidateTo", SV.db.Auras.hyperBuffsEnabled == true and 1 or 0)
+		auraHeader:SetAttribute("weaponTemplate", ("SVUI_AuraTemplate%d"):format(db.size))
+	end
+
+	auraHeader:SetAttribute("separateOwn", db.isolate)
+	auraHeader:SetAttribute("sortMethod", db.sortMethod)
+	auraHeader:SetAttribute("sortDirection", db.sortDir)
+	auraHeader:SetAttribute("maxWraps", db.maxWraps)
+	auraHeader:SetAttribute("wrapAfter", db.wrapAfter)
+
+	auraHeader:SetAttribute("point", DIRECTION_TO_POINT[showBy])
+
+	if(IS_HORIZONTAL_GROWTH[showBy]) then
+		auraHeader:SetAttribute("minWidth", ((db.wrapAfter == 1 and 0 or db.wrapXOffset) + db.size) * db.wrapAfter)
+		auraHeader:SetAttribute("minHeight", (db.wrapYOffset + db.size) * db.maxWraps)
+		auraHeader:SetAttribute("xOffset", DIRECTION_TO_HORIZONTAL_SPACING_MULTIPLIER[showBy] * (db.wrapXOffset + db.size))
+		auraHeader:SetAttribute("yOffset", 0)
+		auraHeader:SetAttribute("wrapXOffset", 0)
+		auraHeader:SetAttribute("wrapYOffset", DIRECTION_TO_VERTICAL_SPACING_MULTIPLIER[showBy] * (db.wrapYOffset + db.size))
+	else
+		auraHeader:SetAttribute("minWidth", (db.wrapXOffset + db.size) * db.maxWraps)
+		auraHeader:SetAttribute("minHeight", ((db.wrapAfter == 1 and 0 or db.wrapYOffset) + db.size) * db.wrapAfter)
+		auraHeader:SetAttribute("xOffset", 0)
+		auraHeader:SetAttribute("yOffset", DIRECTION_TO_VERTICAL_SPACING_MULTIPLIER[showBy] * (db.wrapYOffset + db.size))
+		auraHeader:SetAttribute("wrapXOffset", DIRECTION_TO_HORIZONTAL_SPACING_MULTIPLIER[showBy] * (db.wrapXOffset + db.size))
+		auraHeader:SetAttribute("wrapYOffset", 0)
+	end
+
+	auraHeader:SetAttribute("template", ("SVUI_AuraTemplate%d"):format(db.size))
+
+	local i = 1;
+	local auraChild = select(i, auraHeader:GetChildren())
+
+	while(auraChild) do
+		if ((floor(auraChild:GetWidth() * 100 + 0.5) / 100) ~= db.size) then
+			auraChild:SetSize(db.size, db.size)
+		end
+		if(auraChild.time) then
+			auraChild.time:ClearAllPoints()
+			auraChild.time:SetPoint("TOP", auraChild, "BOTTOM", 1 + SV.db.Auras.timeOffsetH, SV.db.Auras.timeOffsetV)
+			auraChild.count:ClearAllPoints()
+			auraChild.count:SetPoint("BOTTOMRIGHT", -1 + SV.db.Auras.countOffsetH, SV.db.Auras.countOffsetV)
+		end
+		if ((i > (db.maxWraps * db.wrapAfter)) and auraChild:IsShown()) then
+			auraChild:Hide()
+		end
+
+		i = i + 1;
+		auraChild = select(i, auraHeader:GetChildren())
+	end
+end
+
+function MOD:UpdateAuraHolder(newHeight, referenceHolder)
+	if(not newHeight) then return end
+	self.Holder:SetHeight(newHeight)
+	if(self.Holder.Grip) then
+		self.Holder.Grip:SetHeight(newHeight)
+		if((not self.Holder.Grip:HasMoved()) and (referenceHolder and referenceHolder.HasMoved and (not referenceHolder:HasMoved()))) then
+			HOLDER_OFFSET = -8;
+			self.Holder.Grip:ClearAllPoints()
+			self.Holder.Grip:SetPoint("TOPRIGHT", referenceHolder, "TOPLEFT", HOLDER_OFFSET, 0)
+		end
+	end
+	--[[
+	if(self.HyperBuffFrame) then
+		self:Update_ConsolidatedBuffsSettings()
+	end
+	]]--
+end
+--[[
+##########################################################
+UPDATE AND BUILD
+##########################################################
+]]--
+function MOD:ReLoad()
+	if(InCombatLockdown()) then return end
+	local maxShown = #self.media.hyperAuraIcons - 1
+	local CB_HEIGHT = Minimap:GetHeight() - 50;
+	local CB_WIDTH = (CB_HEIGHT / maxShown) + 4;
+	if(SVUI_MinimapFrame) then
+		CB_HEIGHT = SVUI_MinimapFrame:GetHeight() - 50;
+	end
+	self.Holder:SetSize(CB_WIDTH, CB_HEIGHT)
+	AURA_FADE_TIME = SV.db.Auras.fadeBy
+	self:UpdateAuraHeader(SVUI_PlayerBuffs, "buffs");
+	self:UpdateAuraHeader(SVUI_PlayerDebuffs, "debuffs");
+	self:UpdateProcWatch();
+end
+
+function MOD:Load()
+	local maxShown = #self.media.hyperAuraIcons - 1;
+	local CB_HEIGHT = Minimap:GetHeight() - 50;
+	local CB_WIDTH = (CB_HEIGHT / maxShown) + 4;
+
+	if(SVUI_MinimapFrame) then
+		CB_HEIGHT = SVUI_MinimapFrame:GetHeight() - 50;
+	end
+
+	self.Holder:SetSize(CB_WIDTH, CB_HEIGHT)
+	self.Holder:SetPoint("TOPRIGHT", Minimap, "TOPLEFT", HOLDER_OFFSET, 0)
+
+	--[[
+	if(SV.db.Auras.hyperBuffsEnabled) then
+		ConsolidatedBuffs:Die()
+
+		self.HyperBuffFrame:SetAllPoints(self.Holder)
+		self.HyperBuffFrame:SetFrameStrata("BACKGROUND")
+		SV:ManageVisibility(self.HyperBuffFrame)
+
+		for i = 1, NUM_LE_RAID_BUFF_TYPES do
+			local texture = self.media.hyperAuraIcons[i]
+			local buff = CreateFrame("Button", nil, self.HyperBuffFrame)
+			buff.bar = CreateFrame("StatusBar", nil, buff)
+			buff.bar:SetAllPoints(buff)
+			buff.bar:SetStatusBarTexture(texture)
+			buff.bar:SetOrientation("VERTICAL")
+			buff.bar:SetMinMaxValues(0, 100)
+			buff.bar:SetValue(0)
+
+			buff.bg = buff.bar:CreateTexture(nil, "BACKGROUND", nil, -2)
+			buff.bg:WrapPoints(buff, 1, 1)
+			buff.bg:SetTexture(texture)
+			buff.bg:SetVertexColor(0, 0, 0, 0.5)
+
+			buff.empty = buff.bar:CreateTexture(nil, "BACKGROUND", nil, -1)
+			buff.empty:SetAllPoints(buff)
+			buff.empty:SetTexture(texture)
+			buff.empty:SetDesaturated(true)
+			buff.empty:SetVertexColor(0.5, 0.5, 0.5)
+			buff.empty:SetBlendMode("ADD")
+
+			buff:SetAlpha(0.1)
+			buff:SetID(i)
+
+			self.HyperBuffFrame[i] = buff
+		end
+		SV.Events:On("PLAYER_ROLE_CHANGED", PlayerRoleChanged)
+		self:Update_ConsolidatedBuffsSettings()
+	end
+	]]--
+	if(SV.db.Auras.aurasEnabled) then
+		BuffFrame:Die()
+		TemporaryEnchantFrame:Die()
+		InterfaceOptionsFrameCategoriesButton12:SetScale(0.0001)
+
+		local buffHeader = CreateFrame("Frame", "SVUI_PlayerBuffs", self.Holder, "SecureAuraHeaderTemplate")
+		buffHeader:SetClampedToScreen(true)
+		buffHeader:SetPoint("TOPRIGHT", self.Holder, "TOPLEFT", -8, 0)
+		buffHeader:SetAttribute("unit", "player")
+		buffHeader:SetAttribute("filter", "HELPFUL")
+		RegisterStateDriver(buffHeader, "visibility", "[petbattle] hide; show")
+		RegisterAttributeDriver(buffHeader, "unit", "[vehicleui] vehicle; player")
+		buffHeader:SetAttribute("consolidateDuration", -1)
+		buffHeader:SetAttribute("includeWeapons", 1)
+		self:UpdateAuraHeader(buffHeader, "buffs")
+		buffHeader:Show()
+
+		local debuffHeader = CreateFrame("Frame", "SVUI_PlayerDebuffs", self.Holder, "SecureAuraHeaderTemplate")
+		debuffHeader:SetClampedToScreen(true)
+		debuffHeader:SetPoint( "BOTTOMRIGHT", self.Holder, "BOTTOMLEFT", -8, 0)
+		debuffHeader:SetAttribute("unit", "player")
+		debuffHeader:SetAttribute("filter", "HARMFUL")
+		RegisterStateDriver(debuffHeader, "visibility", "[petbattle] hide; show")
+		RegisterAttributeDriver(debuffHeader, "unit", "[vehicleui] vehicle; player")
+		self:UpdateAuraHeader(debuffHeader, "debuffs")
+		debuffHeader:Show()
+	end
+
+	SV:NewAnchor(self.Holder, L["Auras Frame"])
+	SV:ManageVisibility(self.Holder)
+
+	self:InitializeProcWatch()
+end
diff --git a/SVUI_Auras/SVUI_Auras.toc b/SVUI_Auras/SVUI_Auras.toc
new file mode 100644
index 0000000..1a67c50
--- /dev/null
+++ b/SVUI_Auras/SVUI_Auras.toc
@@ -0,0 +1,16 @@
+## Interface: 70000
+## Author: Failcoder
+## Version: 1.3.5
+## Title: |cffFF9900SuperVillain UI: |r|cffFFEF00Auras|r
+## Notes: Aura Plugin for [|cff9911FFSVUI|r].
+## OptionalDeps: LibSharedMedia-3.0
+## RequiredDeps: SVUI_!Core
+## X-SVUIName: Auras
+## X-SVUISchema: Auras
+## X-Email: munglunch@gmail.com
+## X-Website: http://www.supervillainui.com
+## X-Donate: PayPal:munglunch@gmail.com
+## X-License: MIT
+## X-Category: Interface Enhancements
+
+SVUI_Auras.xml
diff --git a/SVUI_Auras/SVUI_Auras.xml b/SVUI_Auras/SVUI_Auras.xml
new file mode 100644
index 0000000..afadecd
--- /dev/null
+++ b/SVUI_Auras/SVUI_Auras.xml
@@ -0,0 +1,119 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+    <Script file='Loader.lua'/>
+	<Script file='SVUI_Auras.lua'/>
+	<Script file="components\procs.lua"/>
+
+	<Button name='SVUI_AuraTemplate' inherits='SecureActionButtonTemplate' virtual='true'>
+        <Size x='26' y='26'/>
+        <Attributes>
+            <Attribute name='type' value='cancelaura'/>
+        </Attributes>
+        <Scripts>
+            <OnLoad>
+                SVUI.Auras:CreateIcon(self)
+                self:RegisterForClicks('RightButtonUp')
+            </OnLoad>
+            <OnEnter>
+                GameTooltip:SetOwner(self, 'ANCHOR_BOTTOMLEFT', -5, -5)
+                if(self:GetAttribute'index') then
+                    GameTooltip:SetUnitAura(SecureButton_GetUnit(self:GetParent()), self:GetID(), self:GetParent():GetAttribute("filter"))
+                elseif(self:GetAttribute'target-slot') then
+                    GameTooltip:SetInventoryItem('player', self:GetID())
+                end
+            </OnEnter>
+            <OnLeave function='GameTooltip_Hide'/>
+        </Scripts>
+    </Button>
+
+    <Button name='SVUI_AuraTemplate16' inherits='SVUI_AuraTemplate' virtual='true'>
+        <Size x='16' y='16'/>
+    </Button>
+
+    <Button name='SVUI_AuraTemplate18' inherits='SVUI_AuraTemplate' virtual='true'>
+        <Size x='18' y='18'/>
+    </Button>
+
+    <Button name='SVUI_AuraTemplate20' inherits='SVUI_AuraTemplate' virtual='true'>
+        <Size x='20' y='20'/>
+    </Button>
+
+    <Button name='SVUI_AuraTemplate22' inherits='SVUI_AuraTemplate' virtual='true'>
+        <Size x='22' y='22'/>
+    </Button>
+
+    <Button name='SVUI_AuraTemplate24' inherits='SVUI_AuraTemplate' virtual='true'>
+        <Size x='24' y='24'/>
+    </Button>
+
+    <Button name='SVUI_AuraTemplate26' inherits='SVUI_AuraTemplate' virtual='true'>
+        <Size x='26' y='26'/>
+    </Button>
+
+    <Button name='SVUI_AuraTemplate28' inherits='SVUI_AuraTemplate' virtual='true'>
+        <Size x='28' y='28'/>
+    </Button>
+
+    <Button name='SVUI_AuraTemplate30' inherits='SVUI_AuraTemplate' virtual='true'>
+        <Size x='30' y='30'/>
+    </Button>
+
+    <Button name='SVUI_AuraTemplate32' inherits='SVUI_AuraTemplate' virtual='true'>
+        <Size x='32' y='32'/>
+    </Button>
+
+    <Button name='SVUI_AuraTemplate34' inherits='SVUI_AuraTemplate' virtual='true'>
+        <Size x='34' y='34'/>
+    </Button>
+
+    <Button name='SVUI_AuraTemplate36' inherits='SVUI_AuraTemplate' virtual='true'>
+        <Size x='36' y='36'/>
+    </Button>
+
+    <Button name='SVUI_AuraTemplate38' inherits='SVUI_AuraTemplate' virtual='true'>
+        <Size x='38' y='38'/>
+    </Button>
+
+    <Button name='SVUI_AuraTemplate40' inherits='SVUI_AuraTemplate' virtual='true'>
+        <Size x='40' y='40'/>
+    </Button>
+
+    <Button name='SVUI_AuraTemplate42' inherits='SVUI_AuraTemplate' virtual='true'>
+        <Size x='42' y='42'/>
+    </Button>
+
+    <Button name='SVUI_AuraTemplate44' inherits='SVUI_AuraTemplate' virtual='true'>
+        <Size x='44' y='44'/>
+    </Button>
+
+    <Button name='SVUI_AuraTemplate46' inherits='SVUI_AuraTemplate' virtual='true'>
+        <Size x='46' y='46'/>
+    </Button>
+
+    <Button name='SVUI_AuraTemplate48' inherits='SVUI_AuraTemplate' virtual='true'>
+        <Size x='48' y='48'/>
+    </Button>
+
+    <Button name='SVUI_AuraTemplate50' inherits='SVUI_AuraTemplate' virtual='true'>
+        <Size x='50' y='50'/>
+    </Button>
+
+    <Button name='SVUI_AuraTemplate52' inherits='SVUI_AuraTemplate' virtual='true'>
+        <Size x='52' y='52'/>
+    </Button>
+
+    <Button name='SVUI_AuraTemplate54' inherits='SVUI_AuraTemplate' virtual='true'>
+        <Size x='54' y='54'/>
+    </Button>
+
+    <Button name='SVUI_AuraTemplate56' inherits='SVUI_AuraTemplate' virtual='true'>
+        <Size x='56' y='56'/>
+    </Button>
+
+    <Button name='SVUI_AuraTemplate58' inherits='SVUI_AuraTemplate' virtual='true'>
+        <Size x='58' y='58'/>
+    </Button>
+
+    <Button name='SVUI_AuraTemplate60' inherits='SVUI_AuraTemplate' virtual='true'>
+        <Size x='60' y='60'/>
+    </Button>
+</Ui>
\ No newline at end of file
diff --git a/SVUI_Auras/assets/AURA-CRIT.blp b/SVUI_Auras/assets/AURA-CRIT.blp
new file mode 100644
index 0000000..c13b8c3
Binary files /dev/null and b/SVUI_Auras/assets/AURA-CRIT.blp differ
diff --git a/SVUI_Auras/assets/AURA-HASTE.blp b/SVUI_Auras/assets/AURA-HASTE.blp
new file mode 100644
index 0000000..571f9ca
Binary files /dev/null and b/SVUI_Auras/assets/AURA-HASTE.blp differ
diff --git a/SVUI_Auras/assets/AURA-HEART.blp b/SVUI_Auras/assets/AURA-HEART.blp
new file mode 100644
index 0000000..f849890
Binary files /dev/null and b/SVUI_Auras/assets/AURA-HEART.blp differ
diff --git a/SVUI_Auras/assets/AURA-MASTERY.blp b/SVUI_Auras/assets/AURA-MASTERY.blp
new file mode 100644
index 0000000..ca9a60f
Binary files /dev/null and b/SVUI_Auras/assets/AURA-MASTERY.blp differ
diff --git a/SVUI_Auras/assets/AURA-MULTISTRIKE.blp b/SVUI_Auras/assets/AURA-MULTISTRIKE.blp
new file mode 100644
index 0000000..6ce3690
Binary files /dev/null and b/SVUI_Auras/assets/AURA-MULTISTRIKE.blp differ
diff --git a/SVUI_Auras/assets/AURA-POWER.blp b/SVUI_Auras/assets/AURA-POWER.blp
new file mode 100644
index 0000000..60e07d1
Binary files /dev/null and b/SVUI_Auras/assets/AURA-POWER.blp differ
diff --git a/SVUI_Auras/assets/AURA-SPELL.blp b/SVUI_Auras/assets/AURA-SPELL.blp
new file mode 100644
index 0000000..36d1ae0
Binary files /dev/null and b/SVUI_Auras/assets/AURA-SPELL.blp differ
diff --git a/SVUI_Auras/assets/AURA-STATS.blp b/SVUI_Auras/assets/AURA-STATS.blp
new file mode 100644
index 0000000..8db97fd
Binary files /dev/null and b/SVUI_Auras/assets/AURA-STATS.blp differ
diff --git a/SVUI_Auras/assets/AURA-VERSATILITY.blp b/SVUI_Auras/assets/AURA-VERSATILITY.blp
new file mode 100644
index 0000000..9b05708
Binary files /dev/null and b/SVUI_Auras/assets/AURA-VERSATILITY.blp differ
diff --git a/SVUI_Auras/components/procs.lua b/SVUI_Auras/components/procs.lua
new file mode 100644
index 0000000..06d20aa
--- /dev/null
+++ b/SVUI_Auras/components/procs.lua
@@ -0,0 +1,227 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack    = _G.unpack;
+local select    = _G.select;
+local pairs     = _G.pairs;
+local ipairs    = _G.ipairs;
+local type      = _G.type;
+local error     = _G.error;
+local pcall     = _G.pcall;
+local tostring  = _G.tostring;
+local tonumber  = _G.tonumber;
+local string 	= _G.string;
+local math 		= _G.math;
+local table 	= _G.table;
+--[[ STRING METHODS ]]--
+local format = string.format;
+--[[ MATH METHODS ]]--
+local abs, ceil, floor, round = math.abs, math.ceil, math.floor, math.round;
+--[[ TABLE METHODS ]]--
+local tremove, twipe = table.remove, table.wipe;
+--BLIZZARD API
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+local GameTooltip           = _G.GameTooltip;
+local ReloadUI              = _G.ReloadUI;
+local hooksecurefunc        = _G.hooksecurefunc;
+local GetTime               = _G.GetTime;
+local UnitName              = _G.UnitName;
+local UnitGUID              = _G.UnitGUID;
+local UnitAura              = _G.UnitAura;
+local UnitBuff              = _G.UnitBuff;
+local UnitDebuff            = _G.UnitDebuff;
+local UnitStat              = _G.UnitStat;
+local UnitLevel             = _G.UnitLevel;
+local UnitClass             = _G.UnitClass;
+local NUM_LE_RAID_BUFF_TYPES = _G.NUM_LE_RAID_BUFF_TYPES;
+local RAID_CLASS_COLORS     = _G.RAID_CLASS_COLORS;
+local CUSTOM_CLASS_COLORS   = _G.CUSTOM_CLASS_COLORS;
+local GetItemQualityColor   = _G.GetItemQualityColor;
+local GetInventoryItemQuality   = _G.GetInventoryItemQuality;
+local GetInventoryItemTexture   = _G.GetInventoryItemTexture;
+local GetWeaponEnchantInfo  = _G.GetWeaponEnchantInfo;
+local RegisterStateDriver   = _G.RegisterStateDriver;
+local UnregisterStateDriver = _G.UnregisterStateDriver;
+local RegisterAttributeDriver   = _G.RegisterAttributeDriver;
+local GetRaidBuffTrayAuraInfo 	= _G.GetRaidBuffTrayAuraInfo;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L
+local MOD = SV.Auras;
+if(not MOD) then return end;
+--[[
+##########################################################
+LOCAL VARS
+##########################################################
+]]--
+local ProcWatch = CreateFrame('Frame', 'SVUI_ProcWatch', UIParent);
+
+local OnCooldDownExpired = function(self)
+	self.timeLeft = nil;
+	self:FadeOut(0.2, 1, 0, true)
+end
+
+local function CreateProcIcon()
+	local proc = CreateFrame("Frame", nil, ProcWatch)
+
+ 	local bg = proc:CreateTexture(nil, "BACKGROUND")
+	bg:SetAllPoints()
+	bg:SetColorTexture(0,0,0,0.5)
+
+	proc.icon = proc:CreateTexture(nil, "BORDER")
+	proc.icon:InsetPoints(proc, 2, 2)
+	proc.icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+	proc.icon:SetVertexColor(1,1,1,0.6)
+
+	proc.count = proc:CreateFontString(nil, "ARTWORK")
+	proc.count:SetPoint("BOTTOMRIGHT", (-1 + SV.db.Auras.countOffsetH), (1 + SV.db.Auras.countOffsetV))
+	proc.count:SetFontObject(SVUI_Font_Aura)
+
+	proc.time = proc:CreateFontString(nil, "ARTWORK")
+	proc.time:SetPoint("TOP", proc, "BOTTOM", 1 + SV.db.Auras.timeOffsetH, 0 + SV.db.Auras.timeOffsetV)
+	proc.time:SetFontObject(SVUI_Font_Aura)
+	proc.HideAfterCooldown = true
+	proc.cooldown = SV.API:CD(proc);
+
+	proc.highlight = proc:CreateTexture(nil, "HIGHLIGHT")
+	proc.highlight:SetTexture(SV.media.statusbar.default)
+	proc.highlight:SetVertexColor(1, 1, 1, 0.45)
+	proc.highlight:InsetPoints(proc, 2, 2)
+
+	SV.Animate:Kapow(proc, false, true, true)
+
+	return proc;
+end
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+local PROC_UNIT_AURA = function(self, event, unit)
+	if(not unit) then return end
+
+	local index = 1
+	local SPELLS = self.cache
+	local PROCS = self.slots
+	local _, name, texture, count, duration, expiration, caster, key, spellID
+	local filter = "HELPFUL";
+	local lastProc;
+	local lastIndex = 1;
+
+	while true do
+		name, _, texture, count, _, duration, expiration, caster, _, _, spellID = UnitAura(unit, index, filter)
+		if not name then
+			if filter == "HELPFUL" then
+				filter = "HARMFUL"
+				index = 1
+			else
+				break
+			end
+		else
+			local aura = PROCS[lastIndex]
+			if(SPELLS[spellID] and aura and duration and (duration > 0)) then
+				aura:ClearAllPoints()
+				if(not lastProc) then
+					aura:SetPoint('RIGHT', self, 'RIGHT', 0, 0)
+				else
+					aura:SetPoint('RIGHT', lastProc, 'LEFT', -1, 0)
+				end
+				local timeleft = expiration - duration;
+				local lastTimer = aura.LastTimer or 0
+
+				if(lastTimer < expiration) then
+					aura.anim:Stop()
+					aura.icon:SetTexture(texture)
+					aura:Show()
+					aura.anim[2]:SetDuration(duration)
+      		aura.anim:Play()
+      		aura.cooldown:SetCooldown(timeleft, duration)
+      	end
+      	aura.LastTimer = expiration
+
+				local textCount = '';
+				if(count and (count > 1)) then
+					textCount = count
+				end
+				aura.count:SetText(textCount);
+
+				lastProc = aura;
+				lastIndex = lastIndex + 1;
+			end
+			index = index + 1
+		end
+	end
+
+	for x=lastIndex, #PROCS do
+		PROCS[x]:Hide()
+	end
+end
+
+function MOD:UpdateProcWatch()
+	ProcWatch.cache = {}
+	ProcWatch.slots = {}
+	local pwSize = SV.db.Auras.procSize or 40;
+	local CONFIG = SV.db.Filters.Procs
+	local i,j = 1,1;
+	for procID,procData in pairs(CONFIG) do
+		if(procData.enable) then
+			local spellID = tonumber(procID);
+			local spellName,_,spellTexture = GetSpellInfo(spellID)
+			if spellName then
+				local proc = ProcWatch.slots[j];
+				ProcWatch.cache[spellID] = true
+				if(not proc) then
+					proc = CreateProcIcon()
+					ProcWatch.slots[j] = proc
+				end;
+				j = j + 1;
+				proc.name = spellName;
+				proc.index = i;
+				proc.spellID = spellID;
+				proc:SetWidth(pwSize)
+				proc:SetHeight(pwSize)
+				proc:ClearAllPoints()
+				proc:SetPoint('RIGHT', ProcWatch, 'RIGHT', -((i - 1) * 43), 0)
+				proc.icon:SetTexture(spellTexture)
+				proc:Hide();
+
+				i = i + 1
+			end
+		end
+	end;
+end;
+
+function MOD:InitializeProcWatch()
+	if(not SV.db.Auras.procsEnabled) then return end;
+
+	if(not SV.db.Filters.Procs) then
+		SV.db.Filters.Procs = {}
+	end
+
+	local ProcsAnchor = CreateFrame('Frame', 'SVUI_ProcWatchFrame', SV.Screen)
+	ProcsAnchor:SetSize(172,40)
+	ProcsAnchor:SetPoint("TOPRIGHT", SV.Screen, "CENTER", -50, -50)
+
+	ProcWatch:SetParent(ProcsAnchor)
+	ProcWatch:SetWidth(720)
+	ProcWatch:SetHeight(40)
+	ProcWatch:SetPoint('RIGHT', ProcsAnchor, 'RIGHT', 0, 0)
+	ProcWatch:RegisterUnitEvent("UNIT_AURA", "player")
+	ProcWatch:SetScript('OnEvent', PROC_UNIT_AURA)
+
+	SV:NewAnchor(ProcsAnchor, L["Procs Frame"])
+
+	self:UpdateProcWatch();
+	SV.Events:On("AURA_FILTER_OPTIONS_CHANGED", MOD.UpdateProcWatch, true);
+end;
diff --git a/SVUI_Chat/LICENSE.txt b/SVUI_Chat/LICENSE.txt
new file mode 100644
index 0000000..05ceba8
--- /dev/null
+++ b/SVUI_Chat/LICENSE.txt
@@ -0,0 +1,31 @@
+
+The MIT License
+
+Copyright (c) 2010, Failcoder (Steve Jackson)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy
+of this software and associated documentation files (the "Software"), to
+deal
+in the Software without restriction, including without limitation the
+rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/SVUI_Chat/Loader.lua b/SVUI_Chat/Loader.lua
new file mode 100644
index 0000000..c6675f5
--- /dev/null
+++ b/SVUI_Chat/Loader.lua
@@ -0,0 +1,202 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+
+local SV = _G["SVUI"];
+local L = SV.L
+local name, obj = ...
+local MOD = SV:NewModule(name, obj, "SVUI_Global_ChatCache", "SVUI_Private_ChatCache");
+local Schema = MOD.Schema;
+
+SV:AssignMedia("font", "chatdialog", "SVUI Default Font", 12, "OUTLINE");
+SV:AssignMedia("font", "chattab", "SVUI Caps Font", 12, "OUTLINE");
+SV:AssignMedia("globalfont", "chatdialog", "SVUI_Font_Chat");
+SV:AssignMedia("globalfont", "chattab", "SVUI_Font_ChatTab");
+
+MOD.media = {}
+MOD.media.dockIcon = [[Interface\AddOns\SVUI_Chat\assets\DOCK-ICON-CHAT]];
+MOD.media.scrollIcon = [[Interface\AddOns\SVUI_Chat\assets\CHAT-SCROLL]];
+MOD.media.whisperIcon = [[Interface\AddOns\SVUI_Chat\assets\CHAT-WHISPER]];
+
+SV.defaults[Schema] = {
+	["docked"] = "BottomLeft",
+	["tabHeight"] = 20,
+	["tabWidth"] = 75,
+	["tabStyled"] = true,
+	["font"] = "SVUI Default Font",
+	["fontOutline"] = "OUTLINE",
+	["tabFont"] = "SVUI Tab Font",
+	["tabFontSize"] = 11,
+	["tabFontOutline"] = "OUTLINE",
+	["url"] = true,
+	["hyperlinkHover"] = true,
+	["throttleInterval"] = 45,
+	["fade"] = false,
+	["sticky"] = true,
+	["smileys"] = true,
+	["shortChannels"] = true,
+	["hideRealms"] = false,
+	["mention"] = "Mention Alert",
+	["psst"] = "Whisper Alert",
+	["noWipe"] = false,
+	["timeStampFormat"] = "NONE",
+	["secretWords"] = "%MYNAME%, SVUI",
+	["basicTools"] = true,
+	["bubbles"] = true,
+};
+
+function MOD:LoadOptions()
+	local chatFonts = {
+		["chatdialog"] = {
+			order = 1,
+			name = "Chat",
+			desc = "Font used for chat text."
+		},
+		["chattab"] = {
+			order = 2,
+			name = "Chat Tabs",
+			desc = "Font used for chat tab labels."
+		},
+	};
+
+	SV:GenerateFontOptionGroup("Chat", 5, "Fonts used for the chat frame.", chatFonts)
+
+	SV.Options.args[Schema] = {
+		type = "group",
+		name = Schema,
+		get = function(a)return SV.db[Schema][a[#a]]end,
+		set = function(a,b)MOD:ChangeDBVar(b,a[#a]); end,
+		args = {
+			intro = {
+				order = 1,
+				type = "description",
+				name = L["CHAT_DESC"],
+				width = 'full'
+			},
+			common = {
+				order = 2,
+				type = "group",
+				name = L["General"],
+				guiInline = true,
+				args = {
+					sticky = {
+						order = 1,
+						type = "toggle",
+						name = L["Sticky Chat"],
+						desc = L["When opening the Chat Editbox to type a message having this option set means it will retain the last channel you spoke in. If this option is turned off opening the Chat Editbox should always default to the SAY channel."]
+					},
+					url = {
+						order = 2,
+						type = "toggle",
+						name = L["URL Links"],
+						desc = L["Attempt to create URL links inside the chat."],
+						set = function(a,b) MOD:ChangeDBVar(b,a[#a]) end
+					},
+					hyperlinkHover = {
+						order = 3,
+						type = "toggle",
+						name = L["Hyperlink Hover"],
+						desc = L["Display the hyperlink tooltip while hovering over a hyperlink."],
+						set = function(a,b) MOD:ChangeDBVar(b,a[#a]); MOD:ToggleHyperlinks(b); end
+					},
+					smileys = {
+						order = 4,
+						type = "toggle",
+						name = L["Emotion Icons"],
+						desc = L["Display emotion icons in chat."]
+					},
+					tabStyled = {
+						order = 5,
+						type = "toggle",
+						name = L["Custom Tab Style"],
+						set = function(a,b) MOD:ChangeDBVar(b,a[#a]);SV:StaticPopup_Show("RL_CLIENT") end,
+					},
+					shortChannels = {
+						order = 6,
+						type = "toggle",
+						name = L["Abbreviation"],
+						desc = "Shortened channel names",
+					},
+					hideRealms = {
+						order = 7,
+						type = "toggle",
+						name = L['Player Realms'],
+						desc = L['Show/hide the players realm next to their name.'],
+					},
+					bubbles = {
+						order = 8,
+						type = "toggle",
+						name = L['Chat Bubbles'],
+						desc = L['Style the blizzard chat bubbles.'],
+						get = function(a)return SV.db[Schema][a[#a]] end,
+						set = function(a,b) MOD:ChangeDBVar(b,a[#a]);SV:StaticPopup_Show("RL_CLIENT")end
+					},
+					spacer1 = {
+						order = 9,
+						type = "description",
+						name = ""
+					},
+					timeStampFormat = {
+						order = 10,
+						type = "select",
+						name = TIMESTAMPS_LABEL,
+						desc = OPTION_TOOLTIP_TIMESTAMPS,
+						values = {
+							["NONE"] = NONE,
+							["%I:%M "] = "03:27",
+							["%I:%M:%S "] = "03:27:32",
+							["%I:%M %p "] = "03:27 PM",
+							["%I:%M:%S %p "] = "03:27:32 PM",
+							["%H:%M "] = "15:27",
+							["%H:%M:%S "] = "15:27:32"
+						}
+					},
+					psst = {
+						order = 11,
+						type = "select",
+						dialogControl = "LSM30_Sound",
+						name = L["Whisper Alert"],
+						disabled = function()return not SV.db[Schema].psst end,
+						values = AceVillainWidgets.sound,
+						set = function(a,b) MOD:ChangeDBVar(b,a[#a]) end
+					},
+					mention = {
+						order = 12,
+						type = "select",
+						dialogControl = "LSM30_Sound",
+						name = L["Mention Alert"],
+						disabled = function()return not SV.db[Schema].mention end,
+						values = AceVillainWidgets.sound,
+						set = function(a,b) MOD:ChangeDBVar(b,a[#a]) end
+					},
+					spacer2 = {
+						order = 13,
+						type = "description",
+						name = ""
+					},
+					throttleInterval = {
+						order = 14,
+						type = "range",
+						name = L["Spam Interval"],
+						desc = L["Prevent the same messages from displaying in chat more than once within this set amount of seconds, set to zero to disable."],
+						min = 0,
+						max = 120,
+						step = 1,
+						width = "full",
+						set = function(a,b) MOD:ChangeDBVar(b,a[#a]) end
+					},
+				}
+			},
+		}
+	}
+end
diff --git a/SVUI_Chat/SVUI_Chat.lua b/SVUI_Chat/SVUI_Chat.lua
new file mode 100644
index 0000000..48aa78f
--- /dev/null
+++ b/SVUI_Chat/SVUI_Chat.lua
@@ -0,0 +1,1967 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pcall         = _G.pcall;
+local print         = _G.print;
+local ipairs        = _G.ipairs;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local rawset        = _G.rawset;
+local rawget        = _G.rawget;
+local tostring      = _G.tostring;
+local tonumber      = _G.tonumber;
+local getmetatable  = _G.getmetatable;
+local setmetatable  = _G.setmetatable;
+--STRING
+local string        = _G.string;
+local upper         = string.upper;
+local format        = string.format;
+local find          = string.find;
+local match         = string.match;
+local gsub          = string.gsub;
+local len          	= string.len;
+local sub          	= string.sub;
+local trim          = string.trim;
+--MATH
+local math          = _G.math;
+local floor         = math.floor
+local random 		= math.random;
+--TABLE
+local table         = _G.table;
+local tsort         = table.sort;
+local tconcat       = table.concat;
+local tinsert       = _G.tinsert;
+local tremove       = _G.tremove;
+local wipe          = _G.wipe;
+--BLIZZARD API
+local time 					= _G.time;
+local difftime 			= _G.difftime;
+
+local ChatFrame_AddMessageEventFilter = _G.ChatFrame_AddMessageEventFilter;
+local ChatEdit_ChooseBoxForSend = _G.ChatEdit_ChooseBoxForSend;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local MOD = SV.Chat;
+if(not MOD) then return end;
+--[[
+##########################################################
+LOCAL VARS
+##########################################################
+]]--
+local SetAllChatHooks, SetParseHandlers;
+local internalTest = false
+local locale = GetLocale()
+local NewHook = hooksecurefunc;
+--[[
+	Quick explaination of what Im doing with all of these locals...
+	Unlike many of the other modules, Chat has to continuously
+	reference config settings which can start to get sluggish. What
+	I have done is set local variables for every database value
+	that the module can read efficiently. The function "UpdateLocals"
+	is used to refresh these any time a change is made to configs
+	and once when the mod is loaded.
+]]--
+local PLAYER_NAME = UnitName("player");
+local PLAYER_FILTER = PLAYER_NAME:upper();
+local CHAT_THROTTLE = 45;
+local CHAT_ALLOW_URL = true;
+local CHAT_HOVER_URL = true;
+local CHAT_STICKY = true;
+local TAB_WIDTH = 75;
+local TAB_HEIGHT = 20;
+local TAB_SKINS = true;
+local CHAT_FADING = false;
+local CHAT_ABBREV = false;
+local TIME_STAMP_MASK = "NONE";
+local THROTTLE_CACHE = {};
+local COPY_LINES = {};
+local ACTIVE_HYPER_LINK;
+local TABS_DIRTY = false;
+local HIDE_REALM = false;
+--[[
+##########################################################
+INIT SETTINGS
+##########################################################
+]]--
+local REFRESH_LOCKED = false;
+local CHANNEL_LINK   		= "|Hchannel:%1$s|h%d:|h"
+local CHANNEL_PATTERN      	= "|Hchannel:(.-)|h%[(%d+)%.%s?([^:%-%]]+)%s?[:%-]?%s?[^|%]]*%]|h%s?"
+local CHANNEL_PATTERN_PLUS 	= CHANNEL_PATTERN .. ".+"
+local CHANNEL_STRINGS 		= {
+	[L["Conversation"]] 	= L["S_Conversation"],
+	[L["General"]] 			= L["S_General"],
+	[L["LocalDefense"]] 	= L["S_LocalDefense"],
+	[L["LookingForGroup"]] 	= L["S_LookingForGroup"],
+	[L["Trade"]] 			= L["S_Trade"],
+	[L["WorldDefense"]] 	= L["WorldDefense"],
+}
+local INTERNAL_TABLES = { 'channelList', 'zoneChannelList', 'messageTypeList' };
+local SECRET_SOUND = [[Interface\AddOns\SVUI_!Core\assets\sounds\whisper.mp3]];
+local WHISPER_SOUND = [[Interface\AddOns\SVUI_!Core\assets\sounds\whisper.mp3]];
+
+local GENERAL_LINK_PATTERN = "[^%:]+";
+local GENERAL_REALM_PATTERN = "%-[^|]+";
+local PLAYER_PATTERN = "|Hplayer:(.-)|h%[(.-)%]|h";
+local PLAYER_LINK    = "|Hplayer:%s|h%s|h"
+local PLAYER_BN_LINK = "|HBNplayer:%s|h%s%s|h"
+local BNPLAYER_PATTERN = "|HBNplayer:(.-)|h%[(|Kb(%d+).-)%](.*)|h"
+--[[
+##########################################################
+LOCAL FUNCTIONS
+##########################################################
+]]--
+local function case_insensitive(source)
+  local p = source:gsub("(%%?)(.)", function(percent, letter)
+    if percent ~= "" or not letter:match("%a") then
+      return percent .. letter
+    else
+      return format("[%s%s]", letter:lower(), letter:upper())
+    end
+  end)
+  return p
+end
+
+local PLAYERNAME_MATCH = case_insensitive(PLAYER_NAME);
+
+local AddModifiedMessage;
+local ScrollIndicator = CreateFrame("Frame", nil)
+local HighLight_OnUpdate = function(self)
+	if(self:IsMouseOver(50, -2, 0, 50)) then
+		self.texture:SetGradientAlpha("HORIZONTAL",0,1,0,0.8,0,0.3,0,0)
+	else
+		self.texture:SetGradientAlpha("HORIZONTAL",0,1,1,0.8,0,0.3,0.3,0)
+	end
+end
+do
+	local EmoteCount = 38;
+	local EmotePatterns = {
+		{
+			"%:%-%@","%:%@","%:%-%)","%:%)","%:D","%:%-D","%;%-D","%;D","%=D",
+			"xD","XD","%:%-%(","%:%(","%:o","%:%-o","%:%-O","%:O","%:%-0",
+			"%:P","%:%-P","%:p","%:%-p","%=P","%=p","%;%-p","%;p","%;P","%;%-P",
+			"%;%-%)","%;%)","%:S","%:%-S","%:%,%(","%:%,%-%(","%:%'%(",
+			"%:%'%-%(","<3","</3",
+			--"%:%F",
+		},
+		{
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\angry.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\angry.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\happy.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\happy.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\grin.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\grin.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\grin.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\grin.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\grin.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\grin.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\grin.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\sad.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\sad.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\surprise.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\surprise.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\surprise.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\surprise.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\surprise.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\tongue.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\tongue.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\tongue.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\tongue.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\tongue.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\tongue.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\tongue.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\tongue.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\tongue.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\tongue.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\winky.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\winky.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\hmm.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\hmm.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\weepy.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\weepy.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\weepy.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\weepy.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\heart.blp]],
+			[[Interface\AddOns\SVUI_Chat\assets\Emoticons\broken_heart.blp]],
+			--[[Interface\AddOns\SVUI_Chat\assets\Emoticons\middle_finger.blp]]
+		}
+	}
+
+	local function GetEmoticon(pattern)
+		for i=1, #EmotePatterns[1] do
+			local emote,icon = EmotePatterns[1][i], EmotePatterns[2][i];
+			pattern = gsub(pattern, emote, "|T" .. icon .. ":16|t");
+		end
+		return pattern;
+	end
+
+	local function SetEmoticon(text)
+		if not text then return end
+		if (not SV.db.Chat.smileys or text:find(" / run") or text:find(" / dump") or text:find(" / script")) then
+			return text
+		end
+		local result = "";
+		local maxLen = len(text);
+		local count = 1;
+		local temp, pattern;
+		while count  <= maxLen do
+			temp = maxLen;
+			local section = find(text, "|H", count, true)
+			if section ~= nil then temp = section end
+			pattern = sub(text, count, temp);
+			result = result .. GetEmoticon(pattern)
+			count = temp  +  1;
+			if section ~= nil then
+				temp = find(text, "|h]|r", count, -1) or find(text, "|h", count, -1)
+				temp = temp or maxLen;
+				if count < temp then
+					result = result..sub(text, count, temp)
+					count = temp  +  1;
+				end
+			end
+		end
+		return result
+	end
+
+	local SVUI_ParseMessage = function(self, event, text, ...)
+		if(not CHAT_ALLOW_URL) then
+			text = SetEmoticon(text)
+			return false, text, ...
+		end
+		local result, ct = text:gsub("(%a+)://(%S+)%s?", "%1://%2")
+		if ct > 0 then
+			return false, SetEmoticon(result), ...
+		end
+		result, ct = text:gsub("www%.([_A-Za-z0-9-]+)%.(%S+)%s?", "www.%1.%2")
+		if ct > 0 then
+			return false, SetEmoticon(result), ...
+		end
+		result, ct = text:gsub("([_A-Za-z0-9-%.]+)@([_A-Za-z0-9-]+)(%.+)([_A-Za-z0-9-%.]+)%s?", "%1@%2%3%4")
+		if ct > 0 then
+			return false, SetEmoticon(result), ...
+		end
+		text = SetEmoticon(text)
+		return false, text, ...
+	end
+
+	local function _concatTimeStamp(msg)
+		if (TIME_STAMP_MASK and TIME_STAMP_MASK ~= 'NONE' ) then
+			local timeStamp = BetterDate(TIME_STAMP_MASK, time());
+			timeStamp = timeStamp:gsub(' ', '')
+			timeStamp = timeStamp:gsub('AM', ' AM')
+			timeStamp = timeStamp:gsub('PM', ' PM')
+			msg = '|cffB3B3B3['..timeStamp..'] |r'..msg
+		end
+		return msg
+	end
+
+	local function _getlink(this, prefix, text, color)
+	    text = tostring(text)
+	    local colorstring = ("|cff%s%s|r"):format(color or "ffffff", tostring(this))
+	    return format("|H%s:%s|h%s|h", prefix, text, colorstring)
+	end
+
+	local function _parse(arg1, arg2, arg3)
+		internalTest = true;
+		local prefix = (" [%s]"):format(arg2)
+		local slink = _getlink(prefix, "url", arg2, "0099FF")
+		return ("%s "):format(slink)
+	end
+
+	local function _escape(arg1)
+		return arg1:gsub("([%%%+%-%.%[%]%*%?])", "%%%1")
+	end
+
+	function AddModifiedMessage(self, message, ...)
+		internalTest = false;
+		if type(message) == "string" then
+			-- if(message:find("%pHshare%p+") or message:find("%pHSHARE%p+")) then
+			-- 	internalTest = true
+			-- end
+
+			-- print(message)
+
+			if((not internalTest) and CHAT_ABBREV) then
+				local channelData, channelID, channelName = message:match(CHANNEL_PATTERN_PLUS)
+				if(channelData) then
+					local shortName = CHANNEL_STRINGS[channelName] or CHANNEL_STRINGS[channelName:lower()] or channelName:sub(1, 2);
+					message = message:gsub(CHANNEL_PATTERN, CHANNEL_LINK:format(channelData, channelID, shortName))
+				end
+
+				local playerData, playerName = message:match(PLAYER_PATTERN)
+
+				if(playerData) then
+					local strName = playerName
+					if(HIDE_REALM) then
+						if(playerName:match("|cff")) then
+							strName = playerName:gsub(GENERAL_REALM_PATTERN, "")
+						else
+							strName = playerName:match("[^%-]+")
+						end
+					else
+						if(not playerName:match("|cff")) then
+							strName = playerName:match("[^%-]+")
+						end
+					end
+					strName = "[" .. strName .. "]"
+					message = message:gsub(PLAYER_PATTERN, PLAYER_LINK:format(playerData, strName))
+				elseif(channelID) then
+					message = message:gsub("(|Hchannel:.-|h): ", "%1 ", 1)
+				end
+
+				local bnData, bnName, bnID, bnExtra = message:match(BNPLAYER_PATTERN)
+				if bnData and bnName then
+					local toastIcon = message:match("|TInterface\\FriendsFrame\\UI%-Toast%-ToastIcons.-|t")
+					if toastIcon then
+						local gameIcon = message:match("|TInterface\\ChatFrame\\UI%-ChatIcon.-|t")
+						if gameIcon then
+							message = message:gsub(_escape(toastIcon), gameIcon, 1)
+							bnExtra = bnExtra:gsub("%s?%(.-%)", "")
+						end
+					end
+					message = gsub(message, BNPLAYER_PATTERN, format(PLAYER_BN_LINK, bnData, bnName, bnExtra or ""))
+				end
+			end
+
+			if(message:find("%pTInterface%p+") or message:find("%pTINTERFACE%p+")) then
+				internalTest = true
+			end
+
+			if not internalTest then message = message:gsub("(%s?)(%d%d?%d?%.%d%d?%d?%.%d%d?%d?%.%d%d?%d?:%d%d?%d?%d?%d?)(%s?)", _parse) end
+			if not internalTest then message = message:gsub("(%s?)(%d%d?%d?%.%d%d?%d?%.%d%d?%d?%.%d%d?%d?)(%s?)", _parse) end
+			if not internalTest then message = message:gsub("(%s?)([%w_-]+%.?[%w_-]+%.[%w_-]+:%d%d%d?%d?%d?)(%s?)", _parse) end
+			if not internalTest then message = message:gsub("(%s?)(%a+://[%w_/%.%?%%=~&-'%-]+)(%s?)", _parse) end
+			if not internalTest then message = message:gsub("(%s?)(www%.[%w_/%.%?%%=~&-'%-]+)(%s?)", _parse) end
+			if not internalTest then message = message:gsub("(%s?)([_%w-%.~-]+@[_%w-]+%.[_%w-%.]+)(%s?)", _parse) end
+			if(self.___isFaded) then
+				--message = message:gsub("|TInterface\\TargetingFrame\\UI%-RaidTargetingIcon_(.*)|t", "")
+				message = message:gsub("|TInterface.-|t", "")
+				message = message:gsub("(%s?)({.-})(%s?)", "");
+			end
+		end
+		self.TempAddMessage(self, _concatTimeStamp(message), ...)
+	end
+
+	local Standard_ChatEventFilter = function(self, event, message, author, ...)
+		if locale == 'enUS' or locale == 'enGB' then
+			if message:find('[\227-\237]') then
+				return true;
+			end
+		end
+
+		return SVUI_ParseMessage(self, event, message, author, ...)
+	end
+
+	local AntiSpam_ChatEventFilter = function(self, event, message, author, ...)
+		if locale == 'enUS' or locale == 'enGB' then
+			if message:find('[\227-\237]') then
+				return true;
+			end
+		end
+
+		--print(message)
+		local test, flags = message:gsub("(%s?)({.-})(%s?)", "");
+    if(flags and (flags > 1)) then
+    	if(flags > 2) then
+			return true;
+	    end
+    end
+
+		if(CHAT_THROTTLE ~= 0) then
+			local sentFrom = author:upper()
+			if(not sentFrom:find(PLAYER_FILTER)) then
+				local msg
+				if(self.GetID) then
+					local chatID = self:GetID() or 0;
+					msg = chatID .. sentFrom .. message;
+				else
+					msg = sentFrom .. message;
+				end
+				if(msg ~= nil) then
+					if THROTTLE_CACHE[msg] then
+						local timeDiff = (time() - THROTTLE_CACHE[msg]) or 0
+						if timeDiff <= CHAT_THROTTLE then
+							return true;
+						end
+					end
+					THROTTLE_CACHE[msg] = time()
+				end
+			end
+		end
+
+		if(message:find(PLAYERNAME_MATCH) and (not InCombatLockdown())) then
+			PlaySoundFile(SECRET_SOUND, "Master")
+		end
+
+		return SVUI_ParseMessage(self, event, message, author, ...)
+	end
+
+	function SetParseHandlers()
+		ChatFrame_AddMessageEventFilter("CHAT_MSG_CHANNEL", AntiSpam_ChatEventFilter)
+		ChatFrame_AddMessageEventFilter("CHAT_MSG_YELL", AntiSpam_ChatEventFilter)
+		ChatFrame_AddMessageEventFilter("CHAT_MSG_SAY", AntiSpam_ChatEventFilter)
+
+		ChatFrame_AddMessageEventFilter("CHAT_MSG_WHISPER_INFORM", Standard_ChatEventFilter)
+		ChatFrame_AddMessageEventFilter("CHAT_MSG_WHISPER", Standard_ChatEventFilter)
+		ChatFrame_AddMessageEventFilter("CHAT_MSG_GUILD", Standard_ChatEventFilter)
+		ChatFrame_AddMessageEventFilter("CHAT_MSG_OFFICER", Standard_ChatEventFilter)
+		ChatFrame_AddMessageEventFilter("CHAT_MSG_PARTY", Standard_ChatEventFilter)
+		ChatFrame_AddMessageEventFilter("CHAT_MSG_PARTY_LEADER", Standard_ChatEventFilter)
+		ChatFrame_AddMessageEventFilter("CHAT_MSG_RAID", Standard_ChatEventFilter)
+		ChatFrame_AddMessageEventFilter("CHAT_MSG_RAID_LEADER", Standard_ChatEventFilter)
+		ChatFrame_AddMessageEventFilter("CHAT_MSG_INSTANCE_CHAT", Standard_ChatEventFilter)
+		ChatFrame_AddMessageEventFilter("CHAT_MSG_INSTANCE_CHAT_LEADER", Standard_ChatEventFilter)
+		ChatFrame_AddMessageEventFilter("CHAT_MSG_BN_CONVERSATION", Standard_ChatEventFilter)
+		ChatFrame_AddMessageEventFilter("CHAT_MSG_BN_WHISPER", Standard_ChatEventFilter)
+		ChatFrame_AddMessageEventFilter("CHAT_MSG_BN_WHISPER_INFORM", Standard_ChatEventFilter)
+		ChatFrame_AddMessageEventFilter("CHAT_MSG_BN_INLINE_TOAST_BROADCAST", Standard_ChatEventFilter);
+	end
+end
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+local TabsList = {};
+
+local function removeIconFromLine(text)
+	-- for i=1, 8 do
+	-- 	text = gsub(text, "|TInterface\\TargetingFrame\\UI%-RaidTargetingIcon_"..i..":0|t", "")
+	-- end
+	text = gsub(text, "(|TInterface(.*)|t)", "")
+	return text
+end
+
+function MOD:FadeLines(frame)
+	--print('Fading Lines for '..frame:GetName())
+	if(frame.___isFaded) then return end
+	for i = select("#", frame:GetRegions()), 1, -1 do
+		local region = select(i, frame:GetRegions())
+		if region:GetObjectType() == "FontString" then
+			local line = tostring(region:GetText())
+			local newtext = removeIconFromLine(line)
+			region:SetText(newtext)
+			region:SetAlpha(0)
+		end
+	end
+	frame.___isFaded = true;
+end
+
+function MOD:ShowLines(frame)
+	for i = select("#", frame:GetRegions()), 1, -1 do
+		local region = select(i, frame:GetRegions())
+		if region:GetObjectType() == "FontString" then
+			region:SetAlpha(1)
+		end
+	end
+	frame.___isFaded = nil;
+end
+
+function MOD:GetLines(...)
+	local index = 1
+	for i = select("#", ...), 1, -1 do
+		local region = select(i, ...)
+		if region:GetObjectType() == "FontString" then
+			local line = tostring(region:GetText())
+			COPY_LINES[index] = removeIconFromLine(line)
+			index = index + 1
+		end
+	end
+	return index - 1
+end
+
+do
+	local EB_HISTORY, EBH_LINE = {},{};
+	local doskey = false;
+
+	local _hook_AddHistoryLine = function(self, text)
+		if(not text or len(text) == 0) then
+			return
+		end
+		local cmd = text:match("^(/%S+)")
+		if(cmd and IsSecureCmd(cmd)) then
+			return
+		end
+		local ebName = self:GetName();
+		local frameHistory = EB_HISTORY[ebName];
+		local histCount = #frameHistory;
+		for i=1,histCount do
+			if frameHistory[i] == text then
+				EBH_LINE[ebName] = i + 1
+				return
+			end
+		end
+		histCount=histCount+1;
+		frameHistory[histCount] = text;
+		local histLines = self:GetHistoryLines();
+		for i=1,histCount do
+			if i > histLines then
+				frameHistory[i] = nil;
+				histCount=histCount-1;
+			end
+		end
+		EBH_LINE[ebName] = histCount+1;
+	end
+
+	local function UpdateFromEditBoxHistory(self, increment)
+		local ebName = self:GetName();
+		if(#EB_HISTORY[ebName] == 0) then return end
+		local current_line = EBH_LINE[ebName] + increment
+		if(current_line < 1) then
+			current_line = #EB_HISTORY[ebName];
+		elseif(current_line > #EB_HISTORY[ebName]) then
+			current_line = 1;
+		end
+		EBH_LINE[ebName] = current_line;
+		if(EB_HISTORY[ebName][current_line] ~= self:GetText()) then
+			local text = EB_HISTORY[ebName][current_line];
+			self:SetText(trim(text));
+			self:SetCursorPosition(len(text));
+		end
+	end
+
+	local SetHyperlink = ItemRefTooltip.SetHyperlink
+	function ItemRefTooltip:SetHyperlink(data, ...)
+		if (data):sub(1, 3) == "url" then
+			local ChatFrameEditBox = ChatEdit_ChooseBoxForSend()
+			local currentLink = (data):sub(5)
+			if (not ChatFrameEditBox:IsShown()) then
+				ChatEdit_ActivateChat(ChatFrameEditBox)
+			end
+			ChatFrameEditBox:Insert(currentLink)
+			ChatFrameEditBox:HighlightText()
+		else
+			SetHyperlink(self, data, ...)
+		end
+	end
+
+	local _hook_TabTextColor = function(self, r, g, b, a)
+		local val = r + g + b;
+		if(val ~= 3) then
+			self:SetTextColor(1, 1, 1, 1)
+			self:SetShadowColor(0, 0, 0)
+			self:SetShadowOffset(2, -2)
+		end
+	end
+
+	local EditBox_OnArrowPressed = function(self, key)
+		if(not key) then return end
+		if(doskey) then
+			if(key == "LEFT") then
+				self:SetCursorPosition(0)
+			elseif(key == "RIGHT") then
+				self:SetCursorPosition(self:GetNumLetters())
+			end
+			doskey = false
+		elseif key == "UP" then
+			doskey = true
+			return UpdateFromEditBoxHistory(self, -1)
+		elseif key == "DOWN" then
+			doskey = true
+			return UpdateFromEditBoxHistory(self, 1)
+		end
+	end
+
+	local EditBox_OnEditFocusGained = function(self)
+		self:Show()
+		if not self.DockLink:IsShown()then
+			self.DockLink.editboxforced = true;
+			self.DockLink.Bar.Button:GetScript("OnEnter")(self.DockLink.Bar.Button)
+		end
+		self.DockLink.Alert:Activate(self)
+	end
+
+	local EditBox_OnEditFocusLost = function(self)
+		if self.DockLink.editboxforced then
+			self.DockLink.editboxforced = nil;
+			if self.DockLink:IsShown()then
+				self.DockLink.Bar.Button:GetScript("OnLeave")(self.DockLink.Bar.Button)
+			end
+		end
+		self:Hide()
+		self.DockLink.Alert:Deactivate()
+		doskey = false
+	end
+
+	local EditBox_OnTextChanged = function(self)
+		local text = self:GetText()
+		if(InCombatLockdown()) then
+			local max = 5;
+			if(len(text) > max) then
+				local testText = true;
+				for i = 1, max, 1 do
+					if(sub(text, 0 - i, 0 - i) ~= sub(text, -1 - i, -1 - i)) then
+						testText = false;
+						break
+					end
+				end
+				if(testText) then
+					self:Hide()
+					return
+				end
+			end
+		end
+
+		if(text:len() < 5) then
+			if(text:sub(1, 4) == "/tt ") then
+				local name, realm = UnitName("target")
+				if(name) then
+					name = gsub(name, " ", "")
+					if(name and (not UnitIsSameServer("player", "target"))) then
+						name = name.."-"..gsub(realm, " ", "")
+					end
+				else
+					name = L["Invalid Target"]
+				end
+				ChatFrame_SendTell(name, ChatFrame1)
+			end
+			if(text:sub(1, 4) == "/gr ") then
+				self:SetText(MOD:GetGroupDistribution()..text:sub(5))
+				ChatEdit_ParseText(self, 0)
+				doskey = false
+			end
+		end
+
+		local result, ct = text:gsub("|Kf(%S+)|k(%S+)%s(%S+)|k", "%2 %3")
+		if(ct > 0) then
+			result = result:gsub("|", "")
+			self:SetText(result)
+			doskey = false
+		end
+	end
+
+	local function _customTab(tab, holder)
+		if(tab.Holder) then return end
+		local chatID = tab.chatID;
+		local tabName = tab:GetName();
+
+		holder.widthMultiplier = 1.75;
+		holder:SetWidth(holder:GetWidth() * 1.75)
+
+		tab:SetParent(holder)
+		tab:ClearAllPoints()
+		tab:SetAllPoints(holder)
+
+		if(tab.conversationIcon) then
+			tab:SetPanelColor("VERTICAL", 0.1, 0.53, 0.65, 0.6, 0.2, 1)
+			holder.Icon:SetGradient("VERTICAL", 0.1, 0.53, 0.65, 0.3, 0.7, 1)
+		else
+			tab:SetPanelColor("default")
+			holder.Icon:SetGradient(unpack(SV.media.gradient.icon))
+		end
+
+		holder.Icon:SetAlpha(0.5);
+		holder.Icon:ClearAllPoints()
+		holder.Icon:InsetPoints(holder, 6, 3)
+		holder.Icon:SetDrawLayer("BORDER")
+		tab.icon = holder.Icon;
+
+		tab:SetAlpha(1);
+		tab:EnableMouse(false);
+
+		tab.SetAlpha = SV.fubar
+		tab.SetHeight = SV.fubar
+		tab.SetWidth = SV.fubar
+		tab.SetSize = SV.fubar
+		tab.SetParent = SV.fubar
+		tab.ClearAllPoints = SV.fubar
+		tab.SetAllPoints = SV.fubar
+		tab.SetPoint = SV.fubar
+
+		holder.link = tab
+		tab.Holder = holder
+	end
+
+	local ChatDockTab_OnEnter = function(self)
+		self = self.link
+		local chatID = self:GetID();
+		local chatFrame = _G[("ChatFrame%d"):format(chatID)];
+		local tabText = self.text:GetText() or "Chat "..chatID;
+		GameTooltip:AddLine(tabText, 1, 1, 0);
+		GameTooltip:AddLine(" ", 1, 1, 1);
+	    if ( chatFrame.isTemporary and chatFrame.chatType == "BN_CONVERSATION" ) then
+	        BNConversation_DisplayConversationTooltip(tonumber(chatFrame.chatTarget));
+	    else
+	        GameTooltip_AddNewbieTip(self, CHAT_OPTIONS_LABEL, 1.0, 1.0, 1.0, NEWBIE_TOOLTIP_CHATOPTIONS, 1);
+	    end
+	end
+
+	local ChatDock_ResizeCallback = function(self)
+		if(not InCombatLockdown()) then
+			local chat = self.Owner;
+			chat:ClearAllPoints();
+			chat:SetAllPoints(self);
+		end
+	end
+
+	local ChatDock_HideCallback = function(self)
+		--print('ChatDock_HideCallback ' .. self:GetName())
+		--print('ChatDock_HideCallback: ' .. self.Button:GetName())
+		local chat = self.Owner;
+		MOD:FadeLines(chat)
+		chat:FadeOut(0.2, chat:GetAlpha(), 0, true)
+		chat:ForceHide(true)
+	end
+
+	local ChatDock_ShowCallback = function(self)
+		--print('ChatDock_ShowCallback ' .. self:GetName())
+		local chat = self.Owner;
+		MOD:ShowLines(chat)
+		chat:ForceHide(false)
+		chat:FadeIn(0.2, chat:GetAlpha(), 1)
+	end
+
+	local ChatDock_LeftClickCallback = function(self, button)
+		local chatTab = self.link
+		local chatFrame = _G[("ChatFrame%d"):format(chatTab:GetID())];
+		-- if(not self.isFloating) then
+		-- 	FCF_Tab_OnClick(chatTab, button);
+		-- end
+		ScrollIndicator:ClearAllPoints()
+		ScrollIndicator:SetPoint("BOTTOMRIGHT", chatFrame, "BOTTOMRIGHT", 6, 0)
+		if(chatFrame:AtBottom() and ScrollIndicator:IsShown()) then
+			SV.Animate:StopFlash(ScrollIndicator)
+			ScrollIndicator:Hide()
+		elseif(not chatFrame:AtBottom() and not ScrollIndicator:IsShown()) then
+			ScrollIndicator:Show()
+			SV.Animate:Flash(ScrollIndicator,1,true)
+		end
+		if(not InCombatLockdown()) then
+			chatFrame:ClearAllPoints();
+			chatFrame:SetAllPoints(chatFrame.Dock);
+		end
+	end
+
+	local ChatDock_FontSizeSliderFunc = function(self, value)
+		SV.media.shared.font.chatdialog.size = value;
+		SV.Events:Trigger("FONT_GROUP_UPDATED", "chatdialog");
+	end
+
+	local function ConfigChatFrame(chat)
+		if(not chat) then return; end
+		local chatName = chat:GetName();
+		local chatID = chat:GetID();
+		local tabName = chatName.."Tab";
+		local tabText = _G[chatName.."TabText"];
+		local tab = _G[tabName];
+		local editBoxName = chatName.."EditBox";
+		local editBox = _G[editBoxName];
+		local dropdown = _G[tabName.."DropDown"]
+		local tabEnabled = (chat.inUse or chat.isDocked or chat.isTemporary);
+		-------------------------------------------
+		SV:SetFrameVisibilityLocks(chat);
+		-------------------------------------------
+		--chat:SetStyle("Frame", "Transparent", true, 1, 3, 6);
+		--chat.Panel:Hide();
+		chat.Dock = SV.Dock:NewDocklet("BottomLeft", format("SVUI_ChatFrameDock%d", chatID), "Chat Frame "..chatID, MOD.media.dockIcon, ChatDockTab_OnEnter);
+		chat.Dock.Owner = chat;
+
+		local ChatDock_ExtendedOptions;
+		if(chatID == 1) then
+			ScrollIndicator:ClearAllPoints()
+			ScrollIndicator:SetPoint("BOTTOMRIGHT", chat, "BOTTOMRIGHT", 6, 0)
+			ChatDock_ExtendedOptions = function()
+				local t = {};
+				local currentFontSize = SV.media.shared.font.chatdialog.size;
+				tinsert(t, { title = CHAT, divider = true });
+				tinsert(t, { text = RENAME_CHAT_WINDOW, func = function() CURRENT_CHAT_FRAME_ID = 1; FCF_RenameChatWindow_Popup(); end });
+				tinsert(t, { text = NEW_CHAT_WINDOW, func = function() CURRENT_CHAT_FRAME_ID = 1; SV:StaticPopup_Show("NEW_CHAT_DOCK"); end });
+				tinsert(t, { text = RESET_ALL_WINDOWS, func = function() CURRENT_CHAT_FRAME_ID = 1; MOD:ResetChatWindows(); end });
+				tinsert(t, { text = CHAT_CONFIGURATION, func = function() CURRENT_CHAT_FRAME_ID = 1; ShowUIPanel(ChatConfigFrame); end });
+				tinsert(t, { title = FONT_SIZE, divider = true });
+				tinsert(t, { range = {8,20}, value = currentFontSize, func = ChatDock_FontSizeSliderFunc });
+				return t;
+			end
+		else
+			ChatDock_ExtendedOptions = function()
+				local t = {};
+				tinsert(t, { title = CHAT, divider = true });
+				if(not chat.isTemporary) then
+					tinsert(t, { text = RENAME_CHAT_WINDOW, func = function() CURRENT_CHAT_FRAME_ID = chatID; FCF_RenameChatWindow_Popup(); end });
+					tinsert(t, { text = CHAT_CONFIGURATION, func = function() CURRENT_CHAT_FRAME_ID = chatID; ShowUIPanel(ChatConfigFrame); end });
+				end
+				tinsert(t, { text = CLOSE_CHAT_WINDOW, func = function() CURRENT_CHAT_FRAME_ID = chatID; FCF_Close(); end });
+				return t;
+			end
+		end
+
+		chat.Dock:SetVisibilityCallbacks(ChatDock_ShowCallback, ChatDock_HideCallback, ChatDock_ResizeCallback);
+		chat.Dock:SetClickCallbacks(ChatDock_LeftClickCallback, false, ChatDock_ExtendedOptions);
+		--chat.Dock:FadeCallback(ChatDock_ResizeCallback, false, true);
+		-------------------------------------------
+		SV:FontManager(chat, "chatdialog", "LEFT")
+		SV:FontManager(editBox, "chatdialog", "LEFT", false, "NONE")
+		SV:FontManager(tabText, "chattab")
+
+		if(SV.media.shared.font.chatdialog.outline ~= 'NONE' ) then
+			chat:SetShadowColor(0, 0, 0, 0)
+			chat:SetShadowOffset(0, 0)
+		else
+			chat:SetShadowColor(0, 0, 0, 1)
+			chat:SetShadowOffset(1, -1)
+		end
+
+		chat:SetFrameLevel(10)
+		chat:SetClampRectInsets(0, 0, 0, 0)
+		chat:SetClampedToScreen(false);
+		chat:SetMovable(true);
+		chat:SetUserPlaced(true);
+
+		chat:RemoveTextures(true)
+		chat:SetBackdropColor(0,0,0,0)
+		chat:SetBackdropBorderColor(1,0,0,1)
+
+		_G[chatName.."ButtonFrame"]:Die()
+		-------------------------------------------
+		_G[tabName .."Left"]:SetTexture("")
+		_G[tabName .."Middle"]:SetTexture("")
+		_G[tabName .."Right"]:SetTexture("")
+		_G[tabName .."SelectedLeft"]:SetTexture("")
+		_G[tabName .."SelectedMiddle"]:SetTexture("")
+		_G[tabName .."SelectedRight"]:SetTexture("")
+		_G[tabName .."HighlightLeft"]:SetTexture("")
+		_G[tabName .."HighlightMiddle"]:SetTexture("")
+		_G[tabName .."HighlightRight"]:SetTexture("")
+
+		tabText:SetTextColor(1, 1, 1, 1)
+		tabText:SetShadowColor(0, 0, 0)
+		tabText:SetShadowOffset(2, -2)
+		tabText:ClearAllPoints()
+		tabText:InsetPoints(tab)
+		tabText:SetJustifyH("CENTER")
+		tabText:SetJustifyV("MIDDLE")
+		tabText:SetAlpha(1)
+		NewHook(tabText, "SetTextColor", _hook_TabTextColor)
+		tabText:Show()
+		tab.text = tabText
+
+		if tab.conversationIcon then
+			tab.conversationIcon:SetAlpha(0)
+			tab.conversationIcon:ClearAllPoints()
+			tab.conversationIcon:SetPoint("TOPLEFT", tab, "TOPLEFT", 0, 0)
+		end
+
+		tab.chatID = chatID;
+
+		_customTab(tab, chat.Dock.Button)
+		-------------------------------------------
+		local ebPoint1, ebPoint2, ebPoint3 = select(6, editBox:GetRegions())
+		ebPoint1:Die()
+		ebPoint2:Die()
+		ebPoint3:Die()
+		_G[editBoxName.."FocusLeft"]:Die()
+		_G[editBoxName.."FocusMid"]:Die()
+		_G[editBoxName.."FocusRight"]:Die()
+		editBox:SetAltArrowKeyMode(false)
+		editBox:SetAllPoints(chat.Dock.Parent.Alert)
+		SV.API:Set("!_EditBox", editBox, false, false, -2, -1)
+
+		if(not EB_HISTORY[editBoxName]) then
+			editBox:HookScript("OnEditFocusGained", EditBox_OnEditFocusGained)
+			editBox:HookScript("OnEditFocusLost", EditBox_OnEditFocusLost)
+			editBox:HookScript("OnTextChanged", EditBox_OnTextChanged)
+			editBox:HookScript("OnArrowPressed", EditBox_OnArrowPressed)
+			hooksecurefunc(editBox, "AddHistoryLine", _hook_AddHistoryLine)
+			EB_HISTORY[editBoxName] = {};
+			EBH_LINE[editBoxName] = {};
+		end
+
+		editBox.DockLink = chat.Dock.Parent;
+		-------------------------------------------
+		chat:SetTimeVisible(100)
+		chat:SetFading(CHAT_FADING)
+		--chat:HookScript("OnHyperlinkClick", SVUI_OnHyperlinkShow)
+
+		local alertSize = chat.Dock.Bar:GetHeight();
+		local alertOffset = alertSize * 0.25
+		local alert = CreateFrame("Frame", nil, tab)
+		alert:SetSize(alertSize, alertSize)
+		alert:SetFrameStrata("DIALOG")
+		alert:SetPoint("TOPRIGHT", tab, "TOPRIGHT", alertOffset, alertOffset)
+		local alticon = alert:CreateTexture(nil, "OVERLAY")
+		alticon:SetAllPoints(alert)
+		alticon:SetTexture(MOD.media.whisperIcon)
+		alert:Hide()
+		chat.WhisperAlert = alert
+
+		--copy chat button
+		tab.CopyButton = CreateFrame('Frame', format("SVUI_CopyChatButton%d", chatID), chat)
+		tab.CopyButton:SetAlpha(0.35)
+		tab.CopyButton:SetSize(38, 18)
+		tab.CopyButton:SetPoint('TOPRIGHT', chat, 'TOPRIGHT', 0, 0)
+		tab.CopyButton:SetStyle("Frame", "Lite")
+
+		tab.CopyButton.Title = tab.CopyButton:CreateFontString()
+		tab.CopyButton.Title:SetFontObject(SVUI_Font_ChatTab)
+		tab.CopyButton.Title:SetText("copy")
+		tab.CopyButton.Title:InsetPoints(tab.CopyButton)
+		tab.CopyButton.Title:SetTextColor(1,0.8,0)
+
+		tab.CopyButton:SetScript("OnMouseUp", function(self, btn)
+			if btn == "RightButton" and chatID == 1 then
+				ToggleFrame(ChatMenu)
+			else
+				MOD:CopyChat(chat)
+			end
+		end)
+
+		tab.CopyButton:SetScript("OnEnter", function(self) self:FadeIn() end)
+		tab.CopyButton:SetScript("OnLeave", function(self) self:FadeOut() end)
+		tab.CopyButton:FadeOut()
+	end
+
+	local _linkTokens = {
+		['item'] = true,
+		['spell'] = true,
+		['unit'] = true,
+		['quest'] = true,
+		['enchant'] = true,
+		['achievement'] = true,
+		['instancelock'] = true,
+		['talent'] = true,
+		['glyph'] = true,
+	}
+
+	local _hook_OnHyperlinkEnter = function(self, refString)
+		if(not CHAT_HOVER_URL or InCombatLockdown()) then return; end
+		local token = refString:match("^([^:]+)")
+		if _linkTokens[token] then
+			ShowUIPanel(GameTooltip)
+			GameTooltip:SetOwner(self, "ANCHOR_CURSOR")
+			GameTooltip:SetHyperlink(refString)
+			ACTIVE_HYPER_LINK = self;
+			GameTooltip:Show()
+		end
+	end
+
+	local _hook_OnHyperlinkLeave = function(self, refString)
+		if(not CHAT_HOVER_URL) then return; end
+		local token = refString:match("^([^:]+)")
+		if _linkTokens[token] then
+			HideUIPanel(GameTooltip)
+			ACTIVE_HYPER_LINK = nil;
+		end
+	end
+
+	local _hook_OnMessageScrollChanged = function(self)
+		if(not CHAT_HOVER_URL) then return; end
+		if(ACTIVE_HYPER_LINK == self) then
+			HideUIPanel(GameTooltip)
+			ACTIVE_HYPER_LINK = false;
+		end
+		if(self:AtBottom() and ScrollIndicator:IsShown()) then
+			SV.Animate:StopFlash(ScrollIndicator)
+			ScrollIndicator:Hide()
+		elseif(not self:AtBottom() and not ScrollIndicator:IsShown()) then
+			ScrollIndicator:Show()
+			ScrollIndicator.parent = self
+			SV.Animate:Flash(ScrollIndicator,1,true)
+		end
+	end
+
+	local _hook_OnMouseWheel = function(self, delta)
+		if(IsShiftKeyDown()) then
+			if(delta and delta > 0) then
+				self:ScrollToTop()
+			else
+				self:ScrollToBottom()
+			end
+		end
+		if(self:AtBottom() and ScrollIndicator:IsShown()) then
+			SV.Animate:StopFlash(ScrollIndicator)
+			ScrollIndicator:Hide()
+		elseif(not self:AtBottom() and not ScrollIndicator:IsShown()) then
+			ScrollIndicator:Show()
+			SV.Animate:Flash(ScrollIndicator,1,true)
+		end
+	end
+
+	local _hook_TabOnEnter = function(self)
+		if self.conversationIcon then
+			self.conversationIcon:Show()
+		end
+	end
+
+	local _hook_TabOnLeave = function(self)
+		if self.conversationIcon then
+			self.conversationIcon:Hide()
+		end
+	end
+
+	local _forced_SetPoint = function(self, a1, p, a2, x, y)
+		if(not self.Dock) then return end
+		if((a1 ~= 'LEFT') or (a2 ~= 'LEFT') or (x ~= 0) or (y ~= 0)) then
+			self:ClearAllPoints()
+			self:SetPoint('LEFT', p, 'LEFT', 0, 0)
+			self:SetSize(self.Dock:GetSize());
+		end
+	end
+
+	local _forced_SetAllPoints = function(self, parent)
+		if(self.Dock and (parent ~= self.Dock)) then
+			self:ClearAllPoints()
+			self:SetAllPoints(self.Dock)
+		end
+	end
+
+	function MOD:RefreshChatFrames(event, forced)
+		--print(event)
+		if ((not forced) and (REFRESH_LOCKED and (IsMouseButtonDown("LeftButton") or InCombatLockdown()))) then return; end
+
+		for i,name in pairs(CHAT_FRAMES) do
+			local chat = _G[name]
+			local id = chat:GetID()
+			local tab = _G[name.."Tab"]
+			local tabText = _G[name.."TabText"]
+
+			if(not chat.Dock) then
+				ConfigChatFrame(chat)
+			end
+
+			--FCF_SetLocked(chat, true);
+
+			--/script print(ChatFrame1:GetLeft())
+			--/script print(ChatFrame11:GetLeft())
+			--/script local a1,p,a2,x,y = ChatFrame1.Dock:GetPoint(); print(p:GetName())print(a1..' '..a2..' '..x..' '..y)
+			--/script local a1,p,a2,x,y = ChatFrame11.Dock:GetPoint(); print(p:GetName())print(a1..' '..a2..' '..x..' '..y)
+
+			--/script ChatFrame11:SetBackdrop({bgFile = [[Interface\AddOns\SVUI_!Core\assets\backgrounds\DEFAULT]]})
+			--/script ChatFrame11:ClearAllPoints()
+			--/script ChatFrame11:SetAllPoints(ChatFrame11.Dock)
+			--/script ChatFrame11.Dock:ClearAllPoints()
+			--/script ChatFrame11.Dock:SetAllPoints(ChatFrame1.Dock)
+			chat:SetBackdrop({
+				bgFile = [[Interface\AddOns\SVUI_!Core\assets\textures\EMPTY]],
+			    tile = false,
+			    tileSize = 0,
+			    edgeFile = [[Interface\AddOns\SVUI_!Core\assets\textures\EMPTY]],
+			    edgeSize = 1,
+			    insets =
+			    {
+			        left = 0,
+			        right = 0,
+			        top = 0,
+			        bottom = 0,
+			    },
+			})
+			chat:SetBackdropColor(0,0,0,0);
+			chat:SetBackdropBorderColor(0,0,0,0);
+
+			-- chat:SetPoint("TOPLEFT", chat.Dock, "TOPLEFT", 0, 0);
+			-- chat:SetPoint("BOTTOMLEFT", chat.Dock, "BOTTOMLEFT", 0, 0);
+			-- chat:SetPoint("TOPRIGHT", chat.Dock, "TOPRIGHT", 0, 0);
+			-- chat:SetPoint("BOTTOMRIGHT", chat.Dock, "BOTTOMRIGHT", 0, 0);
+			--local CHAT_WIDTH, CHAT_HEIGHT = chat.Dock:GetSize();
+			--chat:SetSize(CHAT_WIDTH - 4, CHAT_HEIGHT - 4);
+
+			--FCF_SavePositionAndDimensions(chat)
+
+			--/svdf ChatFrame11
+			--/svdf SVUI_ChatFrameDock11
+			-- /script ChatFrame11:ClearAllPoints();
+			-- /script ChatFrame11:WrapPoints(SVUI_ChatFrameDock11,10,10);
+
+			--tab.Holder.CanFloat = true;
+			--tabText:Hide()
+			if(tab.CopyButton and (GetMouseFocus() ~= tab.CopyButton)) then
+				tab.CopyButton:SetAlpha(0)
+			end
+			if tab.conversationIcon then
+				tab.conversationIcon:Hide()
+			end
+
+			if((not chat.TempAddMessage) and (chat:GetID() ~= 2)) then
+				chat.TempAddMessage = chat.AddMessage;
+				chat.AddMessage = AddModifiedMessage
+			end
+
+			if(not chat.hookedHyperLinks) then
+				chat:HookScript('OnHyperlinkEnter', _hook_OnHyperlinkEnter)
+				chat:HookScript('OnHyperlinkLeave', _hook_OnHyperlinkLeave)
+				chat:HookScript('OnMessageScrollChanged', _hook_OnMessageScrollChanged)
+				chat:HookScript('OnMouseWheel', _hook_OnMouseWheel)
+				tab:HookScript('OnEnter', _hook_TabOnEnter)
+				tab:HookScript('OnLeave', _hook_TabOnLeave)
+				chat.hookedHyperLinks = true
+			end
+
+			chat.isDocked = nil;
+			chat.hasBeenFaded = nil;
+			chat.isUninteractable = true;
+			chat.oldAlpha = 0;
+			--FCF_FadeInChatFrame(chat);
+			local isActive = MOD:IsChatActive(chat)
+			chat.Dock:UpdateBackdrop()
+			chat.Dock.Button:SetDocked(isActive)
+			chat:ClearAllPoints();
+			chat:SetAllPoints(chat.Dock);
+			FCF_SetLocked(chat, true);
+			SetChatWindowUninteractable(i, false);
+			if(chat.name) then
+				tabText:SetText(chat.name)
+			end
+		end
+
+		REFRESH_LOCKED = true
+	end
+end
+
+local function OpenNewSVUIChatFrame(newname)
+	local chatFrame, chatTab;
+	for i,name in pairs(CHAT_FRAMES) do
+		chatFrame = _G[name];
+		chatTab = _G[name.."Tab"];
+		local key = format("SVUI_ChatFrameDock%d", i);
+		local tabText = newname;
+		if((not newname) or (newname == "")) then
+			tabText = format(CHAT_NAME_TEMPLATE, i);
+		end
+		if(not MOD:IsChatActive(chatFrame)) then
+			FCF_SetWindowName(chatFrame, tabText);
+			FCF_SetLocked(chatFrame, false);
+
+			-- clear stale messages
+			chatFrame:Clear();
+
+			-- Listen to the standard messages
+			ChatFrame_RemoveAllMessageGroups(chatFrame);
+			ChatFrame_RemoveAllChannels(chatFrame);
+			ChatFrame_ReceiveAllPrivateMessages(chatFrame);
+			--ChatFrame_ReceiveAllBNConversations(chatFrame);
+
+			ChatFrame_AddMessageGroup(chatFrame, "SAY");
+			ChatFrame_AddMessageGroup(chatFrame, "YELL");
+			ChatFrame_AddMessageGroup(chatFrame, "GUILD");
+			ChatFrame_AddMessageGroup(chatFrame, "WHISPER");
+			ChatFrame_AddMessageGroup(chatFrame, "BN_WHISPER");
+			ChatFrame_AddMessageGroup(chatFrame, "PARTY");
+			ChatFrame_AddMessageGroup(chatFrame, "PARTY_LEADER");
+			ChatFrame_AddMessageGroup(chatFrame, "CHANNEL");
+
+			--Clear the edit box history.
+			chatFrame.editBox:ClearHistory();
+
+			-- Show the frame and tab
+			chatFrame:Show();
+			chatTab:Show();
+			SetChatWindowShown(i, true);
+
+			-- Dock the frame by default
+			-- FCF_DockFrame(chatFrame, (#FCFDock_GetChatFrames(GENERAL_CHAT_DOCK)+1), true);
+			-- FCF_FadeInChatFrame(FCFDock_GetSelectedWindow(GENERAL_CHAT_DOCK));
+
+			--FCF_CopyChatSettings(chatFrame, DEFAULT_CHAT_FRAME);
+			MOD:SaveActiveFlag(key,tabText);
+			chatFrame:FadeIn(0.2, chatFrame:GetAlpha(), 1)
+			MOD.RefreshChatFrames()
+			return;
+		end
+	end
+end
+
+function MOD:ResetChatWindows()
+	REFRESH_LOCKED = false;
+	FCF_ResetChatWindows();
+
+	MOD:ResetInternalData();
+
+	for k,v in pairs(SV.Dock.private.Disabled) do
+		if k:find("ChatFrame") then
+			SV.Dock.private.Disabled[k] = nil
+		end
+	end
+
+	for i=1, NUM_CHAT_WINDOWS do
+		local chatFrame = _G["ChatFrame"..i];
+		if(chatFrame) then
+			chatFrame.isUninteractable = true;
+			chatFrame:SetMovable(true);
+		end
+	end
+
+	FCF_SetLocked(ChatFrame1, true)
+	FCF_SetWindowName(ChatFrame1, GENERAL)
+	if(ChatFrame1.Dock) then
+		ChatFrame1.Dock:UpdateBackdrop()
+		ChatFrame1.Dock:SetDocked(true)
+	end
+	MOD:SaveActiveFlag('SVUI_ChatFrameDock1',GENERAL);
+
+	FCF_SetLocked(ChatFrame2, true)
+	FCF_SetWindowName(ChatFrame2, GUILD_EVENT_LOG)
+	if(ChatFrame2.Dock) then
+		ChatFrame2.Dock:UpdateBackdrop()
+		ChatFrame2.Dock:SetDocked(true)
+	end
+	MOD:SaveActiveFlag('SVUI_ChatFrameDock2',GUILD_EVENT_LOG);
+
+	FCF_OpenNewWindow(LOOT)
+	FCF_SetLocked(ChatFrame3, true)
+	FCF_SetWindowName(ChatFrame3, LOOT)
+	if(ChatFrame3.Dock) then
+		ChatFrame3.Dock:UpdateBackdrop()
+		ChatFrame3.Dock:SetDocked(true)
+	end
+	MOD:SaveActiveFlag('SVUI_ChatFrameDock3',LOOT);
+
+	for i=4, NUM_CHAT_WINDOWS do
+		local chatFrame = _G["ChatFrame"..i];
+		if(chatFrame and chatFrame.Dock) then
+			chatFrame.Dock:SetDocked(false)
+		end
+	end
+
+	ChatFrame_RemoveAllMessageGroups(ChatFrame1)
+	ChatFrame_AddMessageGroup(ChatFrame1, "SAY")
+	ChatFrame_AddMessageGroup(ChatFrame1, "EMOTE")
+	ChatFrame_AddMessageGroup(ChatFrame1, "YELL")
+	ChatFrame_AddMessageGroup(ChatFrame1, "GUILD")
+	ChatFrame_AddMessageGroup(ChatFrame1, "OFFICER")
+	ChatFrame_AddMessageGroup(ChatFrame1, "GUILD_ACHIEVEMENT")
+	ChatFrame_AddMessageGroup(ChatFrame1, "WHISPER")
+	ChatFrame_AddMessageGroup(ChatFrame1, "MONSTER_SAY")
+	ChatFrame_AddMessageGroup(ChatFrame1, "MONSTER_EMOTE")
+	ChatFrame_AddMessageGroup(ChatFrame1, "MONSTER_YELL")
+	ChatFrame_AddMessageGroup(ChatFrame1, "MONSTER_BOSS_EMOTE")
+	ChatFrame_AddMessageGroup(ChatFrame1, "PARTY")
+	ChatFrame_AddMessageGroup(ChatFrame1, "PARTY_LEADER")
+	ChatFrame_AddMessageGroup(ChatFrame1, "RAID")
+	ChatFrame_AddMessageGroup(ChatFrame1, "RAID_LEADER")
+	ChatFrame_AddMessageGroup(ChatFrame1, "RAID_WARNING")
+	ChatFrame_AddMessageGroup(ChatFrame1, "INSTANCE_CHAT")
+	ChatFrame_AddMessageGroup(ChatFrame1, "INSTANCE_CHAT_LEADER")
+	ChatFrame_AddMessageGroup(ChatFrame1, "BATTLEGROUND")
+	ChatFrame_AddMessageGroup(ChatFrame1, "BATTLEGROUND_LEADER")
+	ChatFrame_AddMessageGroup(ChatFrame1, "BG_HORDE")
+	ChatFrame_AddMessageGroup(ChatFrame1, "BG_ALLIANCE")
+	ChatFrame_AddMessageGroup(ChatFrame1, "BG_NEUTRAL")
+	ChatFrame_AddMessageGroup(ChatFrame1, "SYSTEM")
+	ChatFrame_AddMessageGroup(ChatFrame1, "ERRORS")
+	ChatFrame_AddMessageGroup(ChatFrame1, "AFK")
+	ChatFrame_AddMessageGroup(ChatFrame1, "DND")
+	ChatFrame_AddMessageGroup(ChatFrame1, "IGNORED")
+	ChatFrame_AddMessageGroup(ChatFrame1, "ACHIEVEMENT")
+	ChatFrame_AddMessageGroup(ChatFrame1, "BN_WHISPER")
+	ChatFrame_AddMessageGroup(ChatFrame1, "BN_CONVERSATION")
+	ChatFrame_AddMessageGroup(ChatFrame1, "BN_INLINE_TOAST_ALERT")
+	ChatFrame_AddMessageGroup(ChatFrame1, "COMBAT_FACTION_CHANGE")
+	ChatFrame_AddMessageGroup(ChatFrame1, "SKILL")
+	ChatFrame_AddMessageGroup(ChatFrame1, "LOOT")
+	ChatFrame_AddMessageGroup(ChatFrame1, "MONEY")
+	ChatFrame_AddMessageGroup(ChatFrame1, "COMBAT_XP_GAIN")
+	ChatFrame_AddMessageGroup(ChatFrame1, "COMBAT_HONOR_GAIN")
+	ChatFrame_AddMessageGroup(ChatFrame1, "COMBAT_GUILD_XP_GAIN")
+
+	ChatFrame_RemoveAllMessageGroups(ChatFrame3)
+	ChatFrame_AddMessageGroup(ChatFrame3, "COMBAT_FACTION_CHANGE")
+	ChatFrame_AddMessageGroup(ChatFrame3, "SKILL")
+	ChatFrame_AddMessageGroup(ChatFrame3, "LOOT")
+	ChatFrame_AddMessageGroup(ChatFrame3, "MONEY")
+	ChatFrame_AddMessageGroup(ChatFrame3, "COMBAT_XP_GAIN")
+	ChatFrame_AddMessageGroup(ChatFrame3, "COMBAT_HONOR_GAIN")
+	ChatFrame_AddMessageGroup(ChatFrame3, "COMBAT_GUILD_XP_GAIN")
+
+	ChatFrame_AddChannel(ChatFrame1, GENERAL)
+
+	ToggleChatColorNamesByClassGroup(true, "SAY")
+	ToggleChatColorNamesByClassGroup(true, "EMOTE")
+	ToggleChatColorNamesByClassGroup(true, "YELL")
+	ToggleChatColorNamesByClassGroup(true, "GUILD")
+	ToggleChatColorNamesByClassGroup(true, "OFFICER")
+	ToggleChatColorNamesByClassGroup(true, "GUILD_ACHIEVEMENT")
+	ToggleChatColorNamesByClassGroup(true, "ACHIEVEMENT")
+	ToggleChatColorNamesByClassGroup(true, "WHISPER")
+	ToggleChatColorNamesByClassGroup(true, "PARTY")
+	ToggleChatColorNamesByClassGroup(true, "PARTY_LEADER")
+	ToggleChatColorNamesByClassGroup(true, "RAID")
+	ToggleChatColorNamesByClassGroup(true, "RAID_LEADER")
+	ToggleChatColorNamesByClassGroup(true, "RAID_WARNING")
+	ToggleChatColorNamesByClassGroup(true, "BATTLEGROUND")
+	ToggleChatColorNamesByClassGroup(true, "BATTLEGROUND_LEADER")
+	ToggleChatColorNamesByClassGroup(true, "INSTANCE_CHAT")
+	ToggleChatColorNamesByClassGroup(true, "INSTANCE_CHAT_LEADER")
+	ToggleChatColorNamesByClassGroup(true, "CHANNEL1")
+	ToggleChatColorNamesByClassGroup(true, "CHANNEL2")
+	ToggleChatColorNamesByClassGroup(true, "CHANNEL3")
+	ToggleChatColorNamesByClassGroup(true, "CHANNEL4")
+	ToggleChatColorNamesByClassGroup(true, "CHANNEL5")
+	ToggleChatColorNamesByClassGroup(true, "CHANNEL6")
+	ToggleChatColorNamesByClassGroup(true, "CHANNEL7")
+	ToggleChatColorNamesByClassGroup(true, "CHANNEL8")
+	ToggleChatColorNamesByClassGroup(true, "CHANNEL9")
+	ToggleChatColorNamesByClassGroup(true, "CHANNEL10")
+	ToggleChatColorNamesByClassGroup(true, "CHANNEL11")
+
+	ChangeChatColor("CHANNEL1", 195 / 255, 230 / 255, 232 / 255)
+	ChangeChatColor("CHANNEL2", 232 / 255, 158 / 255, 121 / 255)
+	ChangeChatColor("CHANNEL3", 232 / 255, 228 / 255, 121 / 255)
+
+	MOD:ReLoad()
+end
+--[[
+##########################################################
+CHAT HISTORY FUNCTIONS
+##########################################################
+]]--
+local function MessageTimeStamp()
+	local timestamp, current;
+	local actual = time();
+	local estimate = GetTime()
+	if(not estimate) then
+		current = random(1, 999)
+	else
+		current = select(2, ("."):split(estimate, 2)) or 0
+	end
+	timestamp = ("%d.%d"):format(actual, current)
+	return timestamp;
+end
+
+function MOD:SAVE_CHAT_HISTORY(event, ...)
+	local temp_cache = {}
+	for i = 1, select('#', ...) do
+		temp_cache[i] = select(i, ...) or false
+	end
+	if(#temp_cache > 0) then
+	  	temp_cache[20] = event
+	  	local timestamp = MessageTimeStamp()
+		local lineNum, lineID = 0
+
+		self.ChatHistory[timestamp] = temp_cache
+
+		for id, data in pairs(self.ChatHistory) do
+			lineNum = lineNum + 1
+			if((not lineID) or lineID > id) then
+				lineID = id
+			end
+		end
+
+		if(lineNum > 128) then
+			self.ChatHistory[lineID] = nil
+		end
+	end
+	temp_cache = nil
+end
+
+function MOD:EnableChatHistory()
+	self:RegisterEvent("CHAT_MSG_CHANNEL", "SAVE_CHAT_HISTORY")
+	self:RegisterEvent("CHAT_MSG_EMOTE", "SAVE_CHAT_HISTORY")
+	self:RegisterEvent("CHAT_MSG_GUILD_ACHIEVEMENT", "SAVE_CHAT_HISTORY")
+	self:RegisterEvent("CHAT_MSG_RAID_WARNING", "SAVE_CHAT_HISTORY")
+	self:RegisterEvent("CHAT_MSG_SAY", "SAVE_CHAT_HISTORY")
+	self:RegisterEvent("CHAT_MSG_YELL", "SAVE_CHAT_HISTORY")
+	self:RegisterEvent("CHAT_MSG_WHISPER_INFORM", "SAVE_CHAT_HISTORY")
+	self:RegisterEvent("CHAT_MSG_GUILD", "SAVE_CHAT_HISTORY")
+	self:RegisterEvent("CHAT_MSG_OFFICER", "SAVE_CHAT_HISTORY")
+	self:RegisterEvent("CHAT_MSG_PARTY", "SAVE_CHAT_HISTORY")
+	self:RegisterEvent("CHAT_MSG_PARTY_LEADER", "SAVE_CHAT_HISTORY")
+	self:RegisterEvent("CHAT_MSG_RAID", "SAVE_CHAT_HISTORY")
+	self:RegisterEvent("CHAT_MSG_RAID_LEADER", "SAVE_CHAT_HISTORY")
+	self:RegisterEvent("CHAT_MSG_INSTANCE_CHAT", "SAVE_CHAT_HISTORY")
+	self:RegisterEvent("CHAT_MSG_INSTANCE_CHAT_LEADER", "SAVE_CHAT_HISTORY")
+	self:RegisterEvent("CHAT_MSG_BN_CONVERSATION", "SAVE_CHAT_HISTORY")
+	self:RegisterEvent("CHAT_MSG_BN_WHISPER_INFORM", "SAVE_CHAT_HISTORY")
+
+	local temp_cache, data_cache = {}
+	local count = 1;
+	for id, _ in pairs(self.ChatHistory) do
+		temp_cache[count] = tonumber(id);
+		count=count+1;
+	end
+	tsort(temp_cache, function(a, b)
+		return a < b
+	end)
+	for i = 1, #temp_cache do
+		local lineID = tostring(temp_cache[i])
+		data_cache = self.ChatHistory[lineID]
+		if(data_cache) then
+			local GUID = data_cache[12]
+			if((type(data_cache) == "table") and data_cache[20] ~= nil and (GUID and type(GUID) == "string")) then
+				if(not GUID:find("Player-")) then
+					self.ChatHistory[lineID] = nil
+				else
+					ChatFrame_MessageEventHandler(DEFAULT_CHAT_FRAME, data_cache[20], unpack(data_cache))
+				end
+			end
+		end
+	end
+
+	temp_cache = nil
+	data_cache = nil
+	wipe(self.ChatHistory)
+end
+
+function MOD:DisableChatHistory()
+	self:UnregisterEvent("CHAT_MSG_CHANNEL")
+	self:UnregisterEvent("CHAT_MSG_EMOTE")
+	self:UnregisterEvent("CHAT_MSG_GUILD_ACHIEVEMENT")
+	self:UnregisterEvent("CHAT_MSG_RAID_WARNING")
+	self:UnregisterEvent("CHAT_MSG_SAY")
+	self:UnregisterEvent("CHAT_MSG_YELL")
+	self:UnregisterEvent("CHAT_MSG_WHISPER_INFORM")
+	self:UnregisterEvent("CHAT_MSG_GUILD")
+	self:UnregisterEvent("CHAT_MSG_OFFICER")
+	self:UnregisterEvent("CHAT_MSG_PARTY")
+	self:UnregisterEvent("CHAT_MSG_PARTY_LEADER")
+	self:UnregisterEvent("CHAT_MSG_RAID")
+	self:UnregisterEvent("CHAT_MSG_RAID_LEADER")
+	self:UnregisterEvent("CHAT_MSG_INSTANCE_CHAT")
+	self:UnregisterEvent("CHAT_MSG_INSTANCE_CHAT_LEADER")
+	self:UnregisterEvent("CHAT_MSG_BN_CONVERSATION")
+	self:UnregisterEvent("CHAT_MSG_BN_WHISPER_INFORM")
+end
+--[[
+##########################################################
+EVENTS
+##########################################################
+]]--
+function MOD:CHAT_MSG_WHISPER(event, ...)
+	if(not InCombatLockdown() and WHISPER_SOUND) then PlaySoundFile(WHISPER_SOUND, "Master") end
+	if(self.db.general.saveChats) then
+		self:SAVE_CHAT_HISTORY(event, ...)
+	end
+end
+
+function MOD:CHAT_MSG_BN_WHISPER(event, ...)
+	if(not InCombatLockdown() and WHISPER_SOUND) then PlaySoundFile(WHISPER_SOUND, "Master") end
+	if(self.db.general.saveChats) then
+		self:SAVE_CHAT_HISTORY(event, ...)
+	end
+end
+
+function MOD:PET_BATTLE_CLOSE()
+	for _, frameName in pairs(CHAT_FRAMES) do
+		local chat = _G[frameName]
+		if chat and _G[frameName.."Tab"]:GetText():match(PET_BATTLE_COMBAT_LOG) then
+			CURRENT_CHAT_FRAME_ID = chat:GetID();
+			FCF_Close();
+		end
+	end
+end
+--[[
+##########################################################
+HOOKS
+##########################################################
+]]--
+do
+	local _hook_ChatEditOnEnterKey = function(self, input)
+		local ctype = self:GetAttribute("chatType");
+		local attr = (not CHAT_STICKY) and "SAY" or ctype;
+		local chat = self:GetParent();
+		if not chat.isTemporary and ChatTypeInfo[ctype].sticky == 1 then
+			self:SetAttribute("chatType", attr);
+		end
+	end
+
+	local _hook_ChatFontUpdate = function(self, chat, size)
+		if(C_PetBattles.IsInBattle()) then return end
+		SV.Events:Trigger("FONT_GROUP_UPDATED", "chatdialog");
+		if ( not chat ) then
+			chat = FCF_GetCurrentChatFrame();
+		end
+		if(SV.media.shared.font.chatdialog.outline ~= 'NONE' )then
+			chat:SetShadowColor(0, 0, 0, 0)
+			chat:SetShadowOffset(0, 0)
+		else
+			chat:SetShadowColor(0, 0, 0, 1)
+			chat:SetShadowOffset(1, -1)
+		end
+	end
+
+	local _hook_GDMFrameSetPoint = function(self)
+		self:SetAllPoints(SV.Dock.BottomLeft.Bar)
+	end
+
+	local _hook_GDMScrollSetPoint = function(self, point, anchor, attachTo, x, y)
+		if(anchor == GeneralDockManagerOverflowButton and x == 0 and y == 0) then
+			self:SetPoint(point, anchor, attachTo, -2, -6)
+		end
+	end
+
+	local _hook_OnUpdateHeader = function(editBox)
+		local attrib = editBox:GetAttribute("chatType")
+		if attrib == "CHANNEL" then
+			local channel = GetChannelName(editBox:GetAttribute("channelTarget"))
+			if channel == 0 then
+				editBox:SetBackdropBorderColor(0,0,0)
+			else
+				editBox:SetBackdropBorderColor(ChatTypeInfo[attrib..channel].r, ChatTypeInfo[attrib..channel].g, ChatTypeInfo[attrib..channel].b)
+			end
+		elseif attrib then
+			editBox:SetBackdropBorderColor(ChatTypeInfo[attrib].r, ChatTypeInfo[attrib].g, ChatTypeInfo[attrib].b)
+		end
+	end
+
+	local _hook_FCFStartAlertFlash = function(self)
+		if(not self.WhisperAlert) then return end
+		self.WhisperAlert:Show()
+		SV.Animate:Flash(self.WhisperAlert,1,true)
+	end
+
+	local _hook_FCFStopAlertFlash = function(self)
+		if(not self.WhisperAlert) then return end
+		SV.Animate:StopFlash(self.WhisperAlert)
+		self.WhisperAlert:Hide()
+	end
+
+	local _hook_FCF_SetWindowColor = function(self, r, g, b)
+		local name = self:GetName();
+		local chat = _G[name]
+		local id = chat:GetID()
+		local tab = _G[name.."Tab"]
+		if(tab.Holder.isFloating) then
+			chat:SetBackdropColor(r,g,b,1)
+		else
+			chat:SetBackdropColor(0,0,0,0)
+		end
+	end
+
+	local _hook_FCF_SetWindowAlpha = function(self, a)
+		local name = self:GetName();
+		local chat = _G[name]
+		local id = chat:GetID()
+		local tab = _G[name.."Tab"]
+		if(tab.Holder.isFloating) then
+			local r,g,b = chat:GetBackdropColor()
+			chat:SetBackdropColor(r,g,b,a)
+		end
+	end
+
+	local _hook_FCF_Close = function(self)
+		local chatFrame = self or _G["ChatFrame" .. CURRENT_CHAT_FRAME_ID]
+		if((not chatFrame) or (not chatFrame.Dock)) then return end
+		local key = format("SVUI_ChatFrameDock%d", chatFrame:GetID())
+		chatFrame.Dock:SetDocked(false);
+		MOD:DeleteActiveFlag(key);
+	end
+
+	local _hook_FCF_Tab_OnClick = function(self)
+		if(not self) then
+			self = FCF_GetCurrentChatFrame();
+		end
+	end
+
+	local _hook_FCF_OpenTemporaryWindow = function(...)
+		--print('_hook_FCF_OpenTemporaryWindow')
+		for id, chatFrameName in pairs(CHAT_FRAMES) do
+			local frame = _G[chatFrameName];
+			local key = format("SVUI_ChatFrameDock%d", id)
+			if ( frame.isTemporary and (not MOD.private.activeTabs[key]) ) then
+				local tabText = frame.name;
+				if(tabText) then
+					MOD:SaveActiveFlag(key,tabText);
+				end
+				if(frame.Dock) then
+					frame.oldAlpha = 0;
+					frame.Dock:UpdateBackdrop();
+				end;
+				break;
+			end
+		end
+		MOD.RefreshChatFrames();
+		--print(chatFrame:GetName())
+	end
+
+	local _hook_FCF_OpenNewWindow = function(...)
+		--print('_hook_FCF_OpenNewWindow')
+		OpenNewSVUIChatFrame(...);
+		--print(chatFrame:GetName())
+	end
+
+	local _hook_FCF_FadeInChatFrame = function(chat)
+		chat:ForceHide(false)
+	end
+
+	local _hook_FCF_FadeOutChatFrame = function(chat)
+		chat:ForceHide(true)
+	end
+
+	_G.FCFDock_UpdateTabs = function(dock, forceUpdate)
+		if ( not dock.isDirty and not forceUpdate ) then
+			return;
+		end
+
+		for index, chatFrame in ipairs(dock.DOCKED_CHAT_FRAMES) do
+			local chatTab = _G[chatFrame:GetName().."Tab"];
+			chatTab:Show();
+		end
+
+		dock.isDirty = false;
+
+		return FCFDock_ScrollToSelectedTab(dock);
+	end
+
+	_G.FCF_UpdateDockPosition = function() end
+	_G.FCF_RestorePositionAndDimensions = function() end
+
+	--TESTS
+	local _hook_FCF_DockFrame = function(self)
+		FCF_SetLocked(self, false);
+		if(self.Dock) then
+			local key = self.Dock:GetName();
+			local tabText = self.name;
+			if(tabText) then
+				MOD:SaveActiveFlag(key,tabText);
+			end
+			self.oldAlpha = 0;
+			self.Dock:UpdateBackdrop();
+			--self.Dock.Parent.Bar:SetDefault(self.Dock.Button)
+		end;
+		MOD.RefreshChatFrames();
+	end
+
+	function SetAllChatHooks()
+		NewHook('FCF_StartAlertFlash', _hook_FCFStartAlertFlash)
+		NewHook('FCF_StopAlertFlash', _hook_FCFStopAlertFlash)
+		NewHook('FCF_OpenNewWindow', _hook_FCF_OpenNewWindow)
+		NewHook('FCF_UnDockFrame', MOD.RefreshChatFrames)
+		NewHook('FCF_DockFrame', _hook_FCF_DockFrame)
+		NewHook('FCF_OpenTemporaryWindow', _hook_FCF_OpenTemporaryWindow)
+		NewHook('ChatEdit_OnEnterPressed', _hook_ChatEditOnEnterKey)
+		NewHook('FCF_SetChatWindowFontSize', _hook_ChatFontUpdate)
+		NewHook(GeneralDockManager, 'SetPoint', _hook_GDMFrameSetPoint)
+		NewHook(GeneralDockManagerScrollFrame, 'SetPoint', _hook_GDMScrollSetPoint)
+		--NewHook("FCF_SetWindowColor", _hook_FCF_SetWindowColor)
+		--NewHook("FCFDock_UpdateTabs", function() print('FCFDock_UpdateTabs') end)
+		NewHook("FCF_Close", _hook_FCF_Close)
+		NewHook("ChatEdit_UpdateHeader", _hook_OnUpdateHeader)
+
+		-- TESTING
+		--NewHook('FCFDock_AddChatFrame', _hook_FCFDock_AddChatFrame)
+		--NewHook('FCF_DockUpdate', _hook_FCF_DockUpdate)
+		--NewHook("FCF_FadeInChatFrame", _hook_FCF_FadeInChatFrame)
+		--NewHook("FCF_FadeOutChatFrame", _hook_FCF_FadeOutChatFrame)
+	end
+end
+
+local ScrollFullButton = function(self)
+	if(not self.parent) then return end
+	self.parent:ScrollToBottom()
+	self:Hide()
+end
+
+function MOD:CopyChat(frame)
+	if not SVUI_CopyChatFrame:IsShown() then
+		SVUI_CopyChatFrame:Show()
+		local lineCt = self:GetLines(frame:GetRegions())
+		local text = tconcat(COPY_LINES, "\n", 1, lineCt)
+		SVUI_CopyChatFrameEditBox:SetText(text)
+	else
+		SVUI_CopyChatFrame:Hide()
+	end
+end
+
+function MOD:UpdateLocals()
+	PLAYER_NAME = UnitName("player");
+	PLAYER_FILTER = PLAYER_NAME:upper();
+	CHAT_THROTTLE = SV.db.Chat.throttleInterval;
+	CHAT_ALLOW_URL = SV.db.Chat.url;
+	CHAT_HOVER_URL = SV.db.Chat.hyperlinkHover;
+	CHAT_STICKY = SV.db.Chat.sticky;
+	TAB_WIDTH = SV.db.Chat.tabWidth;
+	TAB_HEIGHT = SV.db.Chat.tabHeight;
+	TAB_SKINS = SV.db.Chat.tabStyled;
+	CHAT_ABBREV = SV.db.Chat.shortChannels;
+	CHAT_FADING = SV.db.Chat.fade;
+	WHISPER_SOUND = LSM:Fetch("sound", SV.db.Chat.psst);
+	SECRET_SOUND = LSM:Fetch("sound", SV.db.Chat.mention);
+	TIME_STAMP_MASK = SV.db.Chat.timeStampFormat;
+	HIDE_REALM = SV.db.Chat.hideRealms;
+	if(CHAT_THROTTLE and CHAT_THROTTLE == 0) then
+		wipe(THROTTLE_CACHE)
+	end
+end
+
+local function ExpandChatDock(location)
+	if(not location) then return end
+	local needsUpdate = false;
+	for _, name in pairs(CHAT_FRAMES) do
+		local chat = _G[name];
+		if(chat and (location == chat.Dock.Parent.Bar.Data.Location)) then
+			needsUpdate = true;
+		end
+	end
+	if(needsUpdate) then SV.Timers:ExecuteTimer(MOD.RefreshChatFrames, 0.1); end
+end
+
+local function DockFadeInChat(location, default)
+	--print('DockFadeInChat ' .. location)
+	if(not location) then return end
+	for _, name in pairs(CHAT_FRAMES) do
+		local chat = _G[name];
+		if(chat and chat.Dock and (location == chat.Dock.Parent.Bar.Data.Location)) then
+			local buttonName = chat.Dock.Button:GetName();
+			if((default == buttonName) and (not SV.Dock.private.Disabled[buttonName])) then
+				MOD:ShowLines(chat)
+				chat:FadeIn(0.2, chat:GetAlpha(), 1)
+			else
+				MOD:FadeLines(chat)
+				chat:FadeOut(2, chat:GetAlpha(), 0, true)
+			end
+		end
+	end
+end
+
+local function DockFadeOutChat(location)
+	--print('DockFadeOutChat ' .. location)
+	if(not location) then return end
+	for _, name in pairs(CHAT_FRAMES) do
+		local chat = _G[name];
+		if(chat and chat.Dock) then
+			local buttonName = chat.Dock.Button:GetName();
+			if((location == chat.Dock.Parent.Bar.Data.Location) or (SV.Dock.private.Disabled[buttonName])) then
+				MOD:FadeLines(chat)
+				chat:FadeOut(2, chat:GetAlpha(), 0, true)
+			end
+		end
+	end
+end
+
+function MOD:ResetInternalData()
+	self:ClearPrivateData();
+	self.private.history = {};
+	self.private.activeTabs = {};
+	self.private.tabNames = {};
+	self.ChatHistory = self.private.history;
+	for _, internal in pairs(INTERNAL_TABLES) do
+		self.private[internal] = {};
+	end
+end
+
+function MOD:IsChatActive(chatFrame)
+	if(not chatFrame) then return false; end
+	local id = chatFrame:GetID();
+	local name,isActive = '',false;
+	local key = format("SVUI_ChatFrameDock%d", id);
+	for tabName, tabKey in pairs(self.private.tabNames) do
+		if(tabKey == key) then
+			name = tabName;
+		end
+	end
+	for tabKey, tabName in pairs(self.private.activeTabs) do
+		if(tabName == name) then
+			isActive = true;
+		end
+	end
+	return isActive;
+end
+
+function MOD:SaveActiveFlag(key,name)
+	if((not key) or (not name)) then return false; end
+	for tabName, tabKey in pairs(self.private.tabNames) do
+		if(tabKey == key) then
+			self.private.tabNames[tabName] = nil;
+		end
+	end
+	for tabKey, tabName in pairs(self.private.activeTabs) do
+		if(tabName == name) then
+			self.private.activeTabs[tabKey] = nil;
+		end
+	end
+	self.private.activeTabs[key] = name;
+	self.private.tabNames[name] = key;
+	return true;
+end
+
+function MOD:DeleteActiveFlag(key)
+	if(not key) then return false; end
+	for tabName, tabKey in pairs(self.private.tabNames) do
+		if(tabKey == key) then
+			self.private.tabNames[tabName] = nil;
+		end
+	end
+	self.private.activeTabs[key] = nil;
+	return true;
+end
+
+function MOD:ReLoad()
+	self:RefreshChatFrames('RELOAD', true)
+end
+
+function MOD:Load()
+	self.private.history = self.private.history or {};
+	self.private.activeTabs = self.private.activeTabs or {};
+	self.private.tabNames = self.private.tabNames or {};
+	self.ChatHistory = self.private.history;
+
+	self:IgnoreSharedKeys('history');
+	self:MakeSharable();
+
+	local baseDock = SV.Dock.BottomLeft;
+
+	ScrollIndicator:SetParent(baseDock)
+	ScrollIndicator:SetSize(20,20)
+	ScrollIndicator:SetPoint("BOTTOMRIGHT", baseDock, "BOTTOMRIGHT", 6, 0)
+	ScrollIndicator:SetFrameStrata("HIGH")
+	ScrollIndicator:EnableMouse(true)
+	ScrollIndicator.icon = ScrollIndicator:CreateTexture(nil, "BACKGROUND")
+	ScrollIndicator.icon:SetAllPoints()
+	ScrollIndicator.icon:SetTexture(MOD.media.scrollIcon)
+	ScrollIndicator.icon:SetBlendMode("ADD")
+	ScrollIndicator:Hide()
+	ScrollIndicator:SetScript("OnMouseDown", ScrollFullButton)
+
+	self:RegisterEvent('UPDATE_CHAT_WINDOWS', 'RefreshChatFrames')
+	self:RegisterEvent('UPDATE_FLOATING_CHAT_WINDOWS', 'RefreshChatFrames')
+	self:RegisterEvent('PET_BATTLE_CLOSE')
+
+	self:UpdateLocals()
+
+	for _, internal in pairs(INTERNAL_TABLES) do
+		self.private[internal] = self.private[internal] or {};
+	end
+
+	for i,name in pairs(CHAT_FRAMES) do
+		local chatFrame = _G[name];
+		if(chatFrame) then
+			SetChatWindowUninteractable(i, false)
+			for _, internal in pairs(INTERNAL_TABLES) do
+				self.private[internal][name] = self.private[internal][name] or {};
+				if(chatFrame[internal]) then
+					for x,y in pairs(chatFrame[internal]) do
+						self.private[internal][name][x] = y
+					end
+				end
+				chatFrame[internal] = self.private[internal][name];
+			end
+			chatFrame.oldAlpha = 0;
+			local key = format("SVUI_ChatFrameDock%d", i)
+			if(self.private.activeTabs[key] or ((not self.private.activeTabs[key]) and (i < 4))) then
+				local tabText = chatFrame.name;
+				if(tabText) then
+					self:SaveActiveFlag(key,tabText);
+				end
+			end
+		end
+	end
+
+	self:RefreshChatFrames('LOAD', true)
+	SetParseHandlers()
+
+	_G.CombatLogQuickButtonFrame_Custom:SetParent(ChatFrame2.Dock)
+	_G.CombatLogQuickButtonFrame_Custom.SetParent = SV.fubar
+
+	_G.GeneralDockManagerOverflowButton:ClearAllPoints()
+	_G.GeneralDockManagerOverflowButton:SetPoint('BOTTOMLEFT', baseDock.Bar, 'BOTTOMRIGHT', 2, 0)
+	_G.GeneralDockManagerOverflowButtonList:SetStyle("!_Frame", 'Transparent')
+	_G.GeneralDockManager:SetAllPoints(baseDock.Bar)
+
+	SetAllChatHooks()
+
+	FriendsMicroButton:Die()
+	ChatFrameMenuButton:Die()
+
+	_G.InterfaceOptionsSocialPanelTimestampsButton:SetAlpha(0)
+	_G.InterfaceOptionsSocialPanelTimestampsButton:SetScale(0.000001)
+	_G.InterfaceOptionsSocialPanelTimestamps:SetAlpha(0)
+	_G.InterfaceOptionsSocialPanelTimestamps:SetScale(0.000001)
+	_G.InterfaceOptionsSocialPanelChatStyle:EnableMouse(false)
+	_G.InterfaceOptionsSocialPanelChatStyleButton:Hide()
+	_G.InterfaceOptionsSocialPanelChatStyle:SetAlpha(0)
+
+	local frame = CreateFrame("Frame", "SVUI_CopyChatFrame", baseDock)
+	frame:SetPoint('BOTTOMLEFT', baseDock, 'TOPLEFT', 0, 0)
+	frame:SetPoint('BOTTOMRIGHT', baseDock, 'TOPRIGHT', 0, 0)
+	frame:SetHeight(baseDock:GetHeight())
+	frame:Hide()
+	frame:EnableMouse(true)
+	frame:SetFrameStrata("DIALOG")
+	SV.Dock.SetThemedBackdrop(frame, true);
+
+	frame.Title = frame:CreateFontString()
+	frame.Title:SetFontObject(SVUI_Font_Header)
+	frame.Title:SetJustifyH('LEFT')
+	frame.Title:SetText("Copy Chat")
+	frame.Title:SetPoint("TOPLEFT", frame, "TOPLEFT", 4, 4)
+	frame.Title:SetTextColor(1,0.8,0)
+
+	local scrollArea = CreateFrame("ScrollFrame", "SVUI_CopyChatScrollFrame", frame, "UIPanelScrollFrameTemplate")
+	scrollArea:SetPoint("TOPLEFT", frame, "TOPLEFT", 8, -30)
+	scrollArea:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -30, 8)
+
+	local editBox = CreateFrame("EditBox", "SVUI_CopyChatFrameEditBox", frame)
+	editBox:SetMultiLine(true)
+	editBox:SetMaxLetters(99999)
+	editBox:EnableMouse(true)
+	editBox:SetAutoFocus(false)
+	editBox:SetFontObject(SVUI_Font_Chat)
+	editBox:SetJustifyH('LEFT')
+	editBox:SetWidth(scrollArea:GetWidth())
+	editBox:SetHeight(200)
+	editBox:SetScript("OnEscapePressed", function() SVUI_CopyChatFrame:Hide() end)
+
+	scrollArea:SetScrollChild(editBox)
+
+	editBox:SetScript("OnTextChanged", function(self, userInput)
+		if userInput then return end
+		local _, max = SVUI_CopyChatScrollFrameScrollBar:GetMinMaxValues()
+		for i=1, max do
+			ScrollFrameTemplate_OnMouseWheel(SVUI_CopyChatScrollFrame, -1)
+		end
+	end)
+
+	local close = CreateFrame("Button", "SVUI_CopyChatFrameCloseButton", frame, "UIPanelCloseButton");
+	close:SetPoint("TOPRIGHT");
+	close:SetFrameLevel(close:GetFrameLevel() + 1);
+	close:EnableMouse(true);
+	SV.API:Set("CloseButton", close);
+	local uisfCount = #UISpecialFrames+1;
+	UISpecialFrames[uisfCount] = "SVUI_CopyChatFrame";
+
+	if(SV.db.Chat.saveChats) then
+		self:EnableChatHistory()
+		self:RegisterEvent("CHAT_MSG_WHISPER")
+		self:RegisterEvent("CHAT_MSG_BN_WHISPER")
+	end
+
+	self:LoadChatBubbles()
+
+	SV.Events:On("DOCK_FADE_IN", DockFadeInChat, true);
+	SV.Events:On("DOCK_FADE_OUT", DockFadeOutChat, true);
+	SV.Events:On("DOCK_EXPANDED", ExpandChatDock, true);
+	SV.Events:On("DOCKLETS_RESET", MOD.ResetChatWindows);
+
+	SV.SystemAlert["NEW_CHAT_DOCK"] = {
+		text = NAME_CHAT_WINDOW,
+		button1 = YES,
+		button2 = NO,
+		hasEditBox = 1,
+		OnAccept = function(self)
+			local name = self.editBox:GetText();
+			self.editBox:SetText("");
+			OpenNewSVUIChatFrame(name);
+		end,
+		EditBoxOnEnterPressed = function(self)
+			local parent = self:GetParent();
+			local editBox = parent.editBox
+			local name = editBox:GetText();
+			editBox:SetText("");
+			parent:Hide();
+			OpenNewSVUIChatFrame(name);
+		end,
+		EditBoxOnEscapePressed = function (self)
+			self:GetParent():Hide();
+		end,
+		hideOnEscape = 1,
+		OnCancel = SV.fubar,
+		timeout = 0,
+		whileDead = 1,
+		state1 = 1
+	};
+end
diff --git a/SVUI_Chat/SVUI_Chat.toc b/SVUI_Chat/SVUI_Chat.toc
new file mode 100644
index 0000000..70de428
--- /dev/null
+++ b/SVUI_Chat/SVUI_Chat.toc
@@ -0,0 +1,18 @@
+## Interface: 70000
+## Author: Failcoder
+## Version: 1.3.5
+## Title: |cffFF9900SuperVillain UI: |r|cffFFEF00Chat|r
+## Notes: Chat Plugin for [|cff9911FFSVUI|r].
+## SavedVariables: SVUI_Global_ChatCache
+## SavedVariablesPerCharacter: SVUI_Private_ChatCache
+## RequiredDeps: SVUI_!Core
+## OptionalDeps: LibSharedMedia-3.0
+## X-SVUIName: Chat
+## X-SVUISchema: Chat
+## X-Email: munglunch@gmail.com
+## X-Website: http://www.supervillainui.com
+## X-Donate: PayPal:munglunch@gmail.com
+## X-License: MIT
+## X-Category: Interface Enhancements
+
+SVUI_Chat.xml
diff --git a/SVUI_Chat/SVUI_Chat.xml b/SVUI_Chat/SVUI_Chat.xml
new file mode 100644
index 0000000..77abf1c
--- /dev/null
+++ b/SVUI_Chat/SVUI_Chat.xml
@@ -0,0 +1,28 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+	<Font name="SVUI_Font_Chat" font="Fonts\ARIALN.TTF" justifyH="LEFT" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="12"/>
+        </FontHeight>
+    </Font>
+    <Font name="SVUI_Font_ChatTab" font="Fonts\skurri.ttf" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="12"/>
+        </FontHeight>
+    </Font>
+
+	<Script file="Loader.lua"/>
+	<Script file="SVUI_Chat.lua"/>
+    <Script file="components\bubbles.lua"/>
+</Ui>
\ No newline at end of file
diff --git a/SVUI_Chat/assets/CHAT-SCROLL.blp b/SVUI_Chat/assets/CHAT-SCROLL.blp
new file mode 100644
index 0000000..c5fc3dc
Binary files /dev/null and b/SVUI_Chat/assets/CHAT-SCROLL.blp differ
diff --git a/SVUI_Chat/assets/CHAT-SVUI-LOGO.blp b/SVUI_Chat/assets/CHAT-SVUI-LOGO.blp
new file mode 100644
index 0000000..a8a3c3d
Binary files /dev/null and b/SVUI_Chat/assets/CHAT-SVUI-LOGO.blp differ
diff --git a/SVUI_Chat/assets/CHAT-WHISPER.blp b/SVUI_Chat/assets/CHAT-WHISPER.blp
new file mode 100644
index 0000000..c07036d
Binary files /dev/null and b/SVUI_Chat/assets/CHAT-WHISPER.blp differ
diff --git a/SVUI_Chat/assets/CHATBUBBLE-BACKDROP.blp b/SVUI_Chat/assets/CHATBUBBLE-BACKDROP.blp
new file mode 100644
index 0000000..a000ecc
Binary files /dev/null and b/SVUI_Chat/assets/CHATBUBBLE-BACKDROP.blp differ
diff --git a/SVUI_Chat/assets/CHATBUBBLE-BG.blp b/SVUI_Chat/assets/CHATBUBBLE-BG.blp
new file mode 100644
index 0000000..9b7cc4b
Binary files /dev/null and b/SVUI_Chat/assets/CHATBUBBLE-BG.blp differ
diff --git a/SVUI_Chat/assets/CHATBUBBLE-TAIL.blp b/SVUI_Chat/assets/CHATBUBBLE-TAIL.blp
new file mode 100644
index 0000000..17e10a6
Binary files /dev/null and b/SVUI_Chat/assets/CHATBUBBLE-TAIL.blp differ
diff --git a/SVUI_Chat/assets/DOCK-ICON-CHAT.blp b/SVUI_Chat/assets/DOCK-ICON-CHAT.blp
new file mode 100644
index 0000000..c61c5fa
Binary files /dev/null and b/SVUI_Chat/assets/DOCK-ICON-CHAT.blp differ
diff --git a/SVUI_Chat/assets/Emoticons/SVUI_Chat_Logo.blp b/SVUI_Chat/assets/Emoticons/SVUI_Chat_Logo.blp
new file mode 100644
index 0000000..a8a3c3d
Binary files /dev/null and b/SVUI_Chat/assets/Emoticons/SVUI_Chat_Logo.blp differ
diff --git a/SVUI_Chat/assets/Emoticons/alert.blp b/SVUI_Chat/assets/Emoticons/alert.blp
new file mode 100644
index 0000000..c92c23f
Binary files /dev/null and b/SVUI_Chat/assets/Emoticons/alert.blp differ
diff --git a/SVUI_Chat/assets/Emoticons/alert2.blp b/SVUI_Chat/assets/Emoticons/alert2.blp
new file mode 100644
index 0000000..35d6774
Binary files /dev/null and b/SVUI_Chat/assets/Emoticons/alert2.blp differ
diff --git a/SVUI_Chat/assets/Emoticons/angry.blp b/SVUI_Chat/assets/Emoticons/angry.blp
new file mode 100644
index 0000000..96caf59
Binary files /dev/null and b/SVUI_Chat/assets/Emoticons/angry.blp differ
diff --git a/SVUI_Chat/assets/Emoticons/broken_heart.blp b/SVUI_Chat/assets/Emoticons/broken_heart.blp
new file mode 100644
index 0000000..b1ff49d
Binary files /dev/null and b/SVUI_Chat/assets/Emoticons/broken_heart.blp differ
diff --git a/SVUI_Chat/assets/Emoticons/grin.blp b/SVUI_Chat/assets/Emoticons/grin.blp
new file mode 100644
index 0000000..0f88411
Binary files /dev/null and b/SVUI_Chat/assets/Emoticons/grin.blp differ
diff --git a/SVUI_Chat/assets/Emoticons/happy.blp b/SVUI_Chat/assets/Emoticons/happy.blp
new file mode 100644
index 0000000..2d91325
Binary files /dev/null and b/SVUI_Chat/assets/Emoticons/happy.blp differ
diff --git a/SVUI_Chat/assets/Emoticons/heart.blp b/SVUI_Chat/assets/Emoticons/heart.blp
new file mode 100644
index 0000000..df57182
Binary files /dev/null and b/SVUI_Chat/assets/Emoticons/heart.blp differ
diff --git a/SVUI_Chat/assets/Emoticons/hmm.blp b/SVUI_Chat/assets/Emoticons/hmm.blp
new file mode 100644
index 0000000..0fd446d
Binary files /dev/null and b/SVUI_Chat/assets/Emoticons/hmm.blp differ
diff --git a/SVUI_Chat/assets/Emoticons/middle_finger.blp b/SVUI_Chat/assets/Emoticons/middle_finger.blp
new file mode 100644
index 0000000..acfa381
Binary files /dev/null and b/SVUI_Chat/assets/Emoticons/middle_finger.blp differ
diff --git a/SVUI_Chat/assets/Emoticons/sad.blp b/SVUI_Chat/assets/Emoticons/sad.blp
new file mode 100644
index 0000000..1d37a06
Binary files /dev/null and b/SVUI_Chat/assets/Emoticons/sad.blp differ
diff --git a/SVUI_Chat/assets/Emoticons/surprise.blp b/SVUI_Chat/assets/Emoticons/surprise.blp
new file mode 100644
index 0000000..1cf4dac
Binary files /dev/null and b/SVUI_Chat/assets/Emoticons/surprise.blp differ
diff --git a/SVUI_Chat/assets/Emoticons/tongue.blp b/SVUI_Chat/assets/Emoticons/tongue.blp
new file mode 100644
index 0000000..7e838d3
Binary files /dev/null and b/SVUI_Chat/assets/Emoticons/tongue.blp differ
diff --git a/SVUI_Chat/assets/Emoticons/weepy.blp b/SVUI_Chat/assets/Emoticons/weepy.blp
new file mode 100644
index 0000000..f0290d4
Binary files /dev/null and b/SVUI_Chat/assets/Emoticons/weepy.blp differ
diff --git a/SVUI_Chat/assets/Emoticons/winky.blp b/SVUI_Chat/assets/Emoticons/winky.blp
new file mode 100644
index 0000000..77514ad
Binary files /dev/null and b/SVUI_Chat/assets/Emoticons/winky.blp differ
diff --git a/SVUI_Chat/assets/whisper.mp3 b/SVUI_Chat/assets/whisper.mp3
new file mode 100644
index 0000000..01aed6b
Binary files /dev/null and b/SVUI_Chat/assets/whisper.mp3 differ
diff --git a/SVUI_Chat/components/bubbles.lua b/SVUI_Chat/components/bubbles.lua
new file mode 100644
index 0000000..fc8aa6b
--- /dev/null
+++ b/SVUI_Chat/components/bubbles.lua
@@ -0,0 +1,81 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local ipairs 	= _G.ipairs;
+local type 		= _G.type;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L;
+local MOD = SV.Chat;
+--[[
+##########################################################
+CHAT BUBBLES
+##########################################################
+]]--
+function MOD:LoadChatBubbles()
+	if(SV.db.Chat.bubbles == true) then
+		local ChatBubbleHandler = CreateFrame("Frame", nil, UIParent)
+
+		local function _style(frame)
+			if(frame:GetName() or (not frame:GetRegions())) then return end
+			local backdrop = frame:GetBackdrop()
+			if((not backdrop) or (not backdrop.bgFile) or (not backdrop.bgFile:find('ChatBubble'))) then return end
+			local needsUpdate = true;
+			for i = 1, frame:GetNumRegions() do
+				local region = select(i, frame:GetRegions())
+				if region:GetObjectType() == "Texture" then
+					if(region:GetTexture() == [[Interface\Tooltips\ChatBubble-Background]]) then
+						region:SetTexture([[Interface\AddOns\SVUI_Chat\assets\CHATBUBBLE-BG]])
+						needsUpdate = false
+					elseif(region:GetTexture() == [[Interface\Tooltips\ChatBubble-Backdrop]]) then
+						region:SetTexture([[Interface\AddOns\SVUI_Chat\assets\CHATBUBBLE-BACKDROP]])
+						needsUpdate = false
+					elseif(region:GetTexture() == [[Interface\Tooltips\ChatBubble-Tail]]) then
+						region:SetTexture([[Interface\AddOns\SVUI_Chat\assets\CHATBUBBLE-TAIL]])
+						needsUpdate = false
+					else
+						region:SetTexture("")
+					end
+				elseif(region:GetObjectType() == "FontString" and not frame.text) then
+					frame.text = region
+				end
+			end
+			if needsUpdate then
+				frame:SetBackdrop(nil);
+				frame:SetClampedToScreen(false)
+				frame:SetFrameStrata("BACKGROUND")
+			end
+			if(frame.text) then
+				frame.text:SetFontObject(SVUI_Font_Default)
+				frame.text:SetShadowColor(0,0,0,1)
+				frame.text:SetShadowOffset(1,-1)
+			end
+		end
+
+		local timer,total = 0,0;
+		ChatBubbleHandler:SetScript("OnUpdate", function(self, elapsed)
+			timer = timer + elapsed
+			if timer > 0.1 then
+				timer = 0
+				local current = WorldFrame:GetNumChildren();
+				if current ~= total then
+					for i = total + 1, current do _style(select(i, WorldFrame:GetChildren())) end
+					total = current
+				end
+			end
+		end)
+	end
+end
diff --git a/SVUI_CraftOMatic/Bindings.xml b/SVUI_CraftOMatic/Bindings.xml
new file mode 100644
index 0000000..85b7a1e
--- /dev/null
+++ b/SVUI_CraftOMatic/Bindings.xml
@@ -0,0 +1,14 @@
+<Bindings>
+  <Binding name="SVUICRAFT_FISH" category="ADDONS" header="SVUICRAFT" runOnUp="false">
+    SVUIFishingMode()
+  </Binding>
+   <Binding name="SVUICRAFT_FARM" category="ADDONS" runOnUp="false">
+    SVUIFarmingMode()
+  </Binding>
+  <Binding name="SVUICRAFT_ARCH" category="ADDONS" runOnUp="false">
+    SVUIArchaeologyMode()
+  </Binding>
+  <Binding name="SVUICRAFT_COOK" category="ADDONS" runOnUp="false">
+    SVUICookingMode()
+  </Binding>
+</Bindings>
\ No newline at end of file
diff --git a/SVUI_CraftOMatic/License.txt b/SVUI_CraftOMatic/License.txt
new file mode 100644
index 0000000..05ceba8
--- /dev/null
+++ b/SVUI_CraftOMatic/License.txt
@@ -0,0 +1,31 @@
+
+The MIT License
+
+Copyright (c) 2010, Failcoder (Steve Jackson)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy
+of this software and associated documentation files (the "Software"), to
+deal
+in the Software without restriction, including without limitation the
+rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/SVUI_CraftOMatic/Loader.lua b/SVUI_CraftOMatic/Loader.lua
new file mode 100644
index 0000000..fd1ef08
--- /dev/null
+++ b/SVUI_CraftOMatic/Loader.lua
@@ -0,0 +1,160 @@
+--[[
+##########################################################
+S V U I   By: S.Jackson
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+
+local SV = _G["SVUI"];
+local L = SV.L;
+local PLUGIN = SV:NewPlugin(...);
+local Schema = PLUGIN.Schema;
+
+SV.defaults[Schema] = {
+	["fontSize"] = 12,
+	["farming"] = {
+		["buttonsize"] = 35,
+		["buttonspacing"] = 3,
+		["onlyactive"] = false,
+		["droptools"] = true,
+		["toolbardirection"] = "HORIZONTAL",
+	},
+	["fishing"] = {
+		["autoequip"] = true,
+	},
+	["cooking"] = {
+		["autoequip"] = true,
+	},
+}
+
+SV:AssignMedia("font", "craftdialog", "SVUI Default Font", 12, "OUTLINE");
+SV:AssignMedia("font", "craftnumber", "SVUI Caps Font", 12, "OUTLINE");
+SV:AssignMedia("globalfont", "craftdialog", "SVUI_Font_Craft");
+SV:AssignMedia("globalfont", "craftnumber", "SVUI_Font_CraftNumber");
+
+function PLUGIN:LoadOptions()
+	local craftFonts = {
+		["craftdialog"] = {
+			order = 1,
+			name = "Craft-O-Matic Dialog",
+			desc = "Font used for log window text."
+		},
+		["craftnumber"] = {
+			order = 2,
+			name = "Craft-O-Matic Numbers",
+			desc = "Font used for log window numbers."
+		},
+	};
+
+	SV:GenerateFontOptionGroup("Craft-O-Matic", 11, "Fonts used for the Craft-O-Matic log window.", craftFonts)
+
+	SV.Options.args[Schema] = {
+		type = "group",
+		name = Schema,
+		get = function(a)return SV.db[Schema][a[#a]]end,
+		set = function(a,b) PLUGIN:ChangeDBVar(b,a[#a]); end,
+		args = {
+			fishing = {
+			    order = 1,
+				type = "group",
+				name = L["Fishing Mode Settings"],
+				guiInline = true,
+				args = {
+					autoequip = {
+						type = "toggle",
+						order = 1,
+						name = L['AutoEquip'],
+						desc = L['Enable/Disable automatically equipping fishing gear.'],
+						get = function(key)return SV.db[Schema].fishing[key[#key]] end,
+						set = function(key, value) PLUGIN:ChangeDBVar(value, key[#key], "fishing") end
+					}
+				}
+			},
+			cooking = {
+			    order = 2,
+				type = "group",
+				name = L["Cooking Mode Settings"],
+				guiInline = true,
+				args = {
+					autoequip = {
+						type = "toggle",
+						order = 1,
+						name = L['AutoEquip'],
+						desc = L['Enable/Disable automatically equipping cooking gear.'],
+						get = function(key)return SV.db[Schema].cooking[key[#key]]end,
+						set = function(key, value) PLUGIN:ChangeDBVar(value, key[#key], "cooking")end
+					}
+				}
+			},
+			farming = {
+			    order = 3,
+				type = "group",
+				name = L["Farming Mode Settings"],
+				guiInline = true,
+				get = function(key)return SV.db[Schema].farming[key[#key]]end,
+				set = function(key, value) SV.db[Schema].farming[key[#key]] = value end,
+				args = {
+					buttonsize = {
+						type = 'range',
+						name = L['Button Size'],
+						desc = L['The size of the action buttons.'],
+						min = 15,
+						max = 60,
+						step = 1,
+						order = 1,
+						set = function(key, value)
+							PLUGIN:ChangeDBVar(value, key[#key], "farming");
+							PLUGIN:RefreshFarmingTools()
+						end,
+					},
+					buttonspacing = {
+						type = 'range',
+						name = L['Button Spacing'],
+						desc = L['The spacing between buttons.'],
+						min = 1,
+						max = 10,
+						step = 1,
+						order = 2,
+						set = function(key, value)
+							PLUGIN:ChangeDBVar(value, key[#key], "farming");
+							PLUGIN:RefreshFarmingTools()
+						end,
+					},
+					onlyactive = {
+						order = 3,
+						type = 'toggle',
+						name = L['Only active buttons'],
+						desc = L['Only show the buttons for the seeds, portals, tools you have in your bags.'],
+						set = function(key, value)
+							PLUGIN:ChangeDBVar(value, key[#key], "farming");
+							PLUGIN:RefreshFarmingTools()
+						end,
+					},
+					droptools = {
+						order = 4,
+						type = 'toggle',
+						name = L['Drop '],
+						desc = L['Automatically drop tools from your bags when leaving the farming area.'],
+					},
+					toolbardirection = {
+						order = 5,
+						type = 'select',
+						name = L['Bar Direction'],
+						desc = L['The direction of the bar buttons (Horizontal or Vertical).'],
+						set = function(key, value) PLUGIN:ChangeDBVar(value, key[#key],"farming"); PLUGIN:RefreshFarmingTools() end,
+						values = {
+								['VERTICAL'] = L['Vertical'], ['HORIZONTAL'] = L['Horizontal']
+						}
+					}
+				}
+			}
+		}
+	}
+end
\ No newline at end of file
diff --git a/SVUI_CraftOMatic/SVUI_CraftOMatic.lua b/SVUI_CraftOMatic/SVUI_CraftOMatic.lua
new file mode 100644
index 0000000..0588fa9
--- /dev/null
+++ b/SVUI_CraftOMatic/SVUI_CraftOMatic.lua
@@ -0,0 +1,731 @@
+--[[
+##########################################################
+S V U I   By: S.Jackson
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+
+--[[ GLOBALS ]]--
+
+local _G = _G;
+local unpack            = _G.unpack;
+local select            = _G.select;
+local assert            = _G.assert;
+local type              = _G.type;
+local error             = _G.error;
+local pcall             = _G.pcall;
+local print             = _G.print;
+local ipairs            = _G.ipairs;
+local pairs             = _G.pairs;
+local next              = _G.next;
+local tostring          = _G.tostring;
+local tonumber          = _G.tonumber;
+local collectgarbage    = _G.collectgarbage;
+local rawset            = _G.rawset;
+local rawget            = _G.rawget;
+local getmetatable      = _G.getmetatable;
+local setmetatable      = _G.setmetatable;
+local loadstring        = _G.loadstring;
+local string    = _G.string;
+local math 		= _G.math;
+local table 	= _G.table;
+local rept      = string.rep;
+local tsort,twipe = table.sort,table.wipe;
+local floor,ceil  = math.floor, math.ceil;
+--BLIZZARD API
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+local GameTooltip           = _G.GameTooltip;
+local hooksecurefunc        = _G.hooksecurefunc;
+local IsAltKeyDown          = _G.IsAltKeyDown;
+local IsShiftKeyDown        = _G.IsShiftKeyDown;
+local IsControlKeyDown      = _G.IsControlKeyDown;
+local IsModifiedClick       = _G.IsModifiedClick;
+local PlaySound             = _G.PlaySound;
+local PlaySoundFile         = _G.PlaySoundFile;
+local PlayMusic             = _G.PlayMusic;
+local StopMusic             = _G.StopMusic;
+local GetTime               = _G.GetTime;
+local ToggleFrame           = _G.ToggleFrame;
+local EquipItemByName       = _G.EquipItemByName;
+local IsSpellKnown      	= _G.IsSpellKnown;
+local ERR_NOT_IN_COMBAT     = _G.ERR_NOT_IN_COMBAT;
+local RAID_CLASS_COLORS     = _G.RAID_CLASS_COLORS;
+local CUSTOM_CLASS_COLORS   = _G.CUSTOM_CLASS_COLORS;
+
+--[[  CONSTANTS ]]--
+
+_G.BINDING_HEADER_SVUICRAFT = "Supervillain UI: Craft-O-Matic";
+_G.BINDING_NAME_SVUICRAFT_FISH = "Toggle Fishing Mode";
+_G.BINDING_NAME_SVUICRAFT_FARM = "Toggle Farming Mode";
+_G.BINDING_NAME_SVUICRAFT_COOK = "Toggle Cooking Mode";
+_G.BINDING_NAME_SVUICRAFT_ARCH = "Toggle Archaeology Mode";
+
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G["SVUI"];
+local L = SV.L;
+local PLUGIN = select(2, ...)
+local CONFIGS = SV.defaults[PLUGIN.Schema];
+
+local NewHook = hooksecurefunc;
+local playerGUID = UnitGUID('player')
+local classColor = RAID_CLASS_COLORS
+--[[
+##########################################################
+GLOBAL BINDINGS
+##########################################################
+]]--
+_G.SVUIFishingMode = function()
+	if InCombatLockdown() then SV:AddonMessage(ERR_NOT_IN_COMBAT); return; end
+	if PLUGIN.CurrentMode and PLUGIN.CurrentMode == "Fishing" then PLUGIN:EndJobModes() else PLUGIN:SetJobMode("Fishing") end
+end
+
+_G.SVUIFarmingMode = function()
+	if InCombatLockdown() then SV:AddonMessage(ERR_NOT_IN_COMBAT); return; end
+	if PLUGIN.CurrentMode and SV.CurrentMode == "Farming" then PLUGIN:EndJobModes() else PLUGIN:SetJobMode("Farming") end
+end
+
+_G.SVUIArchaeologyMode = function()
+	if InCombatLockdown() then SV:AddonMessage(ERR_NOT_IN_COMBAT); return; end
+	if PLUGIN.CurrentMode and PLUGIN.CurrentMode == "Archaeology" then PLUGIN:EndJobModes() else PLUGIN:SetJobMode("Archaeology") end
+end
+
+_G.SVUICookingMode = function()
+	if InCombatLockdown() then SV:AddonMessage(ERR_NOT_IN_COMBAT); return; end
+	if PLUGIN.CurrentMode and PLUGIN.CurrentMode == "Cooking" then PLUGIN:EndJobModes() else PLUGIN:SetJobMode("Cooking") end
+end
+--[[
+##########################################################
+LOCALIZED GLOBALS
+##########################################################
+]]--
+local LOOT_ITEM_SELF = _G.LOOT_ITEM_SELF;
+local LOOT_ITEM_CREATED_SELF = _G.LOOT_ITEM_CREATED_SELF;
+local LOOT_ITEM_SELF_MULTIPLE = _G.LOOT_ITEM_SELF_MULTIPLE
+local LOOT_ITEM_PUSHED_SELF_MULTIPLE = _G.LOOT_ITEM_PUSHED_SELF_MULTIPLE
+local LOOT_ITEM_PUSHED_SELF = _G.LOOT_ITEM_PUSHED_SELF
+--[[
+##########################################################
+LOCAL VARS
+##########################################################
+]]--
+local currentModeKey = false;
+local ModeLogsFrame = CreateFrame("Frame", "SVUI_ModeLogsFrame", UIParent)
+local classColors = CUSTOM_CLASS_COLORS[SV.class]
+local classR, classG, classB = classColors.r, classColors.g, classColors.b
+local classA = 0.35
+local lastClickTime;
+local ICON_FILE = [[Interface\AddOns\SVUI_CraftOMatic\artwork\DOCK-LABORER]]
+local COOK_ICON = [[Interface\AddOns\SVUI_CraftOMatic\artwork\LABORER-COOKING]]
+local FISH_ICON = [[Interface\AddOns\SVUI_CraftOMatic\artwork\LABORER-FISHING]]
+local ARCH_ICON = [[Interface\AddOns\SVUI_CraftOMatic\artwork\LABORER-SURVEY]]
+local FARM_ICON = [[Interface\AddOns\SVUI_CraftOMatic\artwork\LABORER-FARMING]]
+--[[
+##########################################################
+LOCAL FUNCTIONS
+##########################################################
+]]--
+local function onMouseWheel(self, delta)
+	if (delta > 0) then
+		self:ScrollUp()
+	elseif (delta < 0) then
+		self:ScrollDown()
+	end
+end
+
+local function CheckForDoubleClick()
+	if lastClickTime then
+		local pressTime = GetTime()
+		local doubleTime = pressTime - lastClickTime
+		if ( (doubleTime < 0.4) and (doubleTime > 0.05) ) then
+			lastClickTime = nil
+			return true
+		end
+	end
+	lastClickTime = GetTime()
+	return false
+end
+--[[
+##########################################################
+CHAT LOG PARSING FUNCTIONS (from LibDeformat  by:ckknight)
+##########################################################
+]]--
+local ChatDeFormat;
+do
+    local FORMAT_SEQUENCES = {
+        ["s"] = ".+",
+        ["c"] = ".",
+        ["%d*d"] = "%%-?%%d+",
+        ["[fg]"] = "%%-?%%d+%%.?%%d*",
+        ["%%%.%d[fg]"] = "%%-?%%d+%%.?%%d*",
+    }
+
+    local STRING_BASED_SEQUENCES = {
+        ["s"] = true,
+        ["c"] = true,
+    }
+
+    local cache = setmetatable({}, {__mode='k'})
+
+    local function _deformat(pattern)
+        local func = cache[pattern]
+        if func then return func end
+        local unpattern = '^' .. pattern:gsub("([%(%)%.%*%+%-%[%]%?%^%$%%])", "%%%1") .. '$'
+        local number_indexes = {}
+        local index_translation = nil
+        local highest_index
+        if not pattern:find("%%1%$") then
+            local i = 0
+            while true do
+                i = i + 1
+                local first_index
+                local first_sequence
+                for sequence in pairs(FORMAT_SEQUENCES) do
+                    local index = unpattern:find("%%%%" .. sequence)
+                    if index and (not first_index or index < first_index) then
+                        first_index = index
+                        first_sequence = sequence
+                    end
+                end
+                if not first_index then
+                    break
+                end
+                unpattern = unpattern:gsub("%%%%" .. first_sequence, "(" .. FORMAT_SEQUENCES[first_sequence] .. ")", 1)
+                number_indexes[i] = not STRING_BASED_SEQUENCES[first_sequence]
+            end
+            highest_index = i - 1
+        else
+            local i = 0
+            while true do
+                i = i + 1
+                local found_sequence
+                for sequence in pairs(FORMAT_SEQUENCES) do
+                    if unpattern:find("%%%%" .. i .. "%%%$" .. sequence) then
+                        found_sequence = sequence
+                        break
+                    end
+                end
+                if not found_sequence then
+                    break
+                end
+                unpattern = unpattern:gsub("%%%%" .. i .. "%%%$" .. found_sequence, "(" .. FORMAT_SEQUENCES[found_sequence] .. ")", 1)
+                number_indexes[i] = not STRING_BASED_SEQUENCES[found_sequence]
+            end
+            highest_index = i - 1
+            i = 0
+            index_translation = {}
+            pattern:gsub("%%(%d)%$", function(w)
+                i = i + 1
+                index_translation[i] = tonumber(w)
+            end)
+        end
+        if highest_index == 0 then
+            cache[pattern] = SV.fubar
+        else
+            local t = {}
+            t[#t+1] = [=[
+                return function(text)
+                    local ]=]
+            for i = 1, highest_index do
+                if i ~= 1 then
+                    t[#t+1] = ", "
+                end
+                t[#t+1] = "a"
+                if not index_translation then
+                    t[#t+1] = i
+                else
+                    t[#t+1] = index_translation[i]
+                end
+            end
+            t[#t+1] = [=[ = text:match(]=]
+            t[#t+1] = ("%q"):format(unpattern)
+            t[#t+1] = [=[)
+                if not a1 then
+                    return ]=]
+            for i = 1, highest_index do
+                if i ~= 1 then
+                    t[#t+1] = ", "
+                end
+                t[#t+1] = "nil"
+            end
+            t[#t+1] = "\n"
+            t[#t+1] = [=[
+                end
+            ]=]
+            t[#t+1] = "return "
+            for i = 1, highest_index do
+                if i ~= 1 then
+                    t[#t+1] = ", "
+                end
+                t[#t+1] = "a"
+                t[#t+1] = i
+                if number_indexes[i] then
+                    t[#t+1] = "+0"
+                end
+            end
+            t[#t+1] = "\n"
+            t[#t+1] = [=[
+                end
+            ]=]
+            t = table.concat(t, "")
+            cache[pattern] = assert(loadstring(t))()
+        end
+        return cache[pattern]
+    end
+
+    ChatDeFormat = function(text, pattern)
+        if((type(text) == "string") and (type(pattern) == "string")) then
+            return _deformat(pattern)(text)
+        end
+        return false;
+    end
+end
+--[[
+##########################################################
+WORLDFRAME HANDLER
+##########################################################
+]]--
+local _hook_WorldFrame_OnMouseDown = function(self, button)
+	if InCombatLockdown() then return end
+	if(currentModeKey and button == "RightButton" and CheckForDoubleClick()) then
+		local handle = PLUGIN[currentModeKey];
+		if(handle and handle.Bind) then
+			handle.Bind()
+		end
+	end
+end
+
+local ModeCapture_PostClickHandler = function(self, button)
+	if InCombatLockdown() then
+		self:RegisterEvent("PLAYER_REGEN_ENABLED")
+		return
+	end
+	ClearOverrideBindings(self)
+	self.Handler:Hide()
+end
+
+local ModeCapture_EventHandler = function(self, event, ...)
+	if event == "PLAYER_REGEN_ENABLED" then
+		self:UnregisterEvent("PLAYER_REGEN_ENABLED")
+		PLUGIN:ChangeModeGear()
+		ModeCapture_PostClickHandler(self)
+	end
+	if event == "PLAYER_ENTERING_WORLD" then
+		if (IsSpellKnown(131474) or IsSpellKnown(80451) or IsSpellKnown(818)) then
+			WorldFrame:HookScript("OnMouseDown", _hook_WorldFrame_OnMouseDown)
+		end
+		self:UnregisterEvent("PLAYER_ENTERING_WORLD")
+	end
+end
+
+local Handler = CreateFrame("Frame", nil, UIParent)
+Handler:SetPoint("LEFT", UIParent, "RIGHT", 10000, 0)
+local ModeCapture = CreateFrame("Button", "SVUI_ModeCaptureWindow", UIParent, "SecureActionButtonTemplate")
+ModeCapture.Handler = Handler
+ModeCapture:EnableMouse(true)
+ModeCapture:RegisterForClicks("RightButtonUp")
+ModeCapture:RegisterEvent("PLAYER_ENTERING_WORLD")
+ModeCapture:SetScript("PostClick", ModeCapture_PostClickHandler)
+ModeCapture:SetScript("OnEvent", ModeCapture_EventHandler)
+
+ModeCapture:Hide()
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+function PLUGIN:CraftingReset()
+	self.TitleWindow:Clear();
+	self.LogWindow:Clear();
+	self.TitleWindow:AddMessage("Crafting Modes", 1, 1, 0);
+	self.LogWindow:AddMessage("Select a Tool to Begin", 1, 1, 1);
+	self.LogWindow:AddMessage(" ", 0, 1, 1);
+	collectgarbage("collect")
+end
+
+function PLUGIN:ModeLootLoader(mode, msg, info)
+	self.TitleWindow:Clear();
+	self.LogWindow:Clear();
+	self.ModeAlert.HelpText = info
+	if(mode and self[mode]) then
+		if(self[mode].Log) then
+			local stored = self[mode].Log;
+			self.TitleWindow:AddMessage(msg, 1, 1, 1);
+			local previous = false
+			for name,data in pairs(stored) do
+				if type(data) == "table" and data.amount and data.texture then
+					self.LogWindow:AddMessage("|cff55FF55"..data.amount.." x|r |T".. data.texture ..":16:16:0:0:64:64:4:60:4:60|t".." "..name, 0.8, 0.8, 0.8);
+					previous = true
+				end
+			end
+			if(previous) then
+				self.LogWindow:AddMessage("----------------", 0, 0, 0);
+				self.LogWindow:AddMessage(" ", 0, 0, 0);
+			end
+			self.LogWindow:AddMessage(info, 1, 1, 1);
+			self.LogWindow:AddMessage(" ", 1, 1, 1);
+		end
+	else
+		self:CraftingReset()
+	end
+end
+
+function PLUGIN:CheckForModeLoot(msg)
+  	local item, amt = ChatDeFormat(msg, LOOT_ITEM_CREATED_SELF)
+	if not item then
+	  item = ChatDeFormat(msg, LOOT_ITEM_SELF_MULTIPLE)
+	  	if not item then
+		  item = ChatDeFormat(msg, LOOT_ITEM_SELF)
+		  	if not item then
+		      	item = ChatDeFormat(msg, LOOT_ITEM_PUSHED_SELF_MULTIPLE)
+		      	if not item then
+		        	item, amt = ChatDeFormat(msg, LOOT_ITEM_PUSHED_SELF)
+		        	--print(item)
+		      	end
+		    end
+		end
+	end
+	--print(msg)
+	if item then
+		if not amt then
+		  	amt = 1
+		end
+		return item, amt
+	end
+end
+
+function PLUGIN:SetJobMode(category)
+	if InCombatLockdown() then return end
+	if(not category) then
+		self:EndJobModes()
+		return;
+	end
+	self:ChangeModeGear()
+	if(currentModeKey and self[currentModeKey] and self[currentModeKey].Disable) then
+		if(currentModeKey == category) then
+			self:EndJobModes()
+			return;
+		else
+			self:EndJobModes()
+		end
+	end
+	currentModeKey = category;
+	if(self[category] and self[category].Enable) then
+		for key,button in pairs(self.ToolBar.Buttons) do
+			if(key == category) then
+				button.currentColor = "highlight";
+				button.icon:SetGradient(unpack(SV.media.gradient.highlight))
+				button:SetAlpha(1)
+			else
+				button.currentColor = "icon";
+				button.icon:SetGradient(unpack(SV.media.gradient.icon))
+				button:SetAlpha(0.5)
+			end
+		end
+		self[category].Enable()
+	else
+		self:EndJobModes()
+		return;
+	end
+end
+
+function PLUGIN:EndJobModes()
+	for key,button in pairs(self.ToolBar.Buttons) do
+		button.currentColor = "icon";
+		button.icon:SetGradient(unpack(SV.media.gradient.icon));
+		button:SetAlpha(1);
+	end
+	if(currentModeKey and self[currentModeKey] and self[currentModeKey].Disable) then
+		self[currentModeKey].Disable()
+	end
+	currentModeKey = false;
+	--if self.Docklet:IsShown() then self.Docklet.Button:Click() end
+	self:ChangeModeGear()
+	self.ModeAlert:Hide();
+	SV:SCTMessage("Mode Disabled", 1, 0.35, 0);
+	PlaySound("UndeadExploration");
+	self:CraftingReset()
+end
+
+function PLUGIN:ChangeModeGear()
+	if(not self.InModeGear) then return end
+	if InCombatLockdown() then
+		_G["SVUI_ModeCaptureWindow"]:RegisterEvent("PLAYER_REGEN_ENABLED");
+		return
+	else
+		if(self.WornItems["HEAD"]) then
+			EquipItemByName(self.WornItems["HEAD"])
+			self.WornItems["HEAD"] = false
+		end
+		if(self.WornItems["TAB"]) then
+			EquipItemByName(self.WornItems["TAB"])
+			self.WornItems["TAB"] = false
+		end
+		if(self.WornItems["MAIN"]) then
+			EquipItemByName(self.WornItems["MAIN"])
+			self.WornItems["MAIN"] = false
+		end
+		if(self.WornItems["OFF"]) then
+			EquipItemByName(self.WornItems["OFF"])
+			self.WornItems["OFF"] = false
+		end
+
+		self.InModeGear = false
+	end
+end
+
+function PLUGIN:SKILL_LINES_CHANGED()
+	if(currentModeKey and self[currentModeKey] and self[currentModeKey].Update) then
+		self[currentModeKey].Update()
+	end
+end
+--[[
+##########################################################
+BUILD FUNCTION / UPDATE
+##########################################################
+]]--
+local ModeAlert_OnEnter = function(self)
+	if InCombatLockdown() then return; end
+	self:SetBackdropColor(0.9, 0.15, 0.1)
+	GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT", 0, 4)
+	GameTooltip:ClearLines()
+	GameTooltip:AddLine(self.ModeText, 1, 1, 0)
+	GameTooltip:AddLine("")
+	GameTooltip:AddLine("Click here end this mode.", 0.79, 0.23, 0.23)
+	GameTooltip:AddLine("")
+	GameTooltip:AddLine(self.HelpText, 0.74, 1, 0.57)
+	GameTooltip:Show()
+end
+
+local ModeAlert_OnLeave = function(self)
+	GameTooltip:Hide()
+	if InCombatLockdown() then return end
+	self:SetBackdropColor(0.25, 0.52, 0.1)
+end
+
+local ModeAlert_OnHide = function()
+	if InCombatLockdown() then
+		SV:AddonMessage(ERR_NOT_IN_COMBAT);
+		return;
+	end
+	PLUGIN.Docklet.Parent.Alert:Deactivate()
+end
+
+local ModeAlert_OnShow = function(self)
+	if InCombatLockdown() then
+		SV:AddonMessage(ERR_NOT_IN_COMBAT);
+		return;
+	end
+	PLUGIN.Docklet.Parent.Alert:Activate(self)
+end
+
+local ModeAlert_OnMouseDown = function(self)
+	PLUGIN:EndJobModes()
+	self:FadeOut(0.5, 1, 0, true)
+end
+
+local ModeButton_OnEnter = function(self)
+	if InCombatLockdown() then return; end
+	local name = self.modeName
+	self.icon:SetGradient(unpack(SV.media.gradient.yellow))
+	GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT", 0, 4)
+	GameTooltip:ClearLines()
+	GameTooltip:AddLine(L[name .. " Mode"], 1, 1, 1)
+	GameTooltip:Show()
+end
+
+local ModeButton_OnLeave = function(self)
+	if InCombatLockdown() then return; end
+	self.icon:SetGradient(unpack(SV.media.gradient[self.currentColor]))
+	GameTooltip:Hide()
+end
+
+local ModeButton_OnMouseDown = function(self)
+	local name = self.modeName
+	PLUGIN:SetJobMode(name)
+end
+--[[
+##########################################################
+SIZING CALLBACK
+##########################################################
+]]--
+local function ResizeCraftingDock()
+	local DOCK_HEIGHT = PLUGIN.Docklet.Parent.Window:GetHeight();
+	SVUI_ModesDockToolBar:SetHeight(DOCK_HEIGHT);
+end
+
+SV.Events:On("DOCKS_UPDATED", ResizeCraftingDock, true);
+--[[
+##########################################################
+BUILD FUNCTION
+##########################################################
+]]--
+function PLUGIN:Load()
+	CONFIGS = SV.db[self.Schema];
+
+	lastClickTime = nil;
+	self.WornItems = {};
+	self.InModeGear = false;
+
+	self.Docklet = SV.Dock:NewDocklet("BottomRight", "SVUI_ModesDockFrame", self.TitleID, ICON_FILE);
+
+	local DOCK_HEIGHT = self.Docklet.Parent.Window:GetHeight();
+	local DOCKLET_HEIGHT = DOCK_HEIGHT - 4;
+	local BUTTON_SIZE = (DOCK_HEIGHT * 0.25) - 4;
+
+	local toolBar = CreateFrame("Frame", "SVUI_ModesDockToolBar", self.Docklet)
+	toolBar:SetWidth(BUTTON_SIZE + 4);
+	toolBar:SetHeight((BUTTON_SIZE + 4) * 4);
+	toolBar:SetPoint("BOTTOMLEFT", self.Docklet, "BOTTOMLEFT", 0, 0);
+
+	local tool4 = CreateFrame("Frame", nil, toolBar)
+	tool4:SetPoint("BOTTOM",toolBar,"BOTTOM",0,0)
+	tool4:SetSize(BUTTON_SIZE,BUTTON_SIZE)
+	tool4.icon = tool4:CreateTexture(nil, 'BACKGROUND')
+	tool4.icon:SetTexture(FARM_ICON)
+	tool4.icon:InsetPoints(tool4)
+	tool4.icon:SetGradient("VERTICAL", 0.5, 0.53, 0.55, 0.8, 0.8, 1)
+	tool4.modeName = "Farming"
+	tool4.currentColor = "icon"
+	tool4:SetScript('OnEnter', ModeButton_OnEnter)
+	tool4:SetScript('OnLeave', ModeButton_OnLeave)
+	tool4:SetScript('OnMouseDown', ModeButton_OnMouseDown)
+
+	local tool3 = CreateFrame("Frame", nil, toolBar)
+	tool3:SetPoint("BOTTOM",tool4,"TOP",0,2)
+	tool3:SetSize(BUTTON_SIZE,BUTTON_SIZE)
+	tool3.icon = tool3:CreateTexture(nil, 'BACKGROUND')
+	tool3.icon:SetTexture(ARCH_ICON)
+	tool3.icon:InsetPoints(tool3)
+	tool3.icon:SetGradient("VERTICAL", 0.5, 0.53, 0.55, 0.8, 0.8, 1)
+	tool3.modeName = "Archaeology"
+	tool3.currentColor = "icon"
+	tool3:SetScript('OnEnter', ModeButton_OnEnter)
+	tool3:SetScript('OnLeave', ModeButton_OnLeave)
+	tool3:SetScript('OnMouseDown', ModeButton_OnMouseDown)
+
+	local tool2 = CreateFrame("Frame", nil, toolBar)
+	tool2:SetPoint("BOTTOM",tool3,"TOP",0,2)
+	tool2:SetSize(BUTTON_SIZE,BUTTON_SIZE)
+	tool2.icon = tool2:CreateTexture(nil, 'BACKGROUND')
+	tool2.icon:SetTexture(FISH_ICON)
+	tool2.icon:InsetPoints(tool2)
+	tool2.icon:SetGradient("VERTICAL", 0.5, 0.53, 0.55, 0.8, 0.8, 1)
+	tool2.modeName = "Fishing"
+	tool2.currentColor = "icon"
+	tool2:SetScript('OnEnter', ModeButton_OnEnter)
+	tool2:SetScript('OnLeave', ModeButton_OnLeave)
+	tool2:SetScript('OnMouseDown', ModeButton_OnMouseDown)
+
+	local tool1 = CreateFrame("Frame", nil, toolBar)
+	tool1:SetPoint("BOTTOM",tool2,"TOP",0,2)
+	tool1:SetSize(BUTTON_SIZE,BUTTON_SIZE)
+	tool1.icon = tool1:CreateTexture(nil, 'BACKGROUND')
+	tool1.icon:SetTexture(COOK_ICON)
+	tool1.icon:InsetPoints(tool1)
+	tool1.icon:SetGradient("VERTICAL", 0.5, 0.53, 0.55, 0.8, 0.8, 1)
+	tool1.modeName = "Cooking"
+	tool1.currentColor = "icon"
+	tool1:SetScript('OnEnter', ModeButton_OnEnter)
+	tool1:SetScript('OnLeave', ModeButton_OnLeave)
+	tool1:SetScript('OnMouseDown', ModeButton_OnMouseDown)
+
+	local ModeAlert = CreateFrame("Frame", nil, SV.Screen)
+	ModeAlert:SetAllSecurePoints(self.Docklet.Parent.Alert)
+	ModeAlert:SetBackdrop(SV.media.backdrop.button)
+
+	ModeAlert:SetBackdropBorderColor(0,0,0,1)
+	ModeAlert:SetBackdropColor(0.25, 0.52, 0.1)
+	ModeAlert.text = ModeAlert:CreateFontString(nil, 'ARTWORK', 'GameFontWhite')
+	ModeAlert.text:SetAllPoints(ModeAlert)
+	ModeAlert.text:SetTextColor(1, 1, 1)
+	ModeAlert.text:SetJustifyH("CENTER")
+	ModeAlert.text:SetJustifyV("MIDDLE")
+	ModeAlert.text:SetText("Click to Exit")
+	ModeAlert.ModeText = "Click to Exit";
+	ModeAlert.HelpText = "";
+	ModeAlert:SetScript('OnEnter', ModeAlert_OnEnter)
+	ModeAlert:SetScript('OnLeave', ModeAlert_OnLeave)
+	ModeAlert:SetScript('OnHide', ModeAlert_OnHide)
+	ModeAlert:SetScript('OnShow', ModeAlert_OnShow)
+	ModeAlert:SetScript('OnMouseDown', ModeAlert_OnMouseDown)
+	ModeAlert:Hide()
+
+	ModeLogsFrame:SetFrameStrata("MEDIUM")
+	ModeLogsFrame:SetPoint("TOPLEFT", toolBar, "TOPRIGHT", 5, -5)
+	ModeLogsFrame:SetPoint("BOTTOMRIGHT", self.Docklet, "BOTTOMRIGHT", -5, 5)
+	ModeLogsFrame:SetParent(self.Docklet)
+
+	local title = CreateFrame("ScrollingMessageFrame", nil, ModeLogsFrame)
+	title:SetSpacing(4)
+	title:SetClampedToScreen(false)
+	title:SetFrameStrata("MEDIUM")
+	title:SetPoint("TOPLEFT",ModeLogsFrame,"TOPLEFT",0,0)
+	title:SetPoint("BOTTOMRIGHT",ModeLogsFrame,"TOPRIGHT",0,-20)
+	title:SetFontObject(SVUI_Font_Header)
+	title:SetMaxLines(1)
+	title:EnableMouseWheel(false)
+	title:SetFading(false)
+	title:SetInsertMode('TOP')
+
+	title.divider = title:CreateTexture(nil,"OVERLAY")
+  	title.divider:SetColorTexture(0,0,0,0.5)
+  	title.divider:SetPoint("BOTTOMLEFT")
+  	title.divider:SetPoint("BOTTOMRIGHT")
+  	title.divider:SetHeight(1)
+
+	local topleftline = title:CreateTexture(nil,"OVERLAY")
+	topleftline:SetColorTexture(0,0,0,0.5)
+	topleftline:SetPoint("TOPLEFT")
+	topleftline:SetPoint("BOTTOMLEFT")
+	topleftline:SetWidth(1)
+
+	local log = CreateFrame("ScrollingMessageFrame", nil, ModeLogsFrame)
+	log:SetSpacing(4)
+	log:SetClampedToScreen(false)
+	log:SetFrameStrata("MEDIUM")
+	log:SetPoint("TOPLEFT",title,"BOTTOMLEFT",0,0)
+	log:SetPoint("BOTTOMRIGHT",ModeLogsFrame,"BOTTOMRIGHT",0,0)
+	log:SetFontObject(SVUI_Font_Craft)
+	log:SetJustifyH("CENTER")
+	log:SetJustifyV("MIDDLE")
+	log:SetShadowColor(0, 0, 0, 0)
+	log:SetMaxLines(120)
+	log:EnableMouseWheel(true)
+	log:SetScript("OnMouseWheel", onMouseWheel)
+	log:SetFading(false)
+	log:SetInsertMode('TOP')
+
+	local bottomleftline = log:CreateTexture(nil,"OVERLAY")
+	bottomleftline:SetColorTexture(0,0,0,0.5)
+	bottomleftline:SetPoint("TOPLEFT")
+	bottomleftline:SetPoint("BOTTOMLEFT")
+	bottomleftline:SetWidth(1)
+
+	self.ToolBar = toolBar;
+	self.ToolBar.Buttons = {
+		["Cooking"] 	= tool1,
+		["Fishing"] 	= tool2,
+		["Archaeology"] = tool3,
+		["Farming"] 	= tool4
+	};
+
+  	self.ModeAlert = ModeAlert;
+	self.TitleWindow = title;
+	self.LogWindow = log;
+	--self.Docklet:Hide()
+	self.ListenerEnabled = false;
+	self:CraftingReset()
+	self:LoadCookingMode()
+	self:LoadFishingMode()
+	self:LoadArchaeologyMode()
+	self:PrepareFarmingTools()
+
+	self:RegisterEvent("SKILL_LINES_CHANGED")
+	SV.Events:On("DOCK_EXPANDED", ResizeCraftingDock, true);
+end
diff --git a/SVUI_CraftOMatic/SVUI_CraftOMatic.toc b/SVUI_CraftOMatic/SVUI_CraftOMatic.toc
new file mode 100644
index 0000000..7685a2a
--- /dev/null
+++ b/SVUI_CraftOMatic/SVUI_CraftOMatic.toc
@@ -0,0 +1,16 @@
+## Interface: 70000
+## Author: Failcoder
+## Version: 1.0.09
+## Title: |cffFF9900SVUI Plugin: |r|cffFF69B4Craft-O-Matic|r
+## Notes: Supervillain UI [|cff9911FFProfession Tools|r].
+## RequiredDeps: SVUI_!Core
+## OptionalDeps: LibSharedMedia-3.0
+## X-SVUIName: Craft-O-Matic
+## X-SVUISchema: CraftOMatic
+## X-Email: munglunch@gmail.com
+## X-Website: http://www.supervillainui.com
+## X-Donate: PayPal:munglunch@gmail.com
+## X-License: MIT
+## X-Category: Interface Enhancements
+
+SVUI_CraftOMatic.xml
diff --git a/SVUI_CraftOMatic/SVUI_CraftOMatic.xml b/SVUI_CraftOMatic/SVUI_CraftOMatic.xml
new file mode 100644
index 0000000..1a36d47
--- /dev/null
+++ b/SVUI_CraftOMatic/SVUI_CraftOMatic.xml
@@ -0,0 +1,28 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+	<Font name="SVUI_Font_Craft" font="Fonts\ARIALN.TTF" justifyH="LEFT" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="12"/>
+        </FontHeight>
+    </Font>
+    <Font name="SVUI_Font_CraftNumber" font="Fonts\skurri.ttf" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="12"/>
+        </FontHeight>
+    </Font>
+
+	<Script file='Loader.lua'/>
+    <Script file='SVUI_CraftOMatic.lua'/>
+    <Include file="components\_load.xml"/>
+</Ui>
\ No newline at end of file
diff --git a/SVUI_CraftOMatic/artwork/DOCK-LABORER.blp b/SVUI_CraftOMatic/artwork/DOCK-LABORER.blp
new file mode 100644
index 0000000..9397f22
Binary files /dev/null and b/SVUI_CraftOMatic/artwork/DOCK-LABORER.blp differ
diff --git a/SVUI_CraftOMatic/artwork/LABORER-COOKING.blp b/SVUI_CraftOMatic/artwork/LABORER-COOKING.blp
new file mode 100644
index 0000000..fe824f0
Binary files /dev/null and b/SVUI_CraftOMatic/artwork/LABORER-COOKING.blp differ
diff --git a/SVUI_CraftOMatic/artwork/LABORER-FARMING.blp b/SVUI_CraftOMatic/artwork/LABORER-FARMING.blp
new file mode 100644
index 0000000..7127055
Binary files /dev/null and b/SVUI_CraftOMatic/artwork/LABORER-FARMING.blp differ
diff --git a/SVUI_CraftOMatic/artwork/LABORER-FISHING.blp b/SVUI_CraftOMatic/artwork/LABORER-FISHING.blp
new file mode 100644
index 0000000..76474d1
Binary files /dev/null and b/SVUI_CraftOMatic/artwork/LABORER-FISHING.blp differ
diff --git a/SVUI_CraftOMatic/artwork/LABORER-SURVEY.blp b/SVUI_CraftOMatic/artwork/LABORER-SURVEY.blp
new file mode 100644
index 0000000..40f68ae
Binary files /dev/null and b/SVUI_CraftOMatic/artwork/LABORER-SURVEY.blp differ
diff --git a/SVUI_CraftOMatic/components/_load.xml b/SVUI_CraftOMatic/components/_load.xml
new file mode 100644
index 0000000..214eb80
--- /dev/null
+++ b/SVUI_CraftOMatic/components/_load.xml
@@ -0,0 +1,6 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+	<Script file="archaeology.lua"/>
+	<Script file="cooking.lua"/>
+	<Script file="fishing.lua"/>
+	<Script file="farming.lua"/>
+</Ui>
\ No newline at end of file
diff --git a/SVUI_CraftOMatic/components/archaeology.lua b/SVUI_CraftOMatic/components/archaeology.lua
new file mode 100644
index 0000000..05d5250
--- /dev/null
+++ b/SVUI_CraftOMatic/components/archaeology.lua
@@ -0,0 +1,540 @@
+--[[
+##########################################################
+S V U I   By: S.Jackson
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local type 		= _G.type;
+local string    = _G.string;
+local math 		= _G.math;
+local table 	= _G.table;
+local rept,format   = string.rep, string.format;
+local tsort,twipe 	= table.sort, table.wipe;
+local floor,ceil  	= math.floor, math.ceil;
+local min 			= math.min
+--BLIZZARD API
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+local GameTooltip           = _G.GameTooltip;
+local hooksecurefunc        = _G.hooksecurefunc;
+local IsSpellKnown      	= _G.IsSpellKnown;
+local GetSpellInfo      	= _G.GetSpellInfo;
+local GetProfessions      	= _G.GetProfessions;
+local GetProfessionInfo     = _G.GetProfessionInfo;
+local PlaySound             = _G.PlaySound;
+local PlaySoundFile         = _G.PlaySoundFile;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G.SVUI;
+local L = SV.L;
+local PLUGIN = select(2, ...);
+local CONFIGS = SV.defaults[PLUGIN.Schema];
+--[[
+##########################################################
+LOCAL VARS
+##########################################################
+]]--
+local playerRace = select(2,UnitRace("player"))
+local archSpell, survey, surveyIsKnown, skillRank, skillModifier;
+local EnableListener, DisableListener;
+local CanScanResearchSite = CanScanResearchSite
+local GetNumArtifactsByRace = GetNumArtifactsByRace
+local GetArchaeologyRaceInfo = GetArchaeologyRaceInfo
+local GetSelectedArtifactInfo = GetSelectedArtifactInfo
+local GetArtifactProgress = GetArtifactProgress
+local CanSolveArtifact = CanSolveArtifact
+local GetContainerNumSlots = GetContainerNumSlots
+local GetContainerItemInfo = GetContainerItemInfo
+local GetContainerItemID = GetContainerItemID
+local ModeLogsFrame;
+
+local ArchRaces = 0
+local COUNT_TEX = [[Interface\AddOns\SVUI_!Core\assets\textures\Numbers\TYPE2\NUM]]
+local refArtifacts = {};
+local ArchCrafting = CreateFrame("Frame", "SVUI_ArchCrafting", UIParent)
+local KEYSTONE_FORMAT = {"|cff00f12a%d|r/%d", "|cff00f12a%d|r|cff00a1fa/%d|r"};
+local NORMAL_FORMAT = {"%d/%d", "|cff00a1fa%d/%d|r"};
+--[[
+##########################################################
+DATA
+##########################################################
+]]--
+PLUGIN.Archaeology = {};
+PLUGIN.Archaeology.Bars = {};
+PLUGIN.Archaeology.Loaded = false;
+--[[
+##########################################################
+LOCAL FUNCTIONS
+##########################################################
+]]--
+local function EnableSolve(index, button)
+	button:SetAlpha(1)
+	button.text:SetTextColor(1, 1, 1)
+	button:SetScript("OnClick", function(self)
+		SetSelectedArtifact(index)
+		local _, _, _, _, _, numSockets = GetActiveArtifactByRace(index)
+		local _, _, itemID = GetArchaeologyRaceInfo(index)
+		local ready = true
+		if numSockets and numSockets > 0 then
+			for socketNum = 1, numSockets do
+				if not ItemAddedToArtifact(itemID) then
+					SocketItemToArtifact()
+				end
+			end
+		end
+
+		if GetNumArtifactsByRace(index) > 0 then
+			print("Solving...")
+			SolveArtifact()
+		end
+	end)
+end
+
+local function DisableSolve(button)
+	button:SetAlpha(0)
+	button.text:SetTextColor(0.5, 0.5, 0.5)
+	button.text:SetText("")
+	button:SetScript("OnClick", SV.fubar)
+end
+
+local function UpdateArtifactBars(index)
+	local cache = refArtifacts[index]
+	local bar = PLUGIN.Archaeology.Bars[index]
+
+	bar["race"]:SetText(cache["race"])
+
+	if GetNumArtifactsByRace(index) ~= 0 then
+		local keystoneBonus = 0
+		bar["race"]:SetTextColor(1, 0.8, 0)
+		bar["progress"]:SetTextColor(1, 1, 1)
+		if cache["numKeysockets"] then
+			keystoneBonus = min(cache["numKeystones"], cache["numKeysockets"]) * ArchRaces
+		end
+		local actual = min(cache["progress"], cache["total"])
+		local potential = cache["total"]
+		local green = 0.75 * (actual / potential);
+		bar["bar"]:SetMinMaxValues(0, potential)
+		bar["bar"]:SetValue(actual)
+
+		local solveText = SOLVE
+		if (cache["numKeystones"] and cache["numKeystones"] > 0) then
+			if (cache["numKeysockets"] and cache["numKeysockets"] > 0) then
+				solveText = SOLVE.." ["..cache["numKeystones"] .. "/" .. cache["numKeysockets"].."]"
+			end
+		end
+		bar["solve"].text:SetText(solveText)
+
+
+		local FORMAT = NORMAL_FORMAT
+		if keystoneBonus > 0 then
+			FORMAT = KEYSTONE_FORMAT
+		end
+
+		if cache["total"] > 65 then
+			bar["progress"]:SetText(format(FORMAT[2], cache["progress"], cache["total"]))
+		else
+			bar["progress"]:SetText(format(FORMAT[1], cache["progress"], cache["total"]))
+		end
+
+		if cache["canSolve"] then
+			EnableSolve(index, bar["solve"])
+		else
+			DisableSolve(bar["solve"])
+		end
+		bar["bar"]:SetStatusBarColor(0.1, green, 1, 0.5)
+	else
+		DisableSolve(bar["solve"])
+		bar["progress"]:SetText("")
+		bar["bar"]:SetStatusBarColor(0, 0, 0, 0)
+		bar["race"]:SetTextColor(0.25, 0.25, 0.25)
+		bar["progress"]:SetTextColor(0.25, 0.25, 0.25)
+	end
+end
+
+local function UpdateArtifactCache()
+	local found, raceName, raceItemID, cache, _;
+	for index = 1, ArchRaces do
+		found = GetNumArtifactsByRace(index)
+		raceName, _, raceItemID = GetArchaeologyRaceInfo(index)
+		cache = refArtifacts[index]
+		cache["race"] = raceName
+		cache["keyID"] = raceItemID
+		cache["numKeystones"] = 0
+		local oldNum = cache["progress"]
+		if found == 0 then
+			cache["numKeysockets"] = 0
+			cache["progress"] = 0
+			cache["modifier"] = 0
+			cache["total"] = 0
+			cache["canSolve"] = false
+		else
+			SetSelectedArtifact(index)
+			local _, _, _, _, _, keystoneCount = GetSelectedArtifactInfo()
+			local numFragmentsCollected, numFragmentsAdded, numFragmentsRequired = GetArtifactProgress()
+
+			cache["numKeysockets"] = keystoneCount
+			cache["progress"] = numFragmentsCollected
+			cache["modifier"] = numFragmentsAdded
+			cache["total"] = numFragmentsRequired
+			cache["canSolve"] = CanSolveArtifact()
+
+			for i = 0, 4 do
+				for j = 1, GetContainerNumSlots(i) do
+					local slotID = GetContainerItemID(i, j)
+					if slotID == cache["keyID"] then
+						local _, count = GetContainerItemInfo(i, j)
+						if cache["numKeystones"] < cache["numKeysockets"] then
+							cache["numKeystones"] = cache["numKeystones"] + count
+						end
+						if min(cache["numKeystones"], cache["numKeysockets"]) * ArchRaces + cache["progress"] >= cache["total"] then
+							cache["canSolve"] = true
+						end
+					end
+				end
+			end
+		end
+		UpdateArtifactBars(index)
+	end
+end
+
+local function GetTitleAndSkill()
+	local msg = "|cff22ff11Archaeology Mode|r"
+	if(skillRank) then
+		if(skillModifier) then
+			skillRank = skillRank + skillModifier;
+		end
+		msg = msg .. " (|cff00ddff" .. skillRank .. "|r)";
+	end
+	return msg
+end
+--[[
+##########################################################
+EVENT HANDLER
+##########################################################
+]]--
+do
+	local SURVEYCOLOR = {
+		{0.1, 1, 0.1, 1},
+		{1, 0.5, 0.1, 1},
+		{1, 0.1, 0, 1}
+	}
+	local last = 0
+	local time = 3
+
+	local ArchEventHandler = CreateFrame("Frame");
+	local SurveyCooldown = CreateFrame("Frame", nil, UIParent);
+	local ArchSiteFound;
+	local ArchCanSurvey, ArchWillSurvey = false, false;
+
+	SurveyCooldown:SetPoint("CENTER", UIParent, "CENTER", 0, -50)
+	SurveyCooldown:SetSize(50, 50)
+	SurveyCooldown.text = SurveyCooldown:CreateTexture(nil, "OVERLAY")
+	SurveyCooldown.text:SetAllPoints(SurveyCooldown)
+	SurveyCooldown.text:SetVertexColor(0,1,0.12,0.5)
+	SurveyCooldown:SetScale(1)
+	SV.Animate:Kapow(SurveyCooldown)
+
+	local Arch_OnEvent = function(self, event, ...)
+		if(InCombatLockdown() or not archSpell) then return end
+		local NEEDS_UPDATE = false;
+		if(event == "CURRENCY_DISPLAY_UPDATE" or event == "CHAT_MSG_SKILL" or event == "ARTIFACT_COMPLETE") then
+			local msg = GetTitleAndSkill()
+			PLUGIN.TitleWindow:Clear()
+			PLUGIN.TitleWindow:AddMessage(msg)
+			if(event ~= "CHAT_MSG_SKILL") then
+				NEEDS_UPDATE = true
+			end
+		end
+		if(CanScanResearchSite() and (event == "CURRENCY_DISPLAY_UPDATE")) then
+			NEEDS_UPDATE = true
+		elseif(event == "ARCHAEOLOGY_SURVEY_CAST" or event == "ARTIFACT_COMPLETE" or event == "ARTIFACT_DIG_SITE_UPDATED") then
+			NEEDS_UPDATE = true
+		elseif(event == "ARTIFACT_HISTORY_READY" or event == "ARTIFACT_DIGSITE_COMPLETE") then
+			NEEDS_UPDATE = true
+		else
+			ArchCanSurvey = CanScanResearchSite()
+			if(ArchCanSurvey and not ArchWillSurvey) then
+				_G["SVUI_ModeCaptureWindow"]:SetAttribute("type", "spell")
+				_G["SVUI_ModeCaptureWindow"]:SetAttribute('spell', survey)
+				PLUGIN.ModeAlert.HelpText = "Double-Right-Click anywhere on the screen to survey.";
+				ArchWillSurvey = true
+			elseif(not ArchCanSurvey and ArchWillSurvey) then
+				_G["SVUI_ModeCaptureWindow"]:SetAttribute("type", "spell")
+				_G["SVUI_ModeCaptureWindow"]:SetAttribute('spell', archSpell)
+				PLUGIN.ModeAlert.HelpText = "Double-Right-Click anywhere on the screen to open the artifacts window.";
+				ArchWillSurvey = false
+			end
+			if(event == "ZONE_CHANGED_NEW_AREA") then ArchSiteFound = nil end
+			if(not ArchSiteFound) then
+				local sites = ArchaeologyMapUpdateAll();
+				if(sites and sites > 0) then
+					ArchSiteFound = true
+					SV:SCTMessage("Digsite Located", 0.91, 0.78, 0.12);
+				else
+					ArchSiteFound = nil
+				end
+			end
+		end
+
+		if(NEEDS_UPDATE) then
+			UpdateArtifactCache()
+		end
+	end
+
+	local Survey_OnUpdate = function(self, elapsed)
+		last = last + elapsed
+		if last >= 1 then
+			time = time - 1
+			if time > 0 then
+				self.text:SetTexture(COUNT_TEX .. time)
+				self.text:SetVertexColor(unpack(SURVEYCOLOR[time]))
+				if not self.anim:IsPlaying() then
+			        self.anim:Play()
+			    end
+			else
+				time = 3
+				self:SetScript("OnUpdate", nil)
+			end
+			last = 0
+		end
+	end
+
+	local Survey_OnEvent = function(self, event, unit, _, _, _, spellid)
+		if not unit == "player" then return end
+		if spellid == 80451 then
+			time = 3
+			self.text:SetTexture(COUNT_TEX .. 3)
+			self.text:SetVertexColor(1,0,0,1)
+			self:SetScript("OnUpdate", Survey_OnUpdate)
+			if not self.anim:IsPlaying() then
+		        self.anim:Play()
+		    end
+		end
+	end
+
+	function EnableListener()
+		UpdateArtifactCache()
+
+		ArchEventHandler:RegisterEvent("ZONE_CHANGED")
+		ArchEventHandler:RegisterEvent("ZONE_CHANGED_NEW_AREA")
+		ArchEventHandler:RegisterEvent("ZONE_CHANGED_INDOORS")
+
+		ArchEventHandler:RegisterEvent("ARTIFACT_DIG_SITE_UPDATED")
+		ArchEventHandler:RegisterEvent("ARTIFACT_DIGSITE_COMPLETE")
+		ArchEventHandler:RegisterEvent("ARTIFACT_HISTORY_READY")
+		ArchEventHandler:RegisterEvent("ARTIFACT_COMPLETE")
+
+		ArchEventHandler:RegisterEvent("CURRENCY_DISPLAY_UPDATE")
+		ArchEventHandler:RegisterEvent("ARCHAEOLOGY_SURVEY_CAST")
+
+		ArchEventHandler:RegisterEvent("CHAT_MSG_SKILL")
+
+		ArchEventHandler:SetScript("OnEvent", Arch_OnEvent)
+		if(playerRace ~= "Dwarf") then
+			SurveyCooldown:RegisterEvent("UNIT_SPELLCAST_STOP")
+			SurveyCooldown:SetScript("OnEvent", Survey_OnEvent)
+		end
+	end
+
+	function DisableListener()
+		ArchEventHandler:UnregisterAllEvents()
+		ArchEventHandler:SetScript("OnEvent", nil)
+		if(playerRace ~= "Dwarf") then
+			SurveyCooldown:UnregisterAllEvents()
+			SurveyCooldown:SetScript("OnEvent", nil)
+		end
+	end
+end
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+function PLUGIN.Archaeology:Enable()
+	PLUGIN.Archaeology:Update()
+	if(not PLUGIN.Docklet:IsShown()) then PLUGIN.Docklet.Button:Click() end
+
+	PlaySoundFile("Sound\\Item\\UseSounds\\UseCrinklingPaper.wav")
+	PLUGIN.ModeAlert:SetBackdropColor(0.25, 0.52, 0.1)
+	ArchCrafting:Show()
+	local canArch = IsSpellKnown(80451)
+	if(canArch) then
+		ArchCrafting:FadeIn()
+		local msg = GetTitleAndSkill()
+		if surveyIsKnown and CanScanResearchSite() then
+			PLUGIN:ModeLootLoader("Archaeology", msg, "Double-Right-Click anywhere on the screen to survey.");
+			_G["SVUI_ModeCaptureWindow"]:SetAttribute("type", "spell")
+			_G["SVUI_ModeCaptureWindow"]:SetAttribute('spell', survey)
+		else
+			PLUGIN:ModeLootLoader("Archaeology", msg, "Double-Right-Click anywhere on the screen to open the artifacts window.");
+			_G["SVUI_ModeCaptureWindow"]:SetAttribute("type", "spell")
+			_G["SVUI_ModeCaptureWindow"]:SetAttribute('spell', archSpell)
+		end
+		PLUGIN.TitleWindow:Clear();
+		PLUGIN.TitleWindow:AddMessage(msg);
+	else
+		ArchCrafting:FadeOut(0.1,1,0,true)
+		PLUGIN:ModeLootLoader("Archaeology", "WTF is Archaeology?", "You don't know archaeology! \nPicking up a rock and telling everyone that \nyou found a fossil is cute, BUT WRONG!! \nGo find someone who can train you to do this job.");
+		PLUGIN.TitleWindow:Clear();
+		PLUGIN.TitleWindow:AddMessage("WTF is Archaeology?");
+		PLUGIN.LogWindow:Clear();
+		PLUGIN.LogWindow:AddMessage("You don't know archaeology! \nPicking up a rock and telling everyone that \nyou found a fossil is cute, BUT WRONG!! \nGo find someone who can train you to do this job.", 1, 1, 1);
+		PLUGIN.LogWindow:AddMessage(" ", 1, 1, 1);
+	end
+	EnableListener()
+	PLUGIN.ModeAlert:Show()
+	SV:SCTMessage("Archaeology Mode Enabled", 0.28, 0.9, 0.1);
+end
+
+function PLUGIN.Archaeology:Disable()
+	DisableListener()
+	ArchCrafting:FadeOut(0.1,1,0,true)
+end
+
+function PLUGIN.Archaeology:Bind()
+	if InCombatLockdown() then return end
+	if(archSpell) then
+		if surveyIsKnown and CanScanResearchSite() then
+			_G["SVUI_ModeCaptureWindow"]:SetAttribute("type", "spell")
+			_G["SVUI_ModeCaptureWindow"]:SetAttribute('spell', survey)
+			PLUGIN.ModeAlert.HelpText = 'Double-Right-Click anywhere on the screen to survey.'
+		else
+			_G["SVUI_ModeCaptureWindow"]:SetAttribute("type", "spell")
+			_G["SVUI_ModeCaptureWindow"]:SetAttribute('spell', archSpell)
+			PLUGIN.ModeAlert.HelpText = 'Double-Right-Click anywhere on the screen to open the artifacts window.'
+		end
+		SetOverrideBindingClick(_G["SVUI_ModeCaptureWindow"], true, "BUTTON2", "SVUI_ModeCaptureWindow");
+		_G["SVUI_ModeCaptureWindow"].Handler:Show();
+	end
+end
+
+function PLUGIN.Archaeology:Update()
+	surveyIsKnown = IsSpellKnown(80451);
+	survey = GetSpellInfo(80451);
+	local _,_,arch,_,_,_ = GetProfessions();
+	if(arch) then
+		archSpell, _, skillRank, _, _, _, _, skillModifier = GetProfessionInfo(arch)
+	end
+end
+--[[
+##########################################################
+LOADER
+##########################################################
+]]--
+function PLUGIN:LoadArchaeologyMode()
+	ArchRaces = GetNumArchaeologyRaces()
+	for i = 1, ArchRaces do
+		refArtifacts[i] = {}
+	end
+	CONFIGS = SV.db[self.Schema];
+	ModeLogsFrame = self.LogWindow;
+
+	local progressBars = self.Archaeology.Bars
+
+	ArchCrafting:SetParent(ModeLogsFrame)
+	ArchCrafting:SetFrameStrata("MEDIUM")
+	ArchCrafting:InsetPoints(ModeLogsFrame)
+
+	local BAR_WIDTH = (ArchCrafting:GetWidth() * 0.33) - 4
+	local BAR_HEIGHT = (ArchCrafting:GetHeight() / 5) - 4
+
+	for i = 1, ArchRaces do
+		local bar = CreateFrame("StatusBar", nil, ArchCrafting)
+		local solve = CreateFrame("Button", nil, bar, "SecureHandlerClickTemplate")
+		local yOffset,xOffset = 0,0;
+
+		bar:SetStyle("Frame", "Bar")
+		bar:SetStatusBarTexture([[Interface\AddOns\SVUI\assets\artwork\Template\DEFAULT]])
+		bar:SetSize(BAR_WIDTH,BAR_HEIGHT)
+		if(i > 10) then
+			xOffset = (BAR_WIDTH * 2) + 6
+			yOffset = ((i - 11) * (BAR_HEIGHT + 4)) + 4
+		elseif(i > 5) then
+			xOffset = BAR_WIDTH + 4
+			yOffset = ((i - 6) * (BAR_HEIGHT + 4)) + 4
+		else
+			xOffset = 2
+			yOffset = ((i - 1) * (BAR_HEIGHT + 4)) + 4;
+		end
+		bar:SetPoint("TOPLEFT", ArchCrafting, "TOPLEFT", xOffset, -yOffset)
+		bar:SetStatusBarColor(0.2, 0.2, 0.8, 0.5)
+
+		-- Race Text
+		local race = bar:CreateFontString()
+		race:SetFontObject(SVUI_Font_CraftNumber)
+		race:SetText(RACE)
+		race:SetPoint("TOPLEFT", bar, "TOPLEFT", 2, -4)
+		race:SetTextColor(1,0.8,0)
+
+		-- Progress Text
+		local progress = bar:CreateFontString()
+		progress:SetFontObject(SVUI_Font_CraftNumber)
+		progress:SetText("")
+		progress:SetPoint("BOTTOMRIGHT", bar, "BOTTOMRIGHT", -1, 1)
+
+		-- Solve
+		solve:SetAllPoints(bar)
+
+		solve.bg = solve:CreateTexture(nil,"BORDER")
+		solve.bg:SetAllPoints(solve)
+		solve.bg:SetTexture(SV.media.statusbar.default)
+		solve.bg:SetVertexColor(0.1,0.5,0)
+
+		solve.text = solve:CreateFontString(nil,"OVERLAY")
+		solve.text:SetFontObject(SVUI_Font_Craft)
+		solve.text:SetShadowOffset(-1,-1)
+		solve.text:SetShadowColor(0,0,0,0.5)
+		solve.text:SetText(SOLVE)
+		solve.text:SetPoint("CENTER", solve, "CENTER", 2, 0)
+		solve.RaceIndex = i
+		solve.border = bar
+		solve:SetScript("OnEnter", function(self)
+			GameTooltip:SetOwner(self, "ANCHOR_BOTTOMRIGHT", 2, 250)
+			GameTooltip:ClearLines()
+			if GetNumArtifactsByRace(self.RaceIndex) > 0 then
+				self.text:SetTextColor(1, 1, 0)
+				self.border:SetBackdropBorderColor(0,0.8,1)
+				SetSelectedArtifact(self.RaceIndex)
+				local artifactName, artifactDescription, artifactRarity, _, _, keystoneCount = GetSelectedArtifactInfo()
+				local numFragmentsCollected, numFragmentsAdded, numFragmentsRequired = GetArtifactProgress()
+				local r, g, b
+				if artifactRarity == 1 then
+					artifactRarity = ITEM_QUALITY3_DESC
+					r, g, b = GetItemQualityColor(3)
+				else
+					artifactRarity = ITEM_QUALITY1_DESC
+					r, g, b = GetItemQualityColor(1)
+				end
+				GameTooltip:AddLine(artifactName, r, g, b, 1)
+				GameTooltip:AddLine(artifactRarity, r, g, b, r, g, b)
+				GameTooltip:AddDoubleLine(ARCHAEOLOGY_RUNE_STONES..": "..numFragmentsCollected.."/"..numFragmentsRequired, "Keystones: "..keystoneCount, 1, 1, 1, 1, 1, 1)
+				GameTooltip:AddLine(" ")
+				GameTooltip:AddLine(artifactDescription, 1, 1, 1, 1)
+				GameTooltip:Show()
+			end
+		end)
+		solve:SetScript("OnLeave", function(self)
+			self.text:SetTextColor(0.7, 0.7, 0.7)
+			self.border:SetBackdropBorderColor(0,0,0)
+			GameTooltip:Hide()
+		end)
+
+		progressBars[i] = {
+			["bar"] = bar,
+			["race"] = race,
+			["progress"] = progress,
+			["solve"] = solve
+		}
+	end
+	ArchCrafting:FadeOut(0.1,1,0,true)
+	self.Archaeology:Update()
+	UpdateArtifactCache()
+end
diff --git a/SVUI_CraftOMatic/components/cooking.lua b/SVUI_CraftOMatic/components/cooking.lua
new file mode 100644
index 0000000..c869f0d
--- /dev/null
+++ b/SVUI_CraftOMatic/components/cooking.lua
@@ -0,0 +1,262 @@
+--[[
+##########################################################
+S V U I   By: S.Jackson
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local type 		= _G.type;
+local string    = _G.string;
+local math 		= _G.math;
+local table 	= _G.table;
+local rept      = string.rep;
+local tsort,twipe = table.sort,table.wipe;
+local floor,ceil  = math.floor, math.ceil;
+local band 		= _G.bit.band;
+--BLIZZARD API
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+local GameTooltip           = _G.GameTooltip;
+local hooksecurefunc        = _G.hooksecurefunc;
+local IsSpellKnown      	= _G.IsSpellKnown;
+local GetSpellInfo      	= _G.GetSpellInfo;
+local GetProfessions      	= _G.GetProfessions;
+local GetProfessionInfo     = _G.GetProfessionInfo;
+local PlaySound             = _G.PlaySound;
+local PlaySoundFile         = _G.PlaySoundFile;
+local C_PetJournal          = _G.C_PetJournal;
+local GetItemInfo           = _G.GetItemInfo;
+local GetItemCount          = _G.GetItemCount;
+local GetItemQualityColor   = _G.GetItemQualityColor;
+local GetItemFamily         = _G.GetItemFamily;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G.SVUI;
+local L = SV.L;
+local PLUGIN = select(2, ...);
+local CONFIGS = SV.defaults[PLUGIN.Schema];
+--[[
+##########################################################
+LOCAL VARS
+##########################################################
+]]--
+local cookingSpell, campFire, skillRank, skillModifier, usePierre;
+--[[
+##########################################################
+LOCAL FUNCTIONS
+##########################################################
+]]--
+local function UpdateChefWear()
+	if(GetItemCount(46349) > 0) then
+		PLUGIN.WornItems["HEAD"] = GetInventoryItemID("player", INVSLOT_HEAD);
+		EquipItemByName(46349)
+		PLUGIN.InModeGear = true
+	end
+	if(GetItemCount(86468) > 0) then
+		PLUGIN.WornItems["TAB"] = GetInventoryItemID("player", INVSLOT_TABARD);
+		EquipItemByName(86468)
+		PLUGIN.InModeGear = true
+	end
+	if(GetItemCount(86559) > 0) then
+		PLUGIN.WornItems["MAIN"] = GetInventoryItemID("player", INVSLOT_MAINHAND);
+		EquipItemByName(86559)
+		PLUGIN.InModeGear = true
+	end
+	if(GetItemCount(86558) > 0) then
+		PLUGIN.WornItems["OFF"] = GetInventoryItemID("player", INVSLOT_OFFHAND);
+		EquipItemByName(86558)
+		PLUGIN.InModeGear = true
+	end
+end
+
+local function GetTitleAndSkill()
+	local msg = "|cff22ff11Cooking Mode|r"
+	if(skillRank) then
+		if(skillModifier) then
+			skillRank = skillRank + skillModifier;
+		end
+		msg = msg .. " (|cff00ddff" .. skillRank .. "|r)";
+	end
+	return msg
+end
+
+local function FindPierre()
+	local summonedPetGUID = C_PetJournal.GetSummonedPetGUID()
+	if usePierre then
+		if((not summonedPetGUID) or (summonedPetGUID and (summonedPetGUID ~= usePierre))) then
+			C_PetJournal.SummonPetByGUID(usePierre)
+		end
+	else
+		local numPets, numOwned = C_PetJournal.GetNumPets()
+		for index = 1, numOwned, 1 do
+			local petID, _, _, _, _, _, _, _, _, _, companionID = C_PetJournal.GetPetInfoByIndex(index)
+			if(companionID == 70082) then
+				usePierre = petID
+				if((not summonedPetGUID) or (summonedPetGUID and (summonedPetGUID ~= usePierre))) then
+					C_PetJournal.SummonPetByGUID(usePierre)
+				end
+				break
+			end
+		end
+	end
+end
+--[[
+##########################################################
+CORE NAMESPACE
+##########################################################
+]]--
+PLUGIN.Cooking = {};
+PLUGIN.Cooking.Log = {};
+PLUGIN.Cooking.Loaded = false;
+--[[
+##########################################################
+EVENT HANDLER
+##########################################################
+]]--
+local EnableListener, DisableListener
+do
+	local proxyTest = false;
+	local CookEventHandler = CreateFrame("Frame")
+	local LootProxy = function(item, name)
+		if(item) then
+			local mask = [[0x10000]];
+			local itemType = GetItemFamily(item);
+			local pass = band(itemType, mask);
+			if pass > 0 then
+				proxyTest = true;
+			end
+		end
+	end
+
+	local Cook_OnEvent = function(self, event, ...)
+		if(InCombatLockdown()) then return end
+		if(event == "BAG_UPDATE" or event == "CHAT_MSG_SKILL") then
+			local msg = GetTitleAndSkill()
+			PLUGIN.TitleWindow:Clear()
+			PLUGIN.TitleWindow:AddMessage(msg)
+		elseif(event == "CHAT_MSG_LOOT") then
+			local item, amt = PLUGIN:CheckForModeLoot(...);
+			if item then
+				local name, lnk, rarity, lvl, mlvl, itype, stype, cnt, ieq, tex, price = GetItemInfo(item);
+				if proxyTest == false then
+					LootProxy(lnk, name)
+				end
+				if proxyTest == false then return end
+				if not PLUGIN.Cooking.Log[name] then
+					PLUGIN.Cooking.Log[name] = {amount = 0, texture = ""};
+				end
+				local r, g, b, hex = GetItemQualityColor(rarity);
+				local stored = PLUGIN.Cooking.Log
+				local mod = stored[name];
+				local newAmt = mod.amount + 1;
+				if amt >= 2 then newAmt = mod.amount + amt end
+				PLUGIN.Cooking.Log[name].amount = newAmt;
+				PLUGIN.Cooking.Log[name].texture = tex;
+				PLUGIN.LogWindow:Clear();
+				for name,data in pairs(stored) do
+					if type(data) == "table" and data.amount and data.texture then
+						PLUGIN.LogWindow:AddMessage("|cff55FF55"..data.amount.." x|r |T".. data.texture ..":16:16:0:0:64:64:4:60:4:60|t".." "..name, r, g, b);
+					end
+				end
+				PLUGIN.LogWindow:AddMessage("----------------", 0, 0, 0);
+				PLUGIN.LogWindow:AddMessage("Cooked So Far...", 0, 1, 1);
+				PLUGIN.LogWindow:AddMessage(" ", 0, 0, 0);
+				proxyTest = false;
+			end
+		end
+	end
+
+	function EnableListener()
+		CookEventHandler:RegisterEvent("ZONE_CHANGED")
+		CookEventHandler:RegisterEvent("BAG_UPDATE")
+		CookEventHandler:RegisterEvent("CHAT_MSG_SKILL")
+		CookEventHandler:SetScript("OnEvent", Cook_OnEvent)
+	end
+
+	function DisableListener()
+		CookEventHandler:UnregisterAllEvents()
+		CookEventHandler:SetScript("OnEvent", nil)
+	end
+end
+--[[
+##########################################################
+CORE METHODS
+##########################################################
+]]--
+function PLUGIN.Cooking:Enable()
+	PLUGIN.Cooking:Update()
+	if(not PLUGIN.Docklet:IsShown()) then PLUGIN.Docklet.Button:Click() end
+	if(CONFIGS.cooking.autoequip) then
+		UpdateChefWear();
+	end
+	PlaySoundFile("Sound\\Spells\\Tradeskills\\CookingPrepareA.wav")
+	PLUGIN.ModeAlert:SetBackdropColor(0.25, 0.52, 0.1)
+
+	FindPierre()
+
+	if(not IsSpellKnown(818)) then
+		PLUGIN:ModeLootLoader("Cooking", "WTF is Cooking?", "You have no clue how to cook! \nEven toast is a mystery to you. \nGo find a trainer and learn \nhow to do this simple job.");
+		PLUGIN.TitleWindow:Clear();
+		PLUGIN.TitleWindow:AddMessage("WTF is Cooking?");
+		PLUGIN.LogWindow:Clear();
+		PLUGIN.LogWindow:AddMessage("You have no clue how to cook! \nEven toast is a mystery to you. \nGo find a trainer and learn \nhow to do this simple job.", 1, 1, 1);
+		PLUGIN.LogWindow:AddMessage(" ", 1, 1, 1);
+	else
+		local msg = GetTitleAndSkill();
+		--70082
+		if(usePierre or (cookingSpell and (GetSpellCooldown(campFire) > 0))) then
+			PLUGIN:ModeLootLoader("Cooking", msg, "Double-Right-Click anywhere on the screen \nto open your cookbook.");
+			_G["SVUI_ModeCaptureWindow"]:SetAttribute("type", "spell")
+			_G["SVUI_ModeCaptureWindow"]:SetAttribute('spell', cookingSpell)
+		else
+			PLUGIN:ModeLootLoader("Cooking", msg, "Double-Right-Click anywhere on the screen \nto start a cooking fire.");
+			_G["SVUI_ModeCaptureWindow"]:SetAttribute("type", "spell")
+			_G["SVUI_ModeCaptureWindow"]:SetAttribute('spell', campFire)
+		end
+	end
+	EnableListener()
+	PLUGIN.ModeAlert:Show()
+	SV:SCTMessage("Cooking Mode Enabled", 0.28, 0.9, 0.1);
+end
+
+function PLUGIN.Cooking:Disable()
+	DisableListener()
+end
+
+function PLUGIN.Cooking:Bind()
+	if InCombatLockdown() then return end
+	if cookingSpell then
+		if cookingSpell and GetSpellCooldown(campFire) > 0 then
+			_G["SVUI_ModeCaptureWindow"]:SetAttribute("type", "spell")
+			_G["SVUI_ModeCaptureWindow"]:SetAttribute('spell', cookingSpell)
+			PLUGIN.ModeAlert.HelpText = 'Double-Right-Click to open the cooking window.'
+		end
+		SetOverrideBindingClick(_G["SVUI_ModeCaptureWindow"], true, "BUTTON2", "SVUI_ModeCaptureWindow");
+		_G["SVUI_ModeCaptureWindow"].Handler:Show();
+	end
+end
+
+function PLUGIN.Cooking:Update()
+	campFire = GetSpellInfo(818);
+	local _,_,_,_,cook,_ = GetProfessions();
+	if cook ~= nil then
+		cookingSpell, _, skillRank, _, _, _, _, skillModifier = GetProfessionInfo(cook)
+	end
+end
+--[[
+##########################################################
+LOADER
+##########################################################
+]]--
+function PLUGIN:LoadCookingMode()
+	CONFIGS = SV.db[self.Schema];
+	usePierre = FindPierre()
+	self.Cooking:Update()
+end
diff --git a/SVUI_CraftOMatic/components/farming.lua b/SVUI_CraftOMatic/components/farming.lua
new file mode 100644
index 0000000..5b689b9
--- /dev/null
+++ b/SVUI_CraftOMatic/components/farming.lua
@@ -0,0 +1,646 @@
+--[[
+##########################################################
+S V U I   By: S.Jackson
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pcall         = _G.pcall;
+local print         = _G.print;
+local ipairs        = _G.ipairs;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local rawset        = _G.rawset;
+local rawget        = _G.rawget;
+local tostring      = _G.tostring;
+local tonumber      = _G.tonumber;
+local getmetatable  = _G.getmetatable;
+local setmetatable  = _G.setmetatable;
+--STRING
+local string        = _G.string;
+local upper         = string.upper;
+local format        = string.format;
+local find          = string.find;
+local match         = string.match;
+local gsub          = string.gsub;
+
+local math 		= _G.math;
+local table 	= _G.table;
+local rept      = string.rep;
+local tsort,twipe = table.sort,table.wipe;
+local floor,ceil  = math.floor, math.ceil;
+--BLIZZARD API
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+local GameTooltip           = _G.GameTooltip;
+local hooksecurefunc        = _G.hooksecurefunc;
+local IsSpellKnown      	= _G.IsSpellKnown;
+local GetSpellInfo      	= _G.GetSpellInfo;
+local GetProfessions      	= _G.GetProfessions;
+local GetProfessionInfo     = _G.GetProfessionInfo;
+local PlaySound             = _G.PlaySound;
+local PlaySoundFile         = _G.PlaySoundFile;
+local C_PetJournal          = _G.C_PetJournal;
+local GetItemInfo           = _G.GetItemInfo;
+local GetItemCount          = _G.GetItemCount;
+local GetItemQualityColor   = _G.GetItemQualityColor;
+local GetItemFamily         = _G.GetItemFamily;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G.SVUI;
+local L = SV.L;
+local PLUGIN = select(2, ...);
+local CONFIGS = SV.defaults[PLUGIN.Schema];
+--[[
+##########################################################
+LOCAL VARS
+##########################################################
+]]--
+local NUM_SEED_BARS = 7
+local EnableListener, DisableListener, InventoryUpdate, LoadFarmingModeTools;
+local seedButtons,farmToolButtons,portalButtons = {},{},{};
+local DockButton, ModeLogsFrame;
+local refSeeds = {[79102]={1},[89328]={1},[80590]={1},[80592]={1},[80594]={1},[80593]={1},[80591]={1},[89329]={1},[80595]={1},[89326]={1},[80809]={3},[95434]={4},[89848]={3},[95437]={4},[84782]={3},[95436]={4},[85153]={3},[95438]={4},[85162]={3},[95439]={4},[85158]={3},[95440]={4},[84783]={3},[95441]={4},[89849]={3},[95442]={4},[85163]={3},[95443]={4},[89847]={3},[95444]={4},[85216]={2},[85217]={2},[89202]={2},[85215]={2},[89233]={2},[89197]={2},[85219]={2},[91806]={2},[95449]={5},[95450]={6},[95451]={5},[95452]={6},[95457]={5},[95458]={6},[95447]={5},[95448]={6},[95445]={5},[95446]={6},[95454]={5},[95456]={6},[85267]={7},[85268]={7},[85269]={7}};
+local refTools = {[79104]={30254},[80513]={30254},[89880]={30535},[89815]={31938}};
+local refPortals = {[91850]={"Horde"},[91861]={"Horde"},[91862]={"Horde"},[91863]={"Horde"},[91860]={"Alliance"},[91864]={"Alliance"},[91865]={"Alliance"},[91866]={"Alliance"}};
+--[[
+##########################################################
+LOCAL FUNCTIONS
+##########################################################
+]]--
+local Scroll_OnValueChanged = function(self,argValue)
+	FarmModeFrame:SetVerticalScroll(argValue)
+end
+
+local Scroll_OnMouseWheel = function(self, delta)
+	local scroll = self:GetVerticalScroll();
+	local value = (scroll - (20 * delta));
+	if value < -1 then
+		value = 0
+	end
+	if value > 420 then
+		value = 420
+	end
+	self:SetVerticalScroll(value)
+	self.slider:SetValue(value)
+end
+
+local function FindItemInBags(itemId)
+	for container = 0, NUM_BAG_SLOTS do
+		for slot = 1, GetContainerNumSlots(container) do
+			if itemId == GetContainerItemID(container, slot) then
+				return container, slot
+			end
+		end
+	end
+end
+--[[
+##########################################################
+EVENT HANDLER
+##########################################################
+]]--
+do
+	local FarmEventHandler = CreateFrame("Frame")
+
+	local ButtonUpdate = function(button)
+		button.items = GetItemCount(button.itemId)
+		if button.text then
+			button.text:SetText(button.items)
+		end
+		button.icon:SetDesaturated(button.items == 0)
+		button.icon:SetAlpha(button.items == 0 and .25 or 1)
+	end
+
+	local InFarmZone = function()
+		local zone = GetSubZoneText()
+		if (zone == L["Sunsong Ranch"] or zone == L["The Halfhill Market"]) then
+			if PLUGIN.Farming.ToolsLoaded and PLUGIN.ModeAlert:IsShown() then
+				PLUGIN.TitleWindow:Clear()
+	 			PLUGIN.TitleWindow:AddMessage("|cff22ff11Farming Mode|r")
+			end
+			return true
+		else
+			if PLUGIN.Farming.ToolsLoaded and PLUGIN.ModeAlert:IsShown() then
+				PLUGIN.TitleWindow:Clear()
+	 			PLUGIN.TitleWindow:AddMessage("|cffff2211Must be in Sunsong Ranch|r")
+			end
+			return false
+		end
+	end
+
+	local UpdateFarmtoolCooldown = function()
+		for i = 1, NUM_SEED_BARS do
+			for _, button in ipairs(seedButtons[i]) do
+				if button.cooldown then
+					button.cooldown:SetCooldown(GetItemCooldown(button.itemId))
+				end
+			end
+		end
+		for _, button in ipairs(farmToolButtons) do
+			if button.cooldown then
+				button.cooldown:SetCooldown(GetItemCooldown(button.itemId))
+			end
+		end
+		for _, button in ipairs(portalButtons) do
+			if button.cooldown then
+				button.cooldown:SetCooldown(GetItemCooldown(button.itemId))
+			end
+		end
+	end
+
+	local Farm_OnEvent = function(self, event, ...)
+		if(InCombatLockdown()) then return end
+		if(event == "ZONE_CHANGED") then
+			local inZone = InFarmZone()
+			if((not inZone) and CONFIGS.farming.droptools) then
+				for k, v in pairs(refTools) do
+					local container, slot = FindItemInBags(k)
+					if container and slot then
+						PickupContainerItem(container, slot)
+						DeleteCursorItem()
+					end
+				end
+			end
+			InventoryUpdate()
+		elseif(event == "BAG_UPDATE") then
+			InventoryUpdate()
+		elseif(event == "BAG_UPDATE_COOLDOWN") then
+			UpdateFarmtoolCooldown()
+		end
+	end
+
+	InventoryUpdate = function()
+		if InCombatLockdown() then
+			FarmEventHandler:RegisterEvent("PLAYER_REGEN_ENABLED", InventoryUpdate)
+			return
+		else
+			FarmEventHandler:UnregisterEvent("PLAYER_REGEN_ENABLED")
+	 	end
+		for i = 1, NUM_SEED_BARS do
+			for _, button in ipairs(seedButtons[i]) do
+				ButtonUpdate(button)
+			end
+		end
+		for _, button in ipairs(farmToolButtons) do
+			ButtonUpdate(button)
+		end
+		for _, button in ipairs(portalButtons) do
+			ButtonUpdate(button)
+		end
+
+		PLUGIN:RefreshFarmingTools()
+	end
+
+	EnableListener = function()
+		FarmEventHandler:RegisterEvent("ZONE_CHANGED")
+		FarmEventHandler:RegisterEvent("BAG_UPDATE")
+		FarmEventHandler:RegisterEvent("BAG_UPDATE_COOLDOWN")
+		FarmEventHandler:SetScript("OnEvent", Farm_OnEvent)
+	end
+
+	DisableListener = function()
+		FarmEventHandler:UnregisterAllEvents()
+		FarmEventHandler:SetScript("OnEvent", nil)
+	end
+end
+--[[
+##########################################################
+LOADING HANDLER
+##########################################################
+]]--
+do
+	local seedsort = function(a, b) return a.sortname < b.sortname end
+
+	local SeedToSoil = function(group, itemId)
+		if(UnitName("target") ~= L["Tilled Soil"]) then return false; end
+		for i, v in pairs(group) do
+			if i == itemId then return true end
+		end
+		return false
+	end
+
+	local Button_OnEnter = function(self)
+		GameTooltip:SetOwner(self, 'ANCHOR_TOPLEFT', 2, 4)
+		GameTooltip:ClearLines()
+		GameTooltip:AddDoubleLine(self.sortname)
+		if self.allowDrop then
+			GameTooltip:AddLine(L['Right-click to drop the item.'])
+		end
+		GameTooltip:Show()
+	end
+
+	local Button_OnLeave = function()
+		GameTooltip:Hide()
+	end
+
+	local Button_OnMouseDown = function(self, mousebutton)
+		if InCombatLockdown() then return end
+		if mousebutton == "LeftButton" then
+			self:SetAttribute("type", self.buttonType)
+			self:SetAttribute(self.buttonType, self.sortname)
+			if(SeedToSoil(refSeeds, self.itemId)) then
+				local container, slot = FindItemInBags(self.itemId)
+				if container and slot then
+					self:SetAttribute("type", "macro")
+					self:SetAttribute("macrotext", format("/targetexact %s \n/use %s %s", L["Tilled Soil"], container, slot))
+				end
+			end
+			if self.cooldown then
+				self.cooldown:SetCooldown(GetItemCooldown(self.itemId))
+			end
+		elseif mousebutton == "RightButton" and self.allowDrop then
+			self:SetAttribute("type", "click")
+			local container, slot = FindItemInBags(self.itemId)
+			if container and slot then
+				PickupContainerItem(container, slot)
+				DeleteCursorItem()
+			end
+		end
+	end
+
+	local function CreateFarmingButton(index, owner, buttonName, buttonType, name, texture, allowDrop, showCount)
+		local BUTTONSIZE = owner.ButtonSize;
+		local button = CreateFrame("Button", ("FarmingButton"..buttonName.."%d"):format(index), owner, "SecureActionButtonTemplate")
+		button:SetStyle("!_Frame", "Transparent")
+		button.Panel:SetFrameLevel(0)
+		button:SetNormalTexture(nil)
+		button:SetSize(BUTTONSIZE, BUTTONSIZE)
+		button.sortname = name
+		button.itemId = index
+		button.allowDrop = allowDrop
+		button.buttonType = buttonType
+		button.items = GetItemCount(index)
+		button.icon = button:CreateTexture(nil, "OVERLAY", nil, 2)
+		button.icon:SetTexture(texture)
+		button.icon:SetTexCoord(0.1, 0.9, 0.1, 0.9)
+		button.icon:InsetPoints(button,2,2)
+		if showCount then
+			button.text = button:CreateFontString(nil, "OVERLAY")
+			button.text:SetFontObject(SVUI_Font_CraftNumber)
+			button.text:SetPoint("BOTTOMRIGHT", button, 1, 2)
+		end
+		button.cooldown = CreateFrame("Cooldown", ("FarmingButton"..buttonName.."%dCooldown"):format(index), button)
+		button.cooldown:SetAllPoints(button)
+		button:SetScript("OnEnter", Button_OnEnter)
+		button:SetScript("OnLeave", Button_OnLeave)
+		button:SetScript("OnMouseDown", Button_OnMouseDown)
+		return button
+	end
+
+	function LoadFarmingModeTools()
+		local itemError = false
+		for k, v in pairs(refSeeds) do
+			if select(2, GetItemInfo(k)) == nil then print(GetItemInfo(k)) itemError = true end
+		end
+		for k, v in pairs(refTools) do
+			if select(2, GetItemInfo(k)) == nil then print(GetItemInfo(k)) itemError = true end
+		end
+		for k, v in pairs(refPortals) do
+			if select(2, GetItemInfo(k)) == nil then print(GetItemInfo(k)) itemError = true end
+		end
+		if InCombatLockdown() or itemError then
+			if PLUGIN.FarmLoadTimer then
+				PLUGIN.FarmLoadTimer = nil
+				PLUGIN.Farming:Disable()
+				PLUGIN.TitleWindow:AddMessage("|cffffff11The Loader is Being Dumb...|r|cffff1111PLEASE TRY AGAIN|r")
+				return
+			end
+			PLUGIN.TitleWindow:AddMessage("|cffffff11Loading Farm Tools...|r|cffff1111PLEASE WAIT|r")
+			PLUGIN.FarmLoadTimer = SV.Timers:ExecuteTimer(LoadFarmingModeTools, 5)
+		else
+			local horizontal = CONFIGS.farming.toolbardirection == 'HORIZONTAL'
+
+			local seeds, farmtools, portals = {},{},{}
+
+			for k, v in pairs(refSeeds) do
+				seeds[k] = { v[1], GetItemInfo(k) }
+			end
+
+			for k, v in pairs(refTools) do
+				farmtools[k] = { v[1], GetItemInfo(k) }
+			end
+
+			for k, v in pairs(refPortals) do
+				portals[k] = { v[1], GetItemInfo(k) }
+			end
+
+			for i = 1, NUM_SEED_BARS do
+				local seedBar = _G["FarmSeedBar"..i]
+				seedButtons[i] = seedButtons[i] or {}
+				local sbc = 1;
+				for k, v in pairs(seeds) do
+					if v[1] == i then
+						seedButtons[i][sbc] = CreateFarmingButton(k, seedBar, "SeedBar"..i.."Seed", "item", v[2], v[11], false, true);
+						sbc = sbc + 1;
+					end
+					tsort(seedButtons[i], seedsort)
+				end
+			end
+
+			local ftc = 1;
+			for k, v in pairs(farmtools) do
+				farmToolButtons[ftc] = CreateFarmingButton(k, _G["FarmToolBar"], "Tools", "item", v[2], v[11], true, false);
+				ftc = ftc + 1;
+			end
+
+			local playerFaction = UnitFactionGroup('player')
+			local pbc = 1;
+			for k, v in pairs(portals) do
+				if v[1] == playerFaction then
+					portalButtons[pbc] = CreateFarmingButton(k, _G["FarmPortalBar"], "Portals", "item", v[2], v[11], false, true);
+					pbc = pbc + 1;
+				end
+			end
+
+			PLUGIN.Farming.Loaded = true
+			PLUGIN.FarmLoadTimer = nil
+			PLUGIN.FarmEnableTimer = SV.Timers:ExecuteTimer(PLUGIN.Farming.Enable, 1.5)
+		end
+	end
+end
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+PLUGIN.Farming = {};
+PLUGIN.Farming.Loaded = false;
+PLUGIN.Farming.ToolsLoaded = false;
+
+function PLUGIN.Farming:Enable()
+	if InCombatLockdown() then return end
+
+ 	PLUGIN:ModeLootLoader("Farming", "Farming Mode", "This mode will provide you \nwith fast-access buttons for each \nof your seeds and farming tools.");
+
+ 	PLUGIN.TitleWindow:Clear()
+	if(not PLUGIN.Farming.Loaded) then
+		PLUGIN.TitleWindow:AddMessage("|cffffff11Loading Farm Tools...|r")
+		LoadFarmingModeTools()
+		return
+	else
+		if not PLUGIN.Farming.ToolsLoaded then
+			PlaySoundFile("Sound\\Effects\\DeathImpacts\\mDeathImpactColossalDirtA.wav")
+			PLUGIN.TitleWindow:AddMessage("|cff22ff11Farming Mode|r")
+			PLUGIN.ModeAlert:Show()
+			InventoryUpdate()
+			PLUGIN.Farming.ToolsLoaded = true
+			EnableListener()
+			if not FarmModeFrame:IsShown() then FarmModeFrame:Show() end
+			if(not PLUGIN.Docklet:IsShown()) then DockButton:Click() end
+		end
+	end
+end
+
+function PLUGIN.Farming:Disable()
+	if(InCombatLockdown() or (not PLUGIN.Farming.Loaded) or (not PLUGIN.Farming.ToolsLoaded)) then
+		DisableListener()
+		return
+	end
+	if CONFIGS.farming.droptools then
+		for k, v in pairs(refTools) do
+			local container, slot = FindItemInBags(k)
+			if container and slot then
+				PickupContainerItem(container, slot)
+				DeleteCursorItem()
+			end
+		end
+	end
+	if FarmModeFrame:IsShown() then FarmModeFrame:Hide() end
+	PLUGIN.Farming.ToolsLoaded = false
+	DisableListener()
+end
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+function PLUGIN:RefreshFarmingTools()
+	local count, horizontal = 0, CONFIGS.farming.toolbardirection == 'HORIZONTAL'
+	local BUTTONSPACE = CONFIGS.farming.buttonspacing or 2;
+	local lastBar;
+	if not FarmToolBar:IsShown() then
+		_G["FarmSeedBarAnchor"]:SetPoint("TOPLEFT", _G["FarmModeFrameSlots"], "TOPLEFT", 0, 0)
+	else
+		_G["FarmSeedBarAnchor"]:SetPoint("TOPLEFT", _G["FarmToolBar"], horizontal and "BOTTOMLEFT" or "TOPRIGHT", 0, 0)
+	end
+
+	for i = 1, NUM_SEED_BARS do
+
+		local seedBar = _G["FarmSeedBar"..i]
+		count = 0
+		if(seedButtons[i]) then
+			for i, button in ipairs(seedButtons[i]) do
+				local BUTTONSIZE = seedBar.ButtonSize;
+				button:SetPoint("TOPLEFT", seedBar, "TOPLEFT", horizontal and (count * (BUTTONSIZE + BUTTONSPACE) + 1) or 1, horizontal and -1 or -(count * (BUTTONSIZE + BUTTONSPACE) + 1))
+				button:SetSize(BUTTONSIZE,BUTTONSIZE)
+				if (not CONFIGS.farming.onlyactive or (CONFIGS.farming.onlyactive and button.items > 0)) then
+					button.icon:SetVertexColor(1,1,1)
+					count = count + 1
+				elseif (not CONFIGS.farming.onlyactive and button.items <= 0) then
+					button:Show()
+					button.icon:SetVertexColor(0.25,0.25,0.25)
+					count = count + 1
+				else
+					button:Hide()
+				end
+			end
+		end
+		if(CONFIGS.farming.onlyactive and not CONFIGS.farming.undocked) then
+			if count==0 then
+				seedBar:Hide()
+			else
+				seedBar:Show()
+				if(not lastBar) then
+					seedBar:SetPoint("TOPLEFT", _G["FarmSeedBarAnchor"], "TOPLEFT", 0, 0)
+				else
+					seedBar:SetPoint("TOPLEFT", lastBar, horizontal and "BOTTOMLEFT" or "TOPRIGHT", 0, 0)
+				end
+				lastBar = seedBar
+			end
+		end
+	end
+	count = 0;
+	lastBar = nil;
+	FarmToolBar:ClearAllPoints()
+	FarmToolBar:SetAllPoints(FarmToolBarAnchor)
+	for i, button in ipairs(farmToolButtons) do
+		local BUTTONSIZE = FarmToolBar.ButtonSize;
+		button:SetPoint("TOPLEFT", FarmToolBar, "TOPLEFT", horizontal and (count * (BUTTONSIZE + BUTTONSPACE) + 1) or 1, horizontal and -1 or -(count * (BUTTONSIZE + BUTTONSPACE) + 1))
+		button:SetSize(BUTTONSIZE,BUTTONSIZE)
+		if (not CONFIGS.farming.onlyactive or (CONFIGS.farming.onlyactive and button.items > 0)) then
+			button:Show()
+			button.icon:SetVertexColor(1,1,1)
+			count = count + 1
+		elseif (not CONFIGS.farming.onlyactive and button.items == 0) then
+			button:Show()
+			button.icon:SetVertexColor(0.25,0.25,0.25)
+			count = count + 1
+		else
+			button:Hide()
+		end
+	end
+	if(CONFIGS.farming.onlyactive and not CONFIGS.farming.undocked) then
+		if count==0 then
+			FarmToolBarAnchor:Hide()
+			FarmPortalBar:SetPoint("TOPLEFT", FarmModeFrameSlots, "TOPLEFT", 0, 0)
+		else
+			FarmToolBarAnchor:Show()
+			FarmPortalBar:SetPoint("TOPLEFT", FarmToolBarAnchor, "TOPRIGHT", 0, 0)
+		end
+	end
+	count = 0;
+	FarmPortalBar:ClearAllPoints()
+	FarmPortalBar:SetAllPoints(FarmPortalBarAnchor)
+	for i, button in ipairs(portalButtons) do
+		local BUTTONSIZE = FarmPortalBar.ButtonSize;
+		button:SetPoint("TOPLEFT", FarmPortalBar, "TOPLEFT", horizontal and (count * (BUTTONSIZE + BUTTONSPACE) + 1) or 1, horizontal and -1 or -(count * (BUTTONSIZE + BUTTONSPACE) + 1))
+		button:SetSize(BUTTONSIZE,BUTTONSIZE)
+		if (not CONFIGS.farming.onlyactive or (CONFIGS.farming.onlyactive and button.items > 0)) then
+			button:Show()
+			button.icon:SetVertexColor(1,1,1)
+			count = count + 1
+		elseif (not CONFIGS.farming.onlyactive and button.items == 0) then
+			button:Show()
+			button.icon:SetVertexColor(0.25,0.25,0.25)
+			count = count + 1
+		else
+			button:Hide()
+		end
+	end
+	if(CONFIGS.farming.onlyactive) then
+		if count==0 then
+			FarmPortalBar:Hide()
+		else
+			FarmPortalBar:Show()
+		end
+	end
+end
+
+function PLUGIN:PrepareFarmingTools()
+	CONFIGS = SV.db[self.Schema];
+	local horizontal = CONFIGS.farming.toolbardirection == "HORIZONTAL"
+	local BUTTONSPACE = CONFIGS.farming.buttonspacing or 2;
+
+	ModeLogsFrame = self.LogWindow;
+	DockButton = self.Docklet.Button
+
+	if not CONFIGS.farming.undocked then
+		local bgTex = [[Interface\BUTTONS\WHITE8X8]]
+		local bdTex = SV.media.statusbar.glow
+		local farmingDocklet = CreateFrame("ScrollFrame", "FarmModeFrame", ModeLogsFrame);
+		farmingDocklet:SetPoint("TOPLEFT", ModeLogsFrame, 31, -3);
+		farmingDocklet:SetPoint("BOTTOMRIGHT", ModeLogsFrame, -3, 3);
+		farmingDocklet:EnableMouseWheel(true);
+
+		local farmingDockletSlots = CreateFrame("Frame", "FarmModeFrameSlots", farmingDocklet);
+		farmingDockletSlots:SetPoint("TOPLEFT", farmingDocklet, 0, 0);
+		farmingDockletSlots:SetWidth(farmingDocklet:GetWidth())
+		farmingDockletSlots:SetHeight(500);
+		farmingDockletSlots:SetFrameLevel(farmingDocklet:GetFrameLevel() + 1)
+		farmingDocklet:SetScrollChild(farmingDockletSlots)
+
+		local slotSlider = CreateFrame("Slider", "FarmModeSlotSlider", farmingDocklet);
+		slotSlider:SetHeight(farmingDocklet:GetHeight() - 3);
+		slotSlider:SetWidth(18);
+		slotSlider:SetPoint("TOPLEFT", farmingDocklet, -28, 0);
+		slotSlider:SetPoint("BOTTOMLEFT", farmingDocklet, -28, 0);
+		slotSlider:SetBackdrop({bgFile = bgTex, edgeFile = bdTex, edgeSize = 4, insets = {left = 3, right = 3, top = 3, bottom = 3}});
+		slotSlider:SetFrameLevel(6)
+		slotSlider:SetStyle("!_Frame", "Transparent", true);
+		slotSlider:SetThumbTexture("Interface\\Buttons\\UI-ScrollBar-Knob");
+		slotSlider:SetOrientation("VERTICAL");
+		slotSlider:SetValueStep(5);
+		slotSlider:SetMinMaxValues(1, 420);
+		slotSlider:SetValue(1);
+
+		farmingDocklet.slider = slotSlider;
+		slotSlider:SetScript("OnValueChanged", Scroll_OnValueChanged)
+		farmingDocklet:SetScript("OnMouseWheel", Scroll_OnMouseWheel);
+
+		local parentWidth = FarmModeFrameSlots:GetWidth() - 31
+		local BUTTONSIZE = (parentWidth / (horizontal and 10 or 8));
+		local TOOLSIZE = (parentWidth / 8);
+
+		-- FARM TOOLS
+		local farmToolBarAnchor = CreateFrame("Frame", "FarmToolBarAnchor", farmingDockletSlots)
+		farmToolBarAnchor:SetPoint("TOPLEFT", farmingDockletSlots, "TOPLEFT", 0, 0)
+		farmToolBarAnchor:SetSize(horizontal and ((TOOLSIZE + BUTTONSPACE) * 4) or (TOOLSIZE + BUTTONSPACE), horizontal and (TOOLSIZE + BUTTONSPACE) or ((TOOLSIZE + BUTTONSPACE) * 4))
+
+		local farmToolBar = CreateFrame("Frame", "FarmToolBar", farmToolBarAnchor)
+		farmToolBar:SetSize(horizontal and ((TOOLSIZE + BUTTONSPACE) * 4) or (TOOLSIZE + BUTTONSPACE), horizontal and (TOOLSIZE + BUTTONSPACE) or ((TOOLSIZE + BUTTONSPACE) * 4))
+		farmToolBar:SetPoint("TOPLEFT", farmToolBarAnchor, "TOPLEFT", (horizontal and BUTTONSPACE or (TOOLSIZE + BUTTONSPACE)), (horizontal and -(TOOLSIZE + BUTTONSPACE) or -BUTTONSPACE))
+		farmToolBar.ButtonSize = TOOLSIZE;
+
+		-- PORTALS
+		local farmPortalBarAnchor = CreateFrame("Frame", "FarmPortalBarAnchor", farmingDockletSlots)
+		farmPortalBarAnchor:SetPoint("TOPLEFT", farmToolBarAnchor, "TOPRIGHT", 0, 0)
+		farmPortalBarAnchor:SetSize(horizontal and ((TOOLSIZE + BUTTONSPACE) * 4) or (TOOLSIZE + BUTTONSPACE), horizontal and (TOOLSIZE + BUTTONSPACE) or ((TOOLSIZE + BUTTONSPACE) * 4))
+
+		local farmPortalBar = CreateFrame("Frame", "FarmPortalBar", farmPortalBarAnchor)
+		farmPortalBar:SetSize(horizontal and ((TOOLSIZE + BUTTONSPACE) * 4) or (TOOLSIZE + BUTTONSPACE), horizontal and (TOOLSIZE + BUTTONSPACE) or ((TOOLSIZE + BUTTONSPACE) * 4))
+		farmPortalBar:SetPoint("TOPLEFT", farmPortalBarAnchor, "TOPLEFT", (horizontal and BUTTONSPACE or (TOOLSIZE + BUTTONSPACE)), (horizontal and -(TOOLSIZE + BUTTONSPACE) or -BUTTONSPACE))
+		farmPortalBar.ButtonSize = TOOLSIZE;
+
+		-- SEEDS
+		local farmSeedBarAnchor = CreateFrame("Frame", "FarmSeedBarAnchor", farmingDockletSlots)
+		farmSeedBarAnchor:SetPoint("TOPLEFT", farmPortalBarAnchor, horizontal and "BOTTOMLEFT" or "TOPRIGHT", 0, 0)
+		farmSeedBarAnchor:SetSize(horizontal and ((BUTTONSIZE + BUTTONSPACE) * 10) or ((BUTTONSIZE + BUTTONSPACE) * 8), horizontal and ((BUTTONSIZE + BUTTONSPACE) * 8) or ((BUTTONSIZE + BUTTONSPACE) * 10))
+
+		for i = 1, NUM_SEED_BARS do
+			local seedBar = CreateFrame("Frame", "FarmSeedBar"..i, farmSeedBarAnchor)
+			seedBar.ButtonSize = BUTTONSIZE;
+			seedBar:SetSize(horizontal and ((BUTTONSIZE + BUTTONSPACE) * 10) or (BUTTONSIZE + BUTTONSPACE), horizontal and (BUTTONSIZE + BUTTONSPACE) or ((BUTTONSIZE + BUTTONSPACE) * 10))
+			if i == 1 then
+				seedBar:SetPoint("TOPLEFT", farmSeedBarAnchor, "TOPLEFT", 0, 0)
+			else
+				seedBar:SetPoint("TOPLEFT", "FarmSeedBar"..i-1, horizontal and "BOTTOMLEFT" or "TOPRIGHT", 0, 0)
+			end
+		end
+
+		farmingDocklet:Hide()
+	else
+		local BUTTONSIZE = CONFIGS.farming.buttonsize or 35;
+
+		-- SEEDS
+		local farmSeedBarAnchor = CreateFrame("Frame", "FarmSeedBarAnchor", UIParent)
+		farmSeedBarAnchor:SetPoint("TOPRIGHT", SV.Screen, "TOPRIGHT", -40, -300)
+		farmSeedBarAnchor:SetSize(horizontal and ((BUTTONSIZE + BUTTONSPACE) * 10) or ((BUTTONSIZE + BUTTONSPACE) * 8), horizontal and ((BUTTONSIZE + BUTTONSPACE) * 8) or ((BUTTONSIZE + BUTTONSPACE) * 10))
+		for i = 1, NUM_SEED_BARS do
+			local seedBar = CreateFrame("Frame", "FarmSeedBar"..i, farmSeedBarAnchor)
+			seedBar:SetSize(horizontal and ((BUTTONSIZE + BUTTONSPACE) * 10) or (BUTTONSIZE + BUTTONSPACE), horizontal and (BUTTONSIZE + BUTTONSPACE) or ((BUTTONSIZE + BUTTONSPACE) * 10))
+			seedBar:SetPoint("TOPRIGHT", _G["FarmSeedBarAnchor"], "TOPRIGHT", (horizontal and 0 or -((BUTTONSIZE + BUTTONSPACE) * i)), (horizontal and -((BUTTONSIZE + BUTTONSPACE) * i) or 0))
+			seedBar.ButtonSize = BUTTONSIZE;
+		end
+		SV.Mentalo:Add(farmSeedBarAnchor, "Farming Seeds")
+
+		-- FARM TOOLS
+		local farmToolBarAnchor = CreateFrame("Frame", "FarmToolBarAnchor", UIParent)
+		farmToolBarAnchor:SetPoint("TOPRIGHT", farmSeedBarAnchor, horizontal and "BOTTOMRIGHT" or "TOPLEFT", horizontal and 0 or -(BUTTONSPACE * 2), horizontal and -(BUTTONSPACE * 2) or 0)
+		farmToolBarAnchor:SetSize(horizontal and ((BUTTONSIZE + BUTTONSPACE) * 4) or (BUTTONSIZE + BUTTONSPACE), horizontal and (BUTTONSIZE + BUTTONSPACE) or ((BUTTONSIZE + BUTTONSPACE) * 4))
+		local farmToolBar = CreateFrame("Frame", "FarmToolBar", farmToolBarAnchor)
+		farmToolBar:SetSize(horizontal and ((BUTTONSIZE + BUTTONSPACE) * 4) or (BUTTONSIZE + BUTTONSPACE), horizontal and (BUTTONSIZE + BUTTONSPACE) or ((BUTTONSIZE + BUTTONSPACE) * 4))
+		farmToolBar:SetPoint("TOPRIGHT", farmToolBarAnchor, "TOPRIGHT", (horizontal and -BUTTONSPACE or -(BUTTONSIZE + BUTTONSPACE)), (horizontal and -(BUTTONSIZE + BUTTONSPACE) or -BUTTONSPACE))
+		farmToolBar.ButtonSize = BUTTONSIZE;
+		SV.Mentalo:Add(farmToolBarAnchor, "Farming Tools")
+
+		-- PORTALS
+		local farmPortalBarAnchor = CreateFrame("Frame", "FarmPortalBarAnchor", UIParent)
+		farmPortalBarAnchor:SetPoint("TOPRIGHT", farmToolBarAnchor, horizontal and "BOTTOMRIGHT" or "TOPLEFT", horizontal and 0 or -(BUTTONSPACE * 2), horizontal and -(BUTTONSPACE * 2) or 0)
+		farmPortalBarAnchor:SetSize(horizontal and ((BUTTONSIZE + BUTTONSPACE) * 4) or (BUTTONSIZE + BUTTONSPACE), horizontal and (BUTTONSIZE + BUTTONSPACE) or ((BUTTONSIZE + BUTTONSPACE) * 4))
+		local farmPortalBar = CreateFrame("Frame", "FarmPortalBar", farmPortalBarAnchor)
+		farmPortalBar:SetSize(horizontal and ((BUTTONSIZE + BUTTONSPACE) * 4) or (BUTTONSIZE + BUTTONSPACE), horizontal and (BUTTONSIZE + BUTTONSPACE) or ((BUTTONSIZE + BUTTONSPACE) * 4))
+		farmPortalBar:SetPoint("TOPRIGHT", farmPortalBarAnchor, "TOPRIGHT", (horizontal and -BUTTONSPACE or -(BUTTONSIZE + BUTTONSPACE)), (horizontal and -(BUTTONSIZE + BUTTONSPACE) or -BUTTONSPACE))
+		farmPortalBar.ButtonSize = BUTTONSIZE;
+		SV.Mentalo:Add(farmPortalBarAnchor, "Farming Portals")
+	end
+end
diff --git a/SVUI_CraftOMatic/components/fishing.lua b/SVUI_CraftOMatic/components/fishing.lua
new file mode 100644
index 0000000..e34ee6d
--- /dev/null
+++ b/SVUI_CraftOMatic/components/fishing.lua
@@ -0,0 +1,407 @@
+--[[
+##########################################################
+S V U I   By: S.Jackson
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pcall         = _G.pcall;
+local print         = _G.print;
+local ipairs        = _G.ipairs;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local rawset        = _G.rawset;
+local rawget        = _G.rawget;
+local tostring      = _G.tostring;
+local tonumber      = _G.tonumber;
+local getmetatable  = _G.getmetatable;
+local setmetatable  = _G.setmetatable;
+--STRING
+local string        = _G.string;
+local upper         = string.upper;
+local format        = string.format;
+local find          = string.find;
+local match         = string.match;
+local gsub          = string.gsub;
+local rept      = string.rep;
+local math 		= _G.math;
+local table 	= _G.table;
+local tsort,twipe = table.sort,table.wipe;
+local floor,ceil  = math.floor, math.ceil;
+local band 		= _G.bit.band;
+--BLIZZARD API
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+local GameTooltip           = _G.GameTooltip;
+local hooksecurefunc        = _G.hooksecurefunc;
+local IsSpellKnown      	= _G.IsSpellKnown;
+local GetSpellInfo      	= _G.GetSpellInfo;
+local GetProfessions      	= _G.GetProfessions;
+local GetProfessionInfo     = _G.GetProfessionInfo;
+local PlaySound             = _G.PlaySound;
+local PlaySoundFile         = _G.PlaySoundFile;
+local C_PetJournal          = _G.C_PetJournal;
+local GetItemInfo           = _G.GetItemInfo;
+local GetItemCount          = _G.GetItemCount;
+local GetItemQualityColor   = _G.GetItemQualityColor;
+local GetItemFamily         = _G.GetItemFamily;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G.SVUI;
+local L = SV.L;
+local PLUGIN = select(2, ...);
+local CONFIGS = SV.defaults[PLUGIN.Schema];
+--[[
+##########################################################
+LOCAL VARS
+##########################################################
+]]--
+local fishingIsKnown, fishingSpell, fishingLure;
+local proxyTest = false;
+local refLures = {
+	{ ["id"] = 6529, 		["bonus"] = 25, 	["skillReq"] = 1, 	["order"] = 10, }, --Shiny Bauble
+	{ ["id"] = 6811, 		["bonus"] = 50, 	["skillReq"] = 50, 	["order"] = 10, }, --Aquadynamic Fish Lens
+	{ ["id"] = 6530, 		["bonus"] = 50, 	["skillReq"] = 50, 	["order"] = 10, }, --Nightcrawlers
+	{ ["id"] = 7307, 		["bonus"] = 75, 	["skillReq"] = 100, ["order"] = 10, }, --Flesh Eating Worm
+	{ ["id"] = 6532, 		["bonus"] = 75, 	["skillReq"] = 100, ["order"] = 10, }, --Bright Baubles
+	{ ["id"] = 34861, 	["bonus"] = 100, 	["skillReq"] = 100, ["order"] = 10, }, --Sharpened Fish Hook
+	{ ["id"] = 6533, 		["bonus"] = 100, 	["skillReq"] = 100, ["order"] = 10, }, --Aquadynamic Fish Attractor
+	{ ["id"] = 62673, 	["bonus"] = 100, 	["skillReq"] = 100, ["order"] = 10, }, --Feathered Lure
+	{ ["id"] = 46006, 	["bonus"] = 100, 	["skillReq"] = 100, ["order"] = 60, }, --Glow Worm
+	{ ["id"] = 68049, 	["bonus"] = 150, 	["skillReq"] = 250, ["order"] = 5,  }, --Heat-Treated Spinning Lure
+	{ ["id"] = 118391, 	["bonus"] = 200, 	["skillReq"] = 100, ["order"] = 70, }, --Worm Supreme WOD
+	{ ["id"] = 67404, 	["bonus"] = 15, 	["skillReq"] = 1, 	["order"] = 10, }, --Glass Fishing Bobber
+}
+tsort(refLures, function(a,b)
+	if ( a.bonus == b.bonus ) then
+		return a.order < b.order;
+	else
+		return a.bonus < b.bonus;
+	end
+end);
+local refHats = {
+	{ ["id"] = 93732, 	["weight"] = 10, 	["nocast"] = true 	},  --Darkmoon Fishing Hat
+	{ ["id"] = 33820, 	["weight"] = 50, 	["nocast"] = false 	},  --Weather Beaten Fishing Hat
+	{ ["id"] = 19972, 	["weight"] = 75, 	["nocast"] = false 	},  --Lucky Fishing Hat
+	{ ["id"] = 118380, 	["weight"] = 100, ["nocast"] = false 	},  --Hightfish Cap 7Days WOD
+	{ ["id"] = 118393, 	["weight"] = 100, ["nocast"] = false 	},  --Tentacled Hat 7Days WOD
+	{ ["id"] = 88710, 	["weight"] = 100, ["nocast"] = false 	},  --Nats Hat
+	{ ["id"] = 117405, 	["weight"] = 100, ["nocast"] = false 	},  --Nats Drinking Hat
+}
+local refPoles = {
+	{ ["id"] = 118381, 	["weight"] = 50 }, --Ephemeral Fishing Pole 24hours WOD
+	{ ["id"] = 44050, 	["weight"] = 33 }, --Kaluak
+	{ ["id"] = 25978, 	["weight"] = 22 }, --Seths Graphite
+	{ ["id"] = 19022, 	["weight"] = 21 }, --Nat Pagles Extreme Angler
+	{ ["id"] = 6367, 		["weight"] = 20 }, --Big Iron
+	{ ["id"] = 6366, 		["weight"] = 15 }, --Darkwood
+	{ ["id"] = 84661, 	["weight"] = 32 }, --Dragon
+	{ ["id"] = 19970, 	["weight"] = 40 }, --Arcanite
+	{ ["id"] = 45858, 	["weight"] = 25 }, --Nats Lucky
+	{ ["id"] = 45992, 	["weight"] = 31 }, --Jeweled
+	{ ["id"] = 45991, 	["weight"] = 30 }, --Bone
+	{ ["id"] = 6365, 		["weight"] = 5 	}, --Strong
+	{ ["id"] = 12225, 	["weight"] = 4 	}, --Blump Family
+	{ ["id"] = 46337, 	["weight"] = 3 	}, --Staats
+	{ ["id"] = 84660, 	["weight"] = 10 }, --Pandaren
+	{ ["id"] = 6256, 		["weight"] = 1 	}  --Standard
+}
+--[[
+##########################################################
+LOCAL FUNCTIONS
+##########################################################
+]]--
+local function GetFishingSkill()
+	local fishing = select(4, GetProfessions())
+	if (fishing) then
+		local rank = select(3, GetProfessionInfo(fishing))
+		return rank
+	end
+	return 0, 0, 0
+end
+
+local function FishingPoleIsEquipped()
+	local itemId = GetInventoryItemID("player", 16)
+	if itemId then
+		local subclass = select(7, GetItemInfo(itemId))
+		local weaponSubTypesList = select(17, GetAuctionItemSubClasses(1))
+		if subclass == weaponSubTypesList then
+			return true
+		else
+			return false
+		end
+	else
+		return false
+	end
+end
+
+local function UpdateFishingGear(autoequip)
+	local lastBonus, lastWeight = 0,0;
+	local rawskill = GetFishingSkill();
+	local item,id,bonus,count;
+
+	-- Check for and equip a fishing hat, if autoequip is enabled
+	if(autoequip) then
+		local fishingHat = false;
+		for i=1, #refHats do
+			item = refHats[i]
+			id = item.id
+			bonus = item.weight
+			count = GetItemCount(id)
+			if ( count > 0 and bonus > lastWeight ) then
+				fishingHat = id
+				lastWeight = bonus
+				if(item.weight > 10) then
+					fishingLure = id
+					lastBonus = bonus
+				end
+			end
+		end
+		if(fishingHat) then
+			local HelmetID = GetInventoryItemID("player", INVSLOT_HEAD);
+			if(HelmetID) then
+				PLUGIN.WornItems["HEAD"] = HelmetID
+			end
+			EquipItemByName(fishingHat)
+			PLUGIN.InModeGear = true
+		end
+	end
+
+	-- Check for and save best fishing lure
+	for i=1, #refLures do
+		item = refLures[i]
+		id = item.id
+		bonus = item.bonus
+		count = GetItemCount(id)
+		if ( count > 0 and bonus > (lastBonus or 0) ) then
+			if ( item.skillReq <= rawskill ) then
+				fishingLure = id
+				lastBonus = bonus
+			end
+		end
+	end
+
+	-- Check for and equip a fishing pole, if autoequip is enabled
+	if(autoequip) then
+		lastBonus = 0;
+		local fishingPole = false;
+		for i=1, #refPoles do
+			item = refPoles[i]
+			id = item.id
+			bonus = item.weight
+			count = GetItemCount(id)
+			if ( count > 0 and bonus > (lastBonus or 0) ) then
+				fishingPole = id
+				lastBonus = bonus
+			end
+		end
+
+		local MainHandID = GetInventoryItemID("player", INVSLOT_MAINHAND);
+		if(MainHandID) then
+			PLUGIN.WornItems["MAIN"] = MainHandID
+		end
+
+		local OffHandID = GetInventoryItemID("player", INVSLOT_OFFHAND);
+		if(OffHandID) then
+			PLUGIN.WornItems["OFF"] = OffHandID;
+		end
+
+		if(fishingPole) then
+			EquipItemByName(fishingPole)
+			PLUGIN.InModeGear = true
+		end
+	end
+end
+
+local function LootProxy(item, name)
+	if(item) then
+		local mask = [[0x100000]];
+		local itemType = GetItemFamily(item);
+		local pass = band(itemType, mask);
+		if pass > 0 then
+			proxyTest = true;
+		end
+	end
+end
+
+local function GetTitleAndSkill()
+	local skillRank, skillModifier;
+	local msg = "|cff22ff11Fishing Mode|r"
+	local _,_,_,fishing,_,_ = GetProfessions();
+	if fishing ~= nil then
+		_, _, skillRank, _, _, _, _, skillModifier = GetProfessionInfo(fishing)
+		if(skillModifier) then
+			skillRank = skillRank + skillModifier;
+		end
+		msg = msg .. " (|cff00ddff" .. skillRank .. "|r)";
+	end
+	return msg
+end
+--[[
+##########################################################
+CORE NAMESPACE
+##########################################################
+]]--
+PLUGIN.Fishing = {};
+PLUGIN.Fishing.Log = {};
+PLUGIN.Fishing.Loaded = false;
+--[[
+##########################################################
+EVENT HANDLER
+##########################################################
+]]--
+local EnableListener, DisableListener
+do
+	local FishEventHandler = CreateFrame("Frame")
+	local LootProxy = function(item, name)
+		if(item) then
+			local mask = [[0x10000]];
+			local itemType = GetItemFamily(item);
+			local pass = band(itemType, mask);
+			if pass > 0 then
+				proxyTest = true;
+			end
+		end
+	end
+
+	local Fish_OnEvent = function(self, event, ...)
+		if(InCombatLockdown()) then return end
+		if(event == "BAG_UPDATE" or event == "CHAT_MSG_SKILL") then
+			local msg = GetTitleAndSkill()
+			PLUGIN.TitleWindow:Clear()
+			PLUGIN.TitleWindow:AddMessage(msg)
+		elseif(event == "LOOT_OPENED") then
+			if IsFishingLoot() then
+				proxyTest = true;
+			else
+				proxyTest = false;
+			end
+		elseif(event == "CHAT_MSG_LOOT") then
+			local item, amt = PLUGIN:CheckForModeLoot(...);
+			if item then
+				local name, lnk, rarity, lvl, mlvl, itype, stype, cnt, ieq, tex, price = GetItemInfo(item);
+				if proxyTest == false then
+					LootProxy(lnk, name)
+				end
+				if proxyTest == false then return end
+				if not PLUGIN.Fishing.Log[name] then
+					PLUGIN.Fishing.Log[name] = {amount = 0, texture = ""};
+				end
+				local r, g, b, hex = GetItemQualityColor(rarity);
+				local stored = PLUGIN.Fishing.Log
+				local mod = stored[name];
+				local newAmt = mod.amount + 1;
+				if amt >= 2 then newAmt = mod.amount + amt end
+				PLUGIN.Fishing.Log[name].amount = newAmt;
+				PLUGIN.Fishing.Log[name].texture = tex;
+				PLUGIN.LogWindow:Clear();
+
+				for name,data in pairs(stored) do
+					if type(data) == "table" and data.amount and data.texture then
+						PLUGIN.LogWindow:AddMessage("|cff55FF55"..data.amount.." x|r |T".. data.texture ..":16:16:0:0:64:64:4:60:4:60|t".." "..name, r, g, b);
+					end
+				end
+				PLUGIN.LogWindow:AddMessage("----------------", 0, 0, 0);
+				PLUGIN.LogWindow:AddMessage("Caught So Far...", 0, 1, 1);
+				PLUGIN.LogWindow:AddMessage(" ", 0, 0, 0);
+				proxyTest = false;
+			end
+		end
+	end
+
+	function EnableListener()
+		FishEventHandler:RegisterEvent("LOOT_OPENED")
+		FishEventHandler:RegisterEvent("CHAT_MSG_LOOT")
+		FishEventHandler:RegisterEvent("BAG_UPDATE")
+		FishEventHandler:RegisterEvent("CHAT_MSG_SKILL")
+		FishEventHandler:SetScript("OnEvent", Fish_OnEvent)
+	end
+
+	function DisableListener()
+		FishEventHandler:UnregisterAllEvents()
+		FishEventHandler:SetScript("OnEvent", nil)
+	end
+end
+--[[
+##########################################################
+CORE METHODS
+##########################################################
+]]--
+function PLUGIN.Fishing:Enable()
+	PLUGIN:UpdateFishingMode()
+	if(not PLUGIN.Docklet:IsShown()) then PLUGIN.Docklet.Button:Click() end
+	UpdateFishingGear(CONFIGS.fishing.autoequip);
+	PlaySoundFile("Sound\\Spells\\Tradeskills\\FishCast.wav")
+	PLUGIN.ModeAlert:SetBackdropColor(0.25, 0.52, 0.1)
+	if(not IsSpellKnown(131474)) then
+		PLUGIN:ModeLootLoader("Fishing", "WTF is Fishing?", "You have no clue how to fish! \nThe last time you tried \nyou hooked yourself through the eyelid. \nGo find a trainer and learn \nhow to do this properly!");
+	else
+		local msg = GetTitleAndSkill();
+		PLUGIN:ModeLootLoader("Fishing", msg, "Double-Right-Click anywhere on the screen \nto cast your fishing line.");
+	end
+	EnableListener()
+	PLUGIN.ModeAlert:Show()
+	SV:SCTMessage("Fishing Mode Enabled", 0.28, 0.9, 0.1);
+end
+
+function PLUGIN.Fishing:Disable()
+	DisableListener()
+end
+
+function PLUGIN.Fishing:Bind()
+	if InCombatLockdown() then return end
+	if fishingIsKnown then
+		if FishingPoleIsEquipped() then
+			local hasMainHandEnchant = GetWeaponEnchantInfo()
+			if hasMainHandEnchant then
+				_G["SVUI_ModeCaptureWindow"]:SetAttribute("type", "spell")
+				_G["SVUI_ModeCaptureWindow"]:SetAttribute('spell', fishingSpell)
+				PLUGIN.ModeAlert.HelpText = 'Double-Right-Click to fish.'
+			elseif(fishingLure) then
+				_G["SVUI_ModeCaptureWindow"]:SetAttribute("type", "item")
+				_G["SVUI_ModeCaptureWindow"]:SetAttribute("item", "item:" .. fishingLure)
+				if(GetItemCooldown(fishingLure) > 0) then
+					_G["SVUI_ModeCaptureWindow"]:SetAttribute("type", "spell")
+					_G["SVUI_ModeCaptureWindow"]:SetAttribute('spell', fishingSpell)
+					PLUGIN.ModeAlert.HelpText = 'Double-Right-Click to fish.'
+				else
+					PLUGIN.ModeAlert.HelpText = 'Double-Right-Click to apply fishing enchants.'
+				end
+			else
+				_G["SVUI_ModeCaptureWindow"]:SetAttribute("type", "spell")
+				_G["SVUI_ModeCaptureWindow"]:SetAttribute('spell', fishingSpell)
+				PLUGIN.ModeAlert.HelpText = 'Double-Right-Click to fish.'
+			end
+		else
+			_G["SVUI_ModeCaptureWindow"]:SetAttribute("type", "spell")
+			_G["SVUI_ModeCaptureWindow"]:SetAttribute('spell', fishingSpell)
+			PLUGIN.ModeAlert.HelpText = 'Double-Right-Click to fish.'
+		end
+		SetOverrideBindingClick(_G["SVUI_ModeCaptureWindow"], true, "BUTTON2", "SVUI_ModeCaptureWindow");
+		_G["SVUI_ModeCaptureWindow"].Handler:Show();
+	end
+end
+--[[
+##########################################################
+LOADER
+##########################################################
+]]--
+function PLUGIN:UpdateFishingMode()
+	fishingIsKnown = IsSpellKnown(131474);
+	fishingSpell = GetSpellInfo(131474);
+end
+
+function PLUGIN:LoadFishingMode()
+	CONFIGS = SV.db[self.Schema];
+	self:UpdateFishingMode()
+end
diff --git a/SVUI_FightOMatic/Bindings.xml b/SVUI_FightOMatic/Bindings.xml
new file mode 100644
index 0000000..8f5a94e
--- /dev/null
+++ b/SVUI_FightOMatic/Bindings.xml
@@ -0,0 +1,5 @@
+<Bindings>
+  <Binding name="SVUIFIGHT_RADIO" category="ADDONS" header="SVUIFIGHT" runOnUp="false">
+    SVUISayIncoming()
+  </Binding>
+</Bindings>
\ No newline at end of file
diff --git a/SVUI_FightOMatic/License.txt b/SVUI_FightOMatic/License.txt
new file mode 100644
index 0000000..69d4d04
--- /dev/null
+++ b/SVUI_FightOMatic/License.txt
@@ -0,0 +1,31 @@
+
+The MIT License
+
+Copyright (c) 2010, Failcoder (Steve Jackson)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy
+of this software and associated documentation files (the "Software"), to
+deal
+in the Software without restriction, including without limitation the
+rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN
+THE SOFTWARE.
diff --git a/SVUI_FightOMatic/Loader.lua b/SVUI_FightOMatic/Loader.lua
new file mode 100644
index 0000000..8f355d0
--- /dev/null
+++ b/SVUI_FightOMatic/Loader.lua
@@ -0,0 +1,62 @@
+--[[
+##########################################################
+S V U I   By: S.Jackson
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+
+local SV = _G["SVUI"];
+local L = SV.L;
+local AddonName, AddonObj = ...;
+local PLUGIN = SV:NewPlugin(AddonName, AddonObj, "SVUI_Public_FightOMatic");
+local Schema = PLUGIN.Schema;
+
+SV.defaults[Schema] = {
+    ["annoyingEmotes"] = false,
+}
+
+SV:AssignMedia("font", "fightdialog", "SVUI Default Font", 12, "OUTLINE");
+SV:AssignMedia("font", "fightnumber", "SVUI Caps Font", 12, "OUTLINE");
+SV:AssignMedia("globalfont", "fightdialog", "SVUI_Font_Fight");
+SV:AssignMedia("globalfont", "fightnumber", "SVUI_Font_FightNumber");
+
+function PLUGIN:LoadOptions()
+    local fightFonts = {
+      ["fightdialog"] = {
+        order = 1,
+        name = "Fight-O-Matic Dialog",
+        desc = "Font used for log window text."
+      },
+      ["fightnumber"] = {
+        order = 2,
+        name = "Fight-O-Matic Numbers",
+        desc = "Font used for log window numbers."
+      },
+    };
+
+    SV:GenerateFontOptionGroup("Fight-O-Matic", 13, "Font used for Fight-O-Matic text.", fightFonts)
+
+    SV.Options.args[Schema] = {
+        type = "group",
+        name = Schema,
+        get = function(a)return SV.db[Schema][a[#a]]end,
+        set = function(a,b)PLUGIN:ChangeDBVar(b,a[#a]); end,
+        args = {
+            annoyingEmotes = {
+                order = 1,
+                name = L["Annoying Emotes"],
+                desc = L["Aggravate your opponents (and team-mates) with incessant emotes"],
+                type = "toggle",
+                get = function(key) return SV.db[Schema].annoyingEmotes end,
+                set = function(key,value) PLUGIN:ChangeDBVar(value, key[#key]); end
+            }
+        }
+    }
+end
\ No newline at end of file
diff --git a/SVUI_FightOMatic/SVUI_FightOMatic.lua b/SVUI_FightOMatic/SVUI_FightOMatic.lua
new file mode 100644
index 0000000..df51313
--- /dev/null
+++ b/SVUI_FightOMatic/SVUI_FightOMatic.lua
@@ -0,0 +1,1217 @@
+--[[
+##########################################################
+S V U I   By: S.Jackson
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+
+--[[ GLOBALS ]]--
+
+local _G = _G;
+local unpack    = _G.unpack;
+local select    = _G.select;
+local pairs     = _G.pairs;
+local ipairs    = _G.ipairs;
+local type      = _G.type;
+local error     = _G.error;
+local pcall     = _G.pcall;
+local assert    = _G.assert;
+local tostring  = _G.tostring;
+local tonumber  = _G.tonumber;
+local collectgarbage    = _G.collectgarbage;
+local string 	= _G.string;
+local math 		= _G.math;
+local table 	= _G.table;
+local bit       = _G.bit;
+local time      = _G.time;
+--[[ STRING METHODS ]]--
+local format, sub = string.format, string.sub;
+--[[ MATH METHODS ]]--
+local abs, ceil, floor, round, random = math.abs, math.ceil, math.floor, math.round, math.random;
+--[[ TABLE METHODS ]]--
+local tremove, wipe = table.remove, table.wipe;
+--[[ BINARY METHODS ]]--
+local band, bor = bit.band, bit.bor;
+--BLIZZARD API
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+local GameTooltip           = _G.GameTooltip;
+local hooksecurefunc        = _G.hooksecurefunc;
+local IsSpellKnown      	= _G.IsSpellKnown;
+local GetSpellInfo      	= _G.GetSpellInfo;
+local IsAltKeyDown          = _G.IsAltKeyDown;
+local IsShiftKeyDown        = _G.IsShiftKeyDown;
+local IsControlKeyDown      = _G.IsControlKeyDown;
+local IsModifiedClick       = _G.IsModifiedClick;
+local PlaySound             = _G.PlaySound;
+local PlaySoundFile         = _G.PlaySoundFile;
+local UnitName              = _G.UnitName;
+local UnitLevel             = _G.UnitLevel;
+local UnitClass             = _G.UnitClass;
+local UnitExists            = _G.UnitExists;
+local UnitIsUnit            = _G.UnitIsUnit;
+local UnitGUID              = _G.UnitGUID;
+local UnitIsDead            = _G.UnitIsDead;
+local UnitIsPlayer          = _G.UnitIsPlayer;
+local UnitIsFriend          = _G.UnitIsFriend;
+local UnitIsEnemy           = _G.UnitIsEnemy;
+local DoEmote           	= _G.DoEmote;
+local SendChatMessage       = _G.SendChatMessage;
+local GetZoneText           = _G.GetZoneText;
+local GetZonePVPInfo        = _G.GetZonePVPInfo;
+local GetRealZoneText       = _G.GetRealZoneText;
+local CombatLog_Object_IsA  = _G.CombatLog_Object_IsA;
+local ERR_NOT_IN_COMBAT     = _G.ERR_NOT_IN_COMBAT;
+local RAID_CLASS_COLORS     = _G.RAID_CLASS_COLORS;
+local CUSTOM_CLASS_COLORS   = _G.CUSTOM_CLASS_COLORS;
+--[[  CONSTANTS ]]--
+
+_G.BINDING_HEADER_SVUIFIGHT = "Supervillain UI: Fight-O-Matic";
+_G.BINDING_NAME_SVUIFIGHT_RADIO = "Call Out Incoming";
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G["SVUI"];
+local L = SV.L;
+local PLUGIN = select(2, ...)
+local CONFIGS = SV.defaults[PLUGIN.Schema];
+
+local NewHook = hooksecurefunc;
+local RadioSound = SV.Sounds:Blend("Static", "Sparks");
+--[[
+##########################################################
+GLOBAL SLASH FUNCTIONS
+##########################################################
+]]--
+_G.SVUISayIncoming = function()
+	local subzoneText = GetSubZoneText()
+	local msg = ("{rt8} Incoming %s {rt8}"):format(subzoneText)
+	SendChatMessage(msg, "INSTANCE_CHAT")
+	return
+end
+--[[
+##########################################################
+MUNGLUNCH's FAVORITE EMOTE GENERATOR
+##########################################################
+]]--
+local SpecialEmotes = {
+	"ROFL",
+	"CACKLE",
+	"GIGGLE",
+	"GRIN",
+	"SMIRK",
+	"MOON",
+	"LICK",
+	"YAWN",
+	"FLEX",
+	"TICKLE",
+	"TAUNT",
+	"SHOO",
+	"PRAY",
+	"SPIT",
+	"MOCK",
+	"GLOAT",
+	"PITY",
+	"VIOLIN",
+	"BYE",
+}
+
+local LowHealthPlayerEmotes = {
+	"ROFL",
+	"CACKLE",
+	"GIGGLE",
+	"GRIN",
+	"SMIRK",
+	"MOON",
+	"LICK",
+	"YAWN",
+	"BITE",
+	"NOSEPICK"
+}
+
+local LowHealthTargetEmotes = {
+	"ROFL",
+	"CACKLE",
+	"FLEX",
+	"TICKLE",
+	"TAUNT",
+	"SHOO",
+	"PRAY",
+	"SPIT",
+	"MOCK",
+	"GLOAT",
+	"PITY",
+	"VIOLIN",
+	"BYE",
+}
+
+local KOSEmotes = {
+	"THREATEN",
+	"CRACK",
+	"POINT",
+	"GRIN",
+	"SMIRK",
+	"TAUNT",
+	"CHICKEN"
+}
+
+local StealthEmotes = {
+	"CURIOUS",
+	"EYE",
+	"GASP",
+	"GAZE",
+	"MOCK",
+	"NOSEPICK",
+	"PEER",
+	"POINT",
+	"READY",
+	"STARE",
+	"TAP",
+}
+
+
+_G.SVUIEmote = function()
+	local index = random(1,#SpecialEmotes)
+	DoEmote(SpecialEmotes[index])
+end
+
+local function LowHealth_PlayerEmote()
+	local index = random(1,#LowHealthPlayerEmotes)
+	DoEmote(LowHealthPlayerEmotes[index])
+end
+
+local function LowHealth_TargetEmote()
+	local index = random(1,#LowHealthTargetEmotes)
+	DoEmote(LowHealthTargetEmotes[index])
+end
+
+local function KOS_Emote()
+	local index = random(1,#KOSEmotes)
+	DoEmote(KOSEmotes[index])
+end
+
+local function Stealth_Emote(name)
+	local index = random(1,#StealthEmotes)
+	DoEmote(StealthEmotes[index], name)
+end
+--[[
+##########################################################
+VARS
+##########################################################
+]]--
+local EnemyCache, AlertedCache = {},{}
+
+local playerGUID = UnitGUID('player')
+local playerFaction = UnitFactionGroup("player")
+local classColor = RAID_CLASS_COLORS
+local classColors = CUSTOM_CLASS_COLORS[SV.class]
+local classR, classG, classB = classColors.r, classColors.g, classColors.b
+local classA = 0.35
+local fallbackColor = {r=1,g=1,b=1}
+local ACTIVE_ZONE = ""
+--[[ ICONS ]]--
+local INFO_ICON = [[Interface\AddOns\SVUI_FightOMatic\artwork\PVP-INFO]]
+local UTILITY_ICON = [[Interface\AddOns\SVUI_FightOMatic\artwork\PVP-UTILITIES]]
+local RADIO_ICON = [[Interface\AddOns\SVUI_FightOMatic\artwork\PVP-RADIO]]
+local SCANNER_ICON = [[Interface\AddOns\SVUI_FightOMatic\artwork\PVP-SCANNER]]
+local ICON_FILE = [[Interface\AddOns\SVUI_FightOMatic\artwork\DOCK-PVP]]
+local PVP_SAFE = [[Interface\AddOns\SVUI_FightOMatic\artwork\PVP-SAFE]]
+local PVP_HELP = [[Interface\AddOns\SVUI_FightOMatic\artwork\PVP-INCOMING]]
+local PVP_LOST = [[Interface\WorldMap\Skull_64Red]]
+local linkString = "|Hplayer:%s:1|h%s|h"
+--[[ BG MAP DATA ]]--
+local PVP_NODES = {
+	[461] = { --Arathi Basin (5)
+		"Stables", "Lumber", "Blacksmith", "Mine", "Farm"
+	},
+	[935] = { --Deepwind Gorge (3)
+		"Center Mine", "North Mine", "South Mine"
+	},
+	[482] = { --Eye of the Storm (4)
+		"Fel Reaver", "Blood Elf", "Draenei", "Mage"
+	},
+	[736] = { --The Battle for Gilneas (3)
+		"LightHouse", "WaterWorks", "Mines"
+	},
+}
+
+-- local PVP_POI = {
+-- 	[401] = { --Alterac Valley (15)
+-- 		"Stormpike Aid Station", "Dun Baldar North Bunker", "Dun Baldar South Bunker",
+-- 		"Stormpike Graveyard", "Icewing Bunker", "Stonehearth Graveyard",
+-- 		"Stonehearth Bunker", "Snowfall Graveyard", "Iceblood Tower",
+-- 		"Iceblood Graveyard", "Tower Point", "Frostwolf Graveyard",
+-- 		"West Frostwolf Tower", "East Frostwolf Tower", "Frostwolf Relief Hut"
+-- 	},
+-- 	[935] = { --Deepwind Gorge (2)
+-- 		"Horde Cart", "Alliance Cart"
+-- 	},
+-- 	[482] = { --Eye of the Storm (1)
+-- 		"Flag"
+-- 	},
+-- 	[860] = { --Silvershard Mines (1)
+-- 		"Cart"
+-- 	},
+-- 	[512] = { --Strand of the Ancients (5)
+-- 		"Green Emerald", "Blue Sapphire", "Purple Amethyst", "Red Sun", "Yellow Moon"
+-- 	},
+-- 	[540] = { --Isle of Conquest (5)
+-- 		"Quarry", "Hangar", "Workshop", "Docks", "Refinery"
+-- 	},
+-- 	[856] = { --Temple of Kotmogu (4)
+-- 		"Red Orb", "Blue Orb", "Orange Orb", "Purple Orb"
+-- 	},
+-- 	[626] = { --Twin Peaks (2)
+-- 		"Horde Flag", "Alliance Flag"
+-- 	},
+-- 	[443] = { --Warsong Gulch (2)
+-- 		"Horde Flag", "Alliance Flag"
+-- 	},
+-- }
+
+local Safe_OnEnter = function(self)
+	if InCombatLockdown() then return end
+	local zone = self.name
+	if(zone and zone ~= "") then
+		self:SetBackdropBorderColor(1,0.45,0)
+		GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT", 0, 4)
+		GameTooltip:ClearLines()
+		GameTooltip:AddLine(("%s Is Safe!"):format(zone), 1, 1, 1)
+		GameTooltip:Show()
+	end
+end
+
+local Safe_OnLeave = function(self)
+	if InCombatLockdown() then return end
+	self:SetBackdropBorderColor(0,0,0)
+	if(GameTooltip:IsShown()) then GameTooltip:Hide() end
+end
+
+local Safe_OnClick = function(self)
+	local zone = self.name
+	if(zone and zone ~= "") then
+		SendChatMessage(("{rt4} %s Is Safe {rt4}"):format(zone), "INSTANCE_CHAT")
+	end
+end
+
+local Help_OnEnter = function(self)
+	if InCombatLockdown() then return end
+	local zone = self.name
+	if(zone and zone ~= "") then
+		self:SetBackdropBorderColor(1,0.45,0)
+		GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT", 0, 4)
+		GameTooltip:ClearLines()
+		GameTooltip:AddLine(("%s Needs Help!"):format(zone), 1, 1, 1)
+		GameTooltip:Show()
+	end
+end
+
+local Help_OnLeave = function(self)
+	if InCombatLockdown() then return end
+	self:SetBackdropBorderColor(0,0,0)
+	if(GameTooltip:IsShown()) then GameTooltip:Hide() end
+end
+
+local Help_OnClick = function(self)
+	if(self.name and self.name ~= "") then
+		local msg = ("{rt8} Incoming %s {rt8}"):format(self.name)
+		SendChatMessage(msg, "INSTANCE_CHAT")
+	end
+end
+
+local function AddEnemyScan(guid, timestamp)
+	if(EnemyCache[guid]) then
+		return EnemyCache[guid]
+	end
+	local class, classToken, race, raceToken, sex, name, realm = GetPlayerInfoByGUID(guid)
+	local colors = classColor[classToken] or fallbackColor
+	EnemyCache[guid] = {
+        ["name"] = name,
+        ["realm"] = realm,
+        ["class"] = class,
+        ["race"] = race,
+        ["sex"] = sex,
+        ["colors"] = colors,
+        ["time"] = timestamp
+    }
+    PLUGIN:ScannerLog(EnemyCache[guid])
+    return EnemyCache[guid];
+end
+
+local function SaveEnemyScan(guid, timestamp)
+	local enemy = EnemyCache[guid]
+	if(not enemy) then enemy = AddEnemyScan(guid, timestamp) end
+	PLUGIN.public[guid] = {
+        ["name"] = enemy.name,
+        ["realm"] = enemy.realm,
+        ["class"] = enemy.class,
+        ["race"] = enemy.race,
+        ["sex"] = enemy.sex,
+        ["colors"] = enemy.colors,
+        ["time"] = enemy.timestamp
+    }
+    local msg = ("Killed By: %s"):format(enemy.name);
+    SV:SCTMessage(msg, enemy.colors.r, enemy.colors.g, enemy.colors.b, "sticky");
+    PLUGIN:UpdateSummary()
+end
+
+local function KilledEnemyHandler(guid)
+	local enemy = PLUGIN.public[guid]
+	if(enemy and enemy.name) then
+		SV:SCTMessage(("Killed Mortal Enemy: %s"):format(enemy.name), 0.2, 1, 0.1, "sticky");
+	end
+	enemy = EnemyCache[guid]
+	if(enemy) then
+		SV:SCTMessage(("Killed Enemy: %s"):format(enemy.name), 0.1, 0.8, 0);
+	end
+end
+
+local function ClearCacheScans()
+	wipe(EnemyCache)
+	wipe(AlertedCache)
+	if(PLUGIN.LOG and PLUGIN.LOG.Output) then PLUGIN.LOG.Output:Clear() end
+end
+
+local function ClearSavedScans()
+	wipe(PLUGIN.public)
+end
+
+local function EnemyAlarm(name, class, colors, kos)
+	if not name then return end
+	local inInstance, instanceType = IsInInstance()
+	if(instanceType ~= "pvp" and not AlertedCache[name]) then
+		local msg
+		if(kos) then
+			msg = ("Mortal Enemy Detected!: %s"):format(name);
+			SV:SCTMessage(msg, 1, 0, 0)
+		elseif(class and colors) then
+			msg = ("%s Detected"):format(class);
+			SV:SCTMessage(msg, colors.r, colors.g, colors.b)
+	    end
+	    AlertedCache[name] = true
+	end
+end
+
+local function StealthAlarm(spell, name)
+	local msg = ("%s Detected!"):format(spell);
+    SV:SCTMessage(msg, 1, 0.5, 0);
+    print(("%s has %sed nearby!"):format(name, spell))
+    if(CONFIGS.annoyingEmotes) then
+    	Stealth_Emote(name)
+    end
+end
+
+local function PopulateScans()
+	PLUGIN.Title:Clear();
+	PLUGIN.Summary:Clear();
+	PLUGIN.LOG.Output:Clear();
+	PLUGIN.Title:AddMessage(("Scanning %s"):format(ACTIVE_ZONE), 1, 1, 0);
+	PLUGIN.Switch:Show()
+	local stored = PLUGIN.public;
+	local amount = 0
+	for _,data in pairs(stored) do
+		if type(data) == "table" and data.name and data.class then
+			amount = amount + 1;
+		end
+	end
+	PLUGIN.Summary:AddMessage(("You Have |cffff5500%s|r Mortal Enemies"):format(amount), 0.8, 0.8, 0.8);
+	local hasScans = false;
+	for _,data in pairs(EnemyCache) do
+		if type(data) == "table" and data.name and data.class and data.race then
+			local nameLink = linkString:format(data.name, data.name)
+			local hex = ("%s - %s %s"):format(nameLink, data.race, data.class)
+			PLUGIN.LOG.Output:AddMessage(hex, data.colors.r, data.colors.g, data.colors.b);
+			hasScans = true;
+		end
+	end
+end
+
+local function PopulateRadio()
+	PLUGIN.Title:Clear();
+	PLUGIN.Summary:Clear();
+	PLUGIN.LOG.Output:Clear();
+	PLUGIN.Switch:Hide();
+	PLUGIN.Title:AddMessage('Radio Communicator', 1, 1, 0);
+end
+
+local function PopulateStats()
+	PLUGIN.Title:Clear();
+	PLUGIN.Summary:Clear();
+	PLUGIN.LOG.Output:Clear();
+	PLUGIN.Switch:Hide();
+	PLUGIN.Title:AddMessage('PvP Stats', 1, 1, 0);
+end
+
+local function PopulateMisc()
+	PLUGIN.Title:Clear();
+	PLUGIN.Summary:Clear();
+	PLUGIN.LOG.Output:Clear();
+	PLUGIN.Switch:Hide();
+	PLUGIN.Title:AddMessage('Misc', 1, 1, 0);
+end
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+function PLUGIN:UpdateSummary()
+	self.Summary:Clear();
+	local stored = self.public;
+	local amount = 0
+	for _,data in pairs(stored) do
+		if type(data) == "table" and data.name and data.class then
+			amount = amount + 1;
+		end
+	end
+	self.Summary:AddMessage(("You Have |cffff5500%s|r Mortal Enemies"):format(amount), 0.8, 0.8, 0.8);
+end
+
+function PLUGIN:ResetLogs()
+	wipe(EnemyCache)
+	self.Title:Clear();
+	self.Summary:Clear();
+	self.LOG.Output:Clear();
+	self.Title:AddMessage(("Scanning %s"):format(ACTIVE_ZONE), 1, 1, 0);
+	self.Switch:Show()
+	local stored = self.public;
+	local amount = 0
+	for _,data in pairs(stored) do
+		if type(data) == "table" and data.name and data.class then
+			amount = amount + 1;
+		end
+	end
+	self.Summary:AddMessage(("You Have |cffff5500%s|r Mortal Enemies"):format(amount), 0.8, 0.8, 0.8)
+	collectgarbage("collect")
+end
+
+function PLUGIN:PopulateKOS()
+	self.Title:Clear();
+	self.Summary:Clear();
+	self.LOG.Output:Clear();
+	self.Title:AddMessage(("Scanning %s"):format(ACTIVE_ZONE), 1, 1, 0);
+	self.Switch:Show()
+	local stored = self.public;
+	local amount = 0
+	for _,data in pairs(stored) do
+		if type(data) == "table" and data.name and data.class and data.race then
+			amount = amount + 1;
+			local nameLink = linkString:format(data.name, data.name)
+			local hex = ("%s - %s %s"):format(nameLink, data.race, data.class)
+			self.LOG.Output:AddMessage(hex, data.colors.r, data.colors.g, data.colors.b);
+		end
+	end
+	self.Summary:AddMessage(("You Have |cffff5500%s|r Mortal Enemies"):format(amount), 0.8, 0.8, 0.8)
+end
+
+function PLUGIN:PauseScanner()
+	if(not self.InPVP) then
+		self.Title:Clear();
+		self.Summary:Clear();
+		self.LOG.Output:Clear();
+		self.Title:AddMessage("Scanning Paused", 1, 0.1, 0);
+		self.Summary:AddMessage(ACTIVE_ZONE, 1, 0.75, 0);
+		self.Switch:Hide()
+		self.LOG.Output:AddMessage(" ", 1, 1, 1);
+		self.LOG.Output:AddMessage(" ", 1, 1, 1);
+		self.LOG.Output:AddMessage("The Enenmy Scanner Will Resume", 0.8, 0.8, 0.8);
+		self.LOG.Output:AddMessage("When You Leave This BattleGround", 0.8, 0.8, 0.8);
+	else
+		PopulateScans()
+	end
+end
+
+function PLUGIN:ScannerLog(enemy)
+	if(not enemy.name or not enemy.race or not enemy.class) then return end
+    local nameLink = linkString:format(enemy.name, enemy.name)
+	local hex = ("%s - %s %s"):format(nameLink, enemy.race, enemy.class)
+	self.LOG.Output:AddMessage(hex, enemy.colors.r, enemy.colors.g, enemy.colors.b);
+	EnemyAlarm(enemy.name, enemy.class, enemy.colors)
+end
+
+function PLUGIN:UpdateCommunicator()
+	self.COMM.Unavailable:Hide()
+	if(self.InPVP) then
+		self.COMM.Unavailable:Show()
+		for i = 1, 5 do
+			local nodeName = ("SVUI_PVPNode%d"):format(i)
+			local node = _G[nodeName]
+			local safe = node.Safe
+			local help = node.Help
+			safe.name = ""
+			help.name = ""
+			node.Text:SetText("")
+			node:Hide()
+		end
+		self.InPVP = nil
+		self:RegisterEvent("UPDATE_BATTLEFIELD_SCORE")
+		self.Scanning = true
+		PopulateScans()
+	else
+		local mapID = GetCurrentMapAreaID()
+		if(mapID) then
+			local points = PVP_NODES[mapID]
+			if(points) then
+				for i = 1, 5 do
+					local nodeName = ("SVUI_PVPNode%d"):format(i)
+					local node = _G[nodeName]
+					local safe = node.Safe
+					local help = node.Help
+					if(i <= #points) then
+						local name = points[i]
+						safe.name = name
+						help.name = name
+						node.Text:SetText(name)
+						node:Show()
+					else
+						safe.name = ""
+						help.name = ""
+						node.Text:SetText("")
+						node:Hide()
+					end
+				end
+				self.InPVP = true
+				self:UnregisterEvent("UPDATE_BATTLEFIELD_SCORE")
+				self.Scanning = false
+				self:PauseScanner()
+			end
+		end
+	end
+end
+
+function PLUGIN:UpdateZoneStatus()
+	if PLUGIN.ZoneTimer then return end
+	local zoneText = GetRealZoneText() or GetZoneText()
+	if(not zoneText or zoneText == "") then
+		PLUGIN.ZoneTimer = SV.Timers:ExecuteTimer(PLUGIN.UpdateZoneStatus, 5)
+		return
+	end
+	if(zoneText ~= ACTIVE_ZONE) then
+		ClearCacheScans()
+		ACTIVE_ZONE = zoneText
+		PLUGIN.Title:Clear();
+		PLUGIN.Title:AddMessage(("Scanning %s"):format(ACTIVE_ZONE), 1, 1, 0);
+	end
+	local zonePvP = GetZonePVPInfo()
+	if(zonePvP == "sanctuary" or zoneText == "") then
+		PLUGIN.Scanning = false
+	else
+		PLUGIN.Scanning = true
+		local inInstance, instanceType = IsInInstance()
+		if(inInstance and ((instanceType == "party") or (instanceType == "raid"))) then
+			PLUGIN.Scanning = false
+		elseif (not zonePvP or (zonePvP == "friendly") or (not UnitIsPVP("player"))) then
+			PLUGIN.Scanning = false
+		elseif(instanceType == "pvp") then
+			PLUGIN:PauseScanner()
+			PLUGIN.Scanning = false
+			if(not PLUGIN.InPVP) then
+				PLUGIN:UpdateCommunicator()
+			end
+		end
+	end
+	PLUGIN.ZoneTimer = nil
+end
+
+local function ParseIncomingLog(timestamp, event, eGuid, eName, pGuid)
+	local cached;
+	local kos, needsUpdate = false, false
+
+	if(PLUGIN.public[eGuid]) then
+		cached = PLUGIN.public[eGuid]
+		kos = true
+	else
+		cached = EnemyCache[eGuid]
+	end
+
+	if(cached and cached.time) then
+		needsUpdate = (cached.time + 60) < timestamp;
+	else
+		cached = AddEnemyScan(eGuid, timestamp)
+		needsUpdate = true
+	end
+
+	if(cached) then
+		if(needsUpdate) then
+			EnemyAlarm(eName, cached.class, cached.colors, kos)
+			cached.time = timestamp
+		end
+
+		if(pGuid == playerGUID and not AlertedCache[eName]) then
+			AlertedCache[eName] = true
+			local incoming = ("%s Attacking You!"):format(eName);
+			SV:SCTMessage(incoming, 1, 0.05, 0, "crit")
+		end
+	end
+end
+
+local function CheckSourceType(guid, flags)
+	if not guid then return end
+	local isHostile = false;
+	if(flags) then
+		isHostile = CombatLog_Object_IsA(flags, COMBATLOG_FILTER_HOSTILE_PLAYERS)
+	end
+	local srcType = guid:sub(1,6)
+	if((srcType == "Player") and (isHostile == true)) then
+		return true
+	end
+	return false
+end
+
+function PLUGIN:COMBAT_LOG_EVENT_UNFILTERED(_, timestamp, event, _, srcGUID, srcName, srcFlags, sourceRaidFlags, dstGUID, dstName, dstFlags, destRaidFlags, _, spellName)
+	if not srcFlags then return end
+	local flagParse = band(srcFlags, COMBATLOG_OBJECT_REACTION_HOSTILE)
+	local flagged = flagParse == COMBATLOG_OBJECT_REACTION_HOSTILE
+
+	if(flagged) then
+		if(srcGUID and srcName) then
+			if(CheckSourceType(srcGUID, srcFlags)) then
+				if(event == "SPELL_AURA_APPLIED" and (spellName == L["Stealth"] or spellName == L["Prowl"])) then
+					StealthAlarm(spellName, srcName)
+				end
+				if(dstGUID == playerGUID) then
+					PLUGIN.HitBy = srcGUID
+				end
+				if(not PLUGIN.Scanning) then return end
+				ParseIncomingLog(timestamp, event, srcGUID, srcName, dstGUID)
+			end
+		end
+
+		if(PLUGIN.Scanning and dstGUID and dstName) then
+			if(CheckSourceType(dstGUID, dstFlags)) then
+				ParseIncomingLog(timestamp, event, dstGUID, dstName, srcGUID)
+			end
+		end
+	end
+
+	if(PLUGIN.Scanning and event == "PARTY_KILL") then
+		if(srcGUID == playerGUID and dstName) then
+			KilledEnemyHandler(dstGUID)
+		end
+	end
+end
+
+function PLUGIN:EventDistributor(event, ...)
+	local inInstance, instanceType = IsInInstance()
+
+	if(event == "PLAYER_REGEN_ENABLED") then
+		self.HitBy = false;
+		if(instanceType == "pvp") then self.Scanning = false end
+	else
+		if(instanceType ~= "pvp") then
+			if(event == "PLAYER_TARGET_CHANGED") then
+				if(UnitIsPlayer("target") and UnitIsEnemy("target", "player")) then
+					local guid = UnitGUID("target")
+					if(not EnemyCache[guid]) then
+						local timestamp = time()
+						AddEnemyScan(guid, timestamp)
+					elseif(self.public[guid] and self.public[guid].name) then
+						--SV:SCTMessage("Kill On Sight!", 1, 0, 0, "crit")
+						if(CONFIGS.annoyingEmotes) then
+							KOS_Emote()
+						end
+					end
+				end
+			elseif(event == "PLAYER_DEAD") then
+				local guid = self.HitBy
+				if(guid and guid ~= "") then
+					local stamp = time()
+					SaveEnemyScan(guid, stamp)
+				end
+			end
+		else
+			self.Scanning = false
+		end
+	end
+end
+
+local onMouseWheel = function(self, delta)
+	if (delta > 0) then
+		self:ScrollUp()
+	elseif (delta < 0) then
+		self:ScrollDown()
+	end
+end
+
+local function MakeLogWindow()
+	local frame = CreateFrame("Frame", nil, UIParent)
+
+	frame:SetFrameStrata("MEDIUM")
+	frame:SetPoint("TOPLEFT", PLUGIN.Summary, "BOTTOMLEFT",0,0)
+	frame:SetPoint("BOTTOMRIGHT", PLUGIN.Docklet, "BOTTOMRIGHT",0,0)
+	frame:SetParent(PLUGIN.Docklet)
+
+	local output = CreateFrame("ScrollingMessageFrame", nil, frame)
+	output:SetSpacing(4)
+	output:SetClampedToScreen(false)
+	output:SetFrameStrata("MEDIUM")
+	output:SetAllPoints(frame)
+	output:SetFont(SV.media.font.dialog, 11, "OUTLINE")
+	output:SetJustifyH("CENTER")
+	output:SetJustifyV("MIDDLE")
+	output:SetShadowColor(0, 0, 0, 0)
+	output:SetMaxLines(120)
+	output:EnableMouseWheel(true)
+	output:SetHyperlinksEnabled(true)
+	output:SetScript("OnMouseWheel", onMouseWheel)
+	output:SetFading(false)
+	output:SetInsertMode('TOP')
+
+	output:SetScript("OnHyperlinkEnter", function(self, linkData, link, button)
+		local t = link:explode(":")
+		local name = t[2] or ""
+	    SVUI_TargetScanButton:SetAttribute("macrotext", ("/tar %s"):format(name))
+	    SVUI_TargetScanButton:EnableMouse(true)
+	end)
+
+	frame.Output = output
+
+	PLUGIN.LOG = frame
+
+	return PLUGIN.LOG
+end
+
+local function MakeCommWindow()
+
+	local frame = CreateFrame("Frame", nil, UIParent)
+
+	frame:SetFrameStrata("MEDIUM")
+	frame:SetPoint("TOPLEFT", PLUGIN.Summary, "BOTTOMLEFT",0,0)
+	frame:SetPoint("BOTTOMRIGHT", PLUGIN.Docklet, "BOTTOMRIGHT",0,0)
+	frame:SetParent(PLUGIN.Docklet)
+
+	local fallback = CreateFrame("Frame", nil, frame)
+	fallback:SetAllPoints(frame)
+
+	local fbText = fallback:CreateFontString(nil, "OVERLAY")
+	fbText:SetAllPoints(fallback)
+	fbText:SetFont(SV.media.font.default, 12, "NONE")
+	fbText:SetText("Nothing To Broadcast Right Now")
+
+	frame.Unavailable = fallback
+
+	local DOCK_WIDTH = frame:GetWidth() or PLUGIN.Docklet:GetWidth();
+	local DOCK_HEIGHT = frame:GetHeight() or PLUGIN.Docklet:GetHeight();
+	local BUTTON_SIZE = (DOCK_HEIGHT * 0.25) - 4;
+	local sectionWidth = 28
+	local sectionHeight = 22
+	local iconSize = sectionHeight * 0.5
+
+	for i = 1, 5 do
+		local yOffset = (sectionHeight * (i - 1)) + 2
+
+		local poiName = ("SVUI_PVPNode%d"):format(i)
+		local poi = CreateFrame("Frame", poiName, frame)
+		poi:SetPoint("TOPLEFT", frame, "TOPLEFT", 2, -yOffset)
+		poi:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -2, -yOffset)
+		poi:SetHeight(22)
+		poi:SetStyle("Transparent")
+
+		local safe = CreateFrame("Button", nil, poi)
+		safe:SetSize(sectionWidth, sectionHeight)
+		safe:SetPoint("RIGHT", poi, "RIGHT", -2, 0)
+		safe:SetStyle()
+		safe:SetPanelColor("green")
+		local sicon = safe:CreateTexture(nil, "OVERLAY")
+		sicon:SetPoint("CENTER", safe, "CENTER", 0, 0)
+		sicon:SetSize(iconSize,iconSize)
+		sicon:SetTexCoord(0.1, 0.9, 0.1, 0.9)
+		sicon:SetTexture(PVP_SAFE)
+		safe:SetScript("OnEnter", Safe_OnEnter)
+		safe:SetScript("OnLeave", Safe_OnLeave)
+		safe:SetScript("OnClick", Safe_OnClick)
+
+		poi.Safe = safe
+
+		local help = CreateFrame("Button", nil, poi)
+		help:SetSize(sectionWidth, sectionHeight)
+		help:SetPoint("RIGHT", safe, "LEFT", -2, 0)
+		help:SetStyle()
+		help:SetPanelColor("red")
+		local hicon = help:CreateTexture(nil, "OVERLAY")
+		hicon:SetPoint("CENTER", help, "CENTER", 0, 0)
+		hicon:SetSize(iconSize,iconSize)
+		hicon:SetTexCoord(0.1, 0.9, 0.1, 0.9)
+		hicon:SetTexture(PVP_HELP)
+		help:SetScript("OnEnter", Help_OnEnter)
+		help:SetScript("OnLeave", Help_OnLeave)
+		help:SetScript("OnClick", Help_OnClick)
+
+		poi.Help = help
+
+		poi.Text = poi:CreateFontString(nil,"OVERLAY")
+		poi.Text:SetFont(SV.media.font.default, 12, "NONE")
+		poi.Text:SetPoint("TOPLEFT", poi, "TOPLEFT", 2, 0)
+		poi.Text:SetPoint("BOTTOMRIGHT", help, "BOTTOMLEFT", -2, 0)
+		poi.Text:SetJustifyH("CENTER")
+		poi.Text:SetText("")
+		poi:Hide()
+	end
+
+	PLUGIN.COMM = frame
+	PLUGIN.COMM:Hide()
+
+	return PLUGIN.COMM
+end
+
+local function MakeUtilityWindow()
+	local frame = CreateFrame("Frame", nil, UIParent)
+
+	frame:SetFrameStrata("MEDIUM")
+	frame:SetPoint("TOPLEFT", PLUGIN.Summary, "BOTTOMLEFT",0,0)
+	frame:SetPoint("BOTTOMRIGHT", PLUGIN.Docklet, "BOTTOMRIGHT",0,0)
+	frame:SetParent(PLUGIN.Docklet)
+
+	local fbText = frame:CreateFontString(nil, "OVERLAY")
+	fbText:SetAllPoints(frame)
+	fbText:SetFont(SV.media.font.default, 12, "NONE")
+	fbText:SetText("Utilities Coming Soon....")
+
+	PLUGIN.MISC = frame
+	PLUGIN.MISC:Hide()
+	return PLUGIN.MISC
+end
+
+local function MakeInfoWindow()
+	local frame = CreateFrame("Frame", nil, UIParent)
+
+	frame:SetFrameStrata("MEDIUM")
+	frame:SetPoint("TOPLEFT", PLUGIN.Summary, "BOTTOMLEFT",0,0)
+	frame:SetPoint("BOTTOMRIGHT", PLUGIN.Docklet, "BOTTOMRIGHT",0,0)
+	frame:SetParent(PLUGIN.Docklet)
+
+	local DATA_WIDTH = (frame:GetWidth() * 0.5) - 2;
+	local DATA_HEIGHT = frame:GetHeight() - 2;
+
+	local leftColumn = CreateFrame("Frame", "SVUI_FightOMaticInfoLeft", frame)
+	leftColumn:SetSize(DATA_WIDTH, DATA_HEIGHT)
+	leftColumn:SetPoint("LEFT", frame, "LEFT", 0, 0)
+	leftColumn.lockedOpen = true
+	SV.Reports:NewHolder(leftColumn, 3, "ANCHOR_CURSOR", 1, "Transparent")
+	leftColumn:SetFrameLevel(0)
+
+	local rightColumn = CreateFrame("Frame", "SVUI_FightOMaticInfoRight", frame)
+	rightColumn:SetSize(DATA_WIDTH, DATA_HEIGHT)
+	rightColumn:SetPoint("LEFT", leftColumn, "RIGHT", 2, 0)
+	rightColumn.lockedOpen = true
+	SV.Reports:NewHolder(rightColumn, 3, "ANCHOR_CURSOR", 2, "Transparent")
+	rightColumn:SetFrameLevel(0)
+
+	PLUGIN.INFO = frame
+	SV.Reports:UpdateAllReports()
+	PLUGIN.INFO:Hide()
+	return PLUGIN.INFO
+end
+--[[
+##########################################################
+DOCK ELEMENT HANDLERS
+##########################################################
+]]--
+local FightOMaticAlert_OnEnter = function(self)
+	if InCombatLockdown() then return; end
+	self:SetBackdropColor(0.9, 0.15, 0.1)
+	GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT", 0, 4)
+	GameTooltip:ClearLines()
+	GameTooltip:AddLine(self.TText, 1, 1, 0)
+	GameTooltip:Show()
+end
+
+local FightOMaticAlert_OnLeave = function(self)
+	GameTooltip:Hide()
+	if InCombatLockdown() then return end
+	self:SetBackdropColor(0.25, 0.52, 0.1)
+end
+
+local FightOMaticAlert_OnHide = function()
+	if InCombatLockdown() then
+		SV:AddonMessage(ERR_NOT_IN_COMBAT);
+		return;
+	end
+	SV.Dock.BottomRight.Alert:Deactivate()
+end
+
+local FightOMaticAlert_OnShow = function(self)
+	if InCombatLockdown() then
+		SV:AddonMessage(ERR_NOT_IN_COMBAT);
+		self:Hide()
+		return;
+	end
+	self:FadeIn(0.3, 0, 1)
+	SV.Dock.BottomRight.Alert:Activate(self)
+end
+
+local FightOMaticAlert_OnMouseDown = function(self)
+	-- DO STUFF
+	self:FadeOut(0.5, 1, 0, true)
+end
+
+local FightOMaticTool_OnEnter = function(self)
+	if InCombatLockdown() then return; end
+	self.icon:SetGradient(unpack(SV.media.gradient.yellow))
+	GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT", 0, 4)
+	GameTooltip:ClearLines()
+	GameTooltip:AddLine(self.TText, 1, 1, 1)
+	GameTooltip:Show()
+end
+
+local FightOMaticTool_OnLeave = function(self)
+	if InCombatLockdown() then return; end
+	self.icon:SetGradient(unpack(SV.media.gradient[self.currentColor]))
+	GameTooltip:Hide()
+end
+
+local FightOMaticTool_OnMouseDown = function(self)
+	RadioSound()
+	PLUGIN.LOG:FadeOut(0.5, 1, 0, true)
+	PLUGIN.COMM:FadeOut(0.5, 1, 0, true)
+	PLUGIN.MISC:FadeOut(0.5, 1, 0, true)
+	PLUGIN.INFO:FadeOut(0.5, 1, 0, true)
+	self.Window:FadeIn(0.3, 0, 1);
+	for key,button in pairs(PLUGIN.ToolBar.Buttons) do
+		if(key == self.TText) then
+			button.currentColor = "highlight";
+			button.icon:SetGradient(unpack(SV.media.gradient.highlight))
+			button:SetAlpha(1)
+		else
+			button.currentColor = "icon";
+			button.icon:SetGradient(unpack(SV.media.gradient.icon))
+			button:SetAlpha(0.5)
+		end
+	end
+	self.Activate();
+end
+
+local Switch_OnEnter = function(self)
+	GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT", 0, 4)
+	GameTooltip:ClearLines()
+	if(self.ShowingKOS) then
+		GameTooltip:AddDoubleLine("Click", "Show Scan List", 0.1, 1, 0.2, 1, 1, 1)
+	else
+		GameTooltip:AddDoubleLine("Click", 'Show "Kill On Sight" List', 0.1, 1, 0.2, 1, 1, 1)
+	end
+	GameTooltip:AddDoubleLine("[SHIFT] Click", "Clear All Scans", 0.1, 1, 0.2, 1, 1, 1)
+	GameTooltip:AddDoubleLine("[CTRL] Click", 'Clear All "Kill On Sight"', 0.1, 1, 0.2, 1, 1, 1)
+	GameTooltip:Show()
+end
+
+local Switch_OnLeave = function(self)
+	GameTooltip:Hide()
+end
+
+local Switch_OnClick = function(self, button)
+	Switch_OnLeave(self)
+	if(IsControlKeyDown()) then
+		ClearSavedScans()
+		PLUGIN:ResetLogs()
+	elseif(IsShiftKeyDown()) then
+		ClearCacheScans()
+	else
+		if(self.ShowingKOS) then
+			PopulateScans()
+			self.ShowingKOS = false
+		else
+			PLUGIN:PopulateKOS()
+			self.ShowingKOS = true
+		end
+	end
+	Switch_OnEnter(self)
+end
+--[[
+##########################################################
+SIZING CALLBACK
+##########################################################
+]]--
+local function ResizeFightDock()
+	local DOCK_HEIGHT = PLUGIN.Docklet.Parent.Window:GetHeight();
+	SVUI_FightOMaticToolBar:SetHeight(DOCK_HEIGHT);
+end
+--[[
+##########################################################
+BUILD FUNCTION
+##########################################################
+]]--
+function PLUGIN:Load()
+	CONFIGS = SV.db[self.Schema];
+	self.public = self.public or {}
+
+	local ALERT_HEIGHT = 60;
+	local DOCK_WIDTH = SV.Dock.BottomRight.Window:GetWidth();
+	local DOCK_HEIGHT = SV.Dock.BottomRight.Window:GetHeight();
+	local BUTTON_SIZE = (DOCK_HEIGHT * 0.25) - 4;
+
+	self.HitBy = false;
+	self.Scanning = false;
+	self.InPVP = false
+
+	self.Docklet = SV.Dock:NewDocklet("BottomRight", "SVUI_FightOMaticDock", self.TitleID, ICON_FILE)
+
+	local toolBar = CreateFrame("Frame", "SVUI_FightOMaticToolBar", self.Docklet)
+	toolBar:SetWidth(BUTTON_SIZE + 4);
+	toolBar:SetHeight((BUTTON_SIZE + 4) * 4);
+	toolBar:SetPoint("BOTTOMLEFT", self.Docklet, "BOTTOMLEFT", 0, 0);
+
+	local tbDivider = toolBar:CreateTexture(nil,"OVERLAY")
+    tbDivider:SetColorTexture(0,0,0,0.5)
+    tbDivider:SetPoint("TOPRIGHT")
+    tbDivider:SetPoint("BOTTOMRIGHT")
+    tbDivider:SetWidth(1)
+
+    local title = CreateFrame("ScrollingMessageFrame", nil, self.Docklet)
+	title:SetSpacing(4)
+	title:SetClampedToScreen(false)
+	title:SetFrameStrata("MEDIUM")
+	title:SetPoint("TOPLEFT", toolBar, "TOPRIGHT",0,0)
+	title:SetPoint("BOTTOMRIGHT", self.Docklet, "TOPRIGHT",0,-20)
+	title:SetFontObject(SVUI_Font_Header)
+	title:SetMaxLines(1)
+	title:EnableMouseWheel(false)
+	title:SetFading(false)
+	title:SetInsertMode('TOP')
+
+	local divider1 = title:CreateTexture(nil,"OVERLAY")
+    divider1:SetColorTexture(0,0,0,0.5)
+    divider1:SetPoint("BOTTOMLEFT")
+    divider1:SetPoint("BOTTOMRIGHT")
+    divider1:SetHeight(1)
+
+    self.Title = title
+
+    local listbutton = CreateFrame("Button", nil, self.Docklet)
+    listbutton:SetPoint("TOPLEFT", title, "BOTTOMLEFT",0,0)
+	listbutton:SetPoint("BOTTOMRIGHT", title, "BOTTOMRIGHT",0,-14)
+	listbutton:SetStyle("Lite")
+	listbutton.ShowingKOS = false
+	listbutton:SetScript("OnEnter", Switch_OnEnter)
+	listbutton:SetScript("OnLeave", Switch_OnLeave)
+	listbutton:SetScript("OnClick", Switch_OnClick)
+
+	self.Switch = listbutton
+
+    local summary = CreateFrame("ScrollingMessageFrame", nil, self.Docklet)
+	summary:SetSpacing(4)
+	summary:SetClampedToScreen(false)
+	summary:SetFrameStrata("MEDIUM")
+	summary:SetPoint("TOPLEFT", title, "BOTTOMLEFT",0,0)
+	summary:SetPoint("BOTTOMRIGHT", title, "BOTTOMRIGHT",0,-14)
+	summary:SetFontObject(SVUI_Font_Default)
+	summary:SetMaxLines(1)
+	summary:EnableMouse(false)
+	summary:SetFading(false)
+	summary:SetInsertMode('TOP')
+
+	self.Summary = summary
+
+	local divider2 = summary:CreateTexture(nil,"OVERLAY")
+    divider2:SetColorTexture(0,0,0,0.5)
+    divider2:SetPoint("BOTTOMLEFT")
+    divider2:SetPoint("BOTTOMRIGHT")
+    divider2:SetHeight(1)
+
+    local tool4 = CreateFrame("Frame", "SVUI_FightOMaticTool3", toolBar)
+	tool4:SetPoint("BOTTOM",toolBar,"BOTTOM",0,0)
+	tool4:SetSize(BUTTON_SIZE,BUTTON_SIZE)
+	tool4.icon = tool4:CreateTexture(nil, 'OVERLAY')
+	tool4.icon:SetTexture(UTILITY_ICON)
+	tool4.icon:InsetPoints(tool4)
+	tool4.icon:SetGradient(unpack(SV.media.gradient.icon))
+	tool4.TText = "Misc"
+	tool4.TTitle = "Tools and Utilities"
+	tool4.currentColor = "icon"
+	tool4:SetScript('OnEnter', FightOMaticTool_OnEnter)
+	tool4:SetScript('OnLeave', FightOMaticTool_OnLeave)
+	tool4:SetScript('OnMouseDown', FightOMaticTool_OnMouseDown)
+	tool4.Activate = PopulateMisc;
+	tool4.Window = MakeUtilityWindow();
+	tool4:SetAlpha(0.5);
+
+	local tool3 = CreateFrame("Frame", "SVUI_FightOMaticTool4", toolBar)
+	tool3:SetPoint("BOTTOM",tool4,"TOP",0,2)
+	tool3:SetSize(BUTTON_SIZE,BUTTON_SIZE)
+	tool3.icon = tool3:CreateTexture(nil, 'OVERLAY')
+	tool3.icon:SetTexture(INFO_ICON)
+	tool3.icon:InsetPoints(tool3)
+	tool3.icon:SetGradient(unpack(SV.media.gradient.icon))
+	tool3.TText = "Stats"
+	tool3.TTitle = "Statistics and Information"
+	tool3.currentColor = "icon"
+	tool3:SetScript('OnEnter', FightOMaticTool_OnEnter)
+	tool3:SetScript('OnLeave', FightOMaticTool_OnLeave)
+	tool3:SetScript('OnMouseDown', FightOMaticTool_OnMouseDown)
+	tool3.Activate = PopulateStats;
+	tool3.Window = MakeInfoWindow();
+	tool3:SetAlpha(0.5);
+
+	local tool2 = CreateFrame("Frame", "SVUI_FightOMaticTool2", toolBar)
+	tool2:SetPoint("BOTTOM",tool3,"TOP",0,2)
+	tool2:SetSize(BUTTON_SIZE,BUTTON_SIZE)
+	tool2.icon = tool2:CreateTexture(nil, 'OVERLAY')
+	tool2.icon:SetTexture(RADIO_ICON)
+	tool2.icon:InsetPoints(tool2)
+	tool2.icon:SetGradient(unpack(SV.media.gradient.icon))
+	tool2.TText = "Radio"
+	tool2.TTitle = "Radio Communicator"
+	tool2.currentColor = "icon"
+	tool2:SetScript('OnEnter', FightOMaticTool_OnEnter)
+	tool2:SetScript('OnLeave', FightOMaticTool_OnLeave)
+	tool2:SetScript('OnMouseDown', FightOMaticTool_OnMouseDown)
+	tool2.Activate = PopulateRadio;
+	tool2.Window = MakeCommWindow();
+	tool2:SetAlpha(0.5)
+
+	local tool1 = CreateFrame("Frame", "SVUI_FightOMaticTool1", toolBar)
+	tool1:SetPoint("BOTTOM",tool2,"TOP",0,2)
+	tool1:SetSize(BUTTON_SIZE,BUTTON_SIZE)
+	tool1.icon = tool1:CreateTexture(nil, 'OVERLAY')
+	tool1.icon:SetTexture(SCANNER_ICON)
+	tool1.icon:InsetPoints(tool1)
+	tool1.icon:SetGradient(unpack(SV.media.gradient.highlight))
+	tool1.TText = "Scanner"
+	tool1.TTitle = "Enemy Scanner"
+	tool1.currentColor = "highlight"
+	tool1:SetScript('OnEnter', FightOMaticTool_OnEnter)
+	tool1:SetScript('OnLeave', FightOMaticTool_OnLeave)
+	tool1:SetScript('OnMouseDown', FightOMaticTool_OnMouseDown)
+	tool1.Activate = PopulateScans;
+	tool1.Window = MakeLogWindow()
+
+	self.ToolBar = toolBar;
+	self.ToolBar.Buttons = {
+		["Scanner"] = tool1,
+		["Radio"] 	= tool2,
+		["Stats"] 	= tool3,
+		["Misc"] 	= tool4
+	};
+
+	self:ResetLogs()
+
+	local targetButton = CreateFrame("Button", "SVUI_TargetScanButton", UIParent, "SecureActionButtonTemplate")
+	targetButton:SetAllPoints(self.LOG)
+	targetButton:SetFrameLevel(99)
+	targetButton:RegisterForClicks("AnyUp")
+	targetButton:SetAttribute("type1", "macro")
+	targetButton:SetAttribute("macrotext", "/tar")
+	targetButton:EnableMouse(false)
+	targetButton:HookScript("OnClick", function(this) this:EnableMouse(false) end)
+
+	self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
+
+	self:RegisterEvent("PLAYER_TARGET_CHANGED", "EventDistributor")
+	self:RegisterEvent("PLAYER_REGEN_ENABLED", "EventDistributor")
+	self:RegisterEvent("PLAYER_DEAD", "EventDistributor")
+
+	self:RegisterEvent("ZONE_CHANGED", "UpdateZoneStatus")
+	self:RegisterEvent("ZONE_CHANGED_NEW_AREA", "UpdateZoneStatus")
+	self:RegisterEvent("UNIT_FACTION", "UpdateZoneStatus")
+
+	self:RegisterEvent("PLAYER_ENTERING_WORLD", "UpdateCommunicator")
+	self:RegisterEvent("UPDATE_BATTLEFIELD_SCORE", "UpdateCommunicator")
+
+	if(CONFIGS.annoyingEmotes) then
+		SVUI_Player.Health.LowAlertFunc = LowHealth_PlayerEmote
+		SVUI_Target.Health.LowAlertFunc = LowHealth_TargetEmote
+	end
+
+	SV.Events:On("DOCK_EXPANDED", ResizeFightDock, true);
+end
diff --git a/SVUI_FightOMatic/SVUI_FightOMatic.toc b/SVUI_FightOMatic/SVUI_FightOMatic.toc
new file mode 100644
index 0000000..aa3b92a
--- /dev/null
+++ b/SVUI_FightOMatic/SVUI_FightOMatic.toc
@@ -0,0 +1,17 @@
+## Interface: 60000
+## Author: S.Jackson
+## Version: 1.0.0
+## Title: |cffFF9900SVUI Plugin: |r|cffFF69B4Fight-O-Matic|r
+## Notes: Supervillain UI [|cff9911FFPvP Tools|r].
+## SavedVariables: SVUI_Public_FightOMatic
+## RequiredDeps: SVUI_!Core
+## OptionalDeps: LibSharedMedia-3.0
+## X-SVUIName: Fight-O-Matic
+## X-SVUISchema: FightOMatic
+## X-Email: munglunch@gmail.com
+## X-Website: http://www.supervillainui.com
+## X-Donate: PayPal:munglunch@gmail.com
+## X-License: All Rights Reserved
+## X-Category: Interface Enhancements
+
+SVUI_FightOMatic.xml
diff --git a/SVUI_FightOMatic/SVUI_FightOMatic.xml b/SVUI_FightOMatic/SVUI_FightOMatic.xml
new file mode 100644
index 0000000..8d209d7
--- /dev/null
+++ b/SVUI_FightOMatic/SVUI_FightOMatic.xml
@@ -0,0 +1,27 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+	<Font name="SVUI_Font_Fight" font="Fonts\ARIALN.TTF" justifyH="LEFT" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="12"/>
+        </FontHeight>
+    </Font>
+    <Font name="SVUI_Font_FightNumber" font="Fonts\skurri.ttf" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="12"/>
+        </FontHeight>
+    </Font>
+
+	<Script file='Loader.lua'/>
+	<Script file='SVUI_FightOMatic.lua'/>
+</Ui>
\ No newline at end of file
diff --git a/SVUI_FightOMatic/artwork/DOCK-PVP.blp b/SVUI_FightOMatic/artwork/DOCK-PVP.blp
new file mode 100644
index 0000000..a51de9a
Binary files /dev/null and b/SVUI_FightOMatic/artwork/DOCK-PVP.blp differ
diff --git a/SVUI_FightOMatic/artwork/PVP-INCOMING.blp b/SVUI_FightOMatic/artwork/PVP-INCOMING.blp
new file mode 100644
index 0000000..f72c045
Binary files /dev/null and b/SVUI_FightOMatic/artwork/PVP-INCOMING.blp differ
diff --git a/SVUI_FightOMatic/artwork/PVP-INFO.blp b/SVUI_FightOMatic/artwork/PVP-INFO.blp
new file mode 100644
index 0000000..112e648
Binary files /dev/null and b/SVUI_FightOMatic/artwork/PVP-INFO.blp differ
diff --git a/SVUI_FightOMatic/artwork/PVP-RADIO.blp b/SVUI_FightOMatic/artwork/PVP-RADIO.blp
new file mode 100644
index 0000000..8d38764
Binary files /dev/null and b/SVUI_FightOMatic/artwork/PVP-RADIO.blp differ
diff --git a/SVUI_FightOMatic/artwork/PVP-SAFE.blp b/SVUI_FightOMatic/artwork/PVP-SAFE.blp
new file mode 100644
index 0000000..4c84f3e
Binary files /dev/null and b/SVUI_FightOMatic/artwork/PVP-SAFE.blp differ
diff --git a/SVUI_FightOMatic/artwork/PVP-SCANNER.blp b/SVUI_FightOMatic/artwork/PVP-SCANNER.blp
new file mode 100644
index 0000000..6bcd5d3
Binary files /dev/null and b/SVUI_FightOMatic/artwork/PVP-SCANNER.blp differ
diff --git a/SVUI_FightOMatic/artwork/PVP-UTILITIES.blp b/SVUI_FightOMatic/artwork/PVP-UTILITIES.blp
new file mode 100644
index 0000000..eef0a56
Binary files /dev/null and b/SVUI_FightOMatic/artwork/PVP-UTILITIES.blp differ
diff --git a/SVUI_Inventory/LICENSE.txt b/SVUI_Inventory/LICENSE.txt
new file mode 100644
index 0000000..05ceba8
--- /dev/null
+++ b/SVUI_Inventory/LICENSE.txt
@@ -0,0 +1,31 @@
+
+The MIT License
+
+Copyright (c) 2010, Failcoder (Steve Jackson)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy
+of this software and associated documentation files (the "Software"), to
+deal
+in the Software without restriction, including without limitation the
+rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/SVUI_Inventory/Loader.lua b/SVUI_Inventory/Loader.lua
new file mode 100644
index 0000000..f40127e
--- /dev/null
+++ b/SVUI_Inventory/Loader.lua
@@ -0,0 +1,365 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local table 		= _G.table;
+local tsort 		= table.sort;
+
+local SV = _G["SVUI"];
+local L = SV.L;
+local name, obj = ...;
+local MOD = SV:NewModule(name, obj, "SVUI_LootCache", "SVUI_Private_LootCache");
+local Schema = MOD.Schema;
+local pointList = {
+	["TOPLEFT"] = "TOPLEFT",
+	["TOPRIGHT"] = "TOPRIGHT",
+	["BOTTOMLEFT"] = "BOTTOMLEFT",
+	["BOTTOMRIGHT"] = "BOTTOMRIGHT",
+};
+
+MOD.media = {}
+MOD.media.cleanupIcon = [[Interface\AddOns\SVUI_Inventory\assets\BAGS-CLEANUP]];
+MOD.media.bagIcon = [[Interface\AddOns\SVUI_Inventory\assets\BAGS-BAGS]];
+MOD.media.depositIcon = [[Interface\AddOns\SVUI_Inventory\assets\BAGS-DEPOSIT]];
+MOD.media.purchaseIcon = [[Interface\AddOns\SVUI_Inventory\assets\BAGS-PURCHASE]];
+MOD.media.reagentIcon = [[Interface\AddOns\SVUI_Inventory\assets\BAGS-REAGENTS]];
+MOD.media.sortIcon = [[Interface\AddOns\SVUI_Inventory\assets\BAGS-SORT]];
+MOD.media.stackIcon = [[Interface\AddOns\SVUI_Inventory\assets\BAGS-STACK]];
+MOD.media.transferIcon = [[Interface\AddOns\SVUI_Inventory\assets\BAGS-TRANSFER]];
+MOD.media.vendorIcon = [[Interface\AddOns\SVUI_Inventory\assets\BAGS-VENDOR]];
+
+SV:AssignMedia("font", "bagdialog", "SVUI Default Font", 11, "OUTLINE");
+SV:AssignMedia("font", "bagnumber", "SVUI Number Font", 11, "OUTLINE");
+SV:AssignMedia("globalfont", "bagdialog", "SVUI_Font_Bag");
+SV:AssignMedia("globalfont", "bagnumber", "SVUI_Font_Bag_Number");
+
+SV.defaults[Schema] = {
+	["incompatible"] = {
+		["AdiBags"] = true,
+		["ArkInventory"] = true,
+		["Bagnon"] = true,
+	},
+	["sortInverted"] = false,
+	["bags"] = {
+		["xOffset"] = -40,
+		["yOffset"] = 40,
+		["point"] = "BOTTOMRIGHT",
+	},
+	["bank"] = {
+		["xOffset"] = 40,
+		["yOffset"] = 40,
+		["point"] = "BOTTOMLEFT",
+	},
+	["separateBags"] = false,
+	["bagSize"] = 34,
+	["bankSize"] = 34,
+	["alignToChat"] = false,
+	["bagWidth"] = 525,
+	["bankWidth"] = 525,
+	["currencyFormat"] = "ICON",
+	["ignoreItems"] = "",
+	["bagTools"] = true,
+	["iLevels"] = true,
+	["bagBar"] = {
+		["enable"] = false,
+		["showBy"] = "VERTICAL",
+		["sortDirection"] = "ASCENDING",
+		["size"] = 30,
+		["spacing"] = 4,
+		["showBackdrop"] = false,
+		["mouseover"] = false,
+	},
+};
+
+function MOD:LoadOptions()
+	local bagFonts = {
+		["bagdialog"] = {
+			order = 1,
+			name = "Bag Slot Dialog",
+			desc = "Default font used in bag and bank slots"
+		},
+	    ["bagnumber"] = {
+			order = 2,
+			name = "Bag Slot Numbers",
+			desc = "Font used in bag and bank slots to display numeric values."
+		},
+	};
+
+	SV:GenerateFontOptionGroup("Bags", 7, "Fonts used in bag slots.", bagFonts)
+
+	SV.Options.args[Schema] = {
+		type = 'group',
+		name = Schema,
+		childGroups = "tab",
+		get = function(a)return SV.db[Schema][a[#a]]end,
+		set = function(a,b)MOD:ChangeDBVar(b,a[#a]) end,
+		args = {
+			intro = {
+				order = 1,
+				type = "description",
+				name = L["BAGS_DESC"]
+			},
+			bagGroups={
+				order = 2,
+				type = 'group',
+				name = L['Bag Options'],
+				guiInline = true,
+				args = {
+					common = {
+						order = 1,
+						type = "group",
+						guiInline = true,
+						name = L["General"],
+						args = {
+							bagSize = {
+								order = 1,
+								type = "range",
+								name = L["Button Size (Bag)"],
+								desc = L["The size of the individual buttons on the bag frame."],
+								min = 15,
+								max = 45,
+								step = 1,
+								set = function(a,b) MOD:ChangeDBVar(b,a[#a]) MOD:RefreshBagFrames("BagFrame") end,
+								disabled = function()return SV.db[Schema].alignToChat end
+							},
+							bankSize = {
+								order = 2,
+								type = "range",
+								name = L["Button Size (Bank)"],
+								desc = L["The size of the individual buttons on the bank frame."],
+								min = 15,
+								max = 45,
+								step = 1,
+								set = function(a,b) MOD:ChangeDBVar(b,a[#a]) MOD:RefreshBagFrames("BankFrame") end,
+								disabled = function()return SV.db[Schema].alignToChat end
+							},
+							bagWidth = {
+								order = 3,
+								type = "range",
+								name = L["Panel Width (Bags)"],
+								desc = L["Adjust the width of the bag frame."],
+								min = 150,
+								max = 700,
+								step = 1,
+								set = function(a,b) MOD:ChangeDBVar(b,a[#a]) MOD:RefreshBagFrames("BagFrame") end,
+								disabled = function()return SV.db[Schema].alignToChat end
+							},
+							bankWidth = {
+								order = 4,
+								type = "range",
+								name = L["Panel Width (Bank)"],
+								desc = L["Adjust the width of the bank frame."],
+								min = 150,
+								max = 700,
+								step = 1,
+								set = function(a,b) MOD:ChangeDBVar(b,a[#a]) MOD:RefreshBagFrames("BankFrame") end,
+								disabled = function() return SV.db[Schema].alignToChat end
+							},
+							currencyFormat = {
+								order = 5,
+								type = "select",
+								name = L["Currency Format"],
+								desc = L["The display format of the currency icons that get displayed below the main bag. (You have to be watching a currency for this to display)"],
+								values = {
+									["ICON"] = L["Icons Only"],
+									["ICON_TEXT"] = L["Icons and Text"]
+								},
+								set = function(a,b)MOD:ChangeDBVar(b,a[#a]) MOD:RefreshTokens() end
+							},
+							sortInverted = {
+								order = 6,
+								type = "toggle",
+								name = L["Sort Inverted"],
+								desc = L["Direction the bag sorting will use to allocate the items."]
+							},
+							bagTools = {
+								order = 7,
+								type = "toggle",
+								name = L["Profession Tools"],
+								desc = L["Enable/Disable Prospecting, Disenchanting and Milling buttons on the bag frame."],
+								set = function(a,b)MOD:ChangeDBVar(b,a[#a])SV:StaticPopup_Show("RL_CLIENT")end
+							},
+							ignoreItems = {
+								order = 8,
+								name = L["Ignore Items"],
+								desc = L["List of items to ignore when sorting. If you wish to add multiple items you must seperate the word with a comma."],
+								type = "input",
+								width = "full",
+								multiline = true,
+								set = function(a,b) SV.db[Schema][a[#a]] = b end
+							}
+						}
+					},
+					position = {
+						order = 2,
+						type = "group",
+						guiInline = true,
+						name = L["Bag/Bank Positioning"],
+						args = {
+							separateBags = {
+								order = 0,
+								type = "toggle",
+								name = L["Separate Bag Windows"],
+								desc = L["Allows the use of multiple panels for bags, instead of just one."]
+							},
+							alignToChat = {
+								order = 1,
+								type = "toggle",
+								name = L["Align To Docks"],
+								desc = L["Align the width of the bag frame to fit inside dock windows."],
+								set = function(a,b)MOD:ChangeDBVar(b,a[#a]) MOD:RefreshBagFrames() end
+							},
+							bags = {
+								order = 2,
+								type = "group",
+								name = L["Bag Position"],
+								guiInline = true,
+								get = function(key) return SV.db[Schema].bags[key[#key]] end,
+								set = function(key, value) MOD:ChangeDBVar(value, key[#key], "bags"); MOD:ModifyBags() end,
+								args = {
+									point = {
+										order = 1,
+										name = L["Anchor Point"],
+										type = "select",
+										values = pointList,
+									},
+									xOffset = {
+										order = 2,
+										type = "range",
+										name = L["X Offset"],
+										min = -600,
+										max = 600,
+										step = 1,
+									},
+									yOffset = {
+										order = 3,
+										type = "range",
+										name = L["Y Offset"],
+										min = -600,
+										max = 600,
+										step = 1,
+									},
+								}
+							},
+							bank = {
+								order = 3,
+								type = "group",
+								name = L["Bank Position"],
+								guiInline = true,
+								get = function(key) return SV.db[Schema].bank[key[#key]] end,
+								set = function(key, value) MOD:ChangeDBVar(value, key[#key], "bank"); MOD:ModifyBags() end,
+								args = {
+									point = {
+										order = 1,
+										name = L["Anchor Point"],
+										type = "select",
+										values = pointList,
+									},
+									xOffset = {
+										order = 2,
+										type = "range",
+										name = L["X Offset"],
+										min = -600,
+										max = 600,
+										step = 1,
+									},
+									yOffset = {
+										order = 3,
+										type = "range",
+										name = L["Y Offset"],
+										min = -600,
+										max = 600,
+										step = 1,
+									},
+								}
+							},
+						}
+					},
+					bagBar = {
+						order = 4,
+						type = "group",
+						name = L["Bag-Bar"],
+						guiInline = true,
+						get = function(key) return SV.db[Schema].bagBar[key[#key]] end,
+						set = function(key, value) MOD:ChangeDBVar(value, key[#key], "bagBar"); MOD:ModifyBagBar() end,
+						args={
+							enable = {
+								order = 1,
+								type = "toggle",
+								name = L["Bags Bar Enabled"],
+								desc = L["Enable/Disable the Bag-Bar."],
+								get = function() return SV.db[Schema].bagBar.enable end,
+								set = function(key, value) MOD:ChangeDBVar(value, key[#key], "bagBar"); SV:StaticPopup_Show("RL_CLIENT")end
+							},
+							mouseover = {
+								order = 2,
+								name = L["Mouse Over"],
+								desc = L["Hidden unless you mouse over the frame."],
+								type = "toggle"
+							},
+							showBackdrop = {
+								order = 3,
+								name = L["Backdrop"],
+								desc = L["Show/Hide bag bar backdrop"],
+								type = "toggle"
+							},
+							spacer = {
+								order = 4,
+								name = "",
+								type = "description",
+								width = "full",
+							},
+							size = {
+								order = 5,
+								type = "range",
+								name = L["Button Size"],
+								desc = L["Set the size of your bag buttons."],
+								min = 24,
+								max = 60,
+								step = 1
+							},
+							spacing = {
+								order = 6,
+								type = "range",
+								name = L["Button Spacing"],
+								desc = L["The spacing between buttons."],
+								min = 1,
+								max = 10,
+								step = 1
+							},
+							sortDirection = {
+								order = 7,
+								type = "select",
+								name = L["Sort Direction"],
+								desc = L["The direction that the bag frames will grow from the anchor."],
+								values = {
+									["ASCENDING"] = L["Ascending"],
+									["DESCENDING"] = L["Descending"]
+								}
+							},
+							showBy = {
+								order = 8,
+								type = "select",
+								name = L["Bar Direction"],
+								desc = L["The direction that the bag frames be (Horizontal or Vertical)."],
+								values = {
+									["VERTICAL"] = L["Vertical"],
+									["HORIZONTAL"] = L["Horizontal"]
+								}
+							}
+						}
+					},
+				}
+			}
+		}
+	};
+end
diff --git a/SVUI_Inventory/SVUI_Inventory.lua b/SVUI_Inventory/SVUI_Inventory.lua
new file mode 100644
index 0000000..0214620
--- /dev/null
+++ b/SVUI_Inventory/SVUI_Inventory.lua
@@ -0,0 +1,1966 @@
+--[[
+##########################################################
+S V U I  By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local ipairs 	= _G.ipairs;
+local type 		= _G.type;
+local tinsert 	= _G.tinsert;
+local string 	= _G.string;
+local math 		= _G.math;
+local table 	= _G.table;
+--[[ STRING METHODS ]]--
+local find, format, len = string.find, string.format, string.len;
+local sub, byte = string.sub, string.byte;
+--[[ MATH METHODS ]]--
+local floor, ceil, abs = math.floor, math.ceil, math.abs;
+local twipe = table.wipe;
+--BLIZZARD API
+local UnitName   			= _G.UnitName;
+local CreateFrame           = _G.CreateFrame;
+local PlaySoundFile 		= _G.PlaySoundFile;
+local GameTooltip 			= _G.GameTooltip;
+local InCombatLockdown      = _G.InCombatLockdown;
+local hooksecurefunc        = _G.hooksecurefunc;
+
+local SVUI_Font_Default 	= _G.SVUI_Font_Default;
+local SVUI_Font_Header 		= _G.SVUI_Font_Header;
+local SVUI_Font_Bag 		= _G.SVUI_Font_Bag;
+local SVUI_Font_Bag_Number 	= _G.SVUI_Font_Bag_Number;
+
+local BagFilters = _G.SVUI_BagFilterMenu;
+local BagBar = _G.SVUI_BagBar;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L;
+local MOD = SV.Inventory;
+if(not MOD) then return end;
+--[[
+##########################################################
+LOCAL VARS
+##########################################################
+]]--
+local nameKey = UnitName("player");
+local realmKey = GetRealmName();
+local toonClass = select(2,UnitClass("player"));
+local DEBUG_BAGS = false;
+local CreateFrame = _G.CreateFrame;
+local hooksecurefunc = _G.hooksecurefunc;
+local numBagFrame = NUM_BAG_FRAMES + 1;
+local MULTI_BAG_HEIGHT_OFFSET = 0;
+local LOOT_CACHE, GEAR_CACHE, GEARSET_LISTING = {}, {}, {};
+local internalTimer;
+local RefProfessionColors = {
+	[0x0008] = {224/255,187/255,74/255},
+	[0x0010] = {74/255,77/255,224/255},
+	[0x0020] = {18/255,181/255,32/255},
+	[0x0040] = {160/255,3/255,168/255},
+	[0x0080] = {232/255,118/255,46/255},
+	[0x0200] = {8/255,180/255,207/255},
+	[0x0400] = {105/255,79/255,7/255},
+	[0x10000] = {222/255,13/255,65/255},
+	[0x100000] = {18/255,224/255,180/255}
+}
+--[[
+##########################################################
+LOCAL FUNCTIONS
+##########################################################
+]]--
+local goldFormat = "%s|TInterface\\MONEYFRAME\\UI-GoldIcon.blp:16:16|t"
+
+function MOD:UpdateStockpile()
+	local journal = self.public[realmKey]["loot"][nameKey]
+	for id,amt in pairs(journal) do
+		if(not LOOT_CACHE[id]) then
+			LOOT_CACHE[id] = {}
+		end
+		local starting = 0;
+		LOOT_CACHE[id][nameKey] = (starting + amt)
+	end
+end
+
+local function FormatCurrency(amount)
+	if not amount then return end
+	local gold = floor(abs(amount/10000))
+	if gold ~= 0 then
+		gold = BreakUpLargeNumbers(gold)
+		return goldFormat:format(gold)
+	end
+end
+
+local function StyleBagToolButton(button, iconTex)
+	if button.styled then return end
+
+	local bg = button:CreateTexture(nil, "BACKGROUND")
+	bg:WrapPoints(button, 4, 4)
+	bg:SetTexture(SV.media.button.roundbg)
+	bg:SetVertexColor(unpack(SV.media.color.default))
+
+	local outer = button:CreateTexture(nil, "OVERLAY")
+	outer:WrapPoints(button, 5, 5)
+	outer:SetTexture(SV.media.button.round)
+	outer:SetGradient(unpack(SV.media.gradient.special))
+
+	button:SetNormalTexture(iconTex)
+	iconTex = button:GetNormalTexture()
+	iconTex:SetGradient(unpack(SV.media.gradient.medium))
+
+	local icon = button:CreateTexture(nil, "OVERLAY")
+	icon:WrapPoints(button, 5, 5)
+	SetPortraitToTexture(icon, iconTex)
+	hooksecurefunc(icon, "SetTexture", SetPortraitToTexture)
+
+	local hover = button:CreateTexture(nil, "HIGHLIGHT")
+	hover:WrapPoints(button, 5, 5)
+	hover:SetTexture(SV.media.button.round)
+	hover:SetGradient(unpack(SV.media.gradient.yellow))
+
+	if button.SetPushedTexture then
+		local pushed = button:CreateTexture(nil, "BORDER")
+		pushed:WrapPoints(button, 5, 5)
+		pushed:SetTexture(SV.media.button.round)
+		pushed:SetGradient(unpack(SV.media.gradient.highlight))
+		button:SetPushedTexture(pushed)
+	end
+
+	if button.SetCheckedTexture then
+		local checked = button:CreateTexture(nil, "BORDER")
+		checked:WrapPoints(button, 5, 5)
+		checked:SetTexture(SV.media.button.round)
+		checked:SetGradient(unpack(SV.media.gradient.green))
+		button:SetCheckedTexture(checked)
+	end
+
+	if button.SetDisabledTexture then
+		local disabled = button:CreateTexture(nil, "BORDER")
+		disabled:WrapPoints(button, 5, 5)
+		disabled:SetTexture(SV.media.button.round)
+		disabled:SetGradient(unpack(SV.media.gradient.default))
+		button:SetDisabledTexture(disabled)
+	end
+
+	local cd = button:GetName() and _G[button:GetName().."Cooldown"]
+	if cd then
+		cd:ClearAllPoints()
+		cd:InsetPoints()
+	end
+	button.styled = true
+end
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+local function SearchInBags(frame)
+	if((not frame) or (not frame.BagIDs) or (not frame:IsShown())) then return end
+	for _, bagID in ipairs(frame.BagIDs) do
+		local container = frame.Bags[bagID];
+		if(container) then
+			for i = 1, GetContainerNumSlots(bagID) do
+				local _, _, _, _, _, _, _, isFiltered = GetContainerItemInfo(bagID, i)
+				local item = container[i]
+				if(item and item:IsShown()) then
+					if isFiltered then
+						SetItemButtonDesaturated(item, 1)
+						item:SetAlpha(0.4)
+					else
+						SetItemButtonDesaturated(item)
+						item:SetAlpha(1)
+					end
+				end
+			end
+		end
+	end
+end
+
+function MOD:INVENTORY_SEARCH_UPDATE()
+	SearchInBags(self.MasterFrame)
+	SearchInBags(self.BankFrame)
+	SearchInBags(self.ReagentFrame)
+end
+
+local SlotUpdate = function(self, slotID)
+	if(not self[slotID]) then return end
+	local bagID = self:GetID();
+	local slot = self[slotID];
+	local bagType = self.bagFamily;
+
+	slot:Show()
+
+	local texture, count, locked = GetContainerItemInfo(bagID, slotID);
+	local start, duration, enable = GetContainerItemCooldown(bagID, slotID);
+	local isQuestItem, questId, isActiveQuest = GetContainerItemQuestInfo(bagID, slotID);
+	local itemLink = GetContainerItemLink(bagID, slotID);
+	local key, _, quality, _, _, _, _, _, equipSlot
+
+	local itemID = GetContainerItemID(bagID, slotID);
+	if(itemID and MOD.private.junk[itemID]) then
+		slot.JunkIcon:Show()
+	else
+		slot.JunkIcon:Hide()
+	end
+
+	local r,g,b = 0,0,0
+	slot.HasQuestItem = nil
+	if(questId and (not isActiveQuest)) then
+		r,g,b = 1,0.3,0.3
+		slot.questIcon:Show();
+		slot.HasQuestItem = true;
+	elseif(questId or isQuestItem) then
+		r,g,b = 1,0.3,0.3
+		slot.questIcon:Hide();
+		slot.HasQuestItem = true;
+	else
+		slot.questIcon:Hide();
+		if(itemLink) then
+			key, _, quality, _, _, _, _, _, equipSlot = GetItemInfo(itemLink)
+			if(key) then
+				local journal = MOD.public[realmKey]["loot"][nameKey]
+				local id = GetContainerItemID(bagID, slotID)
+				if id ~= 6948 then
+					journal[key] = GetItemCount(id,true)
+				end
+			end
+
+			if(quality) then
+				if(quality > 1) then
+					r,g,b = GetItemQualityColor(quality)
+				elseif(quality == 0) then
+					slot.JunkIcon:Show()
+				end
+			end
+		end
+		if(bagType) then
+			r,g,b = bagType[1],bagType[2],bagType[3]
+		end
+	end
+
+	slot:SetBackdropColor(r,g,b,0.6)
+	slot:SetBackdropBorderColor(r,g,b,1)
+
+	CooldownFrame_Set(slot.cooldown, start, duration, enable);
+
+	if((duration > 0) and (enable == 0)) then
+		SetItemButtonTextureVertexColor(slot, 0.4, 0.4, 0.4)
+	else
+		SetItemButtonTextureVertexColor(slot, 1, 1, 1)
+	end
+
+	if(C_NewItems.IsNewItem(bagID, slotID)) then
+		C_NewItems.RemoveNewItem(bagID, slotID)
+	end
+
+	if(slot.NewItemTexture) then slot.NewItemTexture:Hide() end;
+	if(slot.flashAnim) then slot.flashAnim:Stop() end;
+  if(slot.newitemglowAnim) then slot.newitemglowAnim:Stop() end;
+
+	SetItemButtonTexture(slot, texture)
+	SetItemButtonCount(slot, count)
+	SetItemButtonDesaturated(slot, locked, 0.5, 0.5, 0.5)
+
+	SV:SetGearLabels(slot, bagID, slotID, itemLink, quality, equipSlot)
+end
+
+local ContainerFrame_RefreshSlots = function(self)
+	local bagID = self:GetID()
+	if(not bagID) then return end
+	local maxcount = GetContainerNumSlots(bagID)
+	for slotID = 1, maxcount do
+		self:SlotUpdate(slotID)
+	end
+end
+
+local ContainerFrame_UpdateCooldowns = function(self)
+	if self.isReagent then return end
+	for _, bagID in ipairs(self.BagIDs) do
+		if self.Bags[bagID] then
+			for slotID = 1, GetContainerNumSlots(bagID)do
+				local start, duration, enable = GetContainerItemCooldown(bagID, slotID)
+				if(self.Bags[bagID][slotID]) then
+					CooldownFrame_Set(self.Bags[bagID][slotID].cooldown, start, duration, enable)
+					if duration > 0 and enable == 0 then
+						SetItemButtonTextureVertexColor(self.Bags[bagID][slotID], 0.4, 0.4, 0.4)
+					else
+						SetItemButtonTextureVertexColor(self.Bags[bagID][slotID], 1, 1, 1)
+					end
+				end
+			end
+		end
+	end
+end
+
+local ContainerFrame_UpdateBags = function(self)
+	for _, bagID in ipairs(self.BagIDs) do
+		if self.Bags[bagID] then
+			self.Bags[bagID]:RefreshSlots();
+		end
+	end
+	MOD:UpdateStockpile()
+end
+
+local ContainerFrame_UpdateLayout = function(self)
+	local isBank = self.isBank
+	local containerName = self:GetName()
+	local buttonSpacing = 8;
+	local containerWidth, numContainerColumns, buttonSize
+	local precount = 0;
+	for i, bagID in ipairs(self.BagIDs) do
+		if((not SV.db.Inventory.separateBags) or (isBank or (bagID > 0))) then
+			local numSlots = GetContainerNumSlots(bagID);
+			precount = precount + (numSlots or 0);
+		end
+	end
+
+	if(SV.db.Inventory.alignToChat) then
+		containerWidth = (isBank and SV.db.Dock.dockLeftWidth or SV.db.Dock.dockRightWidth)
+		local avg = 0.08;
+		if(precount > 287) then
+			avg = 0.12
+		elseif(precount > 167) then
+			avg = 0.11
+		elseif(precount > 127) then
+			avg = 0.1
+		elseif(precount > 97) then
+			avg = 0.09
+		end
+
+		numContainerColumns = avg * 100;
+
+		local unitSize = floor(containerWidth / numContainerColumns)
+		buttonSize = unitSize - buttonSpacing;
+	else
+		containerWidth = (isBank and SV.db.Inventory.bankWidth) or SV.db.Inventory.bagWidth
+		buttonSize = isBank and SV.db.Inventory.bankSize or SV.db.Inventory.bagSize;
+		numContainerColumns = floor(containerWidth / (buttonSize + buttonSpacing));
+	end
+
+	local numContainerRows = ceil(precount / numContainerColumns)
+	local containerHeight = (((buttonSize + buttonSpacing) * numContainerRows) - buttonSpacing) + self.topOffset + self.bottomOffset;
+	local holderWidth = ((buttonSize + buttonSpacing) * numContainerColumns) - buttonSpacing;
+	local bottomPadding = (containerWidth - holderWidth) * 0.5;
+	local lastButton, lastRowButton, globalName;
+	local numContainerSlots, fullContainerSlots = GetNumBankSlots();
+	local totalSlots = 0;
+
+	if(SV.db.Inventory.separateBags) then
+		local bpCount = GetContainerNumSlots(0);
+		local bpRows = ceil(bpCount / numContainerColumns);
+		containerHeight = (((buttonSize + buttonSpacing) * bpRows) - buttonSpacing) + self.topOffset + self.bottomOffset;
+	end
+
+	self.ButtonSize = buttonSize;
+	self.holderFrame:SetWidth(holderWidth);
+
+	local menu = self.BagMenu;
+	local lastMenu;
+	for i, bagID in ipairs(self.BagIDs) do
+		if((not isBank and bagID <= 3) or (isBank and bagID ~= -1 and numContainerSlots >= 1 and not (i - 1 > numContainerSlots))) then
+			local menuWidth = ((buttonSize + buttonSpacing) * (isBank and i - 1 or i)) + buttonSpacing;
+			local menuHeight = buttonSize + (buttonSpacing * 2);
+			menu:SetSize(menuWidth, menuHeight)
+			local bagSlot = menu[i];
+
+			if(not bagSlot) then
+				local globalName, bagTemplate;
+				if isBank then
+					globalName = "SVUI_BankBag" .. bagID - 4;
+					bagTemplate = "BankItemButtonBagTemplate";
+				else
+					globalName = "SVUI_MainBag" .. bagID .. "Slot";
+					bagTemplate = "BagSlotButtonTemplate";
+				end
+
+				bagSlot = CreateFrame("CheckButton", globalName, menu, bagTemplate)
+				bagSlot.parent = self;
+
+				bagSlot:SetNormalTexture("")
+				bagSlot:SetCheckedTexture("")
+				bagSlot:SetPushedTexture("")
+				--bagSlot:SetScript("OnClick", nil)
+				bagSlot:RemoveTextures()
+				bagSlot:SetStyle("!_ActionSlot");
+
+				if(not bagSlot.icon) then
+					bagSlot.icon = bagSlot:CreateTexture(nil, "BORDER");
+				end
+				bagSlot.icon:InsetPoints()
+				bagSlot.icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+
+				if(not bagSlot.tooltipText) then
+					bagSlot.tooltipText = ""
+				end
+
+				if(isBank) then
+					bagSlot:SetID(bagID - 4)
+					bagSlot.internalID = bagID;
+				else
+					-- MOD:NewFilterMenu(bagSlot)
+					bagSlot.internalID = (bagID + 1);
+				end
+
+				MOD:NewFilterMenu(bagSlot)
+
+				menu[i] = bagSlot;
+			end
+
+			bagSlot:SetSize(buttonSize, buttonSize)
+			bagSlot:ClearAllPoints()
+
+			if(isBank) then
+				BankFrameItemButton_Update(bagSlot)
+				BankFrameItemButton_UpdateLocked(bagSlot)
+
+				if(i == 2) then
+					bagSlot:SetPoint("BOTTOMLEFT", menu, "BOTTOMLEFT", buttonSpacing, buttonSpacing)
+				else
+					bagSlot:SetPoint("LEFT", lastMenu, "RIGHT", buttonSpacing, 0)
+				end
+			else
+				if(i == 1) then
+					bagSlot:SetPoint("BOTTOMLEFT", menu, "BOTTOMLEFT", buttonSpacing, buttonSpacing)
+				else
+					bagSlot:SetPoint("LEFT", lastMenu, "RIGHT", buttonSpacing, 0)
+				end
+			end
+			lastMenu = bagSlot;
+		end
+
+		local numSlots = GetContainerNumSlots(bagID);
+
+		local bagName = ("%sBag%d"):format(containerName, bagID)
+		local bag;
+
+		if numSlots > 0 then
+			if not self.Bags[bagID] then
+				self.Bags[bagID] = CreateFrame("Frame", bagName, self);
+				self.Bags[bagID]:SetID(bagID);
+				self.Bags[bagID].SlotUpdate = SlotUpdate;
+				self.Bags[bagID].RefreshSlots = ContainerFrame_RefreshSlots;
+			end
+
+			local bagAnchor = self.holderFrame;
+			local numCols = numContainerColumns;
+			local rowCount = 0;
+
+			if(self.Bags[bagID].holderFrame) then
+				bagAnchor = self.Bags[bagID].holderFrame;
+				lastButton = false;
+				lastRowButton = false;
+				totalSlots = 0;
+				numCols = ceil(numSlots * 0.2);
+				local multiSize = (((buttonSize + buttonSpacing) * numCols) - buttonSpacing) + 16
+				self.Bags[bagID]:SetSize(multiSize,multiSize)
+			end
+
+			self.Bags[bagID].numSlots = numSlots;
+			self.Bags[bagID].bagFamily = false;
+
+			local btype = select(2, GetContainerNumFreeSlots(bagID));
+			if RefProfessionColors[btype] then
+				local r, g, b = unpack(RefProfessionColors[btype]);
+				self.Bags[bagID].bagFamily = {r, g, b};
+			end
+
+			for i = 1, MAX_CONTAINER_ITEMS do
+				if self.Bags[bagID][i] then
+					self.Bags[bagID][i]:Hide();
+				end
+			end
+
+			for slotID = 1, numSlots do
+				totalSlots = totalSlots + 1;
+
+				if not self.Bags[bagID][slotID] then
+					local slotName = ("%sSlot%d"):format(bagName, slotID)
+					local iconName = ("%sIconTexture"):format(slotName)
+					local cdName = ("%sCooldown"):format(slotName)
+					local questIcon = ("%sIconQuestTexture"):format(slotName)
+
+					self.Bags[bagID][slotID] = CreateFrame("CheckButton", slotName, self.Bags[bagID], bagID == -1 and "BankItemButtonGenericTemplate" or "ContainerFrameItemButtonTemplate");
+					self.Bags[bagID][slotID]:SetNormalTexture("");
+					self.Bags[bagID][slotID]:SetCheckedTexture("");
+					self.Bags[bagID][slotID]:RemoveTextures();
+					self.Bags[bagID][slotID]:SetStyle("!_ActionSlot");
+
+					if(self.Bags[bagID][slotID].IconBorder) then
+						self.Bags[bagID][slotID].IconBorder:Die()
+					end
+
+					-- if(self.Bags[bagID][slotID].flashAnim) then
+					-- 	self.Bags[bagID][slotID].flashAnim.Play = SV.fubar
+					-- end
+
+					if(not self.Bags[bagID][slotID].NewItemTexture) then
+						self.Bags[bagID][slotID].NewItemTexture = self.Bags[bagID][slotID]:CreateTexture(nil, "OVERLAY", 1);
+					end
+					self.Bags[bagID][slotID].NewItemTexture:InsetPoints(self.Bags[bagID][slotID]);
+					self.Bags[bagID][slotID].NewItemTexture:SetTexture("");
+					self.Bags[bagID][slotID].NewItemTexture:Hide()
+
+					if(not self.Bags[bagID][slotID].JunkIcon) then
+						self.Bags[bagID][slotID].JunkIcon = self.Bags[bagID][slotID]:CreateTexture(nil, "OVERLAY");
+						self.Bags[bagID][slotID].JunkIcon:SetSize(16,16);
+					end
+					self.Bags[bagID][slotID].JunkIcon:SetTexture([[Interface\BUTTONS\UI-GroupLoot-Coin-Up]]);
+					self.Bags[bagID][slotID].JunkIcon:SetPoint("TOPLEFT", self.Bags[bagID][slotID], "TOPLEFT", -4, 4);
+
+					if(not self.Bags[bagID][slotID].icon) then
+						self.Bags[bagID][slotID].icon = self.Bags[bagID][slotID]:CreateTexture(nil, "BORDER");
+					end
+					self.Bags[bagID][slotID].icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS));
+					self.Bags[bagID][slotID].icon:InsetPoints(self.Bags[bagID][slotID]);
+
+					self.Bags[bagID][slotID].questIcon = _G[questIcon] or self.Bags[bagID][slotID]:CreateTexture(nil, "OVERLAY")
+					self.Bags[bagID][slotID].questIcon:SetTexture(TEXTURE_ITEM_QUEST_BANG);
+					self.Bags[bagID][slotID].questIcon:InsetPoints(self.Bags[bagID][slotID]);
+					self.Bags[bagID][slotID].questIcon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS));
+
+					hooksecurefunc(self.Bags[bagID][slotID], "SetBackdropColor", function(self, r, g, b, a) if(self.HasQuestItem and (r ~= 1)) then self:SetBackdropColor(1,0.3,0.3,a) end end)
+					hooksecurefunc(self.Bags[bagID][slotID], "SetBackdropBorderColor", function(self, r, g, b, a) if(self.HasQuestItem and (r ~= 1)) then self:SetBackdropBorderColor(1,0.3,0.3,a) end end)
+
+					self.Bags[bagID][slotID].cooldown = _G[cdName];
+				end
+
+				if(not self.Bags[bagID][slotID].GearInfo) then
+					self.Bags[bagID][slotID].GearInfo = self.Bags[bagID][slotID]:CreateFontString(nil,"OVERLAY")
+					self.Bags[bagID][slotID].GearInfo:SetFontObject(SVUI_Font_Default)
+					self.Bags[bagID][slotID].GearInfo:SetAllPoints(self.Bags[bagID][slotID])
+					self.Bags[bagID][slotID].GearInfo:SetWordWrap(true)
+					self.Bags[bagID][slotID].GearInfo:SetJustifyH('RIGHT')
+					self.Bags[bagID][slotID].GearInfo:SetJustifyV('TOP')
+				end
+
+				if(not self.Bags[bagID][slotID].ItemLevel) then
+					self.Bags[bagID][slotID].ItemLevel = self.Bags[bagID][slotID]:CreateFontString(nil,"OVERLAY")
+					self.Bags[bagID][slotID].ItemLevel:SetFontObject(SVUI_Font_Default)
+					self.Bags[bagID][slotID].ItemLevel:SetAllPoints(self.Bags[bagID][slotID])
+					self.Bags[bagID][slotID].ItemLevel:SetWordWrap(true)
+					self.Bags[bagID][slotID].ItemLevel:SetJustifyH('LEFT')
+					self.Bags[bagID][slotID].ItemLevel:SetJustifyV('BOTTOM')
+				end
+
+				self.Bags[bagID][slotID]:SetID(slotID);
+				self.Bags[bagID][slotID]:SetSize(buttonSize, buttonSize);
+
+				if self.Bags[bagID][slotID]:GetPoint() then
+					self.Bags[bagID][slotID]:ClearAllPoints();
+				end
+
+				if lastButton then
+					if((totalSlots - 1) % numCols == 0) then
+						self.Bags[bagID][slotID]:SetPoint("TOP", lastRowButton, "BOTTOM", 0, -buttonSpacing);
+						lastRowButton = self.Bags[bagID][slotID];
+						rowCount = rowCount + 1;
+					else
+						self.Bags[bagID][slotID]:SetPoint("LEFT", lastButton, "RIGHT", buttonSpacing, 0);
+					end
+				else
+					self.Bags[bagID][slotID]:SetPoint("TOPLEFT", bagAnchor, "TOPLEFT");
+					lastRowButton = self.Bags[bagID][slotID];
+					rowCount = rowCount + 1;
+				end
+
+				lastButton = self.Bags[bagID][slotID];
+
+				self.Bags[bagID]:SlotUpdate(slotID);
+			end
+
+			if(self.Bags[bagID].holderFrame) then
+				local multiWidth = (((buttonSize + buttonSpacing) * numCols) - buttonSpacing) + 16;
+				local multiHeight = (((buttonSize + buttonSpacing) * rowCount) - buttonSpacing) + 50;
+				self.Bags[bagID]:SetSize(multiWidth,multiHeight)
+			end
+		else
+			if(self.Bags[bagID]) then
+				self.Bags[bagID].numSlots = numSlots;
+
+				for i = 1, MAX_CONTAINER_ITEMS do
+					if(self.Bags[bagID][i]) then
+						self.Bags[bagID][i]:Hide();
+					end
+				end
+			end
+
+			if(isBank) then
+				if(menu[i]) then
+					BankFrameItemButton_Update(menu[i])
+					BankFrameItemButton_UpdateLocked(menu[i])
+				end
+			end
+		end
+	end
+
+	self:SetSize(containerWidth, containerHeight);
+	MOD:UpdateStockpile()
+end
+
+local ReagentFrame_UpdateLayout = function(self)
+	if not _G.ReagentBankFrame then return; end
+
+	local ReagentBankFrame = _G.ReagentBankFrame;
+
+	local containerName = self:GetName()
+	local buttonSpacing = 8;
+	local preColumns = ReagentBankFrame.numColumn or 7
+	local preSubColumns = ReagentBankFrame.numSubColumn or 2
+	local numContainerColumns = preColumns * preSubColumns
+	local numContainerRows = ReagentBankFrame.numRow or 7
+	local buttonSize = MOD.BankFrame.ButtonSize
+	local containerWidth = (buttonSize + buttonSpacing) * numContainerColumns + buttonSpacing
+	local containerHeight = (((buttonSize + buttonSpacing) * numContainerRows) - buttonSpacing) + self.topOffset + self.bottomOffset
+	local maxCount = numContainerColumns * numContainerRows
+	local holderWidth = ((buttonSize + buttonSpacing) * numContainerColumns) - buttonSpacing;
+	local lastButton, lastRowButton;
+	local bagID = REAGENTBANK_CONTAINER;
+	local totalSlots = 0;
+
+	self.holderFrame:SetWidth(holderWidth);
+	self.BagID = bagID
+
+	local bag;
+	local bagName = ("%sBag%d"):format(containerName, bagID)
+
+	if not self.Bags[bagID] then
+		bag = CreateFrame("Frame", bagName, self);
+		bag:SetID(bagID);
+		bag.SlotUpdate = SlotUpdate;
+		bag.RefreshSlots = ContainerFrame_RefreshSlots;
+		self.Bags[bagID] = bag
+	else
+		bag = self.Bags[bagID]
+	end
+
+	self.numSlots = maxCount;
+	bag.numSlots = maxCount;
+	bag.bagFamily = false;
+
+	for slotID = 1, maxCount do
+		local slot;
+		totalSlots = totalSlots + 1;
+
+		if not bag[slotID] then
+			local slotName = ("%sSlot%d"):format(bagName, slotID)
+			local iconName = ("%sIconTexture"):format(slotName)
+			local questIcon = ("%sIconQuestTexture"):format(slotName)
+			local cdName = ("%sCooldown"):format(slotName)
+
+			slot = CreateFrame("CheckButton", slotName, bag, "ReagentBankItemButtonGenericTemplate");
+			slot:SetNormalTexture(nil);
+			slot:SetCheckedTexture(nil);
+			slot:RemoveTextures()
+			slot:SetStyle("!_ActionSlot");
+
+			if(slot.IconBorder) then
+				slot.IconBorder:Die()
+			end
+
+			slot.NewItemTexture = slot:CreateTexture(nil, "OVERLAY", 1);
+			slot.NewItemTexture:InsetPoints(slot);
+			slot.NewItemTexture:SetTexture("");
+			slot.NewItemTexture:Hide()
+
+			slot.JunkIcon = slot:CreateTexture(nil, "OVERLAY");
+			slot.JunkIcon:SetSize(16,16);
+			slot.JunkIcon:SetTexture("");
+			slot.JunkIcon:SetPoint("TOPLEFT", slot, "TOPLEFT", -4, 4);
+
+			slot.icon = _G[iconName] or slot:CreateTexture(nil, "BORDER");
+			slot.icon:InsetPoints(slot);
+			slot.icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS));
+
+			slot.questIcon = _G[questIcon] or slot:CreateTexture(nil, "OVERLAY")
+			slot.questIcon:SetTexture(TEXTURE_ITEM_QUEST_BANG);
+			slot.questIcon:InsetPoints(slot);
+			slot.questIcon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS));
+
+			slot.cooldown = _G[cdName];
+
+			bag[slotID] = slot
+		else
+			slot = bag[slotID]
+		end
+
+		slot:SetID(slotID);
+		slot:SetSize(buttonSize, buttonSize);
+
+		if slot:GetPoint() then
+			slot:ClearAllPoints();
+		end
+
+		if lastButton then
+			if((totalSlots - 1) % numContainerColumns == 0) then
+				slot:SetPoint("TOP", lastRowButton, "BOTTOM", 0, -buttonSpacing);
+				lastRowButton = slot;
+			else
+				slot:SetPoint("LEFT", lastButton, "RIGHT", buttonSpacing, 0);
+			end
+		else
+			slot:SetPoint("TOPLEFT", self.holderFrame, "TOPLEFT");
+			lastRowButton = slot;
+		end
+
+		lastButton = slot;
+
+		if(slot.GetInventorySlot) then
+			BankFrameItemButton_Update(slot)
+			BankFrameItemButton_UpdateLocked(slot)
+		end
+
+		bag:SlotUpdate(slotID);
+	end
+
+	self:SetSize(containerWidth, containerHeight);
+	MOD:UpdateStockpile()
+end
+
+function MOD:RefreshBagFrames(frame)
+	if(frame and self[frame]) then
+		self[frame]:UpdateLayout()
+		return
+	else
+		if(self.MasterFrame) then
+			self.MasterFrame:UpdateLayout()
+		end
+		if self.BankFrame then
+			self.BankFrame:UpdateLayout()
+		end
+		if self.ReagentFrame then
+			self.ReagentFrame:UpdateLayout()
+		end
+	end
+end
+
+function SV:SetLootTooltip(tooltip, itemKey)
+	if((not LOOT_CACHE) or (not LOOT_CACHE[itemKey])) then return end
+	tooltip:AddLine(" ")
+	tooltip:AddDoubleLine("|cFFFFDD3C[Character]|r","|cFFFFDD3C[Count]|r")
+	for alt,amt in pairs(LOOT_CACHE[itemKey]) do
+		local hexString = MOD.public[realmKey]["info"][alt] or "|cffCC1410"
+		local name = ("%s%s|r"):format(hexString, alt)
+		local result = ("%s%s|r"):format(hexString, amt)
+		tooltip:AddDoubleLine(name,result)
+	end
+	tooltip:AddLine(" ")
+end
+
+function MOD:UpdateGoldText()
+	self.MasterFrame.goldText:SetText(GetCoinTextureString(GetMoney(), 12))
+end
+
+function MOD:VendorCheck(itemID, bagID, slot)
+	if((not MOD.private) or (not MOD.private.junk)) then return end
+	if(itemID and MOD.private.junk[itemID]) then
+		UseContainerItem(bagID, slot)
+		PickupMerchantItem()
+		return true
+	end
+end
+
+function MOD:ModifyBags()
+	local docked = SV.db.Inventory.alignToChat
+	local anchor, x, y
+
+	MULTI_BAG_HEIGHT_OFFSET = 0;
+
+	if(SV.db.Inventory.separateBags) then
+		for bagID,bag in pairs(self.MasterFrame.Bags) do
+			if(bagID == 1 or bagID == 3) then
+				local bagHeight = bag:GetHeight()
+				MULTI_BAG_HEIGHT_OFFSET = MULTI_BAG_HEIGHT_OFFSET + (bagHeight + 4);
+			end
+		end
+	end
+
+	if(docked) then
+		if self.MasterFrame then
+			self.MasterFrame:ClearAllPoints()
+			self.MasterFrame:SetPoint("BOTTOMRIGHT", SV.Dock.BottomRight, "BOTTOMRIGHT", 0, MULTI_BAG_HEIGHT_OFFSET)
+		end
+		if self.BankFrame then
+			self.BankFrame:ClearAllPoints()
+			self.BankFrame:SetPoint("BOTTOMLEFT", SV.Dock.BottomLeft, "BOTTOMLEFT", 0, 0)
+		end
+	else
+		if self.MasterFrame then
+			local anchor, x, y = SV.db.Inventory.bags.point, SV.db.Inventory.bags.xOffset, SV.db.Inventory.bags.yOffset
+			self.MasterFrame:ClearAllPoints()
+			self.MasterFrame:SetPoint(anchor, SV.Screen, anchor, x, y + MULTI_BAG_HEIGHT_OFFSET)
+		end
+		if self.BankFrame then
+			local anchor, x, y = SV.db.Inventory.bank.point, SV.db.Inventory.bank.xOffset, SV.db.Inventory.bank.yOffset
+			self.BankFrame:ClearAllPoints()
+			self.BankFrame:SetPoint(anchor, SV.Screen, anchor, x, y)
+		end
+	end
+end
+
+do
+	local BagBar_OnEnter = function(self)
+		if(not self.___fade) then return end
+		BagBar:FadeIn()
+	end
+
+	local BagBar_OnLeave = function(self)
+		if(not self.___fade) then return end
+		BagBar:FadeOut()
+	end
+
+	local function AlterBagBarButton(button)
+		local icon = _G[button:GetName().."IconTexture"]
+		button.oldTex = icon:GetTexture()
+		button:RemoveTextures()
+		button:SetStyle("!_Frame", "Default")
+		button:SetStyle("!_ActionSlot", 1, nil, nil, true)
+		icon:SetTexture(button.oldTex)
+		icon:InsetPoints()
+		icon:SetTexCoord(0.1, 0.9, 0.1, 0.9 )
+	end
+
+	function MOD:PositionBagBar(reset)
+		if(not self.BagBarLoaded) then return end
+		if(BagBar.Grip and (not BagBar.Grip:HasMoved())) then
+			BagBar:ClearAllPoints()
+			if(reset) then
+				BagBar:SetPoint("BOTTOMLEFT", SV.Dock.BottomRight.Window, "TOPLEFT", -4, 0)
+			else
+				BagBar:SetPoint("BOTTOMLEFT", self.MasterFrame, "TOPLEFT", -4, 0)
+			end
+		end
+	end
+
+	local function LoadBagBar()
+		local bagFading = SV.db.Inventory.bagBar.mouseover
+
+		BagBar:SetParent(SV.Screen)
+		BagBar:ClearAllPoints()
+		BagBar:SetSize(160, 30)
+		BagBar:SetPoint("BOTTOMLEFT", SV.Dock.BottomRight.Window, "TOPLEFT", -4, 0)
+		BagBar.buttons = {}
+		BagBar.___fade = bagFading;
+		BagBar:EnableMouse(true)
+		BagBar:SetScript("OnEnter", BagBar_OnEnter)
+		BagBar:SetScript("OnLeave", BagBar_OnLeave)
+		BagBar:SetStyle("Frame", "Default")
+
+		MainMenuBarBackpackButton:SetParent(BagBar)
+		MainMenuBarBackpackButton.SetParent = SV.fubar;
+		MainMenuBarBackpackButton.___fade = bagFading;
+		MainMenuBarBackpackButton:ClearAllPoints()
+		MainMenuBarBackpackButton:SetPoint("BOTTOMLEFT", BagBar, "BOTTOMLEFT", 2, 2)
+		MainMenuBarBackpackButtonCount:SetFontObject(SVUI_Font_Default)
+		MainMenuBarBackpackButtonCount:ClearAllPoints()
+		MainMenuBarBackpackButtonCount:SetPoint("BOTTOMRIGHT", MainMenuBarBackpackButton, "BOTTOMRIGHT", -1, 4)
+		MainMenuBarBackpackButton:HookScript("OnEnter", BagBar_OnEnter)
+		MainMenuBarBackpackButton:HookScript("OnLeave", BagBar_OnLeave)
+
+		tinsert(BagBar.buttons, MainMenuBarBackpackButton)
+		AlterBagBarButton(MainMenuBarBackpackButton)
+
+		local frameCount = NUM_BAG_FRAMES - 1;
+
+		for i = 0, frameCount do
+			local bagSlot = _G["CharacterBag"..i.."Slot"]
+			bagSlot:SetParent(BagBar)
+			bagSlot.SetParent = SV.fubar;
+			bagSlot.___fade = bagFading;
+			bagSlot:HookScript("OnEnter", BagBar_OnEnter)
+			bagSlot:HookScript("OnLeave", BagBar_OnLeave)
+			AlterBagBarButton(bagSlot)
+			BagBar.buttons[i + 2] = bagSlot
+		end
+
+		SV:NewAnchor(BagBar, L["Bags Bar"])
+
+		MOD.BagBarLoaded = true
+	end
+
+	function MOD:ModifyBagBar()
+		if(not SV.db.Inventory.bagBar.enable) then return end
+
+		if not self.BagBarLoaded then
+			LoadBagBar()
+		end
+
+		local showBy = SV.db.Inventory.bagBar.showBy
+		local showBG = SV.db.Inventory.bagBar.showBackdrop
+		local sortDir = SV.db.Inventory.bagBar.sortDirection
+		local bagSize = SV.db.Inventory.bagBar.size
+		local bagSpacing = SV.db.Inventory.bagBar.spacing
+		local bagFading = SV.db.Inventory.bagBar.mouseover
+		local bagCount = #BagBar.buttons
+
+		for i = 1, bagCount do
+			local button = BagBar.buttons[i]
+			local lastButton = BagBar.buttons[i - 1]
+
+			button:SetSize(bagSize, bagSize)
+			button:ClearAllPoints()
+
+			if(showBy == "HORIZONTAL" and sortDir == "ASCENDING") then
+				if i == 1 then
+					button:SetPoint("LEFT", BagBar, "LEFT", bagSpacing, 0)
+				elseif lastButton then
+					button:SetPoint("LEFT", lastButton, "RIGHT", bagSpacing, 0)
+				end
+			elseif(showBy == "VERTICAL" and sortDir == "ASCENDING") then
+				if i == 1 then
+					button:SetPoint("TOP", BagBar, "TOP", 0, -bagSpacing)
+				elseif lastButton then
+					button:SetPoint("TOP", lastButton, "BOTTOM", 0, -bagSpacing)
+				end
+			elseif(showBy == "HORIZONTAL" and sortDir == "DESCENDING") then
+				if i == 1 then
+					button:SetPoint("RIGHT", BagBar, "RIGHT", -bagSpacing, 0)
+				elseif lastButton then
+					button:SetPoint("RIGHT", lastButton, "LEFT", -bagSpacing, 0)
+				end
+			else
+				if i == 1 then
+					button:SetPoint("BOTTOM", BagBar, "BOTTOM", 0, bagSpacing)
+				elseif lastButton then
+					button:SetPoint("BOTTOM", lastButton, "TOP", 0, bagSpacing)
+				end
+			end
+
+			button.___fade = bagFading
+		end
+
+		local size1 = (bagSize * bagCount) + (bagSpacing * bagCount) + bagSpacing
+		local size2 = bagSize + (bagSpacing * 2)
+		if(showBy == "HORIZONTAL") then BagBar:SetSize(size1, size2) else BagBar:SetSize(size2, size1) end
+	    if(showBG) then BagBar.Panel:FadeIn() else BagBar.Panel:FadeOut() end
+	    BagBar.___fade = bagFading;
+		if(bagFading) then BagBar:FadeOut() else BagBar:FadeIn() end
+	end
+end
+--[[
+##########################################################
+BAG CONTAINER CREATION
+##########################################################
+]]--
+local NEXT_ACTION_ALLOWED, NEXT_ACTION_TOGGLED = false, false;
+local NEXT_ACTION_FORCED, FORCED_CLOSED, FORCED_OPEN = false, false, false;
+
+do
+	local InventorySearch_OnReset = function(self)
+		self.button:Show()
+		self:ClearFocus()
+		SetItemSearch('')
+	end
+
+	local InventorySearch_OnChar = function(self)
+		local MIN_REPEAT_CHARACTERS = 4;
+		local searchString = self:GetText();
+		if (len(searchString) >= MIN_REPEAT_CHARACTERS) then
+			local repeatChar = true;
+			for i=1, MIN_REPEAT_CHARACTERS - 1, 1 do
+				if ( searchString:sub((0-i), (0-i)) ~= searchString:sub((-1-i),(-1-i)) ) then
+					repeatChar = false;
+					break;
+				end
+			end
+			if ( repeatChar ) then
+				InventorySearch_OnReset(self)
+			end
+		end
+	end
+
+	local InventorySearch_OnTextChanged = function(self)
+		local MIN_REPEAT_CHARACTERS = 4;
+		local searchString = self:GetText();
+		if (len(searchString) >= MIN_REPEAT_CHARACTERS) then
+			local repeatChar = true;
+			for i=1, MIN_REPEAT_CHARACTERS - 1, 1 do
+				if ( searchString:sub((0-i), (0-i)) ~= searchString:sub((-1-i),(-1-i)) ) then
+					repeatChar = false;
+					break;
+				end
+			end
+			if ( repeatChar ) then
+				InventorySearch_OnReset(self)
+			end
+		end
+		SetItemSearch(searchString)
+	end
+
+	local Search_OnClick = function(self, button)
+		local container = self:GetParent()
+		if button == "RightButton"then
+			container.detail:Hide()
+			container.editBox:Show()
+			container.editBox:SetText(SEARCH)
+			container.editBox:HighlightText()
+		else
+			if container.editBox:IsShown()then
+				container.editBox:Hide()
+				container.editBox:ClearFocus()
+				container.detail:Show()
+				SetItemSearch('')
+			else
+				container.detail:Hide()
+				container.editBox:Show()
+				container.editBox:SetText(SEARCH)
+				container.editBox:HighlightText()
+			end
+		end
+	end
+
+	local Vendor_OnClick = function(self)
+		if(IsShiftKeyDown() or (not MerchantFrame or not MerchantFrame:IsShown())) then
+			SV.SystemAlert["DELETE_GRAYS"].Money = SV:VendorGrays(false,true,true)
+			SV:StaticPopup_Show('DELETE_GRAYS')
+		else
+			SV:VendorGrays()
+		end
+	end
+
+	local Token_OnEnter = function(self)
+		GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
+		GameTooltip:SetBackpackToken(self:GetID())
+	end
+
+	local Token_OnLeave = function(self)
+		GameTooltip:Hide()
+	end
+
+	local Token_OnClick = function(self)
+		if IsModifiedClick("CHATLINK") then
+			HandleModifiedItemClick(GetCurrencyLink(self.currencyID))
+		end
+	end
+
+	local TopInfo_OnEnter = function(self)
+		GameTooltip:SetOwner(self,"ANCHOR_BOTTOM",0,-4)
+		GameTooltip:ClearLines()
+
+		local goldData = SV:GetReportData("gold")
+
+		local networth = goldData[nameKey];
+		GameTooltip:AddLine(L[nameKey..": "])
+		GameTooltip:AddDoubleLine(L["Total: "], SV:FormatCurrency(networth), 1,1,1,1,1,1)
+		GameTooltip:AddLine(" ")
+
+		GameTooltip:AddLine(L["Characters: "])
+		for name,amount in pairs(goldData)do
+			if(name ~= nameKey and name ~= 'total') then
+				networth = networth + amount;
+				GameTooltip:AddDoubleLine(name, SV:FormatCurrency(amount), 1,1,1,1,1,1)
+			end
+		end
+
+		GameTooltip:AddLine(" ")
+		GameTooltip:AddLine(L["Server: "])
+		GameTooltip:AddDoubleLine(L["Total: "], SV:FormatCurrency(networth), 1,1,1,1,1,1)
+		GameTooltip:AddLine(" ")
+
+		GameTooltip:Show()
+	end
+
+	local Tooltip_Show = function(self)
+		GameTooltip:SetOwner(self:GetParent(),"ANCHOR_TOP",0,4)
+		GameTooltip:ClearLines()
+		GameTooltip:AddLine(self.ttText)
+
+		if self.ttText2 then
+			GameTooltip:AddLine(' ')
+			GameTooltip:AddDoubleLine(self.ttText2,self.ttText2desc,1,1,1)
+		end
+
+		self:GetNormalTexture():SetGradient(unpack(SV.media.gradient.highlight))
+		GameTooltip:Show()
+	end
+
+	local Tooltip_Hide = function(self)
+		self:GetNormalTexture():SetGradient(unpack(SV.media.gradient.medium))
+		GameTooltip:Hide()
+	end
+
+	local Container_OnDragStart = function(self)
+		if IsShiftKeyDown()then self:StartMoving()end
+	end
+	local Container_OnDragStop = function(self)
+		self:StopMovingOrSizing()
+	end
+	local Container_OnClick = function(self)
+		if IsControlKeyDown() then MOD:ModifyBags() end
+	end
+	local Container_OnEnter = function(self)
+		GameTooltip:SetOwner(self,"ANCHOR_TOPLEFT",0,4)
+		GameTooltip:ClearLines()
+		GameTooltip:AddDoubleLine(L['Hold Shift + Drag:'],L['Temporary Move'],1,1,1)
+		GameTooltip:AddDoubleLine(L['Hold Control + Right Click:'],L['Reset Position'],1,1,1)
+		GameTooltip:Show()
+	end
+
+	local Container_OnShow = function(self)
+		NEXT_ACTION_ALLOWED = true
+		MOD:PositionBagBar()
+		if(SV.db.Inventory.separateBags) then
+			for bagID, bagFrame in ipairs(MOD.MasterFrame.Bags) do
+				bagFrame:Show()
+			end
+		end
+	end
+
+	local Container_OnHide = function(self)
+		NEXT_ACTION_ALLOWED = false
+		MOD:PositionBagBar(true)
+	end
+
+	function MOD:CreateMasterFrame()
+		local bagName = "SVUI_ContainerFrame";
+		local frame = CreateFrame("Button", "SVUI_ContainerFrame", SV.Screen);
+		tinsert(UISpecialFrames, bagName);
+
+		frame:SetStyle("Frame", "Pattern")
+		frame:SetFrameStrata("HIGH")
+		frame.UpdateLayout = ContainerFrame_UpdateLayout;
+		frame.RefreshBags = ContainerFrame_UpdateBags;
+		frame.RefreshCooldowns = ContainerFrame_UpdateCooldowns;
+
+		frame:RegisterEvent("ITEM_LOCK_CHANGED")
+		frame:RegisterEvent("ITEM_UNLOCKED")
+		frame:RegisterEvent("BAG_UPDATE_COOLDOWN")
+		frame:RegisterEvent("BAG_UPDATE")
+		frame:RegisterEvent("EQUIPMENT_SETS_CHANGED")
+		frame:RegisterEvent("PLAYERBANKSLOTS_CHANGED")
+		frame:RegisterEvent("PLAYERREAGENTBANKSLOTS_CHANGED")
+
+		frame:SetMovable(true)
+
+		frame:RegisterForDrag("LeftButton", "RightButton")
+		frame:RegisterForClicks("AnyUp")
+
+		frame:SetScript("OnDragStart", Container_OnDragStart)
+		frame:SetScript("OnDragStop", Container_OnDragStop)
+		frame:SetScript("OnClick", Container_OnClick)
+		frame:SetScript("OnEnter", Container_OnEnter)
+		frame:SetScript("OnLeave", Token_OnLeave)
+		frame:SetScript("OnHide", Container_OnHide)
+		frame:SetScript("OnShow", Container_OnShow)
+		self:SetContainerEvents(frame)
+
+		frame.isBank = false;
+		frame.isReagent = false;
+		frame:Hide()
+		frame.bottomOffset = 32;
+		frame.topOffset = 65;
+		frame.BagIDs = {0, 1, 2, 3, 4}
+		frame.Bags = {}
+
+		frame.closeButton = CreateFrame("Button", "SVUI_ContainerFrameCloseButton", frame, "UIPanelCloseButton")
+		frame.closeButton:SetPoint("TOPRIGHT", -4, -4)
+		SV.API:Set("CloseButton", frame.closeButton);
+		frame.closeButton:SetScript("PostClick", function()
+			if(not InCombatLockdown()) then CloseBag(0) end
+		end)
+
+		frame.holderFrame = CreateFrame("Frame", nil, frame)
+		frame.holderFrame:SetPoint("TOP", frame, "TOP", 0, -frame.topOffset)
+		frame.holderFrame:SetPoint("BOTTOM", frame, "BOTTOM", 0, frame.bottomOffset)
+
+		frame.Title = frame:CreateFontString()
+		frame.Title:SetFontObject(SVUI_Font_Header)
+		frame.Title:SetText(INVENTORY_TOOLTIP)
+		frame.Title:SetPoint("TOPLEFT", frame, "TOPLEFT", 2, -2)
+		frame.Title:SetTextColor(1,0.8,0)
+
+		frame.BagMenu = CreateFrame("Button", "SVUI_ContainerFrameBagMenu", frame)
+		frame.BagMenu:SetPoint("BOTTOMLEFT", frame, "TOPLEFT", 0, 1)
+		frame.BagMenu:SetStyle("!_Frame", "Transparent")
+		frame.BagMenu:Hide()
+
+		frame.goldText = frame:CreateFontString(nil, "OVERLAY")
+		frame.goldText:SetFontObject(SVUI_Font_Bag_Number)
+		frame.goldText:SetPoint("BOTTOMRIGHT", frame.holderFrame, "TOPRIGHT", -2, 4)
+		frame.goldText:SetJustifyH("RIGHT")
+
+		frame.goldInfo = CreateFrame("Frame", nil, frame)
+		frame.goldInfo:SetAllPoints(frame.goldText)
+		frame.goldInfo:SetScript("OnEnter", TopInfo_OnEnter)
+
+		frame.editBox = CreateFrame("EditBox", "SVUI_ContainerFrameEditBox", frame)
+		frame.editBox:SetStyle("Editbox")
+		frame.editBox:SetHeight(15)
+		frame.editBox:Hide()
+		frame.editBox:SetPoint("BOTTOMLEFT", frame.holderFrame, "TOPLEFT", 2, 4)
+		frame.editBox:SetPoint("RIGHT", frame.goldText, "LEFT", -5, 0)
+		frame.editBox:SetAutoFocus(true)
+		frame.editBox:SetScript("OnEscapePressed", InventorySearch_OnReset)
+		frame.editBox:SetScript("OnEnterPressed", InventorySearch_OnReset)
+		frame.editBox:SetScript("OnEditFocusLost", frame.editBox.Hide)
+		frame.editBox:SetScript("OnEditFocusGained", frame.editBox.HighlightText)
+		frame.editBox:SetScript("OnTextChanged", InventorySearch_OnTextChanged)
+		frame.editBox:SetScript("OnChar", InventorySearch_OnChar)
+		frame.editBox.SearchReset = InventorySearch_OnReset
+		frame.editBox:SetText(SEARCH)
+		frame.editBox:SetFontObject(SVUI_Font_Bag)
+
+		local searchButton = CreateFrame("Button", nil, frame)
+		searchButton:RegisterForClicks("LeftButtonUp", "RightButtonUp")
+		searchButton:SetSize(60, 18)
+		searchButton:SetPoint("BOTTOMLEFT", frame.editBox, "BOTTOMLEFT", -2, 0)
+		searchButton:SetStyle("Button")
+		searchButton:SetScript("OnClick", Search_OnClick)
+		local searchText = searchButton:CreateFontString(nil, "OVERLAY")
+		searchText:SetFontObject(SVUI_Font_Bag)
+		searchText:SetAllPoints(searchButton)
+		searchText:SetJustifyH("CENTER")
+		searchText:SetText("|cff9999ff"..SEARCH.."|r")
+		searchButton:SetFontString(searchText)
+		frame.detail = searchButton
+		frame.editBox.button = frame.detail;
+
+		frame.sortButton = CreateFrame("Button", nil, frame)
+		frame.sortButton:SetPoint("TOP", frame, "TOP", 0, -10)
+		frame.sortButton:SetSize(25, 25)
+		StyleBagToolButton(frame.sortButton, MOD.media.cleanupIcon)
+		frame.sortButton.ttText = L["Sort Bags"]
+		frame.sortButton.ttText2 = L["[SHIFT + CLICK]"]
+		frame.sortButton.ttText2desc = L["Filtered Cleanup (Default Sorting)"]
+		frame.sortButton:SetScript("OnEnter", Tooltip_Show)
+		frame.sortButton:SetScript("OnLeave", Tooltip_Hide)
+		local Sort_OnClick = MOD:RunSortingProcess(MOD.Sort, "bags", SortBags)
+		frame.sortButton:SetScript("OnClick", Sort_OnClick)
+
+		frame.stackButton = CreateFrame("Button", nil, frame)
+		frame.stackButton:SetPoint("LEFT", frame.sortButton, "RIGHT", 10, 0)
+		frame.stackButton:SetSize(25, 25)
+		StyleBagToolButton(frame.stackButton, MOD.media.stackIcon)
+		frame.stackButton.ttText = L["Stack Items"]
+		frame.stackButton:SetScript("OnEnter", Tooltip_Show)
+		frame.stackButton:SetScript("OnLeave", Tooltip_Hide)
+		local Stack_OnClick = MOD:RunSortingProcess(MOD.Stack, "bags")
+		frame.stackButton:SetScript("OnClick", Stack_OnClick)
+
+		frame.vendorButton = CreateFrame("Button", nil, frame)
+		frame.vendorButton:SetPoint("RIGHT", frame.sortButton, "LEFT", -10, 0)
+		frame.vendorButton:SetSize(25, 25)
+		StyleBagToolButton(frame.vendorButton, MOD.media.vendorIcon)
+		frame.vendorButton.ttText = L["Vendor Grays"]
+		frame.vendorButton.ttText2 = L["Hold Shift:"]
+		frame.vendorButton.ttText2desc = L["Delete Grays"]
+		frame.vendorButton:SetScript("OnEnter", Tooltip_Show)
+		frame.vendorButton:SetScript("OnLeave", Tooltip_Hide)
+		frame.vendorButton:SetScript("OnClick", Vendor_OnClick)
+
+		frame.bagsButton = CreateFrame("Button", nil, frame)
+		frame.bagsButton:SetPoint("RIGHT", frame.vendorButton, "LEFT", -10, 0)
+		frame.bagsButton:SetSize(25, 25)
+		StyleBagToolButton(frame.bagsButton, MOD.media.bagIcon)
+		frame.bagsButton.ttText = L["Toggle Bags"]
+		frame.bagsButton:SetScript("OnEnter", Tooltip_Show)
+		frame.bagsButton:SetScript("OnLeave", Tooltip_Hide)
+		local BagBtn_OnClick = function()
+			PlaySound("igMainMenuOption");
+			if(BagFilters and BagFilters:IsShown()) then
+				ToggleFrame(BagFilters)
+			end
+			ToggleFrame(frame.BagMenu)
+		end
+		frame.bagsButton:SetScript("OnClick", BagBtn_OnClick)
+
+		frame.transferButton = CreateFrame("Button", nil, frame)
+		frame.transferButton:SetPoint("LEFT", frame.stackButton, "RIGHT", 10, 0)
+		frame.transferButton:SetSize(25, 25)
+		StyleBagToolButton(frame.transferButton, MOD.media.transferIcon)
+		frame.transferButton.ttText = L["Stack Bags to Bank"]
+		frame.transferButton:SetScript("OnEnter", Tooltip_Show)
+		frame.transferButton:SetScript("OnLeave", Tooltip_Hide)
+		local Transfer_OnClick = MOD:RunSortingProcess(MOD.Transfer, "bags bank")
+		frame.transferButton:SetScript("OnClick", Transfer_OnClick)
+
+		frame.currencyButton = CreateFrame("Frame", nil, frame)
+		frame.currencyButton:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", 4, 0)
+		frame.currencyButton:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -4, 0)
+		frame.currencyButton:SetHeight(32)
+
+		for h = 1, MAX_WATCHED_TOKENS do
+			frame.currencyButton[h] = CreateFrame("Button", nil, frame.currencyButton)
+			frame.currencyButton[h]:SetSize(22, 22)
+			frame.currencyButton[h]:SetStyle("!_Frame", "Default")
+			frame.currencyButton[h]:SetID(h)
+			frame.currencyButton[h].icon = frame.currencyButton[h]:CreateTexture(nil, "OVERLAY")
+			frame.currencyButton[h].icon:InsetPoints()
+			frame.currencyButton[h].icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+			frame.currencyButton[h].text = frame.currencyButton[h]:CreateFontString(nil, "OVERLAY")
+			frame.currencyButton[h].text:SetPoint("LEFT", frame.currencyButton[h], "RIGHT", 2, 0)
+			frame.currencyButton[h].text:SetFontObject(SVUI_Font_Bag_Number)
+			frame.currencyButton[h]:SetScript("OnEnter", Token_OnEnter)
+			frame.currencyButton[h]:SetScript("OnLeave", Token_OnLeave)
+			frame.currencyButton[h]:SetScript("OnClick", Token_OnClick)
+			frame.currencyButton[h]:Hide()
+		end
+
+		if(SV.db.Inventory.separateBags) then
+			for i, bagID in ipairs(frame.BagIDs) do
+				if(bagID > 0) then
+					local singleBagFrameName = "SVUI_ContainerFrameBag" .. bagID;
+					local singleBagFrame = CreateFrame("Button", singleBagFrameName, frame);
+					tinsert(UISpecialFrames, singleBagFrameName);
+
+					if(bagID == 1) then
+						singleBagFrame:SetPoint("TOPRIGHT", frame, "BOTTOMRIGHT", 0, -4)
+					elseif(bagID == 2) then
+						singleBagFrame:SetPoint("TOPRIGHT", _G['SVUI_ContainerFrameBag1'], "TOPLEFT", -4, 0)
+					elseif(bagID == 3) then
+						singleBagFrame:SetPoint("TOPRIGHT", _G['SVUI_ContainerFrameBag1'], "BOTTOMRIGHT", 0, -4)
+					else
+						singleBagFrame:SetPoint("TOPRIGHT", _G['SVUI_ContainerFrameBag3'], "TOPLEFT", -4, 0)
+					end
+
+					singleBagFrame:SetStyle("Frame", "Pattern")
+					singleBagFrame:SetFrameStrata("HIGH")
+					singleBagFrame:SetMovable(true)
+					singleBagFrame:RegisterForDrag("LeftButton", "RightButton")
+					singleBagFrame:RegisterForClicks("AnyUp")
+					singleBagFrame:SetID(bagID);
+					singleBagFrame.SlotUpdate = SlotUpdate;
+					singleBagFrame.RefreshSlots = ContainerFrame_RefreshSlots;
+
+					singleBagFrame.closeButton = CreateFrame("Button", singleBagFrameName .. "CloseButton", singleBagFrame, "UIPanelCloseButton")
+					singleBagFrame.closeButton:SetPoint("TOPRIGHT", -4, -4)
+					SV.API:Set("CloseButton", singleBagFrame.closeButton);
+					singleBagFrame.closeButton:SetScript("PostClick", function()
+						if(not InCombatLockdown()) then CloseBag(bagID) end
+					end)
+
+					singleBagFrame.holderFrame = CreateFrame("Frame", nil, singleBagFrame)
+					singleBagFrame.holderFrame:SetPoint("TOPLEFT", singleBagFrame, "TOPLEFT", 8, -42)
+					singleBagFrame.holderFrame:SetPoint("BOTTOMRIGHT", singleBagFrame, "BOTTOMRIGHT", -8, 8)
+
+					singleBagFrame:SetScript("OnDragStart", Container_OnDragStart)
+					singleBagFrame:SetScript("OnDragStop", Container_OnDragStop)
+					singleBagFrame:SetScript("OnClick", Container_OnClick)
+					singleBagFrame:SetScript("OnEnter", Container_OnEnter)
+					singleBagFrame:SetScript("OnLeave", Token_OnLeave)
+					singleBagFrame:SetScript("OnHide", Container_OnHide)
+					singleBagFrame:SetScript("OnShow", Container_OnShow)
+
+					frame.Bags[bagID] = singleBagFrame;
+				end
+			end
+		end
+
+		self.MasterFrame = frame
+	end
+
+	function MOD:CreateBankOrReagentFrame(isReagent)
+		-- Reagent Slots: 1 - 98
+		-- /script print(ReagentBankFrameItem1:GetInventorySlot())
+		local bagName = isReagent and "SVUI_ReagentContainerFrame" or "SVUI_BankContainerFrame"
+		local uisCount = #UISpecialFrames + 1;
+
+		local frame = CreateFrame("Button", bagName, isReagent and self.BankFrame or SV.Screen)
+		frame:SetStyle("Frame", "Pattern")
+		frame:SetFrameStrata("HIGH")
+		frame:SetFrameLevel(self.MasterFrame:GetFrameLevel() + 99)
+
+		frame.UpdateLayout = isReagent and ReagentFrame_UpdateLayout or ContainerFrame_UpdateLayout;
+		frame.RefreshBags = ContainerFrame_UpdateBags;
+		frame.RefreshCooldowns = ContainerFrame_UpdateCooldowns;
+
+		frame:RegisterEvent("ITEM_LOCK_CHANGED")
+		frame:RegisterEvent("ITEM_UNLOCKED")
+		frame:RegisterEvent("BAG_UPDATE_COOLDOWN")
+		frame:RegisterEvent("BAG_UPDATE")
+		frame:RegisterEvent("EQUIPMENT_SETS_CHANGED")
+		frame:RegisterEvent("PLAYERBANKSLOTS_CHANGED")
+		frame:RegisterEvent("PLAYERREAGENTBANKSLOTS_CHANGED")
+
+		frame:SetMovable(true)
+		frame:RegisterForDrag("LeftButton", "RightButton")
+		frame:RegisterForClicks("AnyUp")
+		frame:SetScript("OnDragStart", Container_OnDragStart)
+		frame:SetScript("OnDragStop", Container_OnDragStop)
+		frame:SetScript("OnClick", Container_OnClick)
+		frame:SetScript("OnEnter", Container_OnEnter)
+		frame:SetScript("OnLeave", Token_OnLeave)
+		self:SetContainerEvents(frame)
+
+		frame.isBank = true;
+		frame.isReagent = isReagent;
+		frame:Hide()
+		frame.bottomOffset = 8;
+		frame.topOffset = 60;
+
+		if(isReagent) then
+			frame.BagIDs = {REAGENTBANK_CONTAINER}
+		else
+			frame.BagIDs = {-1, 5, 6, 7, 8, 9, 10, 11}
+		end
+
+		frame.Bags = {}
+
+		frame.closeButton = CreateFrame("Button", bagName.."CloseButton", frame, "UIPanelCloseButton")
+		frame.closeButton:SetPoint("TOPRIGHT", -4, -4)
+		SV.API:Set("CloseButton", frame.closeButton);
+		frame.closeButton:SetScript("PostClick", function()
+			if(not InCombatLockdown()) then CloseBag(0) end
+		end)
+
+		frame.holderFrame = CreateFrame("Frame", nil, frame)
+		frame.holderFrame:SetPoint("TOP", frame, "TOP", 0, -frame.topOffset)
+		frame.holderFrame:SetPoint("BOTTOM", frame, "BOTTOM", 0, frame.bottomOffset)
+
+		frame.Title = frame:CreateFontString()
+		frame.Title:SetFontObject(SVUI_Font_Header)
+		frame.Title:SetText(isReagent and REAGENT_BANK or BANK or "Bank")
+		frame.Title:SetPoint("TOPLEFT", frame, "TOPLEFT", 2, -2)
+		frame.Title:SetTextColor(1,0.8,0)
+
+		frame.sortButton = CreateFrame("Button", nil, frame)
+		frame.sortButton:SetPoint("TOPRIGHT", frame, "TOP", 0, -10)
+		frame.sortButton:SetSize(25, 25)
+		StyleBagToolButton(frame.sortButton, MOD.media.cleanupIcon)
+		frame.sortButton.ttText = L["Sort Bank"]
+		frame.sortButton.ttText2 = L["[SHIFT + CLICK]"]
+		frame.sortButton.ttText2desc = L["Filtered Cleanup (Default Sorting)"]
+		frame.sortButton:SetScript("OnEnter", Tooltip_Show)
+		frame.sortButton:SetScript("OnLeave", Tooltip_Hide)
+
+		frame.stackButton = CreateFrame("Button", nil, frame)
+		frame.stackButton:SetPoint("LEFT", frame.sortButton, "RIGHT", 10, 0)
+		frame.stackButton:SetSize(25, 25)
+		StyleBagToolButton(frame.stackButton, MOD.media.stackIcon)
+		frame.stackButton.ttText = L["Stack Items"]
+		frame.stackButton:SetScript("OnEnter", Tooltip_Show)
+		frame.stackButton:SetScript("OnLeave", Tooltip_Hide)
+
+		if(not isReagent) then
+			frame.BagMenu = CreateFrame("Button", bagName.."BagMenu", frame)
+			frame.BagMenu:SetPoint("BOTTOMLEFT", frame, "TOPLEFT", 0, 1)
+			frame.BagMenu:SetStyle("!_Frame", "Transparent")
+			frame.BagMenu:Hide()
+
+			local Sort_OnClick = MOD:RunSortingProcess(MOD.Sort, "bank", SortBankBags)
+			frame.sortButton:SetScript("OnClick", Sort_OnClick)
+			local Stack_OnClick = MOD:RunSortingProcess(MOD.Stack, "bank")
+			frame.stackButton:SetScript("OnClick", Stack_OnClick)
+
+			frame.transferButton = CreateFrame("Button", nil, frame)
+			frame.transferButton:SetPoint("LEFT", frame.stackButton, "RIGHT", 10, 0)
+			frame.transferButton:SetSize(25, 25)
+			StyleBagToolButton(frame.transferButton, MOD.media.transferIcon)
+			frame.transferButton.ttText = L["Stack Bank to Bags"]
+			frame.transferButton:SetScript("OnEnter", Tooltip_Show)
+			frame.transferButton:SetScript("OnLeave", Tooltip_Hide)
+			local Transfer_OnClick = MOD:RunSortingProcess(MOD.Transfer, "bank bags")
+			frame.transferButton:SetScript("OnClick", Transfer_OnClick)
+
+			tinsert(UISpecialFrames, bagName)
+
+			frame.bagsButton = CreateFrame("Button", nil, frame)
+			frame.bagsButton:SetPoint("RIGHT", frame.sortButton, "LEFT", -10, 0)
+			frame.bagsButton:SetSize(25, 25)
+			StyleBagToolButton(frame.bagsButton, MOD.media.bagIcon)
+			frame.bagsButton.ttText = L["Toggle Bags"]
+			frame.bagsButton:SetScript("OnEnter", Tooltip_Show)
+			frame.bagsButton:SetScript("OnLeave", Tooltip_Hide)
+			local BagBtn_OnClick = function()
+				PlaySound("igMainMenuOption");
+				if(BagFilters and BagFilters:IsShown()) then
+					ToggleFrame(BagFilters)
+				end
+				local numSlots, _ = GetNumBankSlots()
+				if numSlots  >= 1 then
+					ToggleFrame(frame.BagMenu)
+				else
+					SV:StaticPopup_Show("NO_BANK_BAGS")
+				end
+			end
+			frame.bagsButton:SetScript("OnClick", BagBtn_OnClick)
+
+			frame.purchaseBagButton = CreateFrame("Button", nil, frame)
+			frame.purchaseBagButton:SetSize(25, 25)
+			frame.purchaseBagButton:SetPoint("RIGHT", frame.bagsButton, "LEFT", -10, 0)
+			frame.purchaseBagButton:SetFrameLevel(frame.purchaseBagButton:GetFrameLevel()+2)
+			StyleBagToolButton(frame.purchaseBagButton, MOD.media.purchaseIcon)
+			frame.purchaseBagButton.ttText = L["Purchase"]
+			frame.purchaseBagButton:SetScript("OnEnter", Tooltip_Show)
+			frame.purchaseBagButton:SetScript("OnLeave", Tooltip_Hide)
+			local PurchaseBtn_OnClick = function()
+				PlaySound("igMainMenuOption");
+				local _, full = GetNumBankSlots()
+				if not full then
+					SV:StaticPopup_Show("BUY_BANK_SLOT")
+				else
+					SV:StaticPopup_Show("CANNOT_BUY_BANK_SLOT")
+				end
+			end
+			frame.purchaseBagButton:SetScript("OnClick", PurchaseBtn_OnClick)
+
+			local active_icon = IsReagentBankUnlocked() and MOD.media.reagentIcon or MOD.media.purchaseIcon
+			frame.swapButton = CreateFrame("Button", nil, frame)
+			frame.swapButton:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -40, -10)
+			frame.swapButton:SetSize(25, 25)
+			StyleBagToolButton(frame.swapButton, active_icon)
+			frame.swapButton.ttText = L["Toggle Reagents Bank"]
+			frame.swapButton:SetScript("OnEnter", function(self)
+				GameTooltip:SetOwner(self:GetParent(),"ANCHOR_TOP",0,4)
+				GameTooltip:ClearLines()
+				if(not IsReagentBankUnlocked()) then
+					GameTooltip:AddDoubleLine("Purchase Reagents Bank", SV:FormatCurrency(GetReagentBankCost()), 0.1,1,0.1, 1,1,1)
+				else
+					GameTooltip:AddLine(self.ttText)
+				end
+				self:GetNormalTexture():SetGradient(unpack(SV.media.gradient.highlight))
+				GameTooltip:Show()
+			end)
+			frame.swapButton:SetScript("OnLeave", Tooltip_Hide)
+			frame.swapButton:SetScript("OnClick", function()
+				if(not IsReagentBankUnlocked()) then
+					SV:StaticPopup_Show("CONFIRM_BUY_REAGENTBANK_TAB");
+				else
+					PlaySound("igMainMenuOption");
+					if(_G["SVUI_ReagentContainerFrame"]:IsShown()) then
+						_G["SVUI_ReagentContainerFrame"]:Hide()
+					else
+						_G["SVUI_ReagentContainerFrame"]:Show()
+					end
+				end
+			end)
+			frame:SetScript("OnHide", CloseBankFrame)
+			self.BankFrame = frame
+		else
+			local Sort_OnClick = MOD:RunSortingProcess(MOD.Sort, "reagent", SortBankBags)
+			frame.sortButton:SetScript("OnClick", Sort_OnClick)
+			local Stack_OnClick = MOD:RunSortingProcess(MOD.Stack, "reagent")
+			frame.stackButton:SetScript("OnClick", Stack_OnClick)
+
+			frame.transferButton = CreateFrame("Button", nil, frame)
+			frame.transferButton:SetPoint("LEFT", frame.stackButton, "RIGHT", 10, 0)
+			frame.transferButton:SetSize(25, 25)
+			StyleBagToolButton(frame.transferButton, MOD.media.depositIcon)
+			frame.transferButton.ttText = L["Deposit All Reagents"]
+			frame.transferButton:SetScript("OnEnter", Tooltip_Show)
+			frame.transferButton:SetScript("OnLeave", Tooltip_Hide)
+			frame.transferButton:SetScript("OnClick", DepositReagentBank)
+
+			frame:SetPoint("BOTTOMLEFT", self.BankFrame, "BOTTOMRIGHT", 2, 0)
+			self.ReagentFrame = frame
+		end
+
+		SV:UpdateSharedMedia()
+	end
+end
+
+function MOD:RefreshTokens()
+	local frame = MOD.MasterFrame;
+	local index = 0;
+
+	for i=1,MAX_WATCHED_TOKENS do
+		local name,count,icon,currencyID = GetBackpackCurrencyInfo(i)
+		local set = frame.currencyButton[i]
+		set:ClearAllPoints()
+		if name then
+			set.icon:SetTexture(icon)
+			if SV.db.Inventory.currencyFormat == 'ICON_TEXT' then
+				set.text:SetText(name..': '..count)
+			elseif SV.db.Inventory.currencyFormat == 'ICON' then
+				set.text:SetText(count)
+			end
+			set.currencyID = currencyID;
+			set:Show()
+			index = index + 1;
+		else
+			set:Hide()
+		end
+	end
+
+	if index == 0 then
+		frame.bottomOffset = 8;
+		if frame.currencyButton:IsShown() then
+			frame.currencyButton:Hide()
+			MOD.MasterFrame:UpdateLayout()
+		end
+		return
+	elseif not frame.currencyButton:IsShown() then
+		frame.bottomOffset = 28;
+		frame.currencyButton:Show()
+		MOD.MasterFrame:UpdateLayout()
+	end
+
+	frame.bottomOffset = 28;
+	local set = frame.currencyButton;
+	if index == 1 then
+		set[1]:SetPoint("BOTTOM", set, "BOTTOM", -(set[1].text:GetWidth() / 2), 3)
+	elseif index == 2 then
+		set[1]:SetPoint("BOTTOM", set, "BOTTOM", -set[1].text:GetWidth()-set[1]:GetWidth() / 2, 3)
+		frame.currencyButton[2]:SetPoint("BOTTOMLEFT", set, "BOTTOM", set[2]:GetWidth() / 2, 3)
+	else
+		set[1]:SetPoint("BOTTOMLEFT", set, "BOTTOMLEFT", 3, 3)
+		set[2]:SetPoint("BOTTOM", set, "BOTTOM", -(set[2].text:GetWidth() / 3), 3)
+		set[3]:SetPoint("BOTTOMRIGHT", set, "BOTTOMRIGHT", -set[3].text:GetWidth()-set[3]:GetWidth() / 2, 3)
+	end
+end
+
+local function _isBagOpen(bagID)
+	if(MOD.MasterFrame.Bags[0] and MOD.MasterFrame.Bags[0]:IsShown()) then
+		return true
+	elseif(MOD.BankFrame.Bags[bagID] and MOD.BankFrame.Bags[bagID]:IsShown()) then
+		return true
+	end
+	return nil;
+end
+
+local function _openBags()
+	--print('_openBags')
+	GameTooltip:Hide()
+	if(not MOD.MasterFrame:IsShown()) then
+		MOD.MasterFrame:Show()
+		MOD.MasterFrame:RefreshBags()
+		if(SV.Tooltip) then
+			SV.Tooltip.GameTooltip_SetDefaultAnchor(GameTooltip)
+		end
+		MOD.MasterFrame.editBox:SearchReset()
+	end
+end
+
+local function _closeBags()
+	--print('_closeBags')
+	GameTooltip:Hide()
+	if(MOD.MasterFrame:IsShown()) then
+		MOD.MasterFrame:Hide()
+		if(MOD.BankFrame) then
+			MOD.BankFrame:Hide()
+		end
+		if(MOD.ReagentFrame) then
+			MOD.ReagentFrame:Hide()
+		end
+		if(SV.Dock.CloseBreakStuff) then
+			SV.Dock:CloseBreakStuff()
+		end
+		if(SV.Tooltip) then
+			SV.Tooltip.GameTooltip_SetDefaultAnchor(GameTooltip)
+		end
+		MOD.MasterFrame.editBox:SearchReset()
+	end
+	NEXT_ACTION_TOGGLED = false
+end
+
+local function _openAllBags()
+	--print('OpenAllBags --------->')
+	NEXT_ACTION_ALLOWED = true
+	NEXT_ACTION_TOGGLED = false
+	NEXT_ACTION_FORCED = false
+	_openBags()
+end
+
+local function _closeAllBags()
+	--print('<--------- CloseAllBags')
+	FORCED_OPEN = false
+	FORCED_CLOSED = false
+	NEXT_ACTION_ALLOWED = true
+	NEXT_ACTION_FORCED = true
+	NEXT_ACTION_TOGGLED = false
+	_closeBags()
+end
+
+local function _openBackpack()
+	--print('OpenBackpack --------->')
+	if(FORCED_OPEN) then
+		FORCED_OPEN = false
+		FORCED_CLOSED = true
+		ToggleBag(0)
+		CloseAllBags()
+	else
+		--FORCED_CLOSED = NEXT_ACTION_FORCED
+		NEXT_ACTION_ALLOWED = true
+		if(NEXT_ACTION_TOGGLED) then
+			_openBags()
+		end
+	end
+	NEXT_ACTION_FORCED = false
+end
+
+local function _closeBackpack()
+	--print('<--------- CloseBackpack')
+	if(FORCED_CLOSED) then
+		FORCED_OPEN = true
+		FORCED_CLOSED = false
+		CloseAllBags()
+		ToggleBag(0)
+	else
+		NEXT_ACTION_ALLOWED = NEXT_ACTION_FORCED
+		FORCED_OPEN = NEXT_ACTION_FORCED
+		if(NEXT_ACTION_TOGGLED) then
+			_closeBags()
+		end
+	end
+	NEXT_ACTION_FORCED = false
+end
+
+local function _toggleByID(bagID)
+	if(not bagID) then return end
+	local size = GetContainerNumSlots(bagID);
+	if((size > 0) or (bagID == KEYRING_CONTAINER)) then
+		--print('ToggleBag: '..bagID)
+		if(not MOD.MasterFrame:IsShown()) then
+			_openBags()
+		end
+		if(MOD.MasterFrame.Bags[bagID]) then
+			MOD.MasterFrame.Bags[bagID]:RefreshSlots()
+		elseif(MOD.BankFrame and MOD.BankFrame.Bags[bagID]) then
+			MOD.BankFrame.Bags[bagID]:RefreshSlots()
+		elseif(MOD.ReagentFrame and MOD.ReagentFrame.Bags[bagID]) then
+			MOD.ReagentFrame.Bags[bagID]:RefreshSlots()
+		end
+	end
+end
+
+local function _toggleAllBags()
+	--print('[[ ToggleAllBags ]]')
+	NEXT_ACTION_TOGGLED = true
+	if(NEXT_ACTION_ALLOWED) then
+		_openBags()
+	else
+		_closeBags()
+	end
+end
+
+local function _toggleBackpack()
+	--print('[[ ToggleBackpack ]]')
+	NEXT_ACTION_TOGGLED = true
+end
+
+local function _closeSpecialWindows()
+	--print('<--------- CloseSpecialWindows')
+	CloseAllBags()
+end
+
+local _hook_OnModifiedClick = function(self, button)
+	if(MerchantFrame and MerchantFrame:IsShown()) then return end;
+    if(IsAltKeyDown() and (button == "RightButton")) then
+    	local slotID = self:GetID()
+    	local bagID = self:GetParent():GetID()
+    	local itemID = GetContainerItemID(bagID, slotID);
+    	if(itemID) then
+    		if(MOD.private.junk[itemID]) then
+    			if(self.JunkIcon) then self.JunkIcon:Hide() end
+    			MOD.private.junk[itemID] = nil
+	    	else
+	    		if(self.JunkIcon) then self.JunkIcon:Show() end
+	    		MOD.private.junk[itemID] = true
+	    	end
+    	end
+    end
+end
+
+function MOD:BANKFRAME_OPENED()
+	if(not self.BankFrame) then
+		self:CreateBankOrReagentFrame()
+	end
+	self.BankFrame:UpdateLayout()
+
+	if(not self.ReagentFrame) then
+		self:CreateBankOrReagentFrame(true)
+	end
+
+	if(self.ReagentFrame) then
+		self.ReagentFrame:UpdateLayout()
+	end
+
+	self:ModifyBags()
+
+	self.BankFrame:Show()
+	self.BankFrame:RefreshBags()
+	self.MasterFrame:Show()
+	self.MasterFrame:RefreshBags()
+	self.RefreshTokens()
+end
+
+function MOD:BANKFRAME_CLOSED()
+	if(self.BankFrame and self.BankFrame:IsShown()) then
+		self.BankFrame:Hide()
+	end
+	if(self.ReagentFrame and self.ReagentFrame:IsShown()) then
+		self.ReagentFrame:Hide()
+	end
+end
+
+function MOD:PLAYERBANKBAGSLOTS_CHANGED()
+	if(self.BankFrame) then
+		self.BankFrame:UpdateLayout()
+	end
+	if(self.ReagentFrame) then
+		self.ReagentFrame:UpdateLayout()
+	end
+end
+
+function MOD:PLAYER_ENTERING_WORLD()
+	self:UpdateGoldText()
+	self.MasterFrame:RefreshBags()
+end
+
+local function ResetInventoryLogs()
+	if MOD.public[realmKey] then
+		if MOD.public[realmKey]["loot"] and MOD.public[realmKey]["loot"][nameKey] then MOD.public[realmKey]["loot"][nameKey] = {} end
+		if MOD.public[realmKey]["gold"] and MOD.public[realmKey]["gold"][nameKey] then MOD.public[realmKey]["gold"][nameKey] = 0 end
+	end
+end
+--[[
+##########################################################
+BUILD FUNCTION / UPDATE
+##########################################################
+]]--
+function MOD:ReLoad()
+	self:RefreshBagFrames()
+	self:ModifyBags();
+	self:ModifyBagBar();
+end
+
+function MOD:Load()
+	local r,g,b = RAID_CLASS_COLORS[toonClass].r, RAID_CLASS_COLORS[toonClass].g, RAID_CLASS_COLORS[toonClass].b;
+	local hexString = ("|cff%02x%02x%02x"):format(r * 255, g * 255, b * 255);
+
+	if(not LOOT_CACHE) then LOOT_CACHE = {} end
+
+	if(not self.private) then self.private = {} end
+	if(not self.private.junk) then self.private.junk = {} end
+	if(not self.public) then self.public = {} end
+	if(not self.public[realmKey]) then
+		self.public[realmKey] = {}
+	end
+	if(not self.public[realmKey]["loot"]) then
+		self.public[realmKey]["loot"] = {}
+	end
+	if(not self.public[realmKey]["info"]) then
+		self.public[realmKey]["info"] = {}
+	end
+	if(not self.public[realmKey]["loot"][nameKey]) then
+		self.public[realmKey]["loot"][nameKey] = {}
+	end
+	if(not self.public[realmKey]["info"][nameKey]) then
+		self.public[realmKey]["info"][nameKey] = hexString;
+	end
+
+	-- REMOVE DEPRECATED STORAGE
+	if(self.public[realmKey]["bags"]) then
+		local old = self.public[realmKey]["bags"]
+		for toon,data in pairs(old) do
+			if(not self.public[realmKey]["loot"][toon]) then self.public[realmKey]["loot"][toon] = {} end
+			for bag,items in pairs(data) do
+				for itemKey,amt in pairs(items) do
+					local lastAmt = self.public[realmKey]["loot"][toon][itemKey] or 0;
+					self.public[realmKey]["loot"][toon][itemKey] = (lastAmt + amt)
+				end
+			end
+		end
+		self.public[realmKey]["bags"] = nil
+	end
+
+	for index,_ in pairs(self.public[realmKey]["loot"][nameKey]) do
+		if(type(index) ~= string) then
+			self.public[realmKey]["loot"][nameKey][index] = nil
+		end
+	end
+
+	self:UpdateStockpile();
+
+	local journal = self.public[realmKey]["loot"]
+	for altName,items in pairs(journal) do
+		if(altName ~= nameKey) then
+			for itemKey,amt in pairs(items) do
+				if(not LOOT_CACHE[itemKey]) then
+					LOOT_CACHE[itemKey] = {}
+				end
+				LOOT_CACHE[itemKey][altName] = amt
+			end
+		end
+	end
+
+	self:ModifyBagBar()
+	self:CreateMasterFrame()
+	self.MasterFrame:UpdateLayout()
+	self:ModifyBags()
+
+	self:InitializeMenus()
+
+	BankFrame:UnregisterAllEvents()
+	for i = 1, NUM_CONTAINER_FRAMES do
+		local frame = _G["ContainerFrame"..i]
+		if(frame) then frame:Die() end
+	end
+
+	hooksecurefunc("OpenAllBags", _openAllBags)
+	hooksecurefunc("CloseAllBags", _closeAllBags)
+	hooksecurefunc("OpenBackpack", _openBackpack)
+	hooksecurefunc("CloseBackpack", _closeBackpack)
+	hooksecurefunc("ToggleBag", _toggleByID)
+	hooksecurefunc("ToggleAllBags", _toggleAllBags)
+	hooksecurefunc("ToggleBackpack", _toggleBackpack)
+
+	hooksecurefunc("BackpackTokenFrame_Update", self.RefreshTokens)
+	hooksecurefunc("ContainerFrameItemButton_OnModifiedClick", _hook_OnModifiedClick)
+
+	SV.Events:On("SPECIAL_FRAMES_CLOSED", _closeSpecialWindows, true);
+	SV.Events:On("FULL_UI_RESET", ResetInventoryLogs, true);
+
+	self:RegisterEvent("BANKFRAME_OPENED")
+	self:RegisterEvent("BANKFRAME_CLOSED")
+	self:RegisterEvent("INVENTORY_SEARCH_UPDATE")
+	self:RegisterEvent("PLAYER_MONEY", "UpdateGoldText")
+	self:RegisterEvent("PLAYER_ENTERING_WORLD")
+	self:RegisterEvent("PLAYER_TRADE_MONEY", "UpdateGoldText")
+	self:RegisterEvent("TRADE_MONEY_CHANGED", "UpdateGoldText")
+	self:RegisterEvent("PLAYERBANKBAGSLOTS_CHANGED")
+
+	StackSplitFrame:SetFrameStrata("DIALOG")
+
+	SV.SystemAlert["BUY_BANK_SLOT"] = {
+		text = CONFIRM_BUY_BANK_SLOT,
+		button1 = YES,
+		button2 = NO,
+		OnAccept = function(self) PurchaseSlot() end,
+		OnShow = function(self) MoneyFrame_Update(self.moneyFrame, GetBankSlotCost()) end,
+		hasMoneyFrame = 1,
+		timeout = 0,
+		hideOnEscape = 1
+	};
+
+	SV.SystemAlert["CONFIRM_BUY_REAGENTBANK_TAB"] = {
+		text = L["Purchase Reagents Bank?"],
+		button1 = YES,
+		button2 = NO,
+		OnAccept = function(self) BuyReagentBank() end,
+		OnShow = function(self)
+			MoneyFrame_Update(self.moneyFrame, GetReagentBankCost());
+			if(MOD.ReagentFrame) then
+				MOD.ReagentFrame:UpdateLayout()
+				MOD.ReagentFrame:Show()
+				if(MOD.ReagentFrame.swapButton) then
+					MOD.ReagentFrame.swapButton:SetNormalTexture(MOD.media.reagentIcon)
+				end
+			end
+		end,
+		hasMoneyFrame = 1,
+		timeout = 0,
+		hideOnEscape = 1
+	};
+
+	SV.SystemAlert["CANNOT_BUY_BANK_SLOT"] = {
+		text = L["Can't buy anymore slots!"],
+		button1 = ACCEPT,
+		timeout = 0,
+		whileDead = 1
+	};
+
+	SV.SystemAlert["NO_BANK_BAGS"] = {
+		text = L["You must purchase a bank slot first!"],
+		button1 = ACCEPT,
+		timeout = 0,
+		whileDead = 1
+	};
+end
diff --git a/SVUI_Inventory/SVUI_Inventory.toc b/SVUI_Inventory/SVUI_Inventory.toc
new file mode 100644
index 0000000..53b85a0
--- /dev/null
+++ b/SVUI_Inventory/SVUI_Inventory.toc
@@ -0,0 +1,18 @@
+## Interface: 70000
+## Author: Failcoder
+## Version: 1.3.5
+## Title: |cffFF9900SuperVillain UI: |r|cffFFEF00Inventory|r
+## Notes: Inventory Plugin for [|cff9911FFSVUI|r].
+## SavedVariables: SVUI_LootCache
+## SavedVariablesPerCharacter: SVUI_Private_LootCache
+## RequiredDeps: SVUI_!Core
+## OptionalDeps: LibSharedMedia-3.0
+## X-SVUIName: Inventory
+## X-SVUISchema: Inventory
+## X-Email: munglunch@gmail.com
+## X-Website: http://www.supervillainui.com
+## X-Donate: PayPal:munglunch@gmail.com
+## X-License: MIT
+## X-Category: Interface Enhancements
+
+SVUI_Inventory.xml
diff --git a/SVUI_Inventory/SVUI_Inventory.xml b/SVUI_Inventory/SVUI_Inventory.xml
new file mode 100644
index 0000000..d29577f
--- /dev/null
+++ b/SVUI_Inventory/SVUI_Inventory.xml
@@ -0,0 +1,32 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+	<Font name="SVUI_Font_Bag" font="Fonts\ARIALN.TTF" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="12"/>
+        </FontHeight>
+    </Font>
+    <Font name="SVUI_Font_Bag_Number" font="Fonts\MORPHEUS.ttf" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="11"/>
+        </FontHeight>
+    </Font>
+
+    <Frame name="SVUI_BagFilterMenu" frameStrata="DIALOG" hidden="true" />
+    <Frame name="SVUI_BagBar" frameStrata="DIALOG"/>
+
+	<Script file='Loader.lua'/>
+	<Script file='SVUI_Inventory.lua'/>
+	<Script file="components\organization.lua"/>
+	<Script file="components\sorting.lua"/>
+</Ui>
\ No newline at end of file
diff --git a/SVUI_Inventory/assets/BAGS-BAGS.blp b/SVUI_Inventory/assets/BAGS-BAGS.blp
new file mode 100644
index 0000000..89fca54
Binary files /dev/null and b/SVUI_Inventory/assets/BAGS-BAGS.blp differ
diff --git a/SVUI_Inventory/assets/BAGS-CLEANUP.blp b/SVUI_Inventory/assets/BAGS-CLEANUP.blp
new file mode 100644
index 0000000..514d5e0
Binary files /dev/null and b/SVUI_Inventory/assets/BAGS-CLEANUP.blp differ
diff --git a/SVUI_Inventory/assets/BAGS-DEPOSIT.blp b/SVUI_Inventory/assets/BAGS-DEPOSIT.blp
new file mode 100644
index 0000000..683d6a5
Binary files /dev/null and b/SVUI_Inventory/assets/BAGS-DEPOSIT.blp differ
diff --git a/SVUI_Inventory/assets/BAGS-PURCHASE.blp b/SVUI_Inventory/assets/BAGS-PURCHASE.blp
new file mode 100644
index 0000000..49f4726
Binary files /dev/null and b/SVUI_Inventory/assets/BAGS-PURCHASE.blp differ
diff --git a/SVUI_Inventory/assets/BAGS-REAGENTS.blp b/SVUI_Inventory/assets/BAGS-REAGENTS.blp
new file mode 100644
index 0000000..d77f134
Binary files /dev/null and b/SVUI_Inventory/assets/BAGS-REAGENTS.blp differ
diff --git a/SVUI_Inventory/assets/BAGS-SORT.blp b/SVUI_Inventory/assets/BAGS-SORT.blp
new file mode 100644
index 0000000..e1cc720
Binary files /dev/null and b/SVUI_Inventory/assets/BAGS-SORT.blp differ
diff --git a/SVUI_Inventory/assets/BAGS-STACK.blp b/SVUI_Inventory/assets/BAGS-STACK.blp
new file mode 100644
index 0000000..4dca557
Binary files /dev/null and b/SVUI_Inventory/assets/BAGS-STACK.blp differ
diff --git a/SVUI_Inventory/assets/BAGS-TRANSFER.blp b/SVUI_Inventory/assets/BAGS-TRANSFER.blp
new file mode 100644
index 0000000..ec1f188
Binary files /dev/null and b/SVUI_Inventory/assets/BAGS-TRANSFER.blp differ
diff --git a/SVUI_Inventory/assets/BAGS-VENDOR.blp b/SVUI_Inventory/assets/BAGS-VENDOR.blp
new file mode 100644
index 0000000..6106b38
Binary files /dev/null and b/SVUI_Inventory/assets/BAGS-VENDOR.blp differ
diff --git a/SVUI_Inventory/components/organization.lua b/SVUI_Inventory/components/organization.lua
new file mode 100644
index 0000000..75a1c32
--- /dev/null
+++ b/SVUI_Inventory/components/organization.lua
@@ -0,0 +1,284 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+local pairs   = _G.pairs;
+local ipairs  = _G.ipairs;
+local table   = _G.table;
+local match = string.match;
+--[[ TABLE METHODS ]]--
+local tremove, tcopy, twipe, tsort, tcat = table.remove, table.copy, table.wipe, table.sort, table.concat;
+--BLIZZARD API
+local ToggleFrame           = _G.ToggleFrame;
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+local GameTooltip           = _G.GameTooltip;
+local hooksecurefunc        = _G.hooksecurefunc;
+local IsAltKeyDown          = _G.IsAltKeyDown;
+local IsShiftKeyDown        = _G.IsShiftKeyDown;
+local IsControlKeyDown      = _G.IsControlKeyDown;
+local IsModifiedClick       = _G.IsModifiedClick;
+local RAID_CLASS_COLORS     = _G.RAID_CLASS_COLORS;
+local CUSTOM_CLASS_COLORS   = _G.CUSTOM_CLASS_COLORS;
+local SetBagSlotFlag        = _G.SetBagSlotFlag;
+local GetBagSlotFlag        = _G.GetBagSlotFlag;
+local GetContainerNumSlots  = _G.GetContainerNumSlots;
+local CLEAR_ALL                 = _G.CLEAR_ALL;
+local FILTERS                   = _G.FILTERS;
+local NUM_LE_BAG_FILTER_FLAGS   	= _G.NUM_LE_BAG_FILTER_FLAGS;
+local LE_BAG_FILTER_FLAG_EQUIPMENT  = _G.LE_BAG_FILTER_FLAG_EQUIPMENT;
+local BankFrameItemButton_Update        = _G.BankFrameItemButton_Update;
+local BankFrameItemButton_UpdateLocked  = _G.BankFrameItemButton_UpdateLocked;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L;
+local MOD = SV.Inventory;
+local TTIP = SV.Tooltip;
+--[[
+##########################################################
+LOCAL VARS
+##########################################################
+]]--
+local BAG_FILTER_LABELS = _G.BAG_FILTER_LABELS;
+local nameKey = UnitName("player");
+local realmKey = GetRealmName();
+local BagFilters = _G.SVUI_BagFilterMenu;
+--[[
+##########################################################
+LOCAL FUNCTIONS
+##########################################################
+]]--
+local DD_OnClick = function(self)
+	SetBagSlotFlag(self.BagID, self.FilterID, not GetBagSlotFlag(self.BagID, self.FilterID))
+	self:GetParent():Hide()
+end
+
+local DDClear_OnClick = function(self)
+	for i = LE_BAG_FILTER_FLAG_EQUIPMENT, NUM_LE_BAG_FILTER_FLAGS do
+		SetBagSlotFlag(self.BagID, i, false)
+	end
+	self:GetParent():Hide()
+end
+
+local DD_OnEnter = function(self)
+	self.hoverTex:Show()
+end
+
+local DD_OnLeave = function(self)
+	self.hoverTex:Hide()
+end
+
+local SetFilterMenu = function(self)
+	for i = LE_BAG_FILTER_FLAG_EQUIPMENT, NUM_LE_BAG_FILTER_FLAGS do
+		if(GetBagSlotFlag(self.internalID, i)) then
+			BagFilters.buttons[i].activeTex:Show()
+		else
+			BagFilters.buttons[i].activeTex:Hide()
+		end
+		BagFilters.buttons[i].BagID = self.internalID
+	end
+
+	BagFilters.buttons[NUM_LE_BAG_FILTER_FLAGS + 1].BagID = self.internalID
+
+	local maxHeight = ((NUM_LE_BAG_FILTER_FLAGS) * 16) + 30
+	local maxWidth = 135
+
+	BagFilters:SetSize(maxWidth, maxHeight)
+	BagFilters:ClearAllPoints()
+	BagFilters:SetPoint("TOPLEFT", self, "BOTTOMLEFT", 0, -8)
+	ToggleFrame(BagFilters)
+end
+
+local BagMenu_OnEnter = function(self)
+	local parent = self.parent
+	if(not parent) then return end
+	for bagID, bag in pairs(parent.Bags) do
+		local numSlots = GetContainerNumSlots(bagID)
+		for slotID = 1, numSlots do
+			if bag[slotID] then
+				if bagID == self.internalID then
+					bag[slotID]:SetAlpha(1)
+				else
+					bag[slotID]:SetAlpha(0.1)
+				end
+			end
+		end
+	end
+
+	GameTooltip:AppendText(" |cff00FF11[SHIFT-CLICK] To Set Filters|r")
+end
+
+local BagMenu_OnLeave = function(self)
+	local parent = self.parent
+	if(not parent) then return end
+	for bagID, bag in pairs(parent.Bags) do
+		local numSlots = GetContainerNumSlots(bagID)
+		for slotID = 1, numSlots do
+			if bag[slotID] then
+				bag[slotID]:SetAlpha(1)
+			end
+		end
+	end
+end
+
+local BagMenu_OnClick = function(self)
+	if IsShiftKeyDown() then
+		SetFilterMenu(self);
+	elseif(BagFilters:IsShown()) then
+		ToggleFrame(BagFilters)
+	end
+end
+
+function MOD:NewFilterMenu(bag)
+	if(bag.UpdateTooltip) then
+		hooksecurefunc(bag, "UpdateTooltip", BagMenu_OnEnter)
+	end
+	bag:HookScript("OnLeave", BagMenu_OnLeave)
+	bag:HookScript("OnClick", BagMenu_OnClick)
+end
+
+function MOD:InitializeMenus()
+	-- BagFilters:SetParent(SV.Screen)
+	BagFilters:SetStyle("Frame", "Default")
+	BagFilters.buttons = {}
+	BagFilters:SetFrameStrata("DIALOG")
+	BagFilters:SetClampedToScreen(true)
+
+	for i = LE_BAG_FILTER_FLAG_EQUIPMENT, NUM_LE_BAG_FILTER_FLAGS do
+		BagFilters.buttons[i] = CreateFrame("Button", nil, BagFilters)
+
+		BagFilters.buttons[i].hoverTex = BagFilters.buttons[i]:CreateTexture(nil, 'OVERLAY')
+		BagFilters.buttons[i].hoverTex:SetAllPoints()
+		BagFilters.buttons[i].hoverTex:SetTexture([[Interface\AddOns\SVUI_!Core\assets\textures\TITLE-HIGHLIGHT]])
+		BagFilters.buttons[i].hoverTex:SetBlendMode("ADD")
+		BagFilters.buttons[i].hoverTex:Hide()
+
+		BagFilters.buttons[i].activeTex = BagFilters.buttons[i]:CreateTexture(nil, 'OVERLAY')
+		BagFilters.buttons[i].activeTex:SetAllPoints()
+		BagFilters.buttons[i].activeTex:SetTexture([[Interface\AddOns\SVUI_!Core\assets\textures\TITLE-HIGHLIGHT]])
+		BagFilters.buttons[i].activeTex:SetVertexColor(0,0.7,0)
+		BagFilters.buttons[i].activeTex:SetBlendMode("ADD")
+		BagFilters.buttons[i].activeTex:Hide()
+
+		BagFilters.buttons[i].text = BagFilters.buttons[i]:CreateFontString(nil, 'BORDER')
+		BagFilters.buttons[i].text:SetAllPoints()
+		BagFilters.buttons[i].text:SetFont(SV.media.font.default,12,"OUTLINE")
+		BagFilters.buttons[i].text:SetJustifyH("LEFT")
+		BagFilters.buttons[i].text:SetText(BAG_FILTER_LABELS[i])
+
+		BagFilters.buttons[i]:SetScript("OnEnter", DD_OnEnter)
+		BagFilters.buttons[i]:SetScript("OnLeave", DD_OnLeave)
+
+		BagFilters.buttons[i]:SetHeight(16)
+		BagFilters.buttons[i]:SetWidth(115)
+
+		BagFilters.buttons[i].FilterID = i
+		BagFilters.buttons[i]:SetScript("OnClick", DD_OnClick)
+
+		if i == LE_BAG_FILTER_FLAG_EQUIPMENT then
+			BagFilters.buttons[i]:SetPoint("TOPLEFT", BagFilters, "TOPLEFT", 10, -10)
+		else
+			BagFilters.buttons[i]:SetPoint("TOPLEFT", BagFilters.buttons[i - 1], "BOTTOMLEFT", 0, 0)
+		end
+
+		BagFilters.buttons[i]:Show()
+	end
+
+	local clearID = NUM_LE_BAG_FILTER_FLAGS + 1
+
+	BagFilters.buttons[clearID] = CreateFrame("Button", nil, BagFilters)
+	BagFilters.buttons[clearID].hoverTex = BagFilters.buttons[clearID]:CreateTexture(nil, 'OVERLAY')
+	BagFilters.buttons[clearID].hoverTex:SetAllPoints()
+	BagFilters.buttons[clearID].hoverTex:SetTexture([[Interface\AddOns\SVUI_!Core\assets\textures\TITLE-HIGHLIGHT]])
+	BagFilters.buttons[clearID].hoverTex:SetBlendMode("ADD")
+	BagFilters.buttons[clearID].hoverTex:Hide()
+	BagFilters.buttons[clearID].text = BagFilters.buttons[clearID]:CreateFontString(nil, 'BORDER')
+	BagFilters.buttons[clearID].text:SetAllPoints()
+	BagFilters.buttons[clearID].text:SetFont(SV.media.font.default,12,"OUTLINE")
+	BagFilters.buttons[clearID].text:SetJustifyH("LEFT")
+	BagFilters.buttons[clearID].text:SetText(CLEAR_ALL .. " " .. FILTERS)
+	BagFilters.buttons[clearID]:SetScript("OnEnter", DD_OnEnter)
+	BagFilters.buttons[clearID]:SetScript("OnLeave", DD_OnLeave)
+	BagFilters.buttons[clearID]:SetHeight(16)
+	BagFilters.buttons[clearID]:SetWidth(115)
+	BagFilters.buttons[clearID].FilterID = 0
+	BagFilters.buttons[clearID]:SetScript("OnClick", DDClear_OnClick)
+	BagFilters.buttons[clearID]:SetPoint("TOPLEFT", BagFilters.buttons[NUM_LE_BAG_FILTER_FLAGS], "BOTTOMLEFT", 0, -10)
+	BagFilters.buttons[clearID]:Show()
+
+	BagFilters:Hide()
+	SV:ManageVisibility(BagFilters)
+end
+--[[
+##########################################################
+BAG EVENTS
+##########################################################
+]]--
+local UpdateSlot = function(self, bagID, slotID)
+	if((not self.Bags[bagID]) or (self.Bags[bagID] and self.Bags[bagID].numSlots ~= GetContainerNumSlots(bagID)) or (not self.Bags[bagID][slotID])) then
+		return;
+	end
+
+	self.Bags[bagID]:SlotUpdate(slotID)
+end
+
+local UpdateBagSlots = function(self, bagID)
+	if(bagID and self.Bags[bagID]) then
+		local maxcount = GetContainerNumSlots(bagID)
+		for slotID = 1, maxcount do
+			self.Bags[bagID]:SlotUpdate(slotID)
+		end
+		MOD:UpdateStockpile();
+	end
+end
+
+local Container_OnEvent = function(self, event, ...)
+	if(event == "ITEM_LOCK_CHANGED" or event == "ITEM_UNLOCKED") then
+		UpdateSlot(self, ...)
+	elseif(event == "BAG_UPDATE" or event == "EQUIPMENT_SETS_CHANGED") then
+		SV:BuildEquipmentMap()
+		for i, bagID in ipairs(self.BagIDs) do
+			local numSlots = GetContainerNumSlots(bagID)
+			if(not self.Bags[bagID] and numSlots ~= 0) or (self.Bags[bagID] and (numSlots ~= self.Bags[bagID].numSlots)) then
+				self:UpdateLayout();
+				return;
+			end
+		end
+		UpdateBagSlots(self, ...)
+	elseif(event == "BAG_UPDATE_COOLDOWN") then
+		self:RefreshCooldowns()
+	elseif(event == "PLAYERBANKSLOTS_CHANGED") then
+		if(self.isBank and self.BagMenu) then
+			for i, bagID in ipairs(self.BagIDs) do
+				local bagSlot = self.BagMenu[i];
+				if(bagSlot) then
+					BankFrameItemButton_Update(bagSlot)
+					BankFrameItemButton_UpdateLocked(bagSlot)
+				end
+			end
+		end
+		self:RefreshBags();
+	elseif(event == "PLAYERREAGENTBANKSLOTS_CHANGED") then
+		local slotID = ...
+		local container = _G["SVUI_ReagentContainerFrame"]
+		if(slotID and container) then
+			local bagID = container.BagID
+			container.Bags[bagID]:SlotUpdate(slotID)
+		end
+	end
+end
+
+function MOD:SetContainerEvents(frame)
+	frame:SetScript("OnEvent", Container_OnEvent)
+end
diff --git a/SVUI_Inventory/components/sorting.lua b/SVUI_Inventory/components/sorting.lua
new file mode 100644
index 0000000..47b5a07
--- /dev/null
+++ b/SVUI_Inventory/components/sorting.lua
@@ -0,0 +1,946 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+credit: Kemayo.               original logic from BankStack. Adapted to SVUI #
+##############################################################################
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+(<a href="[^0-9\"]+">)
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack            = _G.unpack;
+local select            = _G.select;
+local assert            = _G.assert;
+local type              = _G.type;
+local error             = _G.error;
+local pcall             = _G.pcall;
+local print             = _G.print;
+local ipairs            = _G.ipairs;
+local pairs             = _G.pairs;
+local next              = _G.next;
+local tostring          = _G.tostring;
+local tonumber          = _G.tonumber;
+local collectgarbage    = _G.collectgarbage;
+local tinsert 	= _G.tinsert;
+local string 	= _G.string;
+local math 		= _G.math;
+local bit 		= _G.bit;
+local table 	= _G.table;
+--[[ STRING METHODS ]]--
+local gmatch, gsub, match, split = string.gmatch, string.gsub, string.match, string.split;
+--[[ MATH METHODS ]]--
+local floor = math.floor;
+--[[ BINARY METHODS ]]--
+local band = bit.band;
+--[[ TABLE METHODS ]]--
+local tremove, tcopy, twipe, tsort = table.remove, table.copy, table.wipe, table.sort;
+--BLIZZARD API
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+local GameTooltip           = _G.GameTooltip;
+local hooksecurefunc        = _G.hooksecurefunc;
+local IsAltKeyDown          = _G.IsAltKeyDown;
+local IsShiftKeyDown        = _G.IsShiftKeyDown;
+local IsControlKeyDown      = _G.IsControlKeyDown;
+local IsModifiedClick       = _G.IsModifiedClick;
+local RAID_CLASS_COLORS     = _G.RAID_CLASS_COLORS;
+local CUSTOM_CLASS_COLORS   = _G.CUSTOM_CLASS_COLORS;
+local C_PetJournal          = _G.C_PetJournal;
+local GetTime               = _G.GetTime;
+local GetContainerNumSlots  = _G.GetContainerNumSlots;
+local GetGuildBankTabInfo   = _G.GetGuildBankTabInfo;
+local GetItemFamily         = _G.GetItemFamily;
+local GetGuildBankItemInfo  = _G.GetGuildBankItemInfo;
+local GetContainerItemInfo  = _G.GetContainerItemInfo;
+local GetGuildBankItemLink  = _G.GetGuildBankItemLink;
+local GetContainerItemLink  = _G.GetContainerItemLink;
+local GetItemInfo           = _G.GetItemInfo;
+local GetItemCount          = _G.GetItemCount;
+local GetItemQualityColor   = _G.GetItemQualityColor;
+local GetCursorInfo         = _G.GetCursorInfo;
+local PickupGuildBankItem   = _G.PickupGuildBankItem;
+local PickupContainerItem   = _G.PickupContainerItem;
+local QueryGuildBankTab     = _G.QueryGuildBankTab;
+local GetInventoryItemLink  = _G.GetInventoryItemLink;
+local SplitGuildBankItem    = _G.SplitGuildBankItem;
+local SplitContainerItem    = _G.SplitContainerItem;
+
+local ARMOR                     = _G.ARMOR;
+local ENCHSLOT_WEAPON           = _G.ENCHSLOT_WEAPON;
+local NUM_BAG_FRAMES            = _G.NUM_BAG_FRAMES;
+local NUM_BAG_SLOTS             = _G.NUM_BAG_SLOTS;
+local NUM_BANKBAGSLOTS          = _G.NUM_BANKBAGSLOTS;
+local BANK_CONTAINER            = _G.BANK_CONTAINER;
+local REAGENTBANK_CONTAINER     = _G.REAGENTBANK_CONTAINER;
+local GetAuctionItemSubClasses  = _G.GetAuctionItemSubClasses;
+local ContainerIDToInventoryID  = _G.ContainerIDToInventoryID;
+local GetContainerItemID        = _G.GetContainerItemID;
+local GetCurrentGuildBankTab	= _G.GetCurrentGuildBankTab;
+local GetContainerNumFreeSlots  = _G.GetContainerNumFreeSlots;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L;
+local MOD = SV.Inventory;
+--[[
+##########################################################
+LOCAL VARS
+##########################################################
+]]--
+local WAIT_TIME = 0.05
+local bagGroups = {};
+local initialOrder = {};
+local bagSorted = {};
+local bagLocked = {};
+local targetItems = {};
+local sourceUsed = {};
+local targetSlots = {};
+local specialtyBags = {};
+local emptySlots = {};
+local moveRetries = 0;
+local moveTracker = {};
+local blackListedSlots = {};
+local blackList = {};
+local lastItemID, lockStop, lastDestination, lastMove, itemTypes, itemSubTypes;
+local IterateBagsForSorting;
+local RefEquipmentSlots = {
+	INVTYPE_AMMO = 0,
+	INVTYPE_HEAD = 1,
+	INVTYPE_NECK = 2,
+	INVTYPE_SHOULDER = 3,
+	INVTYPE_BODY = 4,
+	INVTYPE_CHEST = 5,
+	INVTYPE_ROBE = 5,
+	INVTYPE_WAIST = 6,
+	INVTYPE_LEGS = 7,
+	INVTYPE_FEET = 8,
+	INVTYPE_WRIST = 9,
+	INVTYPE_HAND = 10,
+	INVTYPE_FINGER = 11,
+	INVTYPE_TRINKET = 12,
+	INVTYPE_CLOAK = 13,
+	INVTYPE_WEAPON = 14,
+	INVTYPE_SHIELD = 15,
+	INVTYPE_2HWEAPON = 16,
+	INVTYPE_WEAPONMAINHAND = 18,
+	INVTYPE_WEAPONOFFHAND = 19,
+	INVTYPE_HOLDABLE = 20,
+	INVTYPE_RANGED = 21,
+	INVTYPE_THROWN = 22,
+	INVTYPE_RANGEDRIGHT = 23,
+	INVTYPE_RELIC = 24,
+	INVTYPE_TABARD = 25
+}
+local ItemCategories = {
+	AUCTION_CATEGORY_WEAPONS,
+	AUCTION_CATEGORY_ARMOR,
+	AUCTION_CATEGORY_CONTAINERS,
+	AUCTION_CATEGORY_CONSUMABLES,
+	AUCTION_CATEGORY_ITEM_ENHANCEMENT,
+	AUCTION_CATEGORY_GLYPHS,
+	AUCTION_CATEGORY_TRADE_GOODS,
+	AUCTION_CATEGORY_RECIPES,
+	AUCTION_CATEGORY_GEMS,
+	AUCTION_CATEGORY_MISCELLANEOUS,
+	AUCTION_CATEGORY_QUEST_ITEMS,
+	AUCTION_CATEGORY_BATTLE_PETS
+}
+local sortingCache = {
+	[1] = {}, --BAG
+	[2] = {}, --ID
+	[3] = {}, --PETID
+	[4] = {}, --STACK
+	[5] = {}, --MAXSTACK
+	[6] = {}, --MOVES
+}
+
+local scanningCache = {
+	["all"] = {},
+	["bags"] = {},
+	["bank"] = {BANK_CONTAINER},
+	["reagent"] = {REAGENTBANK_CONTAINER},
+	["guild"] = {51,52,53,54,55,56,57,58},
+}
+do
+	local cacheCount = 1;
+	for i = NUM_BAG_SLOTS + 1, (NUM_BAG_SLOTS + NUM_BANKBAGSLOTS), 1 do
+	  scanningCache.bank[cacheCount] = i
+		cacheCount=cacheCount+1;
+	end
+end
+do
+	local cacheCount = 1;
+	for i = 0, NUM_BAG_SLOTS do
+	  scanningCache.bags[cacheCount] = i
+		cacheCount=cacheCount+1;
+	end
+end
+do
+	local cacheCount = 1;
+	for _,i in ipairs(scanningCache.bags) do
+		scanningCache.all[cacheCount] = i
+		cacheCount=cacheCount+1;
+	end
+	for _,i in ipairs(scanningCache.bank) do
+		scanningCache.all[cacheCount] = i
+		cacheCount=cacheCount+1;
+	end
+	for _,i in ipairs(scanningCache.reagent) do
+		scanningCache.all[cacheCount] = i
+		cacheCount=cacheCount+1;
+	end
+	for _,i in ipairs(scanningCache.guild) do
+		scanningCache.all[cacheCount] = i
+		cacheCount=cacheCount+1;
+	end
+end
+--[[
+##########################################################
+SORTING UPDATES HANDLER
+##########################################################
+]]--
+local SortUpdateTimer = CreateFrame("Frame")
+SortUpdateTimer.timeLapse = 0
+SortUpdateTimer:Hide()
+--[[
+##########################################################
+HELPERS
+##########################################################
+]]--
+local function ValidateBag(bagid)
+	return (bagid == BANK_CONTAINER or ((bagid >= 0) and bagid <= (NUM_BAG_SLOTS + NUM_BANKBAGSLOTS)))
+end
+local function ValidateBank(bagid)
+	return (bagid == BANK_CONTAINER or bagid == REAGENTBANK_CONTAINER or (bagid > NUM_BAG_SLOTS and bagid <= NUM_BANKBAGSLOTS))
+end
+local function ValidateGuildBank(bagid)
+	return (bagid > 50 and bagid <= 58)
+end
+local function BagEncoder(bag, slot) return (bag * 100) + slot end
+local function BagDecoder(int) return math.floor(int / 100), int % 100 end
+local function MoveEncoder(source, target) return (source * 10000) + target end
+local function MoveDecoder(move)
+	local s = math.floor(move / 10000)
+	local t = move % 10000
+	s = (t > 9000) and (s + 1) or s
+	t = (t > 9000) and (t - 10000) or t
+	return s, t
+end
+--[[
+##########################################################
+LOCAL FUNCTIONS
+##########################################################
+]]--
+local function SetCacheBlacklist(...)
+	twipe(blackList)
+	for index = 1, select('#', ...) do
+		local name = select(index, ...)
+		local isLink = GetItemInfo(name)
+		if isLink then
+			blackList[isLink] = true
+		end
+	end
+end
+
+local function BuildSortOrder()
+	itemTypes = {}
+	itemSubTypes = {}
+	for i, iType in ipairs(ItemCategories) do
+		itemTypes[iType] = i
+		itemSubTypes[iType] = {}
+		for ii, isType in ipairs({GetAuctionItemSubClasses(i)}) do
+			itemSubTypes[iType][isType] = ii
+		end
+	end
+end
+
+local function UpdateLocation(from, to)
+	if (sortingCache[2][from] == sortingCache[2][to]) and (sortingCache[4][to] < sortingCache[5][to]) then
+		local stackSize = sortingCache[5][to]
+		if (sortingCache[4][to] + sortingCache[4][from]) > stackSize then
+			sortingCache[4][from] = sortingCache[4][from] - (stackSize - sortingCache[4][to])
+			sortingCache[4][to] = stackSize
+		else
+			sortingCache[4][to] = sortingCache[4][to] + sortingCache[4][from]
+			sortingCache[4][from] = nil
+			sortingCache[2][from] = nil
+			sortingCache[5][from] = nil
+		end
+	else
+		sortingCache[2][from], sortingCache[2][to] = sortingCache[2][to], sortingCache[2][from]
+		sortingCache[4][from], sortingCache[4][to] = sortingCache[4][to], sortingCache[4][from]
+		sortingCache[5][from], sortingCache[5][to] = sortingCache[5][to], sortingCache[5][from]
+	end
+end
+
+local function PrimarySort(a, b)
+	local aName, _, _, aLvl, _, _, _, _, _, _, aPrice = GetItemInfo(sortingCache[2][a])
+	local bName, _, _, bLvl, _, _, _, _, _, _, bPrice = GetItemInfo(sortingCache[2][b])
+	if aLvl ~= bLvl and aLvl and bLvl then
+		return aLvl > bLvl
+	end
+	if aPrice ~= bPrice and aPrice and bPrice then
+		return aPrice > bPrice
+	end
+	if aName and bName then
+		return aName < bName
+	end
+end
+
+local function DefaultSort(b, a)
+	local aID = sortingCache[2][a]
+	local bID = sortingCache[2][b]
+	if (not aID) or (not bID) then return aID end
+	if sortingCache[3][a] and sortingCache[3][b] then
+		local aName, _, aType = C_PetJournal.GetPetInfoBySpeciesID(aID);
+		local bName, _, bType = C_PetJournal.GetPetInfoBySpeciesID(bID);
+		if aType and bType and aType ~= bType then
+			return aType > bType
+		end
+		if aName and bName and (type(aName) == type(bName)) and aName ~= bName then
+			return aName < bName
+		end
+	end
+	local aOrder, bOrder = initialOrder[a], initialOrder[b]
+	if aID == bID then
+		local aCount = sortingCache[4][a]
+		local bCount = sortingCache[4][b]
+		if aCount and bCount and aCount == bCount then
+			return aOrder < bOrder
+		elseif aCount and bCount then
+			return aCount < bCount
+		end
+	end
+	local _, _, aRarity, _, _, aType, aSubType, _, aEquipLoc = GetItemInfo(aID)
+	local _, _, bRarity, _, _, bType, bSubType, _, bEquipLoc = GetItemInfo(bID)
+	if sortingCache[3][a] then
+		aRarity = 1
+	end
+	if sortingCache[3][b] then
+		bRarity = 1
+	end
+	if aRarity ~= bRarity and aRarity and bRarity then
+		return aRarity > bRarity
+	end
+	if itemTypes[aType] ~= itemTypes[bType] then
+		return (itemTypes[aType] or 99) < (itemTypes[bType] or 99)
+	end
+	if aType == ARMOR or aType == ENCHSLOT_WEAPON then
+		local aEquipLoc = RefEquipmentSlots[aEquipLoc] or -1
+		local bEquipLoc = RefEquipmentSlots[bEquipLoc] or -1
+		if aEquipLoc == bEquipLoc then
+			return PrimarySort(a, b)
+		end
+		if aEquipLoc and bEquipLoc then
+			return aEquipLoc < bEquipLoc
+		end
+	end
+	if aSubType == bSubType then
+		return PrimarySort(a, b)
+	end
+	return ((itemSubTypes[aType] or {})[aSubType] or 99) < ((itemSubTypes[bType] or {})[bSubType] or 99)
+end
+
+local function ReverseSort(a, b)
+	return DefaultSort(b, a)
+end
+
+local function ConvertLinkToID(link)
+	if not link then return; end
+	if tonumber(match(link, "item:(%d+)")) then
+		return tonumber(match(link, "item:(%d+)"));
+	else
+		return tonumber(match(link, "battlepet:(%d+)")), true;
+	end
+end
+
+local function GetSortingGroup(id)
+	if match(id, "^[-%d,]+$") then
+		local bags = {}
+		local count = 1;
+		for b in gmatch(id, "-?%d+") do
+			bags[count] = tonumber(b);
+			count=count+1;
+		end
+		return bags
+	end
+	return scanningCache[id]
+end
+
+local function GetSortingInfo(bag, slot)
+	if (ValidateGuildBank(bag)) then
+		return GetGuildBankItemInfo(bag - 50, slot)
+	else
+		return GetContainerItemInfo(bag, slot)
+	end
+end
+
+local function GetSortingItemLink(bag, slot)
+	if (ValidateGuildBank(bag)) then
+		return GetGuildBankItemLink(bag - 50, slot)
+	else
+		return GetContainerItemLink(bag, slot)
+	end
+end
+--[[
+##########################################################
+BAG ITERATION METHOD
+##########################################################
+]]--
+do
+	local bagRole;
+
+	local function GetNumSortingSlots(bag, role)
+		if (ValidateGuildBank(bag)) then
+			if not role then role = "deposit" end
+			local name, icon, canView, canDeposit, numWithdrawals = GetGuildBankTabInfo(bag - 50)
+			if name and canView then
+				return 98
+			end
+		else
+			return GetContainerNumSlots(bag)
+		end
+		return 0
+	end
+
+	local function IterateForwards(bagList, i)
+		i = i + 1
+		local step = 1
+		for _,bag in ipairs(bagList) do
+			local slots = GetNumSortingSlots(bag, bagRole)
+			if i > slots + step then
+				step = step + slots
+			else
+				for slot = 1, slots do
+					if step == i then
+						return i, bag, slot
+					end
+					step = step + 1
+				end
+			end
+		end
+		bagRole = nil
+	end
+
+	local function IterateBackwards(bagList, i)
+		i = i + 1
+		local step = 1
+		for ii = #bagList, 1, -1 do
+			local bag = bagList[ii]
+			local slots = GetNumSortingSlots(bag, bagRole)
+			if i > slots + step then
+				step = step + slots
+			else
+				for slot=slots, 1, -1 do
+					if step == i then
+						return i, bag, slot
+					end
+					step = step + 1
+				end
+			end
+		end
+		bagRole = nil
+	end
+
+	function IterateBagsForSorting(bagList, reverse, role)
+		bagRole = role
+		return (reverse and IterateBackwards or IterateForwards), bagList, 0
+	end
+end
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+-- function MOD.Compress(...)
+-- 	for i=1, select("#", ...) do
+-- 		local bags = select(i, ...)
+-- 		MOD.Stack(bags, bags, MOD.IsPartial)
+-- 	end
+-- end
+
+-- function MOD.Organizer(fnType, sourceBags, targetBags)
+-- 	if(fnType == 'stack') then
+-- 		MOD.Stack(sourceBags, targetBags, MOD.IsPartial)
+-- 	elseif(fnType == 'move') then
+-- 		MOD.Stack(sourceBags, targetBags, MOD.IsPartial)
+-- 	else
+-- 		MOD.Sort()
+-- 	end
+-- end
+--[[
+##########################################################
+EXTERNAL SORTING CALLS
+##########################################################
+]]--
+do
+	local function SetSortingPath(source, target)
+		UpdateLocation(source, target)
+		local move=MoveEncoder(source, target);
+		tinsert(sortingCache[6], 1, move)
+	end
+
+	local function IsPartial(bag, slot)
+		local bagSlot = BagEncoder(bag, slot)
+		return ((sortingCache[5][bagSlot] or 0) - (sortingCache[4][bagSlot] or 0)) > 0
+	end
+
+	local function IsSpecialtyBag(bagID)
+		if(bagID == 0 or (ValidateBank(bagID)) or (ValidateGuildBank(bagID))) then return false end
+		local inventorySlot = ContainerIDToInventoryID(bagID)
+		if not inventorySlot then return false end
+		local bag = GetInventoryItemLink("player", inventorySlot)
+		if not bag then return false end
+		local family = GetItemFamily(bag)
+		if family == 0 or family == nil then return false end
+		return family
+	end
+
+	local function CanItemGoInBag(bag, slot, targetBag)
+		if (ValidateGuildBank(targetBag)) then return true end
+		local item = sortingCache[2][(BagEncoder(bag, slot))]
+		local itemFamily = GetItemFamily(item)
+		if itemFamily and itemFamily > 0 then
+			local equipSlot = select(9, GetItemInfo(item))
+			if equipSlot == "INVTYPE_BAG" then
+				itemFamily = 1
+			end
+		end
+		local bagFamily = select(2, GetContainerNumFreeSlots(targetBag))
+		if itemFamily then
+			return (bagFamily == 0) or band(itemFamily, bagFamily) > 0
+		else
+			return false;
+		end
+	end
+
+	local function ShouldMove(source, destination)
+		if((destination == source) or (not sortingCache[2][source])) then return; end
+		if((sortingCache[2][source] == sortingCache[2][destination]) and (sortingCache[4][source] == sortingCache[4][destination])) then return; end
+		return true
+	end
+
+	local function UpdateSorted(source, destination)
+		for i, bs in pairs(bagSorted) do
+			if bs == source then
+				bagSorted[i] = destination
+			elseif bs == destination then
+				bagSorted[i] = source
+			end
+		end
+	end
+
+	local function Sorter(bags, sorter, reverse)
+		if not sorter then sorter = reverse and ReverseSort or DefaultSort end
+		if not itemTypes then BuildSortOrder() end
+		twipe(blackListedSlots)
+		local ignoreItems = SV.db.Inventory.ignoreItems
+		ignoreItems = ignoreItems:gsub(',%s', ',')
+		SetCacheBlacklist(split(",", ignoreItems))
+		for i, bag, slot in IterateBagsForSorting(bags, nil, 'both') do
+			local bagSlot = BagEncoder(bag, slot)
+			local link = GetSortingItemLink(bag, slot);
+			if link and blackList[GetItemInfo(link)] then
+				blackListedSlots[bagSlot] = true
+			end
+			if not blackListedSlots[bagSlot] then
+				initialOrder[bagSlot] = i
+				tinsert(bagSorted, bagSlot)
+			end
+		end
+		tsort(bagSorted, sorter)
+		local passNeeded = true
+		while passNeeded do
+			passNeeded = false
+			local i = 1
+			for _, bag, slot in IterateBagsForSorting(bags, nil, 'both') do
+				local destination = BagEncoder(bag, slot)
+				local source = bagSorted[i]
+				if not blackListedSlots[destination] then
+					if(ShouldMove(source, destination)) then
+						if not (bagLocked[source] or bagLocked[destination]) then
+							SetSortingPath(source, destination)
+							UpdateSorted(source, destination)
+							bagLocked[source] = true
+							bagLocked[destination] = true
+						else
+							passNeeded = true
+						end
+					end
+					i = i + 1
+				end
+			end
+			twipe(bagLocked)
+		end
+		twipe(bagSorted)
+		twipe(initialOrder)
+	end
+
+	local function SortFiller(sourceBags, targetBags, reverse, canMove)
+		if not canMove then canMove = true end
+		for _, bag, slot in IterateBagsForSorting(targetBags, reverse, "deposit") do
+			local bagSlot = BagEncoder(bag, slot)
+			if not sortingCache[2][bagSlot] then
+				tinsert(emptySlots, bagSlot)
+			end
+		end
+		for _, bag, slot in IterateBagsForSorting(sourceBags, not reverse, "withdraw") do
+			if #emptySlots == 0 then break end
+			local bagSlot = BagEncoder(bag, slot)
+			local targetBag, targetSlot = BagDecoder(emptySlots[1])
+			if sortingCache[2][bagSlot] and CanItemGoInBag(bag, slot, targetBag) and (canMove == true or canMove(sortingCache[2][bagSlot], bag, slot)) then
+				SetSortingPath(bagSlot, tremove(emptySlots, 1))
+			end
+		end
+		twipe(emptySlots)
+	end
+
+	function MOD.Sort(...)
+		for i=1, select("#", ...) do
+			local bags = select(i, ...)
+			for _, slotNum in ipairs(bags) do
+				local bagType = IsSpecialtyBag(slotNum)
+				if bagType == false then bagType = 'Normal' end
+				if not sortingCache[1][bagType] then sortingCache[1][bagType] = {} end
+				tinsert(sortingCache[1][bagType], slotNum)
+			end
+			for bagType, sortedBags in pairs(sortingCache[1]) do
+				if bagType ~= 'Normal' then
+					MOD.Stack(sortedBags, IsPartial)
+					SortFiller(sortingCache[1]['Normal'], sortedBags, SV.db.Inventory.sortInverted)
+					MOD.Stack(sortingCache[1]['Normal'], IsPartial)
+					Sorter(sortedBags, nil, SV.db.Inventory.sortInverted)
+					twipe(sortedBags)
+				end
+			end
+			if sortingCache[1]['Normal'] then
+				MOD.Stack(sortingCache[1]['Normal'], IsPartial)
+				Sorter(sortingCache[1]['Normal'], nil, SV.db.Inventory.sortInverted)
+				twipe(sortingCache[1]['Normal'])
+			end
+			twipe(sortingCache[1])
+			twipe(bagGroups)
+		end
+	end
+
+	function MOD.Transfer(sourceBags, targetBags, canMove)
+		if not canMove then canMove = true end
+		for _, bag, slot in IterateBagsForSorting(targetBags, nil, "deposit") do
+			local bagSlot = BagEncoder(bag, slot)
+			local itemID = sortingCache[2][bagSlot]
+			if itemID and (sortingCache[4][bagSlot] ~= sortingCache[5][bagSlot]) then
+				targetItems[itemID] = (targetItems[itemID] or 0) + 1
+				tinsert(targetSlots, bagSlot)
+			end
+		end
+
+		for _, bag, slot in IterateBagsForSorting(sourceBags, true, "withdraw") do
+			local sourceSlot = BagEncoder(bag, slot)
+			local itemID = sortingCache[2][sourceSlot]
+			if itemID and targetItems[itemID] and (canMove == true or canMove(itemID, bag, slot)) then
+				for i = #targetSlots, 1, -1 do
+					local targetedSlot = targetSlots[i]
+					if sortingCache[2][sourceSlot] and sortingCache[2][targetedSlot] == itemID and targetedSlot ~= sourceSlot and not (sortingCache[4][targetedSlot] == sortingCache[5][targetedSlot]) and not sourceUsed[targetedSlot] then
+						SetSortingPath(sourceSlot, targetedSlot)
+						sourceUsed[sourceSlot] = true
+						if sortingCache[4][targetedSlot] == sortingCache[5][targetedSlot] then
+							targetItems[itemID] = (targetItems[itemID] > 1) and (targetItems[itemID] - 1) or nil
+						end
+						if sortingCache[4][sourceSlot] == 0 then
+							targetItems[itemID] = (targetItems[itemID] > 1) and (targetItems[itemID] - 1) or nil
+							break
+						end
+						if not targetItems[itemID] then break end
+					end
+				end
+			end
+		end
+		twipe(targetItems)
+		twipe(targetSlots)
+		twipe(sourceUsed)
+	end
+
+	function MOD.Stack(bags, canMove)
+		if not canMove then canMove = true end
+		for _, bag, slot in IterateBagsForSorting(bags, nil, "deposit") do
+			local bagSlot = BagEncoder(bag, slot)
+			local itemID = sortingCache[2][bagSlot]
+			if itemID and (sortingCache[4][bagSlot] ~= sortingCache[5][bagSlot]) then
+				targetItems[itemID] = (targetItems[itemID] or 0) + 1
+				tinsert(targetSlots, bagSlot)
+			end
+		end
+
+		for _, bag, slot in IterateBagsForSorting(bags, true, "withdraw") do
+			local sourceSlot = BagEncoder(bag, slot)
+			local itemID = sortingCache[2][sourceSlot]
+			if itemID and targetItems[itemID] and (canMove == true or (type(canMove) == "function" and canMove(itemID, bag, slot))) then
+				for i = #targetSlots, 1, -1 do
+					local targetedSlot = targetSlots[i]
+					if sortingCache[2][sourceSlot] and sortingCache[2][targetedSlot] == itemID and targetedSlot ~= sourceSlot and not (sortingCache[4][targetedSlot] == sortingCache[5][targetedSlot]) and not sourceUsed[targetedSlot] then
+						SetSortingPath(sourceSlot, targetedSlot)
+						sourceUsed[sourceSlot] = true
+						if sortingCache[4][targetedSlot] == sortingCache[5][targetedSlot] then
+							targetItems[itemID] = (targetItems[itemID] > 1) and (targetItems[itemID] - 1) or nil
+						end
+						if sortingCache[4][sourceSlot] == 0 then
+							targetItems[itemID] = (targetItems[itemID] > 1) and (targetItems[itemID] - 1) or nil
+							break
+						end
+						if not targetItems[itemID] then break end
+					end
+				end
+			end
+		end
+		twipe(targetItems)
+		twipe(targetSlots)
+		twipe(sourceUsed)
+	end
+end
+--[[
+##########################################################
+INTERNAL SORTING CALLS
+##########################################################
+]]--
+do
+	local function GetSortingItemID(bag, slot)
+		if (ValidateGuildBank(bag)) then
+			local link = GetSortingItemLink(bag, slot)
+			return link and tonumber(string.match(link, "item:(%d+)"))
+		else
+			return GetContainerItemID(bag, slot)
+		end
+	end
+
+	function SortUpdateTimer:StopStacking(message)
+		twipe(sortingCache[6])
+		twipe(moveTracker)
+		moveRetries, lastItemID, lockStop, lastDestination, lastMove = 0, nil, nil, nil, nil
+		self:SetScript("OnUpdate", nil)
+		self:Hide()
+		if(message) then
+			SV:SCTMessage(message, 1, 0.35, 0)
+		end
+	end
+
+	function SortUpdateTimer:MoveItem(move)
+		if GetCursorInfo() == "item" then
+			return false, 'cursorhasitem'
+		end
+		local source, target = MoveDecoder(move)
+		local sourceBag, sourceSlot = BagDecoder(source)
+		local targetBag, targetSlot = BagDecoder(target)
+		local _, sourceCount, sourceLocked = GetSortingInfo(sourceBag, sourceSlot)
+		local _, targetCount, targetLocked = GetSortingInfo(targetBag, targetSlot)
+		if sourceLocked or targetLocked then
+			return false, 'source/target_locked'
+		end
+		local sourceLink = GetSortingItemLink(sourceBag, sourceSlot)
+		local sourceItemID = GetSortingItemID(sourceBag, sourceSlot)
+		local targetItemID = GetSortingItemID(targetBag, targetSlot)
+
+		if not sourceItemID then
+			if moveTracker[source] then
+				return false, 'move incomplete'
+			else
+				return self:StopStacking(L['Confused.. Try Again!'])
+			end
+		end
+
+		local stackSize = select(8, GetItemInfo(sourceItemID))
+
+		local sourceGuild = ValidateGuildBank(sourceBag)
+		local targetGuild = ValidateGuildBank(targetBag)
+
+		if (sourceItemID == targetItemID) and (targetCount ~= stackSize) and ((targetCount + sourceCount) > stackSize) then
+			local amount = (stackSize - targetCount)
+			if (sourceGuild) then
+				SplitGuildBankItem(sourceBag - 50, sourceSlot, amount)
+			else
+				SplitContainerItem(sourceBag, sourceSlot, amount)
+			end
+		else
+			if (sourceGuild) then
+				PickupGuildBankItem(sourceBag - 50, sourceSlot)
+			else
+				PickupContainerItem(sourceBag, sourceSlot)
+			end
+		end
+
+		if GetCursorInfo() == "item" then
+			if (targetGuild) then
+				PickupGuildBankItem(targetBag - 50, targetSlot)
+			else
+				PickupContainerItem(targetBag, targetSlot)
+			end
+		end
+
+		if sourceGuild then
+			QueryGuildBankTab(sourceBag - 50)
+		end
+		if targetGuild then
+			QueryGuildBankTab(targetBag - 50)
+		end
+		return true, sourceItemID, source, targetItemID, target, sourceGuild or targetGuild
+	end
+
+	local SortUpdateTimer_OnUpdate = function(self, elapsed)
+		self.timeLapse = self.timeLapse + (elapsed or 0.01)
+		if(self.timeLapse > 0.05) then
+			self.timeLapse = 0
+			if InCombatLockdown() then
+				return self:StopStacking(L["Can't Clean Bags in Combat!"])
+			end
+			local cursorType, cursorItemID = GetCursorInfo()
+			if cursorType == "item" and cursorItemID then
+				if lastItemID ~= cursorItemID then
+					return self:StopStacking(L["Bag Cleaning Error, Try Again"])
+				end
+				if moveRetries < 100 then
+					local targetBag, targetSlot = BagDecoder(lastDestination)
+					local _, _, targetLocked = GetSortingInfo(targetBag, targetSlot)
+					if not targetLocked then
+						if(ValidateGuildBank(targetBag)) then
+							PickupGuildBankItem(targetBag - 50, targetSlot)
+						else
+							PickupContainerItem(targetBag, targetSlot)
+						end
+						WAIT_TIME = 0.1
+						lockStop = GetTime()
+						moveRetries = moveRetries + 1
+						return
+					end
+				end
+			end
+			if lockStop then
+				local i = 1;
+				for slot, itemID in pairs(moveTracker) do
+					local sourceBag, sourceSlot = BagDecoder(slot)
+					local actualItemID = GetSortingItemID(sourceBag, sourceSlot)
+					if actualItemID ~= itemID then
+						WAIT_TIME = 0.1
+						if (GetTime() - lockStop) > 1.25 then
+							if lastMove and moveRetries < 100 then
+								local success, moveID, moveSource, targetID, moveTarget, wasGuild = self:MoveItem(lastMove)
+								WAIT_TIME = wasGuild and 0.5 or 0.1
+								if not success then
+									lockStop = GetTime()
+									moveRetries = moveRetries + 1
+									return
+								end
+								moveTracker[moveSource] = targetID
+								moveTracker[moveTarget] = moveID
+								lastDestination = moveTarget
+								lastMove = sortingCache[6][i]
+								lastItemID = moveID
+								tremove(sortingCache[6], i)
+								return
+							end
+							self:StopStacking()
+							return
+						end
+						return
+					end
+					moveTracker[slot] = nil
+					i = i + 1;
+				end
+			end
+			lastItemID, lockStop, lastDestination, lastMove = nil, nil, nil, nil
+			twipe(moveTracker)
+			local start, success, moveID, targetID, moveSource, moveTarget, wasGuild
+			start = GetTime()
+			if #sortingCache[6] > 0 then
+				for i = #sortingCache[6], 1, -1 do
+					success, moveID, moveSource, targetID, moveTarget, wasGuild = self:MoveItem(sortingCache[6][i])
+					if not success then
+						WAIT_TIME = wasGuild and 0.3 or 0.1
+						lockStop = GetTime()
+						return
+					end
+					moveTracker[moveSource] = targetID
+					moveTracker[moveTarget] = moveID
+					lastDestination = moveTarget
+					lastMove = sortingCache[6][i]
+					lastItemID = moveID
+					tremove(sortingCache[6], i)
+					if sortingCache[6][i-1] then
+						WAIT_TIME = wasGuild and 0.3 or 0;
+						return
+					end
+				end
+			end
+			self:StopStacking()
+		end
+	end
+
+	function SortUpdateTimer:StartStacking()
+		twipe(sortingCache[5])
+		twipe(sortingCache[4])
+		twipe(sortingCache[2])
+		twipe(moveTracker)
+		if #sortingCache[6] > 0 then
+			self:Show()
+			self:SetScript("OnUpdate", SortUpdateTimer_OnUpdate)
+		else
+			self:StopStacking()
+		end
+	end
+end
+
+function MOD:RunSortingProcess(func, groupsDefaults, altFunc)
+	local bagGroups = {}
+	return function(groups)
+		if(altFunc and IsShiftKeyDown()) then
+			PlaySound("UI_BagSorting_01");
+			altFunc()
+		else
+			if SortUpdateTimer:IsShown() then
+				SortUpdateTimer:StopStacking(L['Already Running.. Bailing Out!'])
+				return;
+			end
+			twipe(bagGroups)
+			if not groups or #groups == 0 then
+				groups = groupsDefaults
+			end
+			for bags in (groups or ""):gmatch("[^%s]+") do
+				if bags == "guild" then
+					bags = GetSortingGroup(bags)
+					if bags then
+						tinsert(bagGroups, {bags[GetCurrentGuildBankTab()]})
+					end
+				else
+					bags = GetSortingGroup(bags)
+					if bags then
+						tinsert(bagGroups, bags)
+					end
+				end
+			end
+			for _, bag, slot in IterateBagsForSorting(scanningCache.all) do
+				local bagSlot = BagEncoder(bag, slot)
+				local itemID, isBattlePet = ConvertLinkToID(GetSortingItemLink(bag, slot))
+				if itemID then
+					if isBattlePet then
+						sortingCache[3][bagSlot] = itemID
+						sortingCache[5][bagSlot] = 1
+					else
+						sortingCache[5][bagSlot] = select(8, GetItemInfo(itemID))
+					end
+					sortingCache[2][bagSlot] = itemID
+					sortingCache[4][bagSlot] = select(2, GetSortingInfo(bag, slot))
+				end
+			end
+			if func(unpack(bagGroups)) == false then
+				return
+			end
+			twipe(bagGroups)
+			SortUpdateTimer:StartStacking()
+		end
+		collectgarbage("collect")
+	end
+end
diff --git a/SVUI_Maps/LICENSE.txt b/SVUI_Maps/LICENSE.txt
new file mode 100644
index 0000000..05ceba8
--- /dev/null
+++ b/SVUI_Maps/LICENSE.txt
@@ -0,0 +1,31 @@
+
+The MIT License
+
+Copyright (c) 2010, Failcoder (Steve Jackson)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy
+of this software and associated documentation files (the "Software"), to
+deal
+in the Software without restriction, including without limitation the
+rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/SVUI_Maps/Loader.lua b/SVUI_Maps/Loader.lua
new file mode 100644
index 0000000..19187af
--- /dev/null
+++ b/SVUI_Maps/Loader.lua
@@ -0,0 +1,313 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+
+local SV = _G["SVUI"];
+local L = SV.L
+local MOD = SV:NewModule(...);
+local Schema = MOD.Schema;
+local textSelect = {
+	['HIDE'] = L['Hide This'],
+	['CUSTOM'] = L['Use Custom Style'],
+	['SIMPLE'] = L['Use Simple Style']
+};
+local colorSelect = {
+	['light'] = L['Light'],
+	['dark'] = L['Dark'],
+	['darkest'] = L['Darkest'],
+	['class'] = L['Class']
+};
+
+MOD.media = {}
+MOD.media.customBlips = [[Interface\AddOns\SVUI_Maps\assets\MINIMAP-OBJECTICONS]];
+MOD.media.defaultBlips = [[Interface\AddOns\SVUI_Maps\assets\DEFAULT-OBJECTICONS]];
+MOD.media.rectangleMask = [[Interface\AddOns\SVUI_Maps\assets\MINIMAP_MASK_RECTANGLE]];
+MOD.media.squareMask = [[Interface\AddOns\SVUI_Maps\assets\MINIMAP_MASK_SQUARE]];
+MOD.media.roundBorder = [[Interface\AddOns\SVUI_Maps\assets\MINIMAP-ROUND]];
+MOD.media.playerArrow = [[Interface\AddOns\SVUI_Maps\assets\MINIMAP_ARROW]];
+MOD.media.corpseArrow = [[Interface\AddOns\SVUI_Maps\assets\MINIMAP_CORPSE_ARROW]];
+MOD.media.guideArrow = [[Interface\AddOns\SVUI_Maps\assets\MINIMAP_GUIDE_ARROW]];
+MOD.media.mailIcon = [[Interface\AddOns\SVUI_Maps\assets\MINIMAP-MAIL]];
+MOD.media.calendarIcon = [[Interface\AddOns\SVUI_Maps\assets\MINIMAP-CALENDAR]];
+MOD.media.trackingIcon = [[Interface\AddOns\SVUI_Maps\assets\MINIMAP-TRACKING]];
+
+SV:AssignMedia("template", "Minimap", "SVUI_StyleTemplate_Minimap");
+SV:AssignMedia("font", "mapinfo", "SVUI Narrator Font", 13, "OUTLINE");
+SV:AssignMedia("font", "mapcoords", "SVUI Number Font", 12, "OUTLINE");
+SV:AssignMedia("globalfont", "mapinfo", "SVUI_Font_MinimapInfo");
+SV:AssignMedia("globalfont", "mapcoords", "SVUI_Font_MinimapCoords");
+
+SV.defaults[Schema] = {
+	["incompatible"] = {
+		["SexyMap"] = true,
+		["SquareMap"] = true,
+		["PocketPlot"] = true,
+	},
+	["customIcons"] = true,
+	["tinyWorldMap"] = true,
+	["calendarShortcut"] = true,
+	["trackingShortcut"] = true,
+	["size"] = 240,
+	["mapShape"] = 'RECTANGLE',
+	["miniPlayerXY"] = true,
+	["worldPlayerXY"] = true,
+	["worldMouseXY"] = true,
+	["bordersize"] = 4,
+	["bordercolor"] = "light",
+	["locationText"] = "CUSTOM",
+	["minimapbar"] = {
+		["enable"] = true,
+		["styleType"] = "HORIZONTAL",
+		["layoutDirection"] = "NORMAL",
+		["perRow"] = 8,
+		["buttonSize"] = 28,
+		["mouseover"] = false,
+	},
+};
+
+function MOD:LoadOptions()
+	local mapFonts = {
+		["mapinfo"] = {
+			order = 1,
+			name = "Map Labels",
+			desc = "Font used for info labels."
+		},
+		["mapcoords"] = {
+			order = 2,
+			name = "Map Coords",
+			desc = "Font used for coordinates."
+		},
+	};
+
+	SV:GenerateFontOptionGroup("Maps", 10, "Fonts used for the minimap.", mapFonts)
+
+	SV.Options.args[Schema] = {
+		name = Schema,
+		type = 'group',
+		childGroups = "tree",
+		get = function(a)return SV.db[Schema][a[#a]]end,
+		set = function(a,b)MOD:ChangeDBVar(b,a[#a]);MOD:ReLoad()end,
+		args = {
+			intro={
+				order = 1,
+				type = 'description',
+				name = L["Options for the Minimap"],
+				width = 'full'
+			},
+			common = {
+				order = 2,
+				type = "group",
+				name = MINIMAP_LABEL,
+				desc = L['General display settings'],
+				guiInline = true,
+				args = {
+					size = {
+						order = 1,
+						type = "range",
+						name = L["Size"],
+						desc = L['Adjust the size of the minimap.'],
+						min = 100,
+						max = 1000,
+						width = "full",
+						step = 1
+					},
+					bordersize = {
+						order = 2,
+						type = "range",
+						name = "Border Size",
+						desc = "Adjust the size of the minimap's outer border",
+						min = 0,
+						max = 20,
+						step = 1,
+						width = "full"
+					},
+					bordercolor = {
+						order = 3,
+						type = 'select',
+						name = "Border Color",
+						desc = "Adjust the color of the minimap's outer border",
+						values = colorSelect,
+					},
+					mapShape = {
+						order = 4,
+						type = "select",
+						name = "Minimap Shape",
+						desc = function()
+							if(GetCVar("rotateMinimap") ~= "0") then
+								return "Disabled while the 'Rotate Minimap' option is enabled.";
+							else
+						 		return "Select the shape of your minimap.";
+						 	end
+						 end,
+						disabled = function() return (GetCVar("rotateMinimap") ~= "0") end,
+						values = {
+							['RECTANGLE'] = 'Rectangular (Default)',
+							['SQUARE'] = 'Square',
+							['ROUND'] = 'Round',
+						},
+					},
+					customIcons = {
+						order = 5,
+						type = "toggle",
+						name = "Custom Blip Icons",
+						desc = "Toggle the use of special map blips.",
+						set = function(a,b) MOD:ChangeDBVar(b,a[#a]); SV:StaticPopup_Show("RL_CLIENT") end
+					},
+					calendarShortcut = {
+						order = 6,
+						type = "toggle",
+						name = "Calendar Button",
+						desc = "Toggle the use of the calendar shortcut.",
+						set = function(a,b) MOD:ChangeDBVar(b,a[#a]); SV:StaticPopup_Show("RL_CLIENT") end
+					},
+					trackingShortcut = {
+						order = 7,
+						type = "toggle",
+						name = "Tracking Button",
+						desc = "Toggle the use of the tracking shortcut.",
+						set = function(a,b) MOD:ChangeDBVar(b,a[#a]); SV:StaticPopup_Show("RL_CLIENT") end
+					}
+				}
+			},
+			spacer1 = {
+				order = 4,
+				type = "group",
+				name = "",
+				guiInline = true,
+				args = {}
+			},
+			common2 = {
+				order = 5,
+				type = "group",
+				name = "Labels and Info",
+				desc = L['Configure various worldmap and minimap texts'],
+				guiInline = true,
+				args = {
+					locationText = {
+						order = 1,
+						type = "select",
+						name = L["Location Text"],
+						values = textSelect,
+						set = function(a,b)MOD:ChangeDBVar(b,a[#a])MOD:ReLoad()end
+					},
+					miniPlayerXY = {
+						order = 2,
+						type = "toggle",
+						name = L["Minimap X/Y Coordinates"],
+						set = function(a,b)MOD:ChangeDBVar(b,a[#a])MOD:ReLoad()end
+					},
+					worldPlayerXY = {
+						order = 3,
+						type = "toggle",
+						name = L["WorldMap Player X/Y Coordinates"],
+						set = function(a,b)MOD:ChangeDBVar(b,a[#a])MOD:ReLoad()end
+					},
+					worldMouseXY = {
+						order = 4,
+						type = "toggle",
+						name = L["WorldMap Mouse X/Y Coordinates"],
+						set = function(a,b)MOD:ChangeDBVar(b,a[#a])MOD:ReLoad()end
+					}
+				}
+			},
+			spacer2 = {
+				order = 6,
+				type = "group",
+				name = "",
+				guiInline = true,
+				args = {}
+			},
+			mmButtons = {
+				order = 7,
+				type = "group",
+				name = "Minimap Buttons",
+				get = function(j)return SV.db[Schema].minimapbar[j[#j]]end,
+				guiInline = true,
+				args = {
+					enable = {
+						order = 1,
+						type = 'toggle',
+						name = L['Buttons Styled'],
+						desc = L['Style the minimap buttons.'],
+						set = function(a,b)MOD:ChangeDBVar(b,a[#a],"minimapbar")SV:StaticPopup_Show("RL_CLIENT")end,
+					},
+					mouseover = {
+						order = 2,
+						name = L["Mouse Over"],
+						desc = L["Hidden unless you mouse over the frame."],
+						type = "toggle",
+						set = function(a,b) MOD:ChangeDBVar(b,a[#a],"minimapbar") MOD:UpdateMinimapButtonSettings(true) end,
+					},
+					styleType = {
+						order = 3,
+						type = 'select',
+						name = L['Button Bar Layout'],
+						desc = L['Change settings for how the minimap buttons are styled.'],
+						set = function(a,b) MOD:ChangeDBVar(b,a[#a],"minimapbar") MOD:UpdateMinimapButtonSettings(true) end,
+						disabled = function()return not SV.db[Schema].minimapbar.enable end,
+						values = {
+							['NOANCHOR'] = L['No Anchor Bar'],
+							['HORIZONTAL'] = L['Horizontal Anchor Bar'],
+							['VERTICAL'] = L['Vertical Anchor Bar']
+						}
+					},
+					buttonSize = {
+						order = 4,
+						type = 'range',
+						name = L['Buttons Size'],
+						desc = L['The size of the minimap buttons.'],
+						min = 16,
+						max = 40,
+						step = 1,
+						width = "full",
+						set = function(a,b)MOD:ChangeDBVar(b,a[#a],"minimapbar")MOD:UpdateMinimapButtonSettings(true) end,
+						disabled = function()return not SV.db[Schema].minimapbar.enable or SV.db[Schema].minimapbar.styleType == 'NOANCHOR'end
+					},
+					perRow = {
+						order = 5,
+						type = 'range',
+						name = L['Buttons Per Row'],
+						min = 1,
+						max = 40,
+						step = 1,
+						width = "full",
+						set = function(a,b)MOD:ChangeDBVar(b,a[#a],"minimapbar")MOD:UpdateMinimapButtonSettings(true) end,
+						disabled = function()return not SV.db[Schema].minimapbar.enable or SV.db[Schema].minimapbar.styleType == 'NOANCHOR'end
+					},
+				}
+			},
+			spacer3 = {
+				order = 8,
+				type = "group",
+				name = "",
+				guiInline = true,
+				args = {}
+			},
+			worldMap = {
+				order = 9,
+				type = "group",
+				name = "WorldMap",
+				guiInline = true,
+				args = {
+					tinyWorldMap = {
+						order = 1,
+						type = "toggle",
+						name = L["Tiny Map"],
+						desc = L["Don't scale the large world map to block out sides of the screen."],
+						set = function(a,b)MOD:ChangeDBVar(b,a[#a])MOD:ReLoad()end
+					},
+				}
+			},
+		}
+	}
+end
diff --git a/SVUI_Maps/SVUI_Maps.lua b/SVUI_Maps/SVUI_Maps.lua
new file mode 100644
index 0000000..020ffdc
--- /dev/null
+++ b/SVUI_Maps/SVUI_Maps.lua
@@ -0,0 +1,1010 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack    = _G.unpack;
+local select    = _G.select;
+local pairs     = _G.pairs;
+local tostring  = _G.tostring;
+local tonumber  = _G.tonumber;
+local tinsert   = _G.tinsert;
+local string    = _G.string;
+local math      = _G.math;
+--[[ STRING METHODS ]]--
+local lower, upper, len = string.lower, string.upper, string.len;
+local match, gsub, find = string.match, string.gsub, string.find;
+--[[ MATH METHODS ]]--
+local parsefloat = math.parsefloat;  -- Uncommon
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L
+local MOD = SV.Maps;
+if(not MOD) then return end;
+--[[
+##########################################################
+LOCALIZED GLOBALS
+##########################################################
+]]--
+local RAID_CLASS_COLORS = _G.RAID_CLASS_COLORS
+--[[
+##########################################################
+LOCAL VARS
+##########################################################
+]]--
+local temp = SLASH_CALENDAR1:gsub("/", "");
+local calendar_string = temp:gsub("^%l", upper)
+local cColor = RAID_CLASS_COLORS[SV.class];
+local MMBHolder, MMBBar;
+
+local NewHook = hooksecurefunc
+local Initialized = false
+local CoordPattern = "%.1f";
+--[[
+##########################################################
+DATA UPVALUES
+##########################################################
+]]--
+local MM_XY_COORD = false;
+local WMP_XY_COORD = false;
+local WMM_XY_COORD = false;
+local WM_TINY = false;
+local MM_COLOR = "darkest"
+local MM_BRDR = 0
+local MM_SIZE = 240
+local MM_BTN_SIZE = 30
+local MM_BTN_ROW = 8
+local MM_OFFSET_TOP = (MM_SIZE * 0.07)
+local MM_OFFSET_BOTTOM = (MM_SIZE * 0.11)
+local MM_WIDTH = MM_SIZE + (MM_BRDR * 2)
+local MM_HEIGHT = (MM_SIZE - (MM_OFFSET_TOP + MM_OFFSET_BOTTOM) + (MM_BRDR * 2))
+local WM_ALPHA = false;
+local MM_BTN_SIZE = 30;
+local MM_SHAPE = 'RECTANGLE';
+local NARR_TEXT = "Meanwhile";
+local NARR_PREFIX = "In ";
+--[[
+##########################################################
+MODULE CHILDREN
+##########################################################
+]]--
+MOD.MinimapButtons = {}
+MOD.Holder = _G["SVUI_MinimapFrame"];
+MOD.InfoTop = _G["SVUI_MinimapInfoTop"];
+MOD.InfoBottom = _G["SVUI_MinimapInfoBottom"];
+local MiniMapCoords = _G["SVUI_MiniMapCoords"];
+local WorldMapCoords = _G["SVUI_WorldMapCoords"];
+--local SVUI_MinimapFrame = CreateFrame("Frame", "SVUI_MinimapFrame", UIParent)
+--local WMCoords = CreateFrame('Frame', 'SVUI_WorldMapCoords', WorldMapFrame)
+--SVUI_MinimapFrame:SetSize(MM_WIDTH, MM_HEIGHT);
+--[[
+##########################################################
+GENERAL HELPERS
+##########################################################
+]]--
+--[[
+ /$$$$$$$  /$$   /$$ /$$$$$$$$/$$$$$$$$/$$$$$$  /$$   /$$  /$$$$$$
+| $$__  $$| $$  | $$|__  $$__/__  $$__/$$__  $$| $$$ | $$ /$$__  $$
+| $$  \ $$| $$  | $$   | $$     | $$ | $$  \ $$| $$$$| $$| $$  \__/
+| $$$$$$$ | $$  | $$   | $$     | $$ | $$  | $$| $$ $$ $$|  $$$$$$
+| $$__  $$| $$  | $$   | $$     | $$ | $$  | $$| $$  $$$$ \____  $$
+| $$  \ $$| $$  | $$   | $$     | $$ | $$  | $$| $$\  $$$ /$$  \ $$
+| $$$$$$$/|  $$$$$$/   | $$     | $$ |  $$$$$$/| $$ \  $$|  $$$$$$/
+|_______/  \______/    |__/     |__/  \______/ |__/  \__/ \______/
+--]]
+local MMB_OnEnter = function(self)
+	if(not SV.db.Maps.minimapbar.mouseover or SV.db.Maps.minimapbar.styleType == "NOANCHOR") then return end
+	UIFrameFadeIn(SVUI_MiniMapButtonBar, 0.2, SVUI_MiniMapButtonBar:GetAlpha(), 1)
+	if self:GetName() ~= "SVUI_MiniMapButtonBar" then
+		self:SetBackdropBorderColor(.7, .7, 0)
+	end
+end
+
+local MMB_OnLeave = function(self)
+	if(not SV.db.Maps.minimapbar.mouseover or SV.db.Maps.minimapbar.styleType == "NOANCHOR") then return end
+	UIFrameFadeOut(SVUI_MiniMapButtonBar, 0.2, SVUI_MiniMapButtonBar:GetAlpha(), 0)
+	if self:GetName() ~= "SVUI_MiniMapButtonBar" then
+		self:SetBackdropBorderColor(0, 0, 0)
+	end
+end
+
+do
+	local reserved = {"Node", "Tab", "Pin", "SVUI_ConsolidatedBuffs", "GameTimeframe", "HelpOpenTicketButton", "SVUI_MinimapFrame", "SVUI_EnhancedMinimap", "QueueStatusMinimapButton", "TimeManagerClockButton", "Archy", "GatherMatePin", "GatherNote", "GuildInstance", "HandyNotesPin", "MinimMap", "Spy_MapNoteList_mini", "ZGVMarker", "ZygorGuidesViewerMapIcon"}
+
+	local function UpdateMinimapButtons()
+		if(not SV.db.Maps.minimapbar.enable) then return end
+
+		MMBBar:SetPoint("CENTER", MMBHolder, "CENTER", 0, 0)
+		MMBBar:SetHeight(MM_BTN_SIZE + 4)
+		MMBBar:SetWidth(MM_BTN_SIZE + 4)
+		MMBBar:SetFrameStrata("LOW")
+		MMBBar:SetFrameLevel(0)
+
+		local list  = MOD.MinimapButtons
+		local count,column = 0,1;
+
+		for name,btn in pairs(list) do
+			local preset = btn.preset;
+			if(SV.db.Maps.minimapbar.styleType == "NOANCHOR") then
+				btn:SetParent(preset.Parent)
+				if preset.DragStart then
+					btn:SetScript("OnDragStart", preset.DragStart)
+				end
+				if preset.DragEnd then
+					btn:SetScript("OnDragStop", preset.DragEnd)
+				end
+				btn:ClearAllPoints()
+				btn:SetSize(preset.Width, preset.Height)
+				btn:SetPoint(preset.Point, preset.relativeTo, preset.relativePoint, preset.xOfs, preset.yOfs)
+				btn:SetFrameStrata(preset.FrameStrata)
+				btn:SetFrameLevel(preset.FrameLevel)
+				btn:SetScale(preset.Scale)
+				btn:SetMovable(true)
+			else
+				btn:SetParent(MMBBar)
+				btn:SetMovable(false)
+				btn:SetScript("OnDragStart", nil)
+				btn:SetScript("OnDragStop", nil)
+				btn:ClearAllPoints()
+				btn:SetFrameStrata("LOW")
+				btn:SetFrameLevel(20)
+				btn:SetSize(MM_BTN_SIZE, MM_BTN_SIZE)
+				if(column > MM_BTN_ROW) then
+					column = 1;
+				end
+				local xPos, yPos = 0,0;
+				local row = floor(count / MM_BTN_ROW);
+				if SV.db.Maps.minimapbar.styleType == "HORIZONTAL"then
+					xPos = ((MM_BTN_SIZE + 2) * column);
+					yPos = ((MM_BTN_SIZE + 2) * row);
+				else
+					xPos = ((MM_BTN_SIZE + 2) * row);
+					yPos = ((MM_BTN_SIZE + 2) * column);
+				end
+				btn:SetPoint("TOPRIGHT", MMBBar, "TOPRIGHT", -xPos, -yPos)
+			end
+			column = column + 1;
+			count = count + 1;
+		end
+
+		if (SV.db.Maps.minimapbar.styleType ~= "NOANCHOR" and (count > 0)) then
+			if SV.db.Maps.minimapbar.styleType == "HORIZONTAL" then
+				MMBBar:SetWidth((MM_BTN_SIZE + 2) * MM_BTN_ROW)
+			else
+				MMBBar:SetHeight((MM_BTN_SIZE + 2) * MM_BTN_ROW)
+			end
+			MMBHolder:SetSize(MMBBar:GetSize())
+			MMBBar:Show()
+		else
+			MMBBar:Hide()
+		end
+	end
+
+	local function SetMinimapButton(btn)
+		if btn == nil or btn:GetName() == nil or btn:GetObjectType() ~= "Button" or not btn:IsVisible() then return end
+		local name = btn:GetName()
+		local isLib = false;
+		if name:sub(1,len("LibDBIcon")) == "LibDBIcon" then isLib = true end
+		if(not isLib) then
+			local count = #reserved
+			for i = 1, count do
+				if name:sub(1,len(reserved[i])) == reserved[i] then return end
+				if name:find(reserved[i]) ~= nil then return end
+			end
+		end
+
+		btn:SetPushedTexture("")
+		btn:SetHighlightTexture("")
+		btn:SetDisabledTexture("")
+
+		if not btn.isStyled then
+			btn:HookScript("OnEnter", MMB_OnEnter)
+			btn:HookScript("OnLeave", MMB_OnLeave)
+			btn:HookScript("OnClick", UpdateMinimapButtons)
+			btn.preset = {}
+			btn.preset.Width, btn.preset.Height = btn:GetSize()
+			btn.preset.Point, btn.preset.relativeTo, btn.preset.relativePoint, btn.preset.xOfs, btn.preset.yOfs = btn:GetPoint()
+			btn.preset.Parent = btn:GetParent()
+			btn.preset.FrameStrata = btn:GetFrameStrata()
+			btn.preset.FrameLevel = btn:GetFrameLevel()
+			btn.preset.Scale = btn:GetScale()
+			if btn:HasScript("OnDragStart") then
+				btn.preset.DragStart = btn:GetScript("OnDragStart")
+			end
+			if btn:HasScript("OnDragEnd") then
+				btn.preset.DragEnd = btn:GetScript("OnDragEnd")
+			end
+			for i = 1, btn:GetNumRegions() do
+				local frame = select(i, btn:GetRegions())
+				if frame:GetObjectType() == "Texture" then
+					local iconFile = frame:GetTexture()
+					if(iconFile ~= nil and (iconFile:find("Border") or iconFile:find("Background") or iconFile:find("AlphaMask"))) then
+						frame:SetTexture("")
+					else
+						frame:ClearAllPoints()
+						frame:SetPoint("TOPLEFT", btn, "TOPLEFT", 2, -2)
+						frame:SetPoint("BOTTOMRIGHT", btn, "BOTTOMRIGHT", -2, 2)
+						frame:SetTexCoord(0.1, 0.9, 0.1, 0.9 )
+						frame:SetDrawLayer("ARTWORK")
+						if name == "PS_MinimapButton" then
+							frame.SetPoint = SV.fubar
+						end
+					end
+				end
+			end
+
+			btn:SetStyle("Button", -1, -1)
+
+			if(name == "DBMMinimapButton") then
+				btn:SetNormalTexture("Interface\\Icons\\INV_Helmet_87")
+			end
+
+			if(name == "SmartBuff_MiniMapButton") then
+				btn:SetNormalTexture(select(3, GetSpellInfo(12051)))
+			end
+
+			btn.isStyled = true
+
+			MOD.MinimapButtons[name] = btn
+		end
+	end
+
+	local StyleMinimapButtons = function()
+		local count = Minimap:GetNumChildren()
+
+		for i=1, count do
+			local child = select(i,Minimap:GetChildren())
+			SetMinimapButton(child)
+		end
+
+		UpdateMinimapButtons()
+
+		if SV.db.Maps.minimapbar.mouseover then
+			MMBBar:SetAlpha(0)
+		else
+			MMBBar:SetAlpha(1)
+		end
+	end
+
+	function MOD:UpdateMinimapButtonSettings(notimer)
+		if(not SV.db.Maps.minimapbar.enable or not MMBBar:IsShown()) then return end
+		if(notimer) then
+			StyleMinimapButtons()
+		else
+			SV.Timers:ExecuteTimer(StyleMinimapButtons, 4)
+		end
+	end
+end
+
+local function UpdateMiniMapCoords()
+	if(WMP_XY_COORD and WorldMapFrame:IsShown()) then return end
+	local skip = IsInInstance()
+	local playerX, playerY = GetPlayerMapPosition("player")
+	if((not skip) and (playerX ~= 0 and playerY ~= 0)) then
+		playerX = parsefloat(100 * playerX, 2)
+		playerY = parsefloat(100 * playerY, 2)
+		if(playerX ~= 0 and playerY ~= 0) then
+			if(not MiniMapCoords:IsShown()) then
+				MiniMapCoords:FadeIn()
+			end
+			MiniMapCoords.XLabel:SetText("X:")
+			MiniMapCoords.X:SetFormattedText(CoordPattern, playerX)
+			MiniMapCoords.YLabel:SetText("Y:")
+			MiniMapCoords.Y:SetFormattedText(CoordPattern, playerY)
+		else
+			-- if(MiniMapCoords:IsShown()) then
+			-- 	MiniMapCoords:FadeOut(0.2, 1, 0)
+			-- end
+			MiniMapCoords.XLabel:SetText("")
+			MiniMapCoords.X:SetText("")
+			MiniMapCoords.YLabel:SetText("")
+			MiniMapCoords.Y:SetText("")
+		end
+	else
+		MiniMapCoords.XLabel:SetText("")
+		MiniMapCoords.X:SetText("")
+		MiniMapCoords.YLabel:SetText("")
+		MiniMapCoords.Y:SetText("")
+	end
+end
+
+local function UpdateWorldMapCoords()
+	if(not WorldMapFrame:IsShown()) then return end
+
+	if(WMP_XY_COORD) then
+		local skip = IsInInstance()
+		local playerX, playerY = GetPlayerMapPosition("player")
+		if((not skip) and (playerX ~= 0 and playerY ~= 0)) then
+			playerX = parsefloat(100 * playerX, 2)
+			playerY = parsefloat(100 * playerY, 2)
+			if(playerX ~= 0 and playerY ~= 0) then
+				if(not WorldMapCoords.Player:IsShown()) then
+					WorldMapCoords.Player:FadeIn()
+				end
+				WorldMapCoords.Player.X:SetFormattedText(CoordPattern, playerX)
+				WorldMapCoords.Player.Y:SetFormattedText(CoordPattern, playerY)
+			else
+				WorldMapCoords.Player:FadeOut(0.2, 1, 0, true)
+			end
+		else
+			WorldMapCoords.Player:FadeOut(0.2, 1, 0, true)
+		end
+	end
+
+	if(WMM_XY_COORD) then
+		local scale = WorldMapDetailFrame:GetEffectiveScale()
+		local width = WorldMapDetailFrame:GetWidth()
+		local height = WorldMapDetailFrame:GetHeight()
+		local centerX, centerY = WorldMapDetailFrame:GetCenter()
+		local cursorX, cursorY = GetCursorPosition()
+		local mouseX = (cursorX / scale - (centerX - (width / 2))) / width;
+		local mouseY = (centerY + (height / 2) - cursorY / scale) / height;
+		if(((mouseX >= 0) and (mouseX <= 1)) and ((mouseY >= 0) and (mouseY <= 1))) then
+			mouseX = parsefloat(100 * mouseX, 2)
+			mouseY = parsefloat(100 * mouseY, 2)
+			if(not WorldMapCoords.Mouse:IsShown()) then
+				WorldMapCoords.Mouse:FadeIn()
+			end
+			WorldMapCoords.Mouse.X:SetFormattedText(CoordPattern, mouseX)
+			WorldMapCoords.Mouse.Y:SetFormattedText(CoordPattern, mouseY)
+		else
+			WorldMapCoords.Mouse:FadeOut(0.2, 1, 0, true)
+		end
+	end
+
+	if(WM_ALPHA and (not WorldMapFrame_InWindowedMode())) then
+		local speed = GetUnitSpeed("player")
+		if(speed ~= 0) then
+			WorldMapFrame:SetAlpha(0.2)
+		else
+			WorldMapFrame:SetAlpha(1)
+		end
+	end
+end
+
+--[[
+ /$$      /$$  /$$$$$$  /$$$$$$$  /$$       /$$$$$$$  /$$      /$$  /$$$$$$  /$$$$$$$
+| $$  /$ | $$ /$$__  $$| $$__  $$| $$      | $$__  $$| $$$    /$$$ /$$__  $$| $$__  $$
+| $$ /$$$| $$| $$  \ $$| $$  \ $$| $$      | $$  \ $$| $$$$  /$$$$| $$  \ $$| $$  \ $$
+| $$/$$ $$ $$| $$  | $$| $$$$$$$/| $$      | $$  | $$| $$ $$/$$ $$| $$$$$$$$| $$$$$$$/
+| $$$$_  $$$$| $$  | $$| $$__  $$| $$      | $$  | $$| $$  $$$| $$| $$__  $$| $$____/
+| $$$/ \  $$$| $$  | $$| $$  \ $$| $$      | $$  | $$| $$\  $ | $$| $$  | $$| $$
+| $$/   \  $$|  $$$$$$/| $$  | $$| $$$$$$$$| $$$$$$$/| $$ \/  | $$| $$  | $$| $$
+|__/     \__/ \______/ |__/  |__/|________/|_______/ |__/     |__/|__/  |__/|__/
+--]]
+
+local function SetLargeWorldMap()
+	if InCombatLockdown() then return end
+
+	if SV.db.Maps.tinyWorldMap == true then
+		-- WorldMapFrame:SetParent(SV.Screen)
+		WorldMapFrame:EnableMouse(false)
+		WorldMapFrame:EnableKeyboard(false)
+		WorldMapFrame:SetScale(1)
+		if WorldMapFrame:GetAttribute('UIPanelLayout-area') ~= 'center'then
+			SetUIPanelAttribute(WorldMapFrame, "area", "center")
+		end
+		if WorldMapFrame:GetAttribute('UIPanelLayout-allowOtherPanels') ~= true then
+			SetUIPanelAttribute(WorldMapFrame, "allowOtherPanels", true)
+		end
+	end
+
+	WorldMapFrameSizeUpButton:Hide()
+	WorldMapFrameSizeDownButton:Show()
+end
+
+local function SetSmallWorldMap()
+	if InCombatLockdown() then return end
+	WorldMapFrameSizeUpButton:Show()
+	WorldMapFrameSizeDownButton:Hide()
+end
+
+local function AdjustMapSize()
+	if InCombatLockdown() then return end
+
+	if WORLDMAP_SETTINGS.size == WORLDMAP_FULLMAP_SIZE then
+		WorldMapFrame:SetPoint("TOP", SV.Screen, "TOP", 0, 0)
+	end
+
+	if SV.db.Maps.tinyWorldMap == true then
+		BlackoutWorld:SetTexture("")
+	else
+		BlackoutWorld:SetColorTexture(0, 0, 0, 1)
+	end
+end
+
+local function UpdateWorldMapConfig()
+	if(not MM_XY_COORD) then
+		if MOD.MMCoordTimer then
+			SV.Timers:RemoveLoop(MOD.MMCoordTimer)
+			MOD.MMCoordTimer = nil;
+		end
+		MiniMapCoords.XLabel:SetText("")
+		MiniMapCoords.X:SetText("")
+		MiniMapCoords.YLabel:SetText("")
+		MiniMapCoords.Y:SetText("")
+	else
+		MiniMapCoords.XLabel:SetText("X:")
+		MiniMapCoords.YLabel:SetText("Y:")
+		UpdateMiniMapCoords()
+		MOD.MMCoordTimer = SV.Timers:ExecuteLoop(UpdateMiniMapCoords, 0.1)
+	end
+
+	if((not WMP_XY_COORD) and (not WMM_XY_COORD)) then
+		if MOD.WMCoordTimer then
+			SV.Timers:RemoveLoop(MOD.WMCoordTimer)
+			MOD.WMCoordTimer = nil;
+		end
+		WorldMapCoords.Player.Name:SetText("")
+		WorldMapCoords.Player.XLabel:SetText("")
+		WorldMapCoords.Player.X:SetText("")
+		WorldMapCoords.Player.YLabel:SetText("")
+		WorldMapCoords.Player.Y:SetText("")
+
+		WorldMapCoords.Mouse.Name:SetText("")
+		WorldMapCoords.Mouse.XLabel:SetText("")
+		WorldMapCoords.Mouse.X:SetText("")
+		WorldMapCoords.Mouse.YLabel:SetText("")
+		WorldMapCoords.Mouse.Y:SetText("")
+	else
+		if(not WMP_XY_COORD) then
+			WorldMapCoords.Player.XLabel:SetText("")
+			WorldMapCoords.Player.X:SetText("")
+			WorldMapCoords.Player.YLabel:SetText("")
+			WorldMapCoords.Player.Y:SetText("")
+			WorldMapCoords.Player.Name:SetText("");
+		else
+			WorldMapCoords.Player.XLabel:SetText("X:")
+			WorldMapCoords.Player.YLabel:SetText("Y:")
+			WorldMapCoords.Player.Name:SetText(PLAYER);
+		end
+		if(not WMM_XY_COORD) then
+			WorldMapCoords.Mouse.XLabel:SetText("")
+			WorldMapCoords.Mouse.X:SetText("")
+			WorldMapCoords.Mouse.YLabel:SetText("")
+			WorldMapCoords.Mouse.Y:SetText("")
+			WorldMapCoords.Mouse.Name:SetText("");
+		else
+			WorldMapCoords.Mouse.XLabel:SetText("X:")
+			WorldMapCoords.Mouse.YLabel:SetText("Y:")
+			WorldMapCoords.Mouse.Name:SetText(MOUSE_LABEL);
+		end
+		UpdateWorldMapCoords()
+		MOD.WMCoordTimer = SV.Timers:ExecuteLoop(UpdateWorldMapCoords, 0.1)
+	end
+
+	if InCombatLockdown()then return end
+	if(not MOD.WorldMapHooked) then
+		NewHook("WorldMap_ToggleSizeUp", AdjustMapSize)
+		NewHook("WorldMap_ToggleSizeDown", SetSmallWorldMap)
+		MOD.WorldMapHooked = true
+	end
+	AdjustMapSize()
+end
+--[[
+##########################################################
+HANDLERS
+##########################################################
+]]--
+local MiniMap_MouseUp = function(self, btn)
+	local position = self:GetPoint()
+	if btn == "RightButton" then
+		local xoff = -1
+		if position:match("RIGHT") then xoff = -16 end
+		ToggleDropDownMenu(1, nil, MiniMapTrackingDropDown, self, xoff, -3)
+	else
+		Minimap_OnClick(self)
+	end
+end
+
+local MiniMap_MouseWheel = function(self, delta)
+	if delta > 0 then
+		_G.MinimapZoomIn:Click()
+	elseif delta < 0 then
+		_G.MinimapZoomOut:Click()
+	end
+end
+
+local Calendar_OnClick = function(self)
+	GameTimeFrame:Click();
+end
+
+local Tracking_OnClick = function(self)
+	local position = self:GetPoint()
+	local xoff = -1
+	if position:match("RIGHT") then xoff = -16 end
+	ToggleDropDownMenu(1, nil, MiniMapTrackingDropDown, self, xoff, -3)
+end
+
+local Basic_OnEnter = function(self)
+	GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT", 0, 4)
+	GameTooltip:ClearLines()
+	GameTooltip:AddLine(self.TText, 1, 1, 1)
+	GameTooltip:Show()
+end
+
+local Basic_OnLeave = function(self)
+	GameTooltip:Hide()
+end
+
+local Tour_OnEnter = function(self, ...)
+	if InCombatLockdown() then
+		GameTooltip:Hide()
+	else
+		GameTooltip:SetOwner(self, "ANCHOR_BOTTOM", 0, -4)
+		GameTooltip:ClearAllPoints()
+		GameTooltip:SetPoint("BOTTOM", self, "BOTTOM", 0, 0)
+		GameTooltip:AddLine(" ")
+		GameTooltip:AddDoubleLine(L["Click : "], L["Toggle WorldMap"], 0.7, 0.7, 1, 0.7, 0.7, 1)
+		GameTooltip:AddDoubleLine(L["ShiftClick : "], L["Announce your position in chat"],0.7, 0.7, 1, 0.7, 0.7, 1)
+		GameTooltip:Show()
+	end
+end
+
+local Tour_OnLeave = function(self, ...)
+	GameTooltip:Hide()
+end
+
+local Tour_OnClick = function(self, btn)
+	if IsShiftKeyDown() then
+		local zoneText = GetRealZoneText() or UNKNOWN;
+		local subZone = GetSubZoneText() or UNKNOWN;
+		local edit_box = ChatEdit_ChooseBoxForSend();
+		local x, y = GetPlayerMapPosition("player");
+		x = tonumber(parsefloat(100 * x, 0));
+		y = tonumber(parsefloat(100 * y, 0));
+		local coords = ("%d, %d"):format(x, y);
+
+		ChatEdit_ActivateChat(edit_box)
+
+		if(zoneText ~= subZone) then
+			local message = ("%s: %s (%s)"):format(zoneText, subZone, coords)
+			edit_box:Insert(message)
+		else
+			local message = ("%s (%s)"):format(zoneText, coords)
+			edit_box:Insert(message)
+		end
+	else
+		ToggleFrame(WorldMapFrame)
+	end
+	GameTooltip:Hide()
+end
+--[[
+##########################################################
+HOOKS
+##########################################################
+]]--
+local _hook_WorldMapZoneDropDownButton_OnClick = function(self)
+	DropDownList1:ClearAllPoints()
+	DropDownList1:SetPoint("TOPRIGHT",self,"BOTTOMRIGHT",-17,-4)
+end
+
+local _hook_WorldMapFrame_OnShow = function()
+	MOD:RegisterEvent("PLAYER_REGEN_DISABLED");
+
+	if InCombatLockdown()then return end
+
+	if(not SV.db.Maps.tinyWorldMap and not Initialized) then
+      WorldMap_ToggleSizeUp()
+      Initialized = true
+    end
+end
+
+local _hook_WorldMapFrame_OnHide = function()
+	MOD:UnregisterEvent("PLAYER_REGEN_DISABLED")
+end
+
+local _hook_DropDownList1 = function(self)
+	local parentScale = UIParent:GetScale()
+	if(self:GetScale() ~= parentScale) then
+		self:SetScale(parentScale)
+	end
+end
+--[[
+##########################################################
+EVENTS
+##########################################################
+]]--
+function MOD:RefreshZoneText()
+	if(not SV.db.Maps.locationText or SV.db.Maps.locationText == "HIDE") then
+		self.InfoTop:Hide();
+		self.InfoBottom:Hide();
+	else
+		if(SV.db.Maps.locationText == "SIMPLE") then
+			self.InfoTop:Hide();
+			self.InfoBottom:Show();
+			NARR_TEXT = "";
+			NARR_PREFIX = "";
+			self.InfoTop.Text:SetText(NARR_TEXT)
+		else
+			self.InfoTop:Show();
+			self.InfoBottom:Show();
+			NARR_TEXT = L['Meanwhile'];
+			NARR_PREFIX = L["..at "];
+			self.InfoTop.Text:SetText(NARR_TEXT)
+		end
+		local zone = GetMinimapZoneText() or UNKNOWN
+		zone = zone:sub(1, 25);
+		local zoneText = ("%s%s"):format(NARR_PREFIX, zone);
+		self.InfoBottom.Text:SetText(zoneText)
+	end
+end
+
+local InfoBottom_OnEnter = function(self)
+	if(not self:IsShown()) then return end
+	local zone = GetRealZoneText() or UNKNOWN
+	zone = zone:sub(1, 25);
+	local zoneText = ("%s%s"):format(L["..in "], zone);
+	self.Text:SetText(zoneText)
+end
+
+local InfoBottom_OnLeave = function(self)
+	if(not self:IsShown()) then return end
+	local zone = GetMinimapZoneText() or UNKNOWN
+	zone = zone:sub(1, 25);
+	local zoneText = ("%s%s"):format(NARR_PREFIX, zone);
+	self.Text:SetText(zoneText)
+end
+
+function MOD:ADDON_LOADED(event, addon)
+	if TimeManagerClockButton then
+		TimeManagerClockButton:Die()
+	end
+	self:UnregisterEvent("ADDON_LOADED")
+	if addon == "Blizzard_FeedbackUI" then
+		FeedbackUIButton:Die()
+	end
+	self:UpdateMinimapButtonSettings()
+end
+
+function MOD:PLAYER_REGEN_ENABLED()
+	WorldMapFrameSizeDownButton:Enable()
+	WorldMapFrameSizeUpButton:Enable()
+	if(self.CombatLocked) then
+		self:RefreshMiniMap()
+		self.CombatLocked = nil
+	end
+end
+
+function MOD:PLAYER_REGEN_DISABLED()
+	WorldMapFrameSizeDownButton:Disable()
+	WorldMapFrameSizeUpButton:Disable()
+end
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+function MOD:RefreshMiniMap()
+	if(InCombatLockdown()) then
+		self.CombatLocked = true
+		return
+	end
+
+	self:UpdateLocals()
+
+	if(self.Holder and self.Holder:IsShown()) then
+		local minimapRotationEnabled = GetCVar("rotateMinimap") ~= "0"
+
+		if(minimapRotationEnabled or (MM_SHAPE == 'ROUND')) then
+			--SV.Dock.TopRight:SetSize(MM_WIDTH, (MM_WIDTH + 4))
+			self.Holder:SetSize(MM_WIDTH, MM_WIDTH)
+			Minimap:SetSize(MM_SIZE,MM_SIZE)
+			self.Holder.Square:Hide()
+			self.Holder.Circle:Show()
+			Minimap:SetHitRectInsets(0, 0, 0, 0)
+			Minimap:InsetPoints(self.Holder, MM_BRDR, MM_BRDR)
+			Minimap:SetMaskTexture('Textures\\MinimapMask')
+		else
+			--SV.Dock.TopRight:SetSize(MM_WIDTH, (MM_HEIGHT + 4))
+			self.Holder:SetSize(MM_WIDTH, MM_HEIGHT)
+			Minimap:SetSize(MM_SIZE,MM_SIZE)
+			self.Holder.Circle:Hide()
+			self.Holder.Square:Show()
+			self.Holder.Square:SetPanelColor(MM_COLOR)
+
+			if MM_SHAPE == 'RECTANGLE' then
+				Minimap:SetPoint("BOTTOMLEFT", self.Holder, "BOTTOMLEFT", MM_BRDR, (MM_OFFSET_BOTTOM - MM_BRDR) * -1)
+				Minimap:SetPoint("TOPRIGHT", self.Holder, "TOPRIGHT", -MM_BRDR, (MM_OFFSET_TOP - MM_BRDR))
+				Minimap:SetMaskTexture(MOD.media.rectangleMask)
+			else
+				Minimap:SetHitRectInsets(0, 0, 0, 0)
+				Minimap:InsetPoints(self.Holder, MM_BRDR, MM_BRDR)
+				Minimap:SetMaskTexture(MOD.media.squareMask)
+			end
+		end
+		Minimap:SetParent(self.Holder)
+		Minimap:SetZoom(1)
+		Minimap:SetZoom(0)
+
+		if(SV.Auras and self.Holder.Grip) then
+			SV.Auras:UpdateAuraHolder(MM_HEIGHT, self.Holder.Grip)
+		end
+	--else
+		--SV.Dock.TopRight:SetSize(MM_WIDTH, (MM_HEIGHT + 4))
+	end
+
+	--self.InfoTop.Text:SetSize(MM_WIDTH,28)
+	self.InfoBottom.Text:SetSize(MM_WIDTH,32)
+	self:RefreshZoneText()
+
+	if TimeManagerClockButton then
+		TimeManagerClockButton:Die()
+	end
+
+	UpdateWorldMapConfig()
+end
+
+local function RotationHook()
+	MOD:RefreshMiniMap()
+end
+--[[
+##########################################################
+BUILD FUNCTION / UPDATE
+##########################################################
+]]--
+function MOD:UpdateLocals()
+	local db = SV.db.Maps
+	if not db then return end
+
+	MM_XY_COORD = db.miniPlayerXY;
+	WMP_XY_COORD = db.worldPlayerXY;
+	WMM_XY_COORD = db.worldMouseXY;
+	WM_TINY = db.tinyWorldMap;
+	MM_COLOR = db.bordercolor
+	MM_BRDR = db.bordersize or 0
+	MM_SIZE = db.size or 240
+	MM_OFFSET_TOP = (MM_SIZE * 0.07)
+	MM_OFFSET_BOTTOM = (MM_SIZE * 0.11)
+	MM_WIDTH = MM_SIZE + (MM_BRDR * 2)
+	MM_SHAPE = db.mapShape;
+	MM_BTN_SIZE = db.minimapbar.buttonSize;
+	MM_BTN_ROW = db.minimapbar.perRow;
+	MM_HEIGHT = (MM_SHAPE == 'RECTANGLE') and (MM_SIZE - (MM_OFFSET_TOP + MM_OFFSET_BOTTOM) + (MM_BRDR * 2)) or MM_WIDTH
+	WM_ALPHA = GetCVarBool("mapFade")
+end
+
+function MOD:ReLoad()
+	self:RefreshMiniMap()
+	self:UpdateMinimapButtonSettings(true)
+end
+
+local function MapTriggerFired()
+	MOD:RefreshMiniMap()
+	MOD:UpdateMinimapButtonSettings()
+end
+
+local _hook_BlipTextures = function(self, texture)
+	if(SV.db.Maps.customIcons and (texture ~= MOD.media.customBlips)) then
+		self:SetBlipTexture(MOD.media.customBlips)
+	else
+		if((not SV.db.Maps.customIcons) and texture ~= MOD.media.defaultBlips) then
+			self:SetBlipTexture(MOD.media.defaultBlips)
+		end
+	end
+end
+
+function MOD:Load()
+	self:UpdateLocals()
+
+	--Minimap:SetPlayerTexture(MOD.media.playerArrow)
+	--Minimap:SetCorpsePOIArrowTexture(MOD.media.corpseArrow)
+	--Minimap:SetPOIArrowTexture(MOD.media.guideArrow)
+	if(SV.db.Maps.customIcons) then
+		--Minimap:SetBlipTexture(MOD.media.customBlips)
+	else
+		--Minimap:SetBlipTexture(MOD.media.defaultBlips)
+	end
+
+	Minimap:SetClampedToScreen(false)
+	if TimeManagerClockButton then
+		TimeManagerClockButton:Die()
+	end
+
+	Minimap:SetQuestBlobRingAlpha(0)
+	Minimap:SetArchBlobRingAlpha(0)
+	Minimap:SetParent(self.Holder)
+	Minimap:SetFrameStrata("LOW")
+	Minimap:SetFrameLevel(Minimap:GetFrameLevel() + 2)
+
+	self.Holder:SetFrameLevel(Minimap:GetFrameLevel() - 2)
+	self.Holder:SetFrameStrata("LOW")
+	self.Holder:SetPoint("TOPRIGHT", SV.Screen, "TOPRIGHT", -15, -20)
+	self.Holder:SetSize(MM_WIDTH, MM_HEIGHT)
+
+	self.Holder.Square = CreateFrame("Frame", nil, self.Holder)
+	self.Holder.Square:WrapPoints(self.Holder, 2)
+	self.Holder.Square:SetStyle("Frame", "Minimap")
+	self.Holder.Square:SetPanelColor(MM_COLOR)
+
+	self.Holder.Circle = self.Holder:CreateTexture(nil, "BACKGROUND", nil, -2)
+	self.Holder.Circle:WrapPoints(self.Holder, 2)
+	self.Holder.Circle:SetTexture(MOD.media.roundBorder)
+	self.Holder.Circle:SetVertexColor(0,0,0)
+	self.Holder.Circle:Hide()
+
+	ShowUIPanel(SpellBookFrame)
+	HideUIPanel(SpellBookFrame)
+	MinimapBorder:Hide()
+	MinimapBorderTop:Hide()
+	MinimapZoomIn:Hide()
+	MinimapZoomOut:Hide()
+	MiniMapVoiceChatFrame:Hide()
+	MinimapNorthTag:Die()
+	GameTimeFrame:Hide()
+	MinimapZoneTextButton:Hide()
+	MiniMapTracking:Hide()
+	MiniMapMailFrame:ClearAllPoints()
+	MiniMapMailFrame:SetPoint("TOPRIGHT", self.Holder, 3, 4)
+	MiniMapMailBorder:Hide()
+	MiniMapMailIcon:SetTexture(MOD.media.mailIcon)
+	MiniMapWorldMapButton:Hide()
+
+	MiniMapInstanceDifficulty:ClearAllPoints()
+	MiniMapInstanceDifficulty:SetParent(Minimap)
+	MiniMapInstanceDifficulty:SetPoint("LEFT", self.Holder, "LEFT", 0, 0)
+
+	GuildInstanceDifficulty:ClearAllPoints()
+	GuildInstanceDifficulty:SetParent(Minimap)
+	GuildInstanceDifficulty:SetPoint("LEFT", self.Holder, "LEFT", 0, 0)
+
+	MiniMapChallengeMode:ClearAllPoints()
+	MiniMapChallengeMode:SetParent(Minimap)
+	MiniMapChallengeMode:SetPoint("LEFT", self.Holder, "LEFT", 12, 0)
+
+	QueueStatusMinimapButton:ClearAllPoints()
+	QueueStatusMinimapButton:SetPoint("BOTTOMLEFT", self.Holder, "BOTTOMLEFT", 2, 1)
+	QueueStatusMinimapButton:SetStyle("Frame", "Default", true, 1, -4, -4)
+
+	QueueStatusFrame:SetClampedToScreen(true)
+	QueueStatusMinimapButtonBorder:Hide()
+	QueueStatusMinimapButton:SetScript("OnShow", function()
+		MiniMapInstanceDifficulty:SetPoint("BOTTOMLEFT", QueueStatusMinimapButton, "TOPLEFT", 0, 0)
+		GuildInstanceDifficulty:SetPoint("BOTTOMLEFT", QueueStatusMinimapButton, "TOPLEFT", 0, 0)
+		MiniMapChallengeMode:SetPoint("BOTTOMLEFT", QueueStatusMinimapButton, "TOPRIGHT", 0, 0)
+	end)
+	QueueStatusMinimapButton:SetScript("OnHide", function()
+		MiniMapInstanceDifficulty:SetPoint("LEFT", self.Holder, "LEFT", 0, 0)
+		GuildInstanceDifficulty:SetPoint("LEFT", self.Holder, "LEFT", 0, 0)
+		MiniMapChallengeMode:SetPoint("LEFT", self.Holder, "LEFT", 12, 0)
+	end)
+
+	if FeedbackUIButton then
+		FeedbackUIButton:Die()
+	end
+
+	local mwfont = SV.media.font.narrator
+
+	self.InfoTop:SetPoint("TOPLEFT", self.Holder, "TOPLEFT", 4, -4)
+	--self.InfoTop:SetSize(100, 22)
+	self.InfoTop:SetStyle("Frame")
+  self.InfoTop:SetPanelColor("yellow")
+  self.InfoTop:SetBackdropColor(1, 1, 0, 1)
+	self.InfoTop:SetFrameLevel(Minimap:GetFrameLevel() + 2)
+
+	self.InfoTop.Text:SetShadowColor(0, 0, 0, 0.3)
+	self.InfoTop.Text:SetShadowOffset(2, -2);
+
+	self.InfoTop.Panel:ClearAllPoints();
+	self.InfoTop.Panel:SetPoint("TOPLEFT", self.InfoTop.Text, "TOPLEFT", -4, 4);
+	self.InfoTop.Panel:SetPoint("BOTTOMRIGHT", self.InfoTop.Text, "BOTTOMRIGHT", 4, -4);
+	self.InfoTop.Panel:SetAttribute("panelLocked", true);
+
+	self.InfoBottom:SetPoint("BOTTOMRIGHT", self.Holder, "BOTTOMRIGHT", 2, -3)
+	self.InfoBottom:SetSize(MM_WIDTH, 28)
+	self.InfoBottom:SetFrameLevel(Minimap:GetFrameLevel() + 1)
+
+	self.InfoBottom.Text:SetShadowColor(0, 0, 0, 0.3)
+	self.InfoBottom.Text:SetShadowOffset(-2, 2)
+	self.InfoBottom:SetScript("OnEnter", InfoBottom_OnEnter)
+	self.InfoBottom:SetScript("OnLeave", InfoBottom_OnLeave)
+
+	Minimap:EnableMouseWheel(true)
+	Minimap:SetScript("OnMouseWheel", MiniMap_MouseWheel)
+	Minimap:SetScript("OnMouseUp", MiniMap_MouseUp)
+
+	SV:NewAnchor(self.Holder, L["Minimap"])
+
+	if(SV.db.Maps.tinyWorldMap) then
+		setfenv(WorldMapFrame_OnShow, setmetatable({ UpdateMicroButtons = SV.fubar }, { __index = _G }))
+		-- WorldMapFrame:SetParent(SV.Screen)
+		WorldMapFrame:HookScript('OnShow', _hook_WorldMapFrame_OnShow)
+		WorldMapFrame:HookScript('OnHide', _hook_WorldMapFrame_OnHide)
+	end
+
+	WorldMapCoords:SetFrameLevel(WorldMapDetailFrame:GetFrameLevel() + 1);
+	WorldMapCoords:SetFrameStrata(WorldMapDetailFrame:GetFrameStrata());
+	WorldMapCoords.Player.Name:SetText(PLAYER);
+	WorldMapCoords.Mouse.Name:SetText(MOUSE_LABEL);
+
+	--SV:NewAnchor(WorldMapCoords, L["WorldMap Coordinates"])
+
+	DropDownList1:HookScript('OnShow', _hook_DropDownList1)
+	WorldFrame:SetAllPoints()
+
+	SV:ManageVisibility(self.Holder)
+
+	MiniMapCoords:ClearAllPoints()
+	MiniMapCoords:SetFrameLevel(Minimap:GetFrameLevel() + 1)
+	MiniMapCoords:SetFrameStrata(Minimap:GetFrameStrata())
+	MiniMapCoords:SetPoint("TOPLEFT", self.Holder, "BOTTOMLEFT", 0, -4)
+	MiniMapCoords:SetWidth(self.Holder:GetWidth())
+	MiniMapCoords:EnableMouse(true)
+	MiniMapCoords:SetScript("OnEnter",Tour_OnEnter)
+	MiniMapCoords:SetScript("OnLeave",Tour_OnLeave)
+	MiniMapCoords:SetScript("OnMouseDown",Tour_OnClick)
+
+	MiniMapCoords.X:SetTextColor(cColor.r, cColor.g, cColor.b)
+	MiniMapCoords.Y:SetTextColor(cColor.r, cColor.g, cColor.b)
+
+	if (SV.db.Maps.calendarShortcut) then
+		local calendarButton = CreateFrame("Button", "SVUI_CalendarButton", MiniMapCoords)
+		calendarButton:SetSize(22,22)
+		calendarButton:SetPoint("RIGHT", MiniMapCoords, "RIGHT", 0, 0)
+		calendarButton:RemoveTextures()
+		calendarButton:SetNormalTexture(MOD.media.calendarIcon)
+		calendarButton:SetPushedTexture(MOD.media.calendarIcon)
+		calendarButton:SetHighlightTexture(MOD.media.calendarIcon)
+		calendarButton.TText = "Calendar"
+		calendarButton:RegisterForClicks("AnyUp")
+		calendarButton:SetScript("OnEnter", Basic_OnEnter)
+		calendarButton:SetScript("OnLeave", Basic_OnLeave)
+		calendarButton:SetScript("OnClick", Calendar_OnClick)
+	end
+
+	if (SV.db.Maps.trackingShortcut) then
+		local trackingButton = CreateFrame("Button", "SVUI_TrackingButton", MiniMapCoords)
+		trackingButton:SetSize(22,22)
+		if (SVUI_CalendarButton) then
+			trackingButton:SetPoint("RIGHT", SVUI_CalendarButton, "LEFT", -4, 0)
+		else
+			trackingButton:SetPoint("RIGHT", MiniMapCoords, "RIGHT", 0, 0)
+		end
+		trackingButton:RemoveTextures()
+		trackingButton:SetNormalTexture(MOD.media.trackingIcon)
+		trackingButton:SetPushedTexture(MOD.media.trackingIcon)
+		trackingButton:SetHighlightTexture(MOD.media.trackingIcon)
+		trackingButton.TText = "Tracking"
+		trackingButton:RegisterForClicks("AnyUp")
+		trackingButton:SetScript("OnEnter", Basic_OnEnter)
+		trackingButton:SetScript("OnLeave", Basic_OnLeave)
+		trackingButton:SetScript("OnClick", Tracking_OnClick)
+	end
+
+	SV:NewAnchor(MiniMapCoords, L["Minimap ToolBar"])
+
+	if(SV.db.Maps.minimapbar.enable == true) then
+		MMBHolder = CreateFrame("Frame", "SVUI_MiniMapButtonHolder", self.Holder)
+		MMBHolder:SetPoint("TOPRIGHT", MiniMapCoords, "BOTTOMRIGHT", 0, -4)
+		MMBHolder:SetSize(self.Holder:GetWidth(), 32)
+		MMBHolder:SetFrameStrata("BACKGROUND")
+		MMBBar = CreateFrame("Frame", "SVUI_MiniMapButtonBar", MMBHolder)
+		MMBBar:SetFrameStrata("LOW")
+		MMBBar:ClearAllPoints()
+		MMBBar:SetPoint("CENTER", MMBHolder, "CENTER", 0, 0)
+		MMBBar:SetScript("OnEnter", MMB_OnEnter)
+		MMBBar:SetScript("OnLeave", MMB_OnLeave)
+		SV:NewAnchor(MMBHolder, L["Minimap Button Bar"])
+		self:UpdateMinimapButtonSettings()
+	end
+
+	self:RefreshMiniMap()
+
+	self:RegisterEvent('ADDON_LOADED')
+	self:RegisterEvent('PLAYER_REGEN_ENABLED')
+	self:RegisterEvent('PLAYER_REGEN_DISABLED')
+	self:RegisterEvent("ZONE_CHANGED", "RefreshZoneText")
+	self:RegisterEvent("ZONE_CHANGED_NEW_AREA", "RefreshZoneText")
+
+	NewHook("Minimap_UpdateRotationSetting", RotationHook)
+
+	SV.Events:On("CORE_INITIALIZED", MapTriggerFired);
+end
diff --git a/SVUI_Maps/SVUI_Maps.toc b/SVUI_Maps/SVUI_Maps.toc
new file mode 100644
index 0000000..67bc904
--- /dev/null
+++ b/SVUI_Maps/SVUI_Maps.toc
@@ -0,0 +1,16 @@
+## Interface: 70000
+## Author: Failcoder
+## Version: 1.3.5
+## Title: |cffFF9900SuperVillain UI: |r|cffFFEF00Maps|r
+## Notes: Maps Plugin for [|cff9911FFSVUI|r].
+## OptionalDeps: LibSharedMedia-3.0
+## RequiredDeps: SVUI_!Core
+## X-SVUIName: Maps
+## X-SVUISchema: Maps
+## X-Email: munglunch@gmail.com
+## X-Website: http://www.supervillainui.com
+## X-Donate: PayPal:munglunch@gmail.com
+## X-License: MIT
+## X-Category: Interface Enhancements
+
+SVUI_Maps.xml
diff --git a/SVUI_Maps/SVUI_Maps.xml b/SVUI_Maps/SVUI_Maps.xml
new file mode 100644
index 0000000..c88817f
--- /dev/null
+++ b/SVUI_Maps/SVUI_Maps.xml
@@ -0,0 +1,213 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+    <Font name="SVUI_Font_MinimapInfo" font="Fonts\ARIALN.TTF" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="13"/>
+        </FontHeight>
+    </Font>
+    <Font name="SVUI_Font_MinimapCoords" font="Fonts\MORPHEUS.ttf" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="13"/>
+        </FontHeight>
+    </Font>
+
+    <Frame name="SVUI_StyleTemplate_Minimap" virtual="true">
+        <Attributes>
+            <Attribute name="panelID" type="string" value="minimap" />
+            <Attribute name="panelPadding" type="number" value="1" />
+            <Attribute name="panelColor" type="string" value="transparent" />
+            <Attribute name="panelGradient" type="string" value="light" />
+            <Attribute name="panelTexUpdate" type="boolean" value="false" />
+            <Attribute name="panelOffset" type="number" value="1" />
+            <Attribute name="panelSkipUpdate" type="boolean" value="false" />
+        </Attributes>
+        <Backdrop bgFile="Interface\BUTTONS\WHITE8X8" edgeFile="Interface\BUTTONS\WHITE8X8" tile="false">
+            <EdgeSize val="2" />
+            <TileSize val="0" />
+            <BackgroundInsets left="1" right="1" top="1" bottom="1" />
+            <Color r="0" g="0" b="0" a="0.5" />
+            <BorderColor r="0" g="0" b="0" a="1" />
+        </Backdrop>
+        <Layers>
+            <Layer level="BACKGROUND" textureSubLevel="1">
+                <Texture parentKey="Skin" nonBlocking="true" file="Interface\AddOns\SVUI_!Core\assets\backgrounds\DEFAULT" setAllPoints="true" />
+                <Color r="0" g="0" b="0" a="0.5" />
+            </Layer>
+            <Layer level="BORDER">
+                <Texture parentKey="BorderLeft" file="Interface\BUTTONS\WHITE8X8">
+                    <Anchors>
+                        <Anchor point="TOPLEFT" relativePoint="TOPLEFT" />
+                        <Anchor point="BOTTOMLEFT" relativePoint="BOTTOMLEFT" />
+                    </Anchors>
+                    <Size>
+                        <AbsDimension x="2" />
+                    </Size>
+                    <Color r="0" g="0" b="0" a="1" />
+                </Texture>
+                <Texture parentKey="BorderRight" file="Interface\BUTTONS\WHITE8X8">
+                    <Anchors>
+                        <Anchor point="TOPRIGHT" relativePoint="TOPRIGHT" />
+                        <Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMRIGHT" />
+                    </Anchors>
+                    <Size>
+                        <AbsDimension x="2" />
+                    </Size>
+                    <Color r="0" g="0" b="0" a="1" />
+                </Texture>
+                <Texture parentKey="BorderTop" file="Interface\BUTTONS\WHITE8X8">
+                    <Anchors>
+                        <Anchor point="TOPLEFT" relativePoint="TOPLEFT" />
+                        <Anchor point="TOPRIGHT" relativePoint="TOPRIGHT" />
+                    </Anchors>
+                    <Size>
+                        <AbsDimension y="2" />
+                    </Size>
+                    <Color r="0" g="0" b="0" a="1" />
+                </Texture>
+                <Texture parentKey="BorderBottom" file="Interface\BUTTONS\WHITE8X8">
+                    <Anchors>
+                        <Anchor point="BOTTOMLEFT" relativePoint="BOTTOMLEFT" />
+                        <Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMRIGHT" />
+                    </Anchors>
+                    <Size>
+                        <AbsDimension y="2" />
+                    </Size>
+                    <Color r="0" g="0" b="0" a="1" />
+                </Texture>
+            </Layer>
+        </Layers>
+        <Frames>
+            <Frame parentKey="Shadow" inherits="SVUI_ShadowTemplate" />
+        </Frames>
+    </Frame>
+
+    <Frame name="SVUI_CoordHolderTemplate" virtual="true">
+        <Layers>
+            <Layer level="ARTWORK">
+                <FontString name="$parentXLabel" parentKey="XLabel" inherits="SVUI_Font_MinimapCoords" text="X:" justifyH="LEFT" justifyV="MIDDLE">
+                    <Anchors>
+                        <Anchor point="LEFT" relativeTo="$parent" relativePoint="LEFT" x="0" y="0" />
+                    </Anchors>
+                    <Color r="1" g="1" b="0" a="1"/>
+                </FontString>
+                <FontString name="$parentX" parentKey="X" inherits="SVUI_Font_MinimapCoords" text="" justifyH="LEFT" justifyV="MIDDLE">
+                    <Size x="50" y="22"/>
+                    <Anchors>
+                        <Anchor point="LEFT" relativeTo="$parentXLabel" relativePoint="RIGHT" x="1" y="0" />
+                    </Anchors>
+                    <Color r="0" g="1" b="0.5" a="1"/>
+                </FontString>
+                <FontString name="$parentYLabel" parentKey="YLabel" inherits="SVUI_Font_MinimapCoords" text="Y:" justifyH="LEFT" justifyV="MIDDLE">
+                    <Anchors>
+                        <Anchor point="LEFT" relativeTo="$parentX" relativePoint="RIGHT" x="0" y="0" />
+                    </Anchors>
+                    <Color r="1" g="1" b="0" a="1"/>
+                </FontString>
+                <FontString name="$parentY" parentKey="Y" inherits="SVUI_Font_MinimapCoords" text="" justifyH="LEFT" justifyV="MIDDLE">
+                    <Size x="50" y="22"/>
+                    <Anchors>
+                        <Anchor point="LEFT" relativeTo="$parentYLabel" relativePoint="RIGHT" x="1" y="0" />
+                    </Anchors>
+                    <Color r="0" g="1" b="0.5" a="1"/>
+                </FontString>
+            </Layer>
+        </Layers>
+    </Frame>
+
+    <Frame name="SVUI_MinimapFrame" parent="UIParent">
+        <Size x="240" y="197"/>
+        <Anchors>
+            <Anchor point="CENTER" relativeTo="Minimap" relativePoint="CENTER" x="0" y="0" />
+        </Anchors>
+    </Frame>
+
+    <Frame name="SVUI_MinimapInfoTop" parent="Minimap">
+        <Size x="18" y="18"/>
+        <Anchors>
+            <Anchor point="TOPLEFT" relativeTo="SVUI_MinimapFrame" relativePoint="TOPLEFT" x="4" y="-4" />
+        </Anchors>
+        <Layers>
+            <Layer level="ARTWORK">
+                <FontString parentKey="Text" inherits="SVUI_Font_MinimapInfo" text="Meanwhile" justifyH="CENTER" justifyV="MIDDLE">
+                    <Anchors>
+                        <Anchor point="TOPLEFT" relativeTo="$parent" relativePoint="TOPLEFT" x="2" y="-2" />
+                    </Anchors>
+                </FontString>
+            </Layer>
+        </Layers>
+    </Frame>
+
+    <Frame name="SVUI_MinimapInfoBottom" parent="Minimap">
+        <Size x="240" y="28"/>
+        <Anchors>
+            <Anchor point="BOTTOMRIGHT" relativeTo="SVUI_MinimapFrame" relativePoint="BOTTOMRIGHT" x="2" y="-3" />
+        </Anchors>
+        <Layers>
+            <Layer level="ARTWORK">
+                <FontString parentKey="Text" inherits="SVUI_Font_MinimapInfo" text="..." justifyH="RIGHT" justifyV="MIDDLE" setAllPoints="true" />
+            </Layer>
+        </Layers>
+    </Frame>
+
+    <Frame name="SVUI_WorldMapCoords" parent="WorldMapFrame" >
+        <Size x="212" y="54"/>
+        <Anchors>
+            <Anchor point="BOTTOMLEFT" relativeTo="WorldMapFrame" relativePoint="BOTTOMLEFT" x="5" y="5" />
+        </Anchors>
+        <Frames>
+            <Frame name="$parentPlayer" parentKey="Player" inherits="SVUI_CoordHolderTemplate">
+                <Size x="142" y="22"/>
+                <Anchors>
+                    <Anchor point="BOTTOMLEFT" relativeTo="$parent" relativePoint="BOTTOMLEFT" x="70" y="5" />
+                </Anchors>
+                <Layers>
+                    <Layer level="ARTWORK">
+                        <FontString name="$parentName" parentKey="Name" inherits="SVUI_Font_MinimapInfo" text="" justifyH="LEFT" justifyV="MIDDLE">
+                            <Anchors>
+                                <Anchor point="RIGHT" relativeTo="$parent" relativePoint="LEFT" x="-2" y="0" />
+                            </Anchors>
+                            <Color r="1" g="1" b="1" a="1"/>
+                        </FontString>
+                    </Layer>
+                </Layers>
+            </Frame>
+            <Frame name="$parentMouse" parentKey="Mouse" inherits="SVUI_CoordHolderTemplate">
+                <Size x="142" y="22"/>
+                <Anchors>
+                    <Anchor point="BOTTOMLEFT" relativeTo="$parent" relativePoint="BOTTOMLEFT" x="70" y="30" />
+                </Anchors>
+                <Layers>
+                    <Layer level="ARTWORK">
+                        <FontString name="$parentName" parentKey="Name" inherits="SVUI_Font_MinimapInfo" text="" justifyH="LEFT" justifyV="MIDDLE">
+                            <Anchors>
+                                <Anchor point="RIGHT" relativeTo="$parent" relativePoint="LEFT" x="-2" y="0" />
+                            </Anchors>
+                            <Color r="1" g="1" b="1" a="1"/>
+                        </FontString>
+                    </Layer>
+                </Layers>
+            </Frame>
+        </Frames>
+    </Frame>
+
+    <Frame name="SVUI_MiniMapCoords" parent="Minimap" inherits="SVUI_CoordHolderTemplate">
+        <Size x="140" y="22"/>
+        <Anchors>
+            <Anchor point="TOPLEFT" relativeTo="$parent" relativePoint="BOTTOMLEFT" x="0" y="-2" />
+        </Anchors>
+    </Frame>
+
+	<Script file='Loader.lua'/>
+	<Script file='SVUI_Maps.lua'/>
+</Ui>
diff --git a/SVUI_Maps/assets/DEFAULT-OBJECTICONS.blp b/SVUI_Maps/assets/DEFAULT-OBJECTICONS.blp
new file mode 100644
index 0000000..0e6b143
Binary files /dev/null and b/SVUI_Maps/assets/DEFAULT-OBJECTICONS.blp differ
diff --git a/SVUI_Maps/assets/MINIMAP-CALENDAR.blp b/SVUI_Maps/assets/MINIMAP-CALENDAR.blp
new file mode 100644
index 0000000..432c650
Binary files /dev/null and b/SVUI_Maps/assets/MINIMAP-CALENDAR.blp differ
diff --git a/SVUI_Maps/assets/MINIMAP-MAIL.blp b/SVUI_Maps/assets/MINIMAP-MAIL.blp
new file mode 100644
index 0000000..bead59e
Binary files /dev/null and b/SVUI_Maps/assets/MINIMAP-MAIL.blp differ
diff --git a/SVUI_Maps/assets/MINIMAP-OBJECTICONS.blp b/SVUI_Maps/assets/MINIMAP-OBJECTICONS.blp
new file mode 100644
index 0000000..99d20dd
Binary files /dev/null and b/SVUI_Maps/assets/MINIMAP-OBJECTICONS.blp differ
diff --git a/SVUI_Maps/assets/MINIMAP-ROUND.blp b/SVUI_Maps/assets/MINIMAP-ROUND.blp
new file mode 100644
index 0000000..1389179
Binary files /dev/null and b/SVUI_Maps/assets/MINIMAP-ROUND.blp differ
diff --git a/SVUI_Maps/assets/MINIMAP-TRACKING.blp b/SVUI_Maps/assets/MINIMAP-TRACKING.blp
new file mode 100644
index 0000000..499fb9c
Binary files /dev/null and b/SVUI_Maps/assets/MINIMAP-TRACKING.blp differ
diff --git a/SVUI_Maps/assets/MINIMAP_ARROW.blp b/SVUI_Maps/assets/MINIMAP_ARROW.blp
new file mode 100644
index 0000000..98b09c4
Binary files /dev/null and b/SVUI_Maps/assets/MINIMAP_ARROW.blp differ
diff --git a/SVUI_Maps/assets/MINIMAP_CORPSE_ARROW.blp b/SVUI_Maps/assets/MINIMAP_CORPSE_ARROW.blp
new file mode 100644
index 0000000..7586ef4
Binary files /dev/null and b/SVUI_Maps/assets/MINIMAP_CORPSE_ARROW.blp differ
diff --git a/SVUI_Maps/assets/MINIMAP_GUIDE_ARROW.blp b/SVUI_Maps/assets/MINIMAP_GUIDE_ARROW.blp
new file mode 100644
index 0000000..93554f8
Binary files /dev/null and b/SVUI_Maps/assets/MINIMAP_GUIDE_ARROW.blp differ
diff --git a/SVUI_Maps/assets/MINIMAP_MASK_RECTANGLE.blp b/SVUI_Maps/assets/MINIMAP_MASK_RECTANGLE.blp
new file mode 100644
index 0000000..06e4de1
Binary files /dev/null and b/SVUI_Maps/assets/MINIMAP_MASK_RECTANGLE.blp differ
diff --git a/SVUI_Maps/assets/MINIMAP_MASK_SQUARE.blp b/SVUI_Maps/assets/MINIMAP_MASK_SQUARE.blp
new file mode 100644
index 0000000..0c0f27b
Binary files /dev/null and b/SVUI_Maps/assets/MINIMAP_MASK_SQUARE.blp differ
diff --git a/SVUI_Maps/assets/MINIMAP_ROTATE_ARROW.blp b/SVUI_Maps/assets/MINIMAP_ROTATE_ARROW.blp
new file mode 100644
index 0000000..32527c0
Binary files /dev/null and b/SVUI_Maps/assets/MINIMAP_ROTATE_ARROW.blp differ
diff --git a/SVUI_NamePlates/LICENSE.txt b/SVUI_NamePlates/LICENSE.txt
new file mode 100644
index 0000000..05ceba8
--- /dev/null
+++ b/SVUI_NamePlates/LICENSE.txt
@@ -0,0 +1,31 @@
+
+The MIT License
+
+Copyright (c) 2010, Failcoder (Steve Jackson)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy
+of this software and associated documentation files (the "Software"), to
+deal
+in the Software without restriction, including without limitation the
+rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/SVUI_NamePlates/Loader.lua b/SVUI_NamePlates/Loader.lua
new file mode 100644
index 0000000..568384d
--- /dev/null
+++ b/SVUI_NamePlates/Loader.lua
@@ -0,0 +1,846 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+
+local SV = _G["SVUI"];
+local L = SV.L;
+local MOD = SV:NewModule(...);
+local Schema = MOD.Schema;
+
+local positionTable = {
+	TOPLEFT = "TOPLEFT",
+	LEFT = "LEFT",
+	BOTTOMLEFT = "BOTTOMLEFT",
+	RIGHT = "RIGHT",
+	TOPRIGHT = "TOPRIGHT",
+	BOTTOMRIGHT = "BOTTOMRIGHT",
+	CENTER = "CENTER",
+	TOP = "TOP",
+	BOTTOM = "BOTTOM",
+	RIGHTTOP = "RIGHTTOP",
+    LEFTTOP = "LEFTTOP",
+    RIGHTBOTTOM = "RIGHTBOTTOM",
+    LEFTBOTTOM = "LEFTBOTTOM"
+};
+
+local activeFilter,filters;
+
+MOD.media = {}
+MOD.media.healthBar = [[Interface\BUTTONS\WHITE8X8]];
+MOD.media.castBar = [[Interface\AddOns\SVUI_!Core\assets\statusbars\GRADIENT]];
+MOD.media.comboIcon = [[Interface\AddOns\SVUI_NamePlates\assets\COMBO-POINT]];
+MOD.media.topArt = [[Interface\AddOns\SVUI_NamePlates\assets\PLATE-TOP]];
+MOD.media.bottomArt = [[Interface\AddOns\SVUI_NamePlates\assets\PLATE-BOTTOM]];
+MOD.media.rightArt = [[Interface\AddOns\SVUI_NamePlates\assets\PLATE-RIGHT]];
+MOD.media.leftArt = [[Interface\AddOns\SVUI_NamePlates\assets\PLATE-LEFT]];
+MOD.media.roles = [[Interface\AddOns\SVUI_NamePlates\assets\PLATE-ROLES]];
+
+SV:AssignMedia("font", "platename", "SVUI Caps Font", 9, "OUTLINE");
+SV:AssignMedia("font", "platenumber", "SVUI Caps Font", 9, "OUTLINE");
+SV:AssignMedia("font", "plateaura", "SVUI Caps Font", 9, "OUTLINE");
+SV:AssignMedia("globalfont", "platename", "SVUI_Font_NamePlate");
+SV:AssignMedia("globalfont", "platenumber", "SVUI_Font_NamePlate_Number");
+SV:AssignMedia("globalfont", "plateaura", "SVUI_Font_NamePlate_Aura");
+SV:AssignMedia("template", "Nameplate", "SVUI_StyleTemplate_Nameplate");
+
+SV.defaults[Schema] = {
+	["themed"] = true,
+	["filter"] = {},
+	["barTexture"] = "SVUI MultiColorBar",
+	["font"] = DIALOGUE_FONT,
+	["fontSize"] = 10,
+	["fontOutline"] = "OUTLINE",
+	["comboPoints"] = true,
+	["nonTargetAlpha"] = 0.6,
+	["combatHide"] = false,
+	["colorNameByValue"] = true,
+	["showthreat"] = true,
+	["targetcount"] = true,
+	["findHealers"] = true,
+	["pointer"] = {
+		["enable"] = true,
+		["colorMatchHealthBar"] = true,
+		["color"] = {0.9, 1, 0.9},
+		["useArrowEffect"] = true,
+	},
+	["healthBar"] = {
+		["lowThreshold"] = 0.4,
+		["width"] = 108,
+		["height"] = 10,
+		["text"] = {
+			["enable"] = false,
+			["format"] = "CURRENT",
+			["xOffset"] = 0,
+			["yOffset"] = 0,
+			["attachTo"] = "CENTER",
+		},
+	},
+	["castBar"] = {
+		["height"] = 8,
+		["color"] = {1, 0.81, 0},
+		["noInterrupt"] = {1, 0.25, 0.25},
+		["text"] = {
+			["enable"] = false,
+			["xOffset"] = 2,
+			["yOffset"] = 0,
+		},
+	},
+	["raidHealIcon"] = {
+		["xOffset"] =  -4,
+		["yOffset"] = 6,
+		["size"] = 36,
+		["attachTo"] = "LEFT",
+	},
+	["auras"] = {
+		["font"] = "SVUI Number Font",
+		["fontSize"] = 7,
+		["fontOutline"] = "OUTLINE",
+		["numAuras"] = 5,
+		["additionalFilter"] = "CC"
+	},
+	["reactions"] = {
+		["tapped"] = {0.6, 0.6, 0.6},
+		["friendlyNPC"] = { 0.31, 0.45, 0.63},
+		["friendlyPlayer"] = {0.29, 0.68, 0.3},
+		["neutral"] = {0.85, 0.77, 0.36},
+		["enemy"] = {0.78, 0.25, 0.25},
+	},
+	["threat"] = {
+		["enable"] = false,
+		["goodScale"] = 1,
+		["badScale"] = 1,
+		["goodColor"] = {0.29, 0.68, 0.3},
+		["badColor"] = {0.78, 0.25, 0.25},
+		["goodTransitionColor"] = {0.85, 0.77, 0.36},
+		["badTransitionColor"] = {0.94, 0.6, 0.06},
+	},
+};
+
+
+local function UpdateFilterGroupOptions()
+	if not activeFilter or not SV.db['NamePlates']['filter'][activeFilter] then
+		SV.Options.args[Schema].args.Filters.args.filterGroup=nil;
+		return
+	end
+	SV.Options.args[Schema].args.Filters.args.filterGroup = {
+		type = "group",
+		name = activeFilter,
+		guiInline = true,
+		order = -10,
+		get = function(d)return SV.db["NamePlates"]["filter"][activeFilter][d[#d]] end,
+		set = function(d,e)
+			SV.db["NamePlates"]["filter"][activeFilter][d[#d]] = e;
+			MOD:PlateIteration("AssertFiltering")
+			MOD:UpdateAllPlates()
+			UpdateFilterGroupOptions()
+		end,
+		args = {
+			enable = {
+				type = "toggle",
+				order = 1,
+				name = L["Enable"],
+				desc = L["Use this filter."]
+			},
+			hide = {
+				type = "toggle",
+				order = 2,
+				name = L["Hide"],
+				desc = L["Prevent any nameplate with this unit name from showing."]
+			},
+			customColor = {
+				type = "toggle",
+				order = 3,
+				name = L["Custom Color"],
+				desc = L["Disable threat coloring for this plate and use the custom color."]
+			},
+			color = {
+				type = "color",
+				order = 4,
+				name = L["Color"],
+				get = function(key)
+					local color = SV.db["NamePlates"]["filter"][activeFilter][key[#key]]
+					if color then
+						return color[1],color[2],color[3],color[4]
+					end
+				end,
+				set = function(key,r,g,b)
+					SV.db["NamePlates"]["filter"][activeFilter][key[#key]] = {}
+					local color = SV.db["NamePlates"]["filter"][activeFilter][key[#key]]
+					if color then
+						color = {r,g,b};
+						UpdateFilterGroupOptions()
+						MOD:PlateIteration("CheckFilterAndHealers")
+						MOD:UpdateAllPlates()
+					end
+				end
+			},
+			customScale = {
+				type = "range",
+				name = L["Custom Scale"],
+				desc = L["Set the scale of the nameplate."],
+				min = 0.67,
+				max = 2,
+				step = 0.01
+			}
+		}
+	}
+end
+
+function MOD:LoadOptions()
+	local plateFonts = {
+		["platename"] = {
+			order = 1,
+			name = "Nameplate Names",
+			desc = "Used on nameplates for unit names."
+		},
+		["platenumber"] = {
+			order = 2,
+			name = "Nameplate Numbers",
+			desc = "Used on nameplates for health and level numbers."
+		},
+	    ["plateaura"] = {
+			order = 3,
+			name = "Nameplate Auras",
+			desc = "Used on nameplates for aura texts."
+		},
+	};
+
+	SV:GenerateFontOptionGroup("NamePlate", 5, "Fonts used in name plates.", plateFonts)
+
+	SV.Options.args[Schema] = {
+		type = "group",
+		name = Schema,
+		childGroups = "tab",
+		args = {
+			commonGroup = {
+				order = 1,
+				type = 'group',
+				name = L['NamePlate Options'],
+				childGroups = "tree",
+				args = {
+					intro={
+						order = 1,
+						type = 'description',
+						name = L["NAMEPLATE_DESC"],
+						width = 'full'
+					},
+					common = {
+						order = 1,
+						type = "group",
+						name = L["General"],
+						get = function(d)return SV.db[Schema][d[#d]]end,
+						set = function(d,e)MOD:ChangeDBVar(e,d[#d]);MOD:UpdateAllPlates() end,
+						args = {
+							themed = {
+								type = "toggle",
+								order = 1,
+								name = L["Super Styled"],
+								desc = L["This will enable/disable the extra fancy styling around elite/rare plates."],
+								set = function(d,e)MOD:ChangeDBVar(e,d[#d])SV:StaticPopup_Show("RL_CLIENT")end
+							},
+							combatHide = {
+								type = "toggle",
+								order = 2,
+								name = L["Combat Toggle"],
+								desc = L["Toggle the nameplates to be invisible outside of combat and visible inside combat."],
+								set = function(d,e)MOD:ChangeDBVar(e,d[#d])MOD:CombatToggle()end
+							},
+							comboPoints = {
+								type = "toggle",
+								order = 3,
+								name = L["Combo Points"],
+								desc = L["Display combo points on nameplates."]
+							},
+							colorNameByValue = {
+								type = "toggle",
+								order = 4,
+								name = L["Color Name By Health Value"],
+								width = 'full',
+							},
+							showthreat = {
+								type = "toggle",
+								order = 5,
+								name = L["Threat Text"],
+								desc = L["Display threat level as text on targeted,	boss or mouseover nameplate."]
+							},
+							barTexture = {
+								type = "select",
+								dialogControl = "LSM30_Statusbar",
+								order = 6,
+								name = L["StatusBar Texture"],
+								desc = L["Main statusbar texture."],
+								values = AceVillainWidgets.statusbar
+							},
+							nonTargetAlpha = {
+								type = "range",
+								order = 7,
+								name = L["Non-Target Alpha"],
+								desc = L["Alpha of nameplates that are not your current target."],
+								width = 'full',
+								min = 0,
+								max = 1,
+								step = 0.01,
+								isPercent = true
+							},
+							spacer1 = {
+								order = 8,
+								type = "description",
+								name = "",
+								width = "full",
+							},
+							reactions = {
+								order = 9,
+								type = "group",
+								name = L["Reaction Coloring"],
+								guiInline = true,
+								get = function(key)
+									local color = SV.db[Schema].reactions[key[#key]]
+									if color then
+										return color[1],color[2],color[3],color[4]
+									end
+								end,
+								set = function(key,r,g,b)
+									local color = {r,g,b}
+									MOD:ChangeDBVar(color, key[#key], "reactions")
+									MOD:UpdateAllPlates()
+								end,
+								args = {
+									friendlyNPC = {
+										type = "color",
+										order = 1,
+										name = L["Friendly NPC"],
+										hasAlpha = false
+									},
+									friendlyPlayer = {
+										name = L["Friendly Player"],
+										order = 2,
+										type = "color",
+										hasAlpha = false
+									},
+									neutral = {
+										name = L["Neutral"],
+										order = 3,
+										type = "color",
+										hasAlpha = false
+									},
+									enemy = {
+										name = L["Enemy"],
+										order = 4,
+										type = "color",
+										hasAlpha = false
+									},
+									tapped = {
+										name = L["Tagged NPC"],
+										order = 5,
+										type = "color",
+										hasAlpha = false
+									},
+								}
+							},
+							threat = {
+								type = "group",
+								name = L["Threat Coloring"],
+								guiInline = true,
+								order = 10,
+								args = {
+									enable = {
+										type = "toggle",
+										order = 1,
+										name = L["Enable Threat Coloring"],
+										width = "full",
+										get = function(key)return SV.db[Schema].threat.enable end,
+										set = function(key,value) SV.db[Schema].threat.enable = value; MOD:UpdateAllPlates() end,
+									},
+									goodColor = {
+										type = "color",
+										order = 2,
+										name = L["Good Threat"],
+										hasAlpha = false,
+										disabled = function(key) return not SV.db[Schema].threat.enable end,
+										get = function(key)
+											local color = SV.db[Schema].threat.goodColor
+											if color then
+												return color[1],color[2],color[3],color[4]
+											end
+										end,
+										set = function(key,r,g,b)
+											SV.db[Schema].threat.goodColor = {r,g,b}
+											MOD:UpdateAllPlates()
+										end,
+									},
+									badColor = {
+										name = L["Bad Threat"],
+										order = 3,
+										type = "color",
+										hasAlpha = false,
+										disabled = function(key) return not SV.db[Schema].threat.enable end,
+										get = function(key)
+											local color = SV.db[Schema].threat.badColor
+											if color then
+												return color[1],color[2],color[3],color[4]
+											end
+										end,
+										set = function(key,r,g,b)
+											SV.db[Schema].threat.badColor = {r,g,b}
+											MOD:UpdateAllPlates()
+										end,
+									},
+									goodTransitionColor = {
+										name = L["Good Threat Transition"],
+										order = 4,
+										type = "color",
+										hasAlpha = false,
+										disabled = function(key) return not SV.db[Schema].threat.enable end,
+										get = function(key)
+											local color = SV.db[Schema].threat.goodTransitionColor
+											if color then
+												return color[1],color[2],color[3],color[4]
+											end
+										end,
+										set = function(key,r,g,b)
+											SV.db[Schema].threat.goodTransitionColor = {r,g,b}
+											MOD:UpdateAllPlates()
+										end,
+									},
+									badTransitionColor = {
+										name = L["Bad Threat Transition"],
+										order = 5,
+										type = "color",
+										hasAlpha = false,
+										disabled = function(key) return not SV.db[Schema].threat.enable end,
+										get = function(key)
+											local color = SV.db[Schema].threat.badTransitionColor
+											if color then
+												return color[1],color[2],color[3],color[4]
+											end
+										end,
+										set = function(key,r,g,b)
+											SV.db[Schema].threat.badTransitionColor = {r,g,b}
+											MOD:UpdateAllPlates()
+										end,
+									},
+								}
+							},
+							scaling = {
+								type = "group",
+								name = L["Threat Scaling"],
+								guiInline = true,
+								order = 11,
+								disabled = function(key) return not SV.db[Schema].threat.enable end,
+								args = {
+									goodScale = {
+										type = "range",
+										name = L["Good"],
+										order = 1,
+										min = 0.5,
+										max = 1.5,
+										step = 0.01,
+										width = 'full',
+										isPercent = true,
+										get = function(key)return SV.db[Schema].threat.goodScale end,
+										set = function(key,value) SV.db[Schema].threat.goodScale = value; MOD:UpdateAllPlates() end,
+									},
+									badScale = {
+										type = "range",
+										name = L["Bad"],
+										order = 1,
+										min = 0.5,
+										max = 1.5,
+										step = 0.01,
+										width = 'full',
+										isPercent = true,
+										get = function(key)return SV.db[Schema].threat.badScale end,
+										set = function(key,value) SV.db[Schema].threat.badScale = value; MOD:UpdateAllPlates() end,
+									}
+								}
+							},
+						}
+					},
+					healthBar = {
+						type = "group",
+						order = 2,
+						name = L["Health Bar"],
+						get = function(d)return SV.db[Schema].healthBar[d[#d]]end,
+						set = function(d,e)MOD:ChangeDBVar(e,d[#d],"healthBar");MOD:UpdateAllPlates()end,
+						args = {
+							width = {
+								type = "range",
+								order = 1,
+								name = L["Width"],
+								desc = L["Controls the width of the nameplate"],
+								type = "range",
+								min = 50,
+								max = 125,
+								step = 1
+							},
+							height = {
+								type = "range",
+								order = 2,
+								name = L["Height"],
+								desc = L["Controls the height of the nameplate"],
+								type = "range",
+								min = 4,
+								max = 30,
+								step = 1
+							},
+							lowThreshold = {
+								type = "range",
+								order = 3,
+								name = L["Low Health Threshold"],
+								desc = L["Color the border of the nameplate yellow when it reaches this point,it will be colored red when it reaches half this value."],
+								isPercent = true,
+								min = 0,
+								max = 1,
+								step = 0.01
+							},
+							fontGroup = {
+								order = 4,
+								type = "group",
+								name = L["Texts"],
+								guiInline = true,
+								get = function(d)return SV.db[Schema].healthBar.text[d[#d]]end,
+								set = function(d,e)MOD:ChangeDBVar(e,d[#d],"healthBar","text");MOD:UpdateAllPlates()end,
+								args = {
+									enable = {
+										type = "toggle",
+										name = L["Enable"],
+										order = 1
+									},
+									attachTo = {
+										type = "select",
+										order = 2,
+										name = L["Attach To"],
+										values = {
+											TOPLEFT = "TOPLEFT",
+											LEFT = "LEFT",
+											BOTTOMLEFT = "BOTTOMLEFT",
+											RIGHT = "RIGHT",
+											TOPRIGHT = "TOPRIGHT",
+											BOTTOMRIGHT = "BOTTOMRIGHT",
+											CENTER = "CENTER",
+											TOP = "TOP",
+											BOTTOM = "BOTTOM"
+										}
+									},
+									format = {
+										type = "select",
+										order = 3,
+										name = L["Format"],
+										values = {
+											["CURRENT_MAX_PERCENT"] = L["Current - Max | Percent"],
+											["CURRENT_PERCENT"] = L["Current - Percent"],
+											["CURRENT_MAX"] = L["Current - Max"],
+											["CURRENT"] = L["Current"],
+											["PERCENT"] = L["Percent"],
+											["DEFICIT"] = L["Deficit"]
+										}
+									},
+									xOffset = {
+										type = "range",
+										order = 4,
+										name = L["X-Offset"],
+										min = -150,
+										max = 150,
+										step = 1
+									},
+									yOffset = {
+										type = "range",
+										order = 5,
+										name = L["Y-Offset"],
+										min = -150,
+										max = 150,
+										step = 1
+									}
+								}
+							}
+						}
+					},
+					castBar = {
+						type = "group",
+						order = 3,
+						name = L["Cast Bar"],
+						get = function(d)return SV.db[Schema].castBar[d[#d]]end,
+						set = function(d,e)MOD:ChangeDBVar(e,d[#d],"castBar");MOD:UpdateAllPlates()end,
+						args = {
+							height = {
+								type = "range",
+								order = 1,
+								name = L["Height"],
+								type = "range",
+								min = 4,
+								max = 30,
+								step = 1
+							},
+							colors = {
+								order = 100,
+								type = "group",
+								name = L["Colors"],
+								guiInline = true,
+								get = function(key)
+									local color = SV.db[Schema].castBar[key[#key]]
+									if color then
+										return color[1],color[2],color[3],color[4]
+									end
+								end,
+								set = function(key,r,g,b)
+									local color = {r,g,b}
+									MOD:ChangeDBVar(color, key[#key], "castBar")
+									MOD:UpdateAllPlates()
+								end,
+								args = {
+									color = {
+										type = "color",
+										order = 1,
+										name = L["Can Interrupt"],
+										hasAlpha = false
+									},
+									noInterrupt = {
+										name = "No Interrupt",
+										order = 2,
+										type = "color",
+										hasAlpha = false
+									}
+								}
+							}
+						}
+					},
+					pointer = {
+						type = "group",
+						order = 4,
+						name = L["Target Indicator"],
+						get = function(d)return SV.db[Schema].pointer[d[#d]]end,
+						set = function(d,e) MOD:ChangeDBVar(e,d[#d],"pointer"); _G.WorldFrame.elapsed = 3; MOD:UpdateAllPlates() end,
+						args = {
+							enable = {
+								order = 1,
+								type = "toggle",
+								name = L["Enable"]
+							},
+							useArrowEffect = {
+								order = 2,
+								type = "toggle",
+								name = L["Use 3D Arrow"]
+							},
+							colorMatchHealthBar = {
+								order = 3,
+								type = "toggle",
+								name = L["Color By Healthbar"],
+								desc = L["Match the color of the healthbar."],
+								set = function(key, value)
+									MOD:ChangeDBVar(value, key[#key], "pointer");
+									if value then
+										_G.WorldFrame.elapsed = 3
+									end
+								end
+							},
+							color = {
+								type = "color",
+								name = L["Color"],
+								order = 4,
+								disabled = function()return SV.db[Schema].pointer.colorMatchHealthBar end,
+								get = function(key)
+									local color = SV.db[Schema].pointer[key[#key]]
+									if color then
+										return color[1],color[2],color[3],color[4]
+									end
+								end,
+								set = function(key,r,g,b)
+									local color = {r,g,b}
+									MOD:ChangeDBVar(color, key[#key], "pointer")
+									MOD:UpdateAllPlates()
+								end,
+							}
+						}
+					},
+					raidHealIcon = {
+						type = "group",
+						order = 5,
+						name = L["Raid Icon"],
+						get = function(d)return SV.db[Schema].raidHealIcon[d[#d]]end,
+						set = function(d,e)MOD:ChangeDBVar(e,d[#d],"raidHealIcon")MOD:UpdateAllPlates()end,
+						args = {
+							attachTo = {
+								type = "select",
+								order = 1,
+								name = L["Attach To"],
+								values = positionTable
+							},
+							xOffset = {
+								type = "range",
+								order = 2,
+								name = L["X-Offset"],
+								min = -150,
+								max = 150,
+								step = 1
+							},
+							yOffset = {
+								type = "range",
+								order = 3,
+								name = L["Y-Offset"],
+								min = -150,
+								max = 150,
+								step = 1
+							},
+							size = {
+								order = 4,
+								type = "range",
+								name = L["Size"],
+								width = "full",
+								min = 10,
+								max = 200,
+								step = 1
+							},
+						}
+					},
+					auras = {
+						type = "group",
+						order = 4,
+						name = L["Auras"],
+						get = function(d)return SV.db[Schema].auras[d[#d]]end,
+						set = function(d,e)MOD:ChangeDBVar(e,d[#d],"auras")MOD:UpdateAllPlates()end,
+						args = {
+							numAuras = {
+								type = "range",
+								order = 1,
+								name = L["Number of Auras"],
+								min = 2,
+								max = 8,
+								step = 1
+							},
+							additionalFilter = {
+								type = "select",
+								order = 2,
+								name = L["Additional Filter"],
+								values = function()
+									filters = {}
+									filters[""] = _G.NONE;
+									for j in pairs(SV.db.Filters.Custom) do
+										filters[j] = j
+									end
+									return filters
+								end
+							},
+							configureButton = {
+								order = 4,
+								name = L["Configure Selected Filter"],
+								type = "execute",
+								width = "full",
+								func = function()ns:SetToFilterConfig(SV.db[Schema].auras.additionalFilter)end
+							},
+							fontGroup = {
+								order = 100,
+								type = "group",
+								guiInline = true,
+								name = L["Fonts"],
+								args = {
+									font = {
+										type = "select",
+										dialogControl = "LSM30_Font",
+										order = 4,
+										name = L["Font"],
+										values = AceVillainWidgets.font
+									},
+									fontSize = {
+										order = 5,
+										name = L["Font Size"],
+										type = "range",
+										min = 6,
+										max = 22,
+										step = 1
+									},
+									fontOutline = {
+										order = 6,
+										name = L["Font Outline"],
+										desc = L["Set the font outline."],
+										type = "select",
+										values = {
+											["NONE"] = L["None"],
+											["OUTLINE"] = "OUTLINE",
+											["MONOCHROMEOUTLINE"] = "MONOCROMEOUTLINE",
+											["THICKOUTLINE"] = "THICKOUTLINE"
+										}
+									}
+								}
+							}
+						}
+					},
+					filters = {
+						type = "group",
+						order = 5,
+						name = L["Filters"],
+						args = {
+							addname = {
+								type = "input",
+								order = 1,
+								name = L["Add Name"],
+								get = function(d)return""end,
+								set = function(d,e)
+									if SV.db["NamePlates"]["filter"][e]then
+										SV:AddonMessage(L["Filter already exists!"])
+										return
+									end
+									SV.db["NamePlates"]["filter"][e] = {
+										["enable"] = true,
+										["hide"] = false,
+										["customColor"] = false,
+										["customScale"] = 1,
+										["color"] = {
+											g = 104/255,
+											h = 138/255,
+											i = 217/255
+										}
+									}
+									UpdateFilterGroupOptions()
+									MOD:UpdateAllPlates()
+								end
+							},
+							deletename = {
+								type = "input",
+								order = 2,
+								name = L["Remove Name"],
+								get = function(d)return""end,
+								set = function(d,e)
+									if SV.db["NamePlates"]["filter"][e] then
+										SV.db["NamePlates"]["filter"][e].enable = false;
+										SV:AddonMessage(L["You can't remove a default name from the filter,disabling the name."])
+									else
+										SV.db["NamePlates"]["filter"][e] = nil;
+										SV.Options.args[Schema].args.Filters.args.filterGroup = nil
+									end
+									UpdateFilterGroupOptions()
+									MOD:UpdateAllPlates()
+								end
+							},
+							selectFilter = {
+								order = 3,
+								type = "select",
+								name = L["Select Filter"],
+								get = function(d)return activeFilter end,
+								set = function(d,e)activeFilter = e;UpdateFilterGroupOptions()end,
+								values = function()
+									filters = {}
+									if(SV.db["NamePlates"]["filter"]) then
+										for j in pairs(SV.db["NamePlates"]["filter"])do
+											filters[j] = j
+										end
+									end
+									return filters
+								end
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+end
diff --git a/SVUI_NamePlates/OLD_SVUI_NamePlates.lua b/SVUI_NamePlates/OLD_SVUI_NamePlates.lua
new file mode 100644
index 0000000..f42b616
--- /dev/null
+++ b/SVUI_NamePlates/OLD_SVUI_NamePlates.lua
@@ -0,0 +1,1555 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+credit: Elv.       NamePlatess was parently nameplates.lua adapted from ElvUI #
+##############################################################################
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack    = _G.unpack;
+local select    = _G.select;
+local pairs     = _G.pairs;
+local ipairs    = _G.ipairs;
+local type      = _G.type;
+local error     = _G.error;
+local pcall     = _G.pcall;
+local tostring  = _G.tostring;
+local tonumber  = _G.tonumber;
+local tinsert   = _G.tinsert;
+local string    = _G.string;
+local math      = _G.math;
+local bit       = _G.bit;
+local table     = _G.table;
+--[[ STRING METHODS ]]--
+local lower, upper = string.lower, string.upper;
+local find, format, split = string.find, string.format, string.split;
+local match, gmatch, gsub = string.match, string.gmatch, string.gsub;
+--[[ MATH METHODS ]]--
+local floor, ceil = math.floor, math.ceil;  -- Basic
+--[[ BINARY METHODS ]]--
+local band, bor = bit.band, bit.bor;
+--[[ TABLE METHODS ]]--
+local tremove, tcopy, twipe, tsort, tconcat = table.remove, table.copy, table.wipe, table.sort, table.concat;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.NamePlates;
+if(not MOD) then return end;
+
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+--[[
+##########################################################
+LOCALIZED GLOBALS
+##########################################################
+]]--
+local SetCVar           	= _G.SetCVar;
+local UIParent              = _G.UIParent;
+local WorldFrame           	= _G.WorldFrame;
+local GameTooltip           = _G.GameTooltip;
+
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+--[[
+##########################################################
+LOCAL VARS
+##########################################################
+]]--
+local numChildren = -1;
+local PlateRegistry, VisiblePlates = {}, {};
+local WorldFrameUpdateHook, UpdatePlateElements, PlateForge;
+local BLIZZ_PLATE, SVUI_PLATE, PLATE_REF, PLATE_ARGS, PLATE_AURAS, PLATE_AURAICONS, PLATE_REALNAME;
+local CURRENT_TARGET_NAME;
+local TARGET_CHECKS = 0;
+local PLATE_TOP = MOD.media.topArt;
+local PLATE_BOTTOM = MOD.media.bottomArt;
+local PLATE_RIGHT = MOD.media.rightArt;
+local PLATE_LEFT = MOD.media.leftArt;
+--[[
+	Quick explaination of what Im doing with all of these locals...
+	Unlike many of the other modules, NamePlatess has to continuously
+	reference config settings which can start to get sluggish. What
+	I have done is set local variables for every database value
+	that the module can read efficiently. The function "UpdateLocals"
+	is used to refresh these any time a change is made to configs
+	and once when the mod is loaded.
+]]--
+local NPBaseAlpha = 0.6;
+local NPCombatHide = false;
+local NPNameMatch = false;
+local NPComboColor={
+	[1]={0.69,0.31,0.31},
+	[2]={0.69,0.31,0.31},
+	[3]={0.65,0.63,0.35},
+	[4]={0.65,0.63,0.35},
+	[5]={0.33,0.59,0.33}
+}
+
+local NPBarTex = [[Interface\BUTTONS\WHITE8X8]];
+
+local NPUsePointer = true;
+local NPPointerMatch = false;
+local NPUseModel = true;
+local NPPointerColor = {0.9, 1, 0.9, 0.5};
+
+local NPUseThreat = false;
+local NPThreatGS = 1;
+local NPThreatBS = 1;
+local NPReactTap = {0.3,0.3,0.3}
+local NPReactNPCGood = {0.31,0.45,0.63}
+local NPReactPlayerGood = {0.29,0.68,0.3}
+local NPReactNeutral = {0.85,0.77,0.36}
+local NPReactEnemy = {0.78,0.25,0.25}
+
+local RIconCoords = {[0]={[0]="STAR", [0.25]="MOON"}, [0.25]={[0]="CIRCLE", [0.25]="SQUARE"}, [0.5]={[0]="DIAMOND", [0.25]="CROSS"}, [0.75]={[0]="TRIANGLE", [0.25]="SKULL"}};
+local RIAnchor = "LEFT";
+local RIXoffset = -4;
+local RIYoffset = 6;
+local RISize = 36;
+
+local HBThresh = 0.4;
+local HBTextFormat = false;
+local HBTextAnchor = "CENTER";
+local HBXoffset = 0;
+local HBYoffset = 0;
+local HBWidth = 108;
+local HBHeight = 9;
+
+local NPIcons = 14;
+local ICON_SIZE = 20;
+
+local CBColor = {0.1,0.81,0}
+local CBNoInterrupt = {1,0.25,0.25}
+local CBHeight = 6;
+local CBText = true;
+local CBXoffset = 0;
+local CBYoffset = 0;
+
+local AuraFilterName, AuraFilter;
+local AuraMaxCount = 5;
+
+local NPFindHealers = false;
+
+local RestrictedPlates = {
+	["Army of the Dead Ghoul"] = true,
+	["Venomous Snake"] = true,
+	["Healing Tide Totem"] = true,
+	["Dragonmaw War Banner"] = true
+};
+local RIconData = {["STAR"] = 0x00000001, ["CIRCLE"] = 0x00000002, ["DIAMOND"] = 0x00000004, ["TRIANGLE"] = 0x00000008, ["MOON"] = 0x00000010, ["SQUARE"] = 0x00000020, ["CROSS"] = 0x00000040, ["SKULL"] = 0x00000080};
+local RIconNames = {"STAR", "CIRCLE", "DIAMOND", "TRIANGLE", "MOON", "SQUARE", "CROSS", "SKULL"}
+local UnitPlateAuras = {};
+local AuraByRaidIcon = {};
+local AuraByName = {};
+local CachedAuraDurations = {};
+local AurasCache = {};
+local AuraClocks = {};
+local ClockIsTicking = false;
+local TickTock = 0;
+local LastKnownTarget;
+--[[
+##########################################################
+COLORING THREAT/REACTIONS
+##########################################################
+]]--
+local CONFIG_THREAT_HOSTILE = { {0.29,0.68,0.3}, {0.85,0.77,0.36}, {0.94,0.6,0.06}, {0.78,0.25,0.25} };
+local CONFIG_THREAT_SCALE = { 1,1,1,1 };
+local PLATE_CLASS_COLORS = {};
+
+do
+	for classToken, colorData in pairs(RAID_CLASS_COLORS) do
+			PLATE_CLASS_COLORS[classToken] = {colorData.r, colorData.g, colorData.b}
+	end
+end
+
+local REACTION_COLORING = {
+	-- (1) PLAYER
+	function(token)
+		if(not token) then
+			return NPReactPlayerGood,NPThreatGS
+		else
+			return PLATE_CLASS_COLORS[token],NPThreatGS
+		end
+	end,
+	-- (2) TAPPED
+	function() return NPReactTap,NPThreatGS end,
+	-- (3) FRIENDLY
+	function() return NPReactNPCGood,NPThreatGS end,
+	-- (4) NEUTRAL
+	function(threatLevel)
+		local color,scale;
+		if((not threatLevel) or (not NPUseThreat) or (not InCombatLockdown())) then
+			color = NPReactNeutral
+			scale = NPThreatGS
+		else
+			color = CONFIG_THREAT_HOSTILE[threatLevel]
+			scale = CONFIG_THREAT_SCALE[threatLevel]
+		end
+		return color,scale
+	end,
+	-- (5) HOSTILE
+	function(threatLevel)
+		local color,scale;
+		if((not threatLevel) or (not NPUseThreat) or (not InCombatLockdown())) then
+			color = NPReactEnemy
+			scale = NPThreatGS
+		else
+			color = CONFIG_THREAT_HOSTILE[threatLevel]
+			scale = CONFIG_THREAT_SCALE[threatLevel]
+		end
+		return color,scale
+	end,
+};
+--[[
+##########################################################
+UTILITY FRAMES
+##########################################################
+]]--
+local NPGrip = _G.SVUI_PlateParentFrame
+local NPGlow = _G.SVUI_PlateGlowFrame
+local AuraClockManager = CreateFrame("Frame")
+--[[
+##########################################################
+PRE VARS/FUNCTIONS
+##########################################################
+]]--
+local formatting = {
+	["CURRENT"] = "%s",
+	["CURRENT_MAX"] = "%s - %s",
+	["CURRENT_PERCENT"] = "%s - %s%%",
+	["CURRENT_MAX_PERCENT"] = "%s - %s | %s%%",
+	["PERCENT"] = "%s%%",
+	["DEFICIT"] = "-%s"
+};
+
+local function IsEnemyPlayer(flags)
+	if((band(flags, COMBATLOG_OBJECT_REACTION_FRIENDLY) == 0) and (band(flags, COMBATLOG_OBJECT_CONTROL_PLAYER) > 0)) then
+		return true
+	end
+end
+
+local function TruncateString(value)
+    if value  >= 1e9 then
+        return ("%.1fb"):format(value / 1e9):gsub("%.?0 + ([kmb])$", "%1")
+    elseif value  >= 1e6 then
+        return ("%.1fm"):format(value / 1e6):gsub("%.?0 + ([kmb])$", "%1")
+    elseif value  >= 1e3 or value  <= -1e3 then
+        return ("%.1fk"):format(value / 1e3):gsub("%.?0 + ([kmb])$", "%1")
+    else
+        return value
+    end
+end
+
+local function SetTextStyle(style, min, max)
+	if max == 0 then max = 1 end
+	local result;
+	local textFormat = formatting[style]
+	if style == "DEFICIT" then
+		local result = max - min;
+		if result  <= 0 then
+			return ""
+		else
+			return format(textFormat, TruncateString(result))
+		end
+	elseif style == "PERCENT" then
+		result = format(textFormat, format("%.1f", min  /  max  *  100))
+		result = result:gsub(".0%%", "%%")
+		return result
+	elseif style == "CURRENT" or (style == "CURRENT_MAX" or style == "CURRENT_MAX_PERCENT" or style == "CURRENT_PERCENT") and min == max then
+		return format(formatting["CURRENT"], TruncateString(min))
+	elseif style == "CURRENT_MAX" then
+		return format(textFormat, TruncateString(min), TruncateString(max))
+	elseif style == "CURRENT_PERCENT" then
+		result = format(textFormat, TruncateString(min), format("%.1f", min  /  max  *  100))
+		result = result:gsub(".0%%", "%%")
+		return result
+	elseif style == "CURRENT_MAX_PERCENT" then
+		result = format(textFormat, TruncateString(min), TruncateString(max), format("%.1f", min  /  max  *  100))
+		result = result:gsub(".0%%", "%%")
+		return result
+	end
+end
+
+local function CreatePlateBorder(plate)
+
+	if(not plate.backdrop) then
+		plate.backdrop = plate:CreateTexture(nil, "BORDER")
+		plate.backdrop:SetDrawLayer("BORDER", -4)
+		plate.backdrop:SetAllPoints(plate)
+		plate.backdrop:SetTexture(SV.media.statusbar.default)
+		plate.backdrop:SetVertexColor(0.1,0.1,0.1)
+
+		plate.bordertop = plate:CreateTexture(nil, "BORDER")
+		plate.bordertop:SetPoint("TOPLEFT", plate, "TOPLEFT", -2, 2)
+		plate.bordertop:SetPoint("TOPRIGHT", plate, "TOPRIGHT", 2, 2)
+		plate.bordertop:SetHeight(2)
+		plate.bordertop:SetColorTexture(0,0,0)
+		plate.bordertop:SetDrawLayer("BORDER", 1)
+
+		plate.borderbottom = plate:CreateTexture(nil, "BORDER")
+		plate.borderbottom:SetPoint("BOTTOMLEFT", plate, "BOTTOMLEFT", -2, -2)
+		plate.borderbottom:SetPoint("BOTTOMRIGHT", plate, "BOTTOMRIGHT", 2, -2)
+		plate.borderbottom:SetHeight(2)
+		plate.borderbottom:SetColorTexture(0,0,0)
+		plate.borderbottom:SetDrawLayer("BORDER", 1)
+
+		plate.borderleft = plate:CreateTexture(nil, "BORDER")
+		plate.borderleft:SetPoint("TOPLEFT", plate, "TOPLEFT", -2, 2)
+		plate.borderleft:SetPoint("BOTTOMLEFT", plate, "BOTTOMLEFT", 2, -2)
+		plate.borderleft:SetWidth(2)
+		plate.borderleft:SetColorTexture(0,0,0)
+		plate.borderleft:SetDrawLayer("BORDER", 1)
+
+		plate.borderright = plate:CreateTexture(nil, "BORDER")
+		plate.borderright:SetPoint("TOPRIGHT", plate, "TOPRIGHT", 2, 2)
+		plate.borderright:SetPoint("BOTTOMRIGHT", plate, "BOTTOMRIGHT", -2, -2)
+		plate.borderright:SetWidth(2)
+		plate.borderright:SetColorTexture(0,0,0)
+		plate.borderright:SetDrawLayer("BORDER", 1)
+	end
+
+	if(not plate.eliteborder) then
+		plate.eliteborder = CreateFrame("Frame", nil, plate)
+		plate.eliteborder:SetAllPoints(plate)
+		plate.eliteborder:SetFrameStrata("BACKGROUND")
+		plate.eliteborder:SetFrameLevel(0)
+
+		plate.eliteborder.top = plate.eliteborder:CreateTexture(nil, "BACKGROUND")
+		plate.eliteborder.top:SetPoint("BOTTOMLEFT", plate.eliteborder, "TOPLEFT", 0, 0)
+		plate.eliteborder.top:SetPoint("BOTTOMRIGHT", plate.eliteborder, "TOPRIGHT", 0, 0)
+		plate.eliteborder.top:SetHeight(22)
+		plate.eliteborder.top:SetTexture(PLATE_TOP)
+		plate.eliteborder.top:SetVertexColor(1, 1, 0)
+		plate.eliteborder.top:SetBlendMode("BLEND")
+
+		plate.eliteborder.bottom = plate.eliteborder:CreateTexture(nil, "BACKGROUND")
+		plate.eliteborder.bottom:SetPoint("TOPLEFT", plate.eliteborder, "BOTTOMLEFT", 0, 0)
+		plate.eliteborder.bottom:SetPoint("TOPRIGHT", plate.eliteborder, "BOTTOMRIGHT", 0, 0)
+		plate.eliteborder.bottom:SetHeight(32)
+		plate.eliteborder.bottom:SetTexture(PLATE_BOTTOM)
+		plate.eliteborder.bottom:SetVertexColor(1, 1, 0)
+		plate.eliteborder.bottom:SetBlendMode("BLEND")
+
+		-- plate.eliteborder.right = plate.eliteborder:CreateTexture(nil, "BACKGROUND")
+		-- plate.eliteborder.right:SetPoint("TOPLEFT", plate.eliteborder, "TOPRIGHT", 0, 0)
+		-- plate.eliteborder.right:SetPoint("BOTTOMLEFT", plate.eliteborder, "BOTTOMRIGHT", 0, 0)
+		-- plate.eliteborder.right:SetWidth(plate:GetHeight() * 4)
+		-- plate.eliteborder.right:SetTexture(PLATE_RIGHT)
+		-- plate.eliteborder.right:SetVertexColor(1, 1, 0)
+		-- plate.eliteborder.right:SetBlendMode("BLEND")
+
+		-- plate.eliteborder.left = plate.eliteborder:CreateTexture(nil, "BACKGROUND")
+		-- plate.eliteborder.left:SetPoint("TOPRIGHT", plate.eliteborder, "TOPLEFT", 0, 0)
+		-- plate.eliteborder.left:SetPoint("BOTTOMRIGHT", plate.eliteborder, "BOTTOMLEFT", 0, 0)
+		-- plate.eliteborder.left:SetWidth(plate:GetHeight() * 4)
+		-- plate.eliteborder.left:SetTexture(PLATE_LEFT)
+		-- plate.eliteborder.left:SetVertexColor(1, 1, 0)
+		-- plate.eliteborder.left:SetBlendMode("BLEND")
+
+		plate.eliteborder:SetAlpha(0.35)
+
+		plate.eliteborder:Hide()
+	end
+end
+--[[
+##########################################################
+UPVALUE PROXYS
+##########################################################
+]]--
+local function ProxyThisPlate(plate, updateName)
+	if(not plate or not plate.frame) then return false; end
+	BLIZZ_PLATE = plate
+	SVUI_PLATE = plate.frame
+	PLATE_AURAS = plate.frame.auras
+	PLATE_AURAICONS = plate.frame.auraicons
+	PLATE_ARGS = plate.setting
+	if updateName then
+		plate.nametext = gsub(plate.name:GetText(), '%s%(%*%)','');
+	end
+	PLATE_REALNAME = plate.nametext
+	return true
+end
+--[[
+##########################################################
+LOCAL HELPERS
+##########################################################
+]]--
+local function ParseByGUID(guid)
+	for plate, _ in pairs(VisiblePlates) do
+		if plate and plate:IsShown() and plate.guid == guid then
+			return plate
+		end
+	end
+end
+
+local function CheckRaidIcon(plate)
+	if(plate and plate.frame) then
+		SVUI_PLATE = plate.frame
+	end
+	if PLATE_REF.raidicon:IsShown() then
+		local ULx,ULy,LLx,LLy,URx,URy,LRx,LRy = PLATE_REF.raidicon:GetTexCoord()
+		PLATE_REF.raidicontype = RIconCoords[ULx][ULy]
+		SVUI_PLATE.raidicon:Show()
+		SVUI_PLATE.raidicon:SetTexCoord(ULx,ULy,LLx,LLy,URx,URy,LRx,LRy)
+	else
+		PLATE_REF.raidicontype = nil;
+		SVUI_PLATE.raidicon:Hide()
+	end
+end
+
+local function UpdateComboPoints()
+	local guid = UnitGUID("target")
+	if (not guid) then return end
+	local numPoints = GetComboPoints(UnitHasVehicleUI('player') and 'vehicle' or 'player', 'target')
+	numPoints = numPoints or 0
+	if(numPoints > 0) then
+		if(LastKnownTarget and LastKnownTarget.guid and LastKnownTarget.guid ~= guid) then
+			LastKnownTarget.frame.combo[1]:Hide()
+			LastKnownTarget.frame.combo[2]:Hide()
+			LastKnownTarget.frame.combo[3]:Hide()
+			LastKnownTarget.frame.combo[4]:Hide()
+			LastKnownTarget.frame.combo[5]:Hide()
+			LastKnownTarget = nil
+		end
+	end
+	local plate = ParseByGUID(guid)
+	if(plate) then
+		for i=1, MAX_COMBO_POINTS do
+			if(i <= numPoints) then
+				plate.frame.combo[i]:Show()
+			else
+				plate.frame.combo[i]:Hide()
+			end
+		end
+		LastKnownTarget = plate
+	end
+end
+--[[
+##########################################################
+AURA HELPERS
+##########################################################
+]]--
+local ClockUpdateHandler = function(self, elapsed)
+	local curTime = GetTime()
+	if curTime < TickTock then return end
+	local deactivate = true;
+	TickTock = curTime + 0.1
+	for frame, expiration in pairs(AuraClocks) do
+		local calc = 0;
+		local expires = expiration - curTime;
+		if expiration < curTime then
+			frame:Hide();
+			AuraClocks[frame] = nil
+		else
+			if expires < 60 then
+				calc = floor(expires)
+				if expires >= 4 then
+					frame.TimeLeft:SetFormattedText("|cffffff00%d|r", calc)
+				elseif expires >= 1 then
+					frame.TimeLeft:SetFormattedText("|cffff0000%d|r", calc)
+				else
+					frame.TimeLeft:SetFormattedText("|cffff0000%.1f|r", expires)
+				end
+			elseif expires < 3600 then
+				calc = ceil(expires / 60);
+				frame.TimeLeft:SetFormattedText("|cffffffff%.1f|r", calc)
+			elseif expires < 86400 then
+				calc = ceil(expires / 3600);
+				frame.TimeLeft:SetFormattedText("|cff66ffff%.1f|r", calc)
+			else
+				calc = ceil(expires / 86400);
+				frame.TimeLeft:SetFormattedText("|cff6666ff%.1f|r", calc)
+			end
+			deactivate = false
+		end
+	end
+	if deactivate then
+		self:SetScript("OnUpdate", nil);
+		ClockIsTicking = false
+	end
+end
+
+local function RegisterAuraClock(frame, expiration)
+	if(not frame) then return end
+	if expiration == 0 then
+		frame:Hide()
+		AuraClocks[frame] = nil
+	else
+		AuraClocks[frame] = expiration
+		frame:Show()
+		if(not ClockIsTicking) then
+			AuraClockManager:SetScript("OnUpdate", ClockUpdateHandler)
+			ClockIsTicking = true
+		end
+	end
+end
+
+local function GetUnitPlateAuras(guid)
+	if guid and UnitPlateAuras[guid] then return UnitPlateAuras[guid] end
+end
+
+local function SetAuraInstance(guid, spellID, expiration, stacks, caster, duration, texture)
+	if(spellID == 65148) then return end
+	local filter = true;
+	if (caster == UnitGUID('player')) then
+		filter = nil;
+	end
+	if(AuraFilter and AuraFilterName) then
+		local name = GetSpellInfo(spellID)
+		if(AuraFilter[name] and AuraFilter[name].enable and ((AuraFilterName ~= 'BlackList') and (AuraFilterName ~= 'Allowed'))) then
+			filter = nil;
+		end
+	end
+	if(not filter and (guid and spellID and caster and texture)) then
+		local auraID = spellID..(tostring(caster or "UNKNOWN_CASTER"))
+		UnitPlateAuras[guid] = UnitPlateAuras[guid] or {}
+			UnitPlateAuras[guid][auraID] = {
+			spellID = spellID,
+			expiration = expiration or 0,
+			stacks = stacks,
+			duration = duration,
+			texture = texture
+		}
+	end
+end
+
+local function UpdateAuraIcon(aura, texture, expiration, stacks, test)
+	if aura and texture and expiration then
+		aura.Icon:SetTexture(texture)
+		if(stacks and stacks > 1) then
+			aura.Stacks:SetText(stacks)
+		else
+			aura.Stacks:SetText("")
+		end
+		aura:Show()
+		RegisterAuraClock(aura, expiration)
+	else
+		RegisterAuraClock(aura, 0)
+	end
+end
+
+local function SortExpires(t)
+	tsort(t, function(a,b) return a.expiration < b.expiration end)
+	return t
+end
+
+local function UpdateAuraIconGrid(plate)
+	local frame = plate.frame;
+	local guid = plate.guid;
+	local iconCache = frame.auraicons;
+	local AurasOnUnit = GetUnitPlateAuras(guid);
+	local AuraSlotIndex = 1;
+	local auraID;
+	if AurasOnUnit then
+		frame.auras:Show()
+		local auraCount = 1
+		for auraID,aura in pairs(AurasOnUnit) do
+			if tonumber(aura.spellID) then
+				aura.name = GetSpellInfo(tonumber(aura.spellID))
+				aura.unit = plate.unit
+				if(aura.expiration > GetTime()) then
+					AurasCache[auraCount] = aura
+					auraCount = auraCount + 1
+				end
+			end
+		end
+	end
+	AurasCache = SortExpires(AurasCache)
+	for index = 1,  #AurasCache do
+		local cachedaura = AurasCache[index]
+		local gridaura = iconCache[AuraSlotIndex]
+		if gridaura and cachedaura.spellID and cachedaura.expiration then
+			UpdateAuraIcon(gridaura, cachedaura.texture, cachedaura.expiration, cachedaura.stacks)
+			AuraSlotIndex = AuraSlotIndex + 1
+		end
+		if(AuraSlotIndex > AuraMaxCount) then
+			break
+		end
+	end
+	if(iconCache[AuraSlotIndex]) then
+		RegisterAuraClock(iconCache[AuraSlotIndex], 0)
+	end
+	twipe(AurasCache)
+end
+
+local function LoadDuration(spellID)
+	if spellID then
+		return CachedAuraDurations[spellID] or 0
+	end
+	return 0
+end
+
+local function SaveDuration(spellID, duration)
+	duration = duration or 0
+	if spellID then CachedAuraDurations[spellID] = duration end
+end
+
+local function CreateAuraIcon(auras, plate)
+
+	local button = CreateFrame("Frame", nil, auras)
+
+	button.bord = button:CreateTexture(nil, "BACKGROUND")
+	button.bord:SetDrawLayer('BACKGROUND', 2)
+	button.bord:SetColorTexture(0,0,0,1)
+	button.bord:SetPoint("TOPLEFT", button, "TOPLEFT", -2, 2)
+	button.bord:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", 2, -2)
+
+	button.Icon = button:CreateTexture(nil, "BORDER")
+	button.Icon:SetPoint("TOPLEFT",button,"TOPLEFT")
+	button.Icon:SetPoint("BOTTOMRIGHT",button,"BOTTOMRIGHT")
+	button.Icon:SetTexCoord(.1, .9, .2, .8)
+
+	button.TimeLeft = button:CreateFontString(nil, 'OVERLAY')
+	button.TimeLeft:SetFontObject(SVUI_Font_NamePlate_Aura)
+	button.TimeLeft:SetPoint("BOTTOMLEFT",button,"TOPLEFT",-3,-1)
+	button.TimeLeft:SetJustifyH('CENTER')
+
+	button.Stacks = button:CreateFontString(nil,"OVERLAY")
+	button.Stacks:SetFontObject(SVUI_Font_NamePlate_Aura)
+	button.Stacks:SetPoint("BOTTOMRIGHT",button,"BOTTOMRIGHT",3,-3)
+
+	button:SetScript('OnHide', function()
+		if plate.guid then
+			UpdateAuraIconGrid(plate)
+		end
+	end)
+
+	button:Hide()
+
+	return button
+end
+
+function MOD:UpdateAuras(plate)
+	if plate.setting.tiny then return end
+	local guid = plate.guid
+	local frame = plate.frame
+	if(NPFindHealers and plate.isHealer) then
+		frame.health.icon:Show()
+	end
+	if not guid then
+		if RAID_CLASS_COLORS[plate.setting.classToken] then
+			local pn = plate.name:GetText()
+			local name = pn:gsub("%s%(%*%)", "")
+			guid = AuraByName[name]
+		--elseif plate.raidicon:IsShown() then
+			--guid = AuraByRaidIcon[plate.raidicontype]
+		end
+		if guid then
+			plate.guid = guid
+		else
+			frame.auras:Hide()
+			return
+		end
+	end
+	UpdateAuraIconGrid(plate)
+	if(self.UseCombo) then
+		local numPoints = GetComboPoints(UnitHasVehicleUI("player") and "vehicle" or "player", "target")
+		for i = 1, MAX_COMBO_POINTS do
+			if(i <= numPoints) then
+				frame.combo[i]:Show()
+			else
+				frame.combo[i]:Hide()
+			end
+		end
+	end
+
+end
+
+function MOD:UpdateAurasByUnitID(unitid)
+	local guid = UnitGUID(unitid)
+	if(guid and UnitPlateAuras[guid]) then
+		local auras = UnitPlateAuras[guid]
+		for auraID, _ in pairs(auras) do
+			UnitPlateAuras[guid][auraID] = nil
+		end
+	end
+	for i = 1, 40 do
+		local spellname , _, texture, count, dispelType, duration, expirationTime, unitCaster, _, _, spellid, _, isBossDebuff = UnitAura(unitid, i, "HARMFUL")
+		if(not spellname) then break end
+		SaveDuration(spellid, duration)
+		SetAuraInstance(guid, spellid, expirationTime, count, UnitGUID(unitCaster or ""), duration, texture)
+	end
+	local name;
+	if UnitPlayerControlled(unitid) then
+		name = UnitName(unitid)
+		AuraByName[name] = guid
+	end
+	local raidIcon = RIconNames[GetRaidTargetIndex(unitid) or ""];
+	if(raidIcon) then
+		AuraByRaidIcon[raidIcon] = guid
+	end
+	self:RequestScanUpdate(guid, raidIcon, name, "UpdateAuras")
+end
+--[[
+##########################################################
+PLATE COLORING
+##########################################################
+]]--
+do
+	local function GetPlateThreatReaction(plate)
+		if plate.aggroHighlight:IsShown() then
+			local r, g, b = plate.aggroHighlight:GetVertexColor()
+			local lastThreat = plate.reaction or 1
+			if g + b < 1 then
+				plate.reaction = 4
+				return 4
+			else
+				if lastThreat > 2 then
+					plate.reaction = 2
+					return 2
+				elseif lastThreat < 3 then
+					plate.reaction = 3
+					return 3
+				end
+			end
+		end
+		plate.reaction = 1
+		return 1
+	end
+
+	local function GetPlateReaction(plate)
+		if plate.guid ~= nil then
+			local class, classToken, _, _, _, _, _ = GetPlayerInfoByGUID(plate.guid)
+			if RAID_CLASS_COLORS[classToken] then
+				plate.setting.classToken = classToken
+				return REACTION_COLORING[1](classToken)
+			end
+		end
+
+		local oldR,oldG,oldB = plate.healthBar:GetStatusBarColor()
+		local r = floor(oldR * 100 + .5) * 0.01;
+		local g = floor(oldG * 100 + .5) * 0.01;
+		local b = floor(oldB * 100 + .5) * 0.01;
+		--print(plate.health:GetStatusBarColor())
+		for classToken, _ in pairs(RAID_CLASS_COLORS) do
+			local bb = b
+			if classToken == 'MONK' then
+				bb = bb - 0.01
+			end
+			if RAID_CLASS_COLORS[classToken].r == r and RAID_CLASS_COLORS[classToken].g == g and RAID_CLASS_COLORS[classToken].b == bb then
+				plate.setting.classToken = classToken
+				return REACTION_COLORING[1](classToken)
+			end
+		end
+
+		plate.setting.classToken = nil
+		if(r + b < 0.25) then
+			return REACTION_COLORING[3]()
+		else
+			local threatReaction = GetPlateThreatReaction(plate)
+			if(r + g > 1.8) then
+				return REACTION_COLORING[4](threatReaction)
+			elseif(g + b < 0.25) then
+				return REACTION_COLORING[5](threatReaction)
+			elseif((r > 0.45 and r < 0.55) and (g > 0.45 and g < 0.55) and (b > 0.45 and b < 0.55)) then
+				REACTION_COLORING[2]()
+			else
+				REACTION_COLORING[1]()
+			end
+		end
+	end
+
+	local function ColorizeAndScale(plate, frame)
+		local unitType = GetPlateReaction(plate)
+
+		plate.setting.classToken = unitType
+
+		local latestColor, scale = GetPlateReaction(plate);
+		local r,g,b
+		if(latestColor) then
+			r,g,b = unpack(latestColor)
+		else
+			r,g,b = plate.healthBar:GetStatusBarColor()
+		end
+
+		frame.health:SetStatusBarColor(r,g,b)
+		if(NPUsePointer and (NPPointerMatch == true) and plate.setting.unit == "target") then
+			NPGlow:SetBackdropColor(r,g,b,0.5)
+			NPGlow:SetBackdropBorderColor(r,g,b,0.5)
+		end
+		--frame.health.elite.bottom:SetVertexColor(r,g,b)
+		--frame.health.elite.right:SetVertexColor(r,g,b)
+		--frame.health.elite.left:SetVertexColor(r,g,b)
+		scale = scale or 1
+		if(not plate.setting.scaled and not plate.setting.tiny and frame.health:GetWidth() ~= (HBWidth * scale)) then
+			frame.health:SetSize(HBWidth * scale, HBHeight * scale)
+			local scaledIconSize = CBHeight + (HBHeight * scale) + 5;
+			plate.castBar.Icon:SetSize(scaledIconSize, scaledIconSize)
+		end
+	end
+
+	function UpdatePlateElements(plate, frame)
+		ColorizeAndScale(plate, frame)
+		frame.health.elitetop:Hide()
+		frame.health.elitebottom:Hide()
+		if(frame.name.SetText) then
+			frame.name:SetText(plate.name:GetText())
+		end
+	end
+end
+--[[
+##########################################################
+PLATE UPDATE HANDLERS
+##########################################################
+]]--
+do
+	local function IsNamePlate(frame)
+		local frameName = frame:GetName()
+		if frameName and frameName:find('^NamePlate%d') then
+			local textObj = select(2, frame:GetChildren())
+			if textObj then
+				local textRegions = textObj:GetRegions()
+				return (textRegions and textRegions:GetObjectType() == 'FontString')
+			end
+		end
+	end
+
+	local function SetPlateAlpha(plate, frame)
+		if plate:GetAlpha() < 1 then
+			frame:SetAlpha(NPBaseAlpha)
+		else
+			frame:SetAlpha(1)
+		end
+	end
+
+	local function UpdatePlateUnit()
+		local plateName = BLIZZ_PLATE.nametext
+
+		if BLIZZ_PLATE:GetAlpha() == 1 and CURRENT_TARGET_NAME and (CURRENT_TARGET_NAME == plateName) then
+			BLIZZ_PLATE.guid = UnitGUID("target")
+			PLATE_ARGS.unit = "target"
+			SVUI_PLATE:SetFrameLevel(2)
+			SVUI_PLATE.highlight:Hide()
+			if(NPUsePointer) then
+				NPGlow:SetParent(SVUI_PLATE)
+				NPGlow:WrapPoints(SVUI_PLATE.health,2,2)
+				NPGlow:SetFrameLevel(0)
+				NPGlow:SetFrameStrata("BACKGROUND")
+				if(not NPGlow:IsShown()) then
+					NPGlow:Show()
+					if(NPUseModel) then
+						NPGlow.FX:Show()
+						NPGlow.FX:SetEffect("platepoint")
+					end
+				end
+			end
+			if((TARGET_CHECKS > 0) or PLATE_ARGS.allowed) then
+				TARGET_CHECKS = TARGET_CHECKS + 1
+				if(TARGET_CHECKS == 2) then
+					TARGET_CHECKS = 0
+				end
+				MOD:UpdateAurasByUnitID('target')
+				if MOD.UseCombo then
+					UpdateComboPoints()
+				end
+				PLATE_ARGS.allowed = nil
+			end
+		elseif UnitExists("mouseover") and (UnitName("mouseover") == plateName) then
+			if(PLATE_ARGS.unit ~= "mouseover" or PLATE_ARGS.allowed) then
+				SVUI_PLATE:SetFrameLevel(1)
+				SVUI_PLATE.highlight:Show()
+				MOD:UpdateAurasByUnitID('mouseover')
+				if MOD.UseCombo then
+					UpdateComboPoints()
+				end
+				PLATE_ARGS.allowed = nil
+			end
+			BLIZZ_PLATE.guid = UnitGUID("mouseover")
+			PLATE_ARGS.unit = "mouseover"
+		else
+			SVUI_PLATE:SetFrameLevel(0)
+			SVUI_PLATE.highlight:Hide()
+			PLATE_ARGS.unit = nil
+		end
+		--CheckRaidIcon()
+		UpdatePlateElements(BLIZZ_PLATE,SVUI_PLATE)
+	end
+
+	function MOD:NAME_PLATE_CREATED(event, ...)
+		local frame = ...;
+		if(not PlateRegistry[frame]) then
+			PlateForge(frame)
+		end
+	end
+
+	function MOD:NAME_PLATE_UNIT_ADDED(event, ...)
+		local namePlateUnitToken = ...;
+		local frame = C_NamePlate.GetNamePlateForUnit(namePlateUnitToken);
+		if(not PlateRegistry[frame]) then
+			PlateForge(frame)
+		end
+	end
+end
+--[[
+##########################################################
+SCRIPT HANDLERS
+##########################################################
+]]--
+do
+	local function HealthBarSizeChanged(self, width, height)
+		if(not ProxyThisPlate(self.sync)) then return; end
+		width = floor(width + 0.5)
+		local numAuras = AuraMaxCount
+		local auraWidth = ((width - (4 * (numAuras - 1))) / numAuras)
+		local auraHeight = (auraWidth * 0.7)
+		for index = 1, numAuras do
+			if not PLATE_AURAICONS[index] then
+				PLATE_AURAICONS[index] = CreateAuraIcon(PLATE_AURAS, SVUI_PLATE);
+			end
+			PLATE_AURAICONS[index]:SetWidth(auraWidth)
+			PLATE_AURAICONS[index]:SetHeight(auraHeight)
+			PLATE_AURAICONS[index]:ClearAllPoints()
+			if(index == 1) then
+				PLATE_AURAICONS[index]:SetPoint("LEFT", PLATE_AURAS, 0, 0)
+			else
+				PLATE_AURAICONS[index]:SetPoint("LEFT", PLATE_AURAICONS[index-1], "RIGHT", 4, 0)
+			end
+		end
+		if(numAuras > #PLATE_AURAICONS) then
+			for index = (numAuras + 1), #PLATE_AURAICONS do
+				RegisterAuraClock(PLATE_AURAICONS[index], 0)
+			end
+		end
+	end
+
+	local function HealthBarValueChanged(self, value)
+		local healthBar = self.sync;
+		local alert = healthBar.alert;
+		local minValue, maxValue = self:GetMinMaxValues()
+		local showText = false
+		healthBar:SetMinMaxValues(minValue, maxValue)
+		healthBar:SetValue(value)
+		local percentValue = (value/maxValue)
+		if percentValue < HBThresh then
+			alert:Show()
+			if percentValue < (HBThresh / 2) then
+				alert:SetBackdropBorderColor(1, 0, 0, 0.9)
+			else
+				alert:SetBackdropBorderColor(1, 1, 0, 0.9)
+			end
+		elseif alert:IsShown() then
+			alert:Hide()
+		end
+		if((value and value > 0) and (maxValue and maxValue > 1) and self:GetScale() == 1) then
+			showText = true
+		end
+		if(HBTextFormat and showText) then
+			healthBar.text:Show()
+			healthBar.text:SetText(SetTextStyle(HBTextFormat, value, maxValue))
+		elseif healthBar.text:IsShown() then
+			healthBar.text:Hide()
+		end
+	end
+
+	local function CastBarValueChanged(self, value)
+		local castBar = self.sync
+		local min, max = self:GetMinMaxValues()
+		local isChannel = value < castBar:GetValue()
+		castBar:SetMinMaxValues(min, max)
+		castBar:SetValue(value)
+		castBar.Text:SetFormattedText("%.1f ", value)
+		local color
+		if(self.shield and self.shield:IsShown()) then
+			color = CBNoInterrupt
+		else
+			if value > 0 and (isChannel and (value/max) <= 0.02 or (value/max) >= 0.98) then
+				color = {0,1,0}
+			else
+				color = CBColor
+			end
+		end
+		castBar:SetStatusBarColor(unpack(color))
+	end
+
+	local function ShowThisPlate(plate)
+		if(not ProxyThisPlate(plate, true)) then return; end
+
+		if RestrictedPlates[PLATE_REALNAME] then
+			SVUI_PLATE:Hide()
+			return
+		elseif(not SVUI_PLATE:IsShown()) then
+			SVUI_PLATE:Show()
+		end
+
+		VisiblePlates[BLIZZ_PLATE] = true
+
+		PLATE_ARGS.tiny = (BLIZZ_PLATE.healthBar:GetEffectiveScale() < 1)
+		SVUI_PLATE:SetSize(BLIZZ_PLATE:GetSize())
+
+		SVUI_PLATE.name:ClearAllPoints()
+		if(PLATE_ARGS.tiny) then
+			SVUI_PLATE.health:SetSize(BLIZZ_PLATE.healthBar:GetWidth() * (BLIZZ_PLATE.healthBar:GetEffectiveScale() * 1.25), HBHeight)
+			SVUI_PLATE.name:SetPoint("BOTTOM", SVUI_PLATE.health, "TOP", 0, 3)
+		else
+			SVUI_PLATE.name:SetPoint("BOTTOMLEFT", SVUI_PLATE.health, "TOPLEFT", 0, 3)
+			SVUI_PLATE.name:SetPoint("BOTTOMRIGHT", SVUI_PLATE.level, "BOTTOMLEFT", -2, 0)
+		end
+
+		UpdatePlateElements(BLIZZ_PLATE, SVUI_PLATE)
+
+		HealthBarValueChanged(BLIZZ_PLATE.healthBar, BLIZZ_PLATE.healthBar:GetValue())
+
+		if(not PLATE_ARGS.tiny) then
+			--CheckRaidIcon()
+			MOD:UpdateAuras(BLIZZ_PLATE)
+		else
+			PLATE_ARGS.allowed = true
+		end
+
+		if(NPUsePointer and (not NPPointerMatch)) then
+			NPGlow:SetBackdropColor(unpack(NPPointerColor))
+			NPGlow:SetBackdropBorderColor(unpack(NPPointerColor))
+		end
+	end
+
+	local function HideThisPlate(plate)
+		if(not ProxyThisPlate(plate)) then return; end
+
+		SVUI_PLATE:Hide()
+		VisiblePlates[plate] = nil
+		PLATE_ARGS.classToken = nil
+		plate.guid = nil
+		PLATE_ARGS.unit = nil
+		PLATE_ARGS.scaled = nil
+		PLATE_ARGS.tiny = nil
+		PLATE_ARGS.allowed = nil
+		if(NPGlow:GetParent() == SVUI_PLATE) then
+			NPGlow:Hide()
+			if(NPGlow.FX:IsShown()) then
+				NPGlow.FX:Hide()
+			end
+		end
+		SVUI_PLATE.health.alert:Hide()
+		SVUI_PLATE.health.icon:Hide()
+		if SVUI_PLATE.health then
+			SVUI_PLATE.health:SetSize(HBWidth, HBHeight)
+			plate.castBar.Icon:SetSize(ICON_SIZE, ICON_SIZE)
+		end
+		if PLATE_AURAS then
+			for index = 1, #PLATE_AURAICONS do
+				RegisterAuraClock(PLATE_AURAICONS[index], 0)
+			end
+		end
+		if MOD.UseCombo then
+			for i=1, MAX_COMBO_POINTS do
+				SVUI_PLATE.combo[i]:Hide()
+			end
+		end
+
+		SVUI_PLATE:SetPoint("BOTTOMLEFT", plate, "BOTTOMLEFT")
+	end
+
+	local function UpdateThisPlate(plate)
+		--print("NamePlate UpdateThisPlate Start")
+		if(not ProxyThisPlate(plate, true)) then return; end
+		SVUI_PLATE.name:SetFontObject(SVUI_Font_NamePlate)
+		SVUI_PLATE.name:SetTextColor(1, 1, 1)
+		-- SVUI_PLATE.level:SetFontObject(SVUI_Font_NamePlate_Number)
+		-- if not PLATE_ARGS.scaled and not PLATE_ARGS.tiny then
+		-- 	SVUI_PLATE.health:SetSize(HBWidth, HBHeight)
+		-- end
+		-- SVUI_PLATE.health:SetStatusBarTexture(NPBarTex)
+		-- SVUI_PLATE.health.text:SetFontObject(SVUI_Font_NamePlate_Number)
+		-- SVUI_PLATE.cast:SetSize(HBWidth, CBHeight)
+		-- SVUI_PLATE.cast:SetStatusBarTexture(NPBarTex)
+		-- SVUI_PLATE.cast.text:SetFont(SV.media.font.default, 8, "OUTLINE")
+		-- SVUI_PLATE.health.icon:ClearAllPoints()
+		-- SV:SetReversePoint(SVUI_PLATE.health.icon, RIAnchor, SVUI_PLATE.health, RIXoffset, RIYoffset)
+		-- SVUI_PLATE.health.icon:SetSize(RISize, RISize)
+		-- for index = 1, #PLATE_AURAICONS do
+		-- 	if PLATE_AURAICONS and PLATE_AURAICONS[index] then
+		-- 		PLATE_AURAICONS[index].TimeLeft:SetFontObject(SVUI_Font_NamePlate_Aura)
+		-- 		PLATE_AURAICONS[index].Stacks:SetFontObject(SVUI_Font_NamePlate_Aura)
+		-- 		PLATE_AURAICONS[index].Icon:SetTexCoord(.07, 0.93, .23, 0.77)
+		-- 	end
+		-- end
+		--
+		-- if(MOD.UseCombo and not SVUI_PLATE.combo:IsShown()) then
+		-- 	SVUI_PLATE.combo:Show()
+		-- elseif(SVUI_PLATE.combo:IsShown()) then
+		-- 	SVUI_PLATE.combo:Hide()
+		-- end
+		--
+		-- ShowThisPlate(plate)
+		-- HealthBarSizeChanged(SVUI_PLATE.health, SVUI_PLATE.health:GetSize())
+	end
+
+	function PlateForge(source)
+		local plate = source.UnitFrame;
+		if(not plate) then return end;
+		--print("NamePlate Creation Start")
+		local ref, skin = {}, {};
+
+		plate.healthBar:SetStatusBarTexture(SV.NoTexture)
+		plate.castBar:SetStatusBarTexture(SV.NoTexture)
+
+		plate.healthBar:Hide()
+		plate.castBar:Hide()
+		plate.name:ClearAllPoints()
+		plate.name:Hide()
+
+		local frame = CreateFrame("Frame", nil, plate)
+
+		--[[ HEALTH BAR ]]--
+		--print("NamePlate Creating Health")
+		frame.health = CreateFrame("StatusBar", nil, frame)
+		frame.health:SetPoint('BOTTOM', frame, 'BOTTOM', 0, 5)
+		frame.health:SetFrameStrata("BACKGROUND")
+		frame.health:SetFrameLevel(1)
+		frame.health:SetStyle("Frame", "Nameplate")
+		frame.health:SetScript("OnSizeChanged", HealthBarSizeChanged)
+		frame.health.elitetop = frame.health.Panel.Top
+		frame.health.elitebottom = frame.health.Panel.Bottom
+		frame.health.sync = plate.healthBar;
+
+		--CreatePlateBorder(frame.health)
+
+		frame.health.text = frame.health:CreateFontString(nil, 'OVERLAY')
+		frame.health.text:SetPoint("CENTER", frame.health, HBTextAnchor, HBXoffset, HBYoffset)
+		frame.health.text:SetJustifyH("CENTER")
+
+		--print("NamePlate Creating LevelText")
+		frame.level = frame.health:CreateFontString(nil, 'OVERLAY')
+		frame.level:SetPoint("BOTTOMRIGHT", frame.health, "TOPRIGHT", 3, 3)
+		frame.level:SetJustifyH("RIGHT")
+
+		frame.name = frame.health:CreateFontString(nil, 'OVERLAY')
+		frame.name:SetJustifyH("LEFT")
+--print("NamePlate Creating Icons")
+		frame.eliteicon = frame:CreateTexture(nil, "OVERLAY")
+		frame.skullicon = frame:CreateTexture(nil, "OVERLAY")
+
+		frame.raidicon = frame:CreateTexture(nil, "ARTWORK")
+		frame.raidicon:SetSize(NPIcons,NPIcons)
+		frame.raidicon:SetPoint("RIGHT", frame.health, "LEFT", -3, 0)
+		--frame.raidicon:SetTexture("Interface\\TargetingFrame\\UI-RaidTargetingIcons")
+		frame.raidicon:SetTexture("")
+
+		frame.health.icon = frame:CreateTexture(nil, 'ARTWORK')
+		frame.health.icon:SetSize(14,14)
+		frame.health.icon:SetPoint("BOTTOMRIGHT", frame.health, "TOPLEFT", -3, 3)
+
+		frame.health.icon:SetTexture(MOD.media.roles)
+		frame.health.icon:SetTexCoord(0,0.5,0.5,1)
+		frame.health.icon:Hide()
+
+		frame.highlight = frame:CreateTexture(nil, 'OVERLAY')
+		frame.highlight:SetAllPoints(frame.health)
+		frame.highlight:SetColorTexture(1, 1, 1, 0.3)
+		frame.highlight:Hide()
+--print("NamePlate Creating Alert")
+		local alert = CreateFrame("Frame", nil, frame)
+		alert:SetFrameLevel(0)
+		alert:WrapPoints(frame.health,2,2)
+		alert:SetBackdrop({
+			edgeFile = SV.media.border.shadow,
+			edgeSize = 2
+		});
+		alert:SetBackdropColor(0, 0, 0, 0)
+		alert:SetBackdropBorderColor(1, 1, 0, 0.9)
+		alert:SetScale(1.5)
+		alert:Hide()
+		frame.health.alert = alert
+
+		plate.healthBar.sync = frame.health
+
+		--[[ CAST BAR ]]--
+--print("NamePlate Creating CastBar")
+		frame.cast = CreateFrame("StatusBar", nil, frame)
+		frame.cast:SetPoint('TOPLEFT', frame.health, 'BOTTOMLEFT', 0, -8)
+		frame.cast:SetPoint('TOPRIGHT', frame.health, 'BOTTOMRIGHT', 0, -8)
+		frame.cast:SetFrameStrata("BACKGROUND")
+		frame.cast:SetStyle("Frame", 'Bar')
+		frame.cast:SetFrameLevel(0)
+
+		frame.cast.text = frame.cast:CreateFontString(nil, 'OVERLAY')
+		frame.cast.text:SetPoint("RIGHT", frame.cast, "LEFT", -4, CBYoffset)
+		frame.cast.text:SetJustifyH("LEFT")
+
+		-- plate.castBar.Text:SetParent(frame.cast)
+		-- plate.castBar.Text:ClearAllPoints()
+		-- plate.castBar.Text:SetPoint("LEFT", frame.cast, "LEFT", CBXoffset, CBYoffset)
+		-- plate.castBar.Text:SetJustifyH("LEFT")
+		--
+		-- plate.castBar.Icon:SetParent(frame.cast)
+		-- plate.castBar.Icon:SetTexCoord(.07, .93, .07, .93)
+		-- plate.castBar.Icon:SetDrawLayer("OVERLAY")
+		-- plate.castBar.Icon:ClearAllPoints()
+		-- plate.castBar.Icon:SetPoint("TOPLEFT", frame.health, "TOPRIGHT", 5, 0)
+
+		-- local bgFrame = CreateFrame("Frame", nil, frame.cast)
+		-- bgFrame:WrapPoints(plate.castBar.Icon)
+		-- bgFrame:SetFrameLevel(bgFrame:GetFrameLevel() - 1)
+		-- bgFrame:SetStyle("Frame", "Bar", true, 2, 0, 0)
+
+		plate.castBar.sync = frame.cast
+--print("NamePlate Creating Combo")
+		frame.combo = CreateFrame("Frame", nil, frame.health)
+		frame.combo:SetPoint("CENTER", frame.health, "BOTTOM")
+		frame.combo:SetSize(68, 1)
+		frame.combo:Hide()
+
+		if MOD.UseCombo then
+			for i = 1, MAX_COMBO_POINTS do
+				frame.combo[i] = frame.combo:CreateTexture(nil, 'OVERLAY')
+				frame.combo[i]:SetTexture(MOD.media.comboIcon)
+				frame.combo[i]:SetSize(12, 12)
+				frame.combo[i]:SetVertexColor(unpack(NPComboColor[i]))
+				if(i == 1) then
+					frame.combo[i]:SetPoint("TOPLEFT", frame.combo, "TOPLEFT")
+				else
+					frame.combo[i]:SetPoint("LEFT", frame.combo[i-1], "RIGHT", 2, 0)
+				end
+				frame.combo[i]:Hide()
+			end
+		end
+--print("NamePlate Creating Auras")
+		frame.auras = CreateFrame("Frame", nil, frame)
+		frame.auras:SetHeight(32); frame.auras:Show()
+		frame.auras:SetPoint('BOTTOMRIGHT', frame.health, 'TOPRIGHT', 0, 10)
+		frame.auras:SetPoint('BOTTOMLEFT', frame.health, 'TOPLEFT', 0, 10)
+		frame.auras:SetFrameStrata("BACKGROUND")
+		frame.auras:SetFrameLevel(0)
+		frame.auraicons = {}
+
+		plate.frame = frame;
+		plate.setting = {};
+--print("NamePlate UpdateThisPlate")
+		UpdateThisPlate(plate)
+--print("NamePlate Setting Hooks")
+		plate:HookScript("OnShow", ShowThisPlate)
+		plate:HookScript("OnHide", HideThisPlate)
+		plate:HookScript("OnSizeChanged", function(self, width, height)
+			self.frame:SetSize(width, height)
+		end)
+
+		plate.healthBar:HookScript("OnValueChanged", HealthBarValueChanged)
+
+		plate.castBar:HookScript("OnShow", function(self) self.sync:Show() end)
+		plate.castBar:HookScript("OnHide", function(self) self.sync:Hide() end)
+		plate.castBar:HookScript("OnValueChanged", CastBarValueChanged)
+
+		VisiblePlates[plate] = true
+		PlateRegistry[source] = true;
+		--print("NamePlate Added")
+	end
+
+	function MOD:UpdateAllPlates()
+		self:UpdateLocals()
+		for plate, _ in pairs(VisiblePlates) do
+			if(plate) then
+				UpdateThisPlate(plate)
+			end
+		end
+	end
+end
+--[[
+##########################################################
+SCANNER
+##########################################################
+]]--
+do
+	local function ParseByName(sourceName)
+		if not sourceName then return; end
+		local SearchFor = split("-", sourceName)
+		for plate, _ in pairs(VisiblePlates) do
+			if plate and plate:IsShown() and plate.nametext == SearchFor and RAID_CLASS_COLORS[plate.setting.classToken] then
+				return plate
+			end
+		end
+	end
+
+	local function ParseByIconName(raidIcon)
+		for plate, _ in pairs(VisiblePlates) do
+			--CheckRaidIcon(plate)
+			if plate and plate:IsShown() and plate.raidicon:IsShown() and (plate.raidicontype and plate.raidicontype == raidIcon) then
+				return plate
+			end
+		end
+	end
+
+	function MOD:RequestScanUpdate(guid, raidIcon, name, callbackFunc, ...)
+		local plate
+		if guid then plate = ParseByGUID(guid) end
+		if (not plate) and name then plate = ParseByName(name) end
+		--if (not plate) and raidIcon then plate = ParseByIconName(raidIcon) end
+		if(plate and callbackFunc and MOD[callbackFunc]) then
+			MOD[callbackFunc](MOD, plate, ...)
+		end
+	end
+end
+--[[
+##########################################################
+EVENTS
+##########################################################
+]]--
+function MOD:PLAYER_ENTERING_WORLD()
+	self:UpdateLocals();
+end
+
+function MOD:UPDATE_MOUSEOVER_UNIT()
+	WorldFrame.elapsed = 0.1
+end
+
+function MOD:PLAYER_REGEN_DISABLED()
+	SetCVar("nameplateShowEnemies", 1)
+end
+
+function MOD:PLAYER_REGEN_ENABLED()
+	SetCVar("nameplateShowEnemies", 0)
+end
+
+function MOD:PLAYER_TARGET_CHANGED()
+	NPGlow:Hide()
+	if(NPGlow.FX:IsShown()) then
+		NPGlow.FX:Hide()
+	end
+	if(UnitExists("target")) then
+		CURRENT_TARGET_NAME = UnitName("target");
+		TARGET_CHECKS = 1;
+		WorldFrame.elapsed = 0.1;
+	else
+		CURRENT_TARGET_NAME = nil;
+		TARGET_CHECKS = 0;
+	end
+end
+
+function MOD:UNIT_COMBO_POINTS(event, unit)
+	if(unit == "player" or unit == "vehicle") then
+		UpdateComboPoints()
+	end
+end
+
+function MOD:UNIT_AURA(event, unit)
+  if(unit == "target" or unit == "focus") then
+    self:UpdateAurasByUnitID(unit)
+		if(self.UseCombo) then
+			UpdateComboPoints()
+		end
+  end
+end
+
+do
+	local COMBAT_HEAL_EVENTS = {
+		["SPELL_HEAL"] = true,
+		["SPELL_AURA_APPLIED"] = true,
+		["SPELL_CAST_START"] = true,
+		["SPELL_CAST_SUCCESS"] = true,
+		["SPELL_PERIODIC_HEAL"] = true,
+	}
+
+	local COMBAT_AURA_EVENTS = {
+		["SPELL_AURA_BROKEN"] = 1,
+		["SPELL_AURA_BROKEN_SPELL"] = 1,
+		["SPELL_AURA_REMOVED"] = 1,
+		["SPELL_AURA_APPLIED"] = 2,
+		["SPELL_AURA_REFRESH"] = 2,
+		["SPELL_AURA_APPLIED_DOSE"] = 3,
+		["SPELL_AURA_REMOVED_DOSE"] = 3,
+	}
+
+	function MOD:COMBAT_LOG_EVENT_UNFILTERED(event, timestamp, combatevent, hideCaster, ...)
+	  local sourceGUID, sourceName, sourceFlags, sourceRaidFlags, destGUID, destName, destFlags, destRaidFlags, spellID, spellname = ...;
+		local hasChange = false;
+		local eventCheck = COMBAT_AURA_EVENTS[combatevent];
+		if(eventCheck and destGUID and spellID) then
+			if(eventCheck > 1) then
+				local stackCount = 1
+				local duration = LoadDuration(spellID)
+				local texture = GetSpellTexture(spellID)
+				if(eventCheck == 3) then stackCount = select(16, ...) end
+				SetAuraInstance(destGUID, spellID, (GetTime() + duration), stackCount, sourceGUID, duration, texture)
+			else
+				local auraID = spellID..(tostring(sourceName or "UNKNOWN_CASTER"))
+				if(auraID and UnitPlateAuras[destGUID] and UnitPlateAuras[destGUID][auraID]) then
+				  UnitPlateAuras[destGUID][auraID] = nil
+				end
+			end
+			hasChange = true;
+		end
+
+		if(NPFindHealers and COMBAT_HEAL_EVENTS[combatevent] and IsEnemyPlayer(sourceFlags) and sourceName) then
+			local healerName = split("-", sourceName)
+			self:RequestScanUpdate(sourceGUID, false, healerName, "UpdateHealer", healerName, spellID)
+			hasChange = true;
+		end
+
+	  if(not hasChange) then
+	    return
+	  end
+
+	  local rawName, raidIcon
+	  if(destName and (band(destFlags, COMBATLOG_OBJECT_CONTROL_PLAYER) > 0)) then
+	    rawName = split("-", destName)
+	    AuraByName[rawName] = destGUID
+	  end
+	  for iconName, bitmask in pairs(RIconData) do
+	    if band(destRaidFlags, bitmask) > 0  then
+	      raidIcon = iconName
+	      AuraByRaidIcon[raidIcon] = destGUID
+	      break
+	    end
+	  end
+	  self:RequestScanUpdate(destGUID, raidIcon, rawName, "UpdateAuras")
+	end
+end
+--[[
+##########################################################
+UPDATE AND BUILD
+##########################################################
+]]--
+local function PlayerRoleUpdate()
+	MOD:UpdateAllPlates()
+end
+
+function MOD:UpdateLocals()
+	local db = SV.db.NamePlates
+	if not db then return end
+
+	NPBarTex = LSM:Fetch("statusbar", db.barTexture);
+
+	NPBaseAlpha = db.nonTargetAlpha;
+	NPCombatHide = db.combatHide;
+
+	RIAnchor = db.raidHealIcon.attachTo;
+	RIXoffset = db.raidHealIcon.xOffset;
+	RIYoffset = db.raidHealIcon.yOffset;
+	RISize = db.raidHealIcon.size;
+
+	HBThresh = db.healthBar.lowThreshold;
+	NPNameMatch = db.colorNameByValue;
+	HBTextFormat = db.healthBar.text.enable and db.healthBar.text.format or false;
+	HBTextAnchor = db.healthBar.text.attachTo;
+	HBXoffset = db.healthBar.text.xOffset;
+	HBYoffset = db.healthBar.text.yOffset;
+	HBWidth = db.healthBar.width;
+	HBHeight = db.healthBar.height;
+
+	NPIcons = HBHeight * 1.5
+
+	CBColor = {db.castBar.color[1], db.castBar.color[2], db.castBar.color[3]}
+	CBNoInterrupt = {db.castBar.noInterrupt[1], db.castBar.noInterrupt[2], db.castBar.noInterrupt[3]}
+	CBHeight = db.castBar.height;
+	CBText = db.castBar.text.enable;
+	CBXoffset = db.castBar.text.xOffset;
+	CBYoffset = db.castBar.text.yOffset;
+
+	ICON_SIZE = CBHeight + HBHeight + 5
+
+	NPUsePointer = db.pointer.enable;
+	NPPointerMatch = db.pointer.colorMatchHealthBar;
+	NPPointerColor = {db.pointer.color[1], db.pointer.color[2], db.pointer.color[3], 0.5};
+	NPUseModel = db.pointer.useArrowEffect
+
+	local rc = db.reactions
+	NPReactTap = {rc.tapped[1], rc.tapped[2], rc.tapped[3]}
+	NPReactNPCGood = {rc.friendlyNPC[1], rc.friendlyNPC[2], rc.friendlyNPC[3]}
+	NPReactPlayerGood = {rc.friendlyPlayer[1], rc.friendlyPlayer[2], rc.friendlyPlayer[3]}
+	NPReactNeutral = {rc.neutral[1], rc.neutral[2], rc.neutral[3]}
+	NPReactEnemy = {rc.enemy[1], rc.enemy[2], rc.enemy[3]}
+
+	AuraMaxCount = db.auras.numAuras;
+	AuraFilterName = db.auras.additionalFilter
+	AuraFilter = SV.db.Filters[AuraFilterName]
+
+	NPFindHealers = db.findHealers
+
+	local tc = SV.db.NamePlates.threat
+	NPUseThreat = tc.enable;
+	NPThreatGS = tc.goodScale;
+	NPThreatBS = tc.badScale;
+	if(SV.ClassRole == 'TANK') then
+		CONFIG_THREAT_HOSTILE = {
+			{tc.badColor[1], tc.badColor[2], tc.badColor[3]},
+			{tc.badTransitionColor[1], tc.badTransitionColor[2], tc.badTransitionColor[3]},
+			{tc.goodTransitionColor[1], tc.goodTransitionColor[2], tc.goodTransitionColor[3]},
+			{tc.goodColor[1], tc.goodColor[2], tc.goodColor[3]}
+		};
+		CONFIG_THREAT_SCALE = { NPThreatBS, NPThreatBS, NPThreatGS, NPThreatGS };
+	else
+		CONFIG_THREAT_HOSTILE = {
+			{tc.goodColor[1], tc.goodColor[2], tc.goodColor[3]},
+			{tc.goodTransitionColor[1], tc.goodTransitionColor[2], tc.goodTransitionColor[3]},
+			{tc.badTransitionColor[1], tc.badTransitionColor[2], tc.badTransitionColor[3]},
+			{tc.badColor[1], tc.badColor[2], tc.badColor[3]}
+		};
+		CONFIG_THREAT_SCALE = { NPThreatGS, NPThreatGS, NPThreatBS, NPThreatBS };
+	end
+
+	if(not db.themed) then
+		PLATE_TOP = SV.NoTexture
+		PLATE_BOTTOM = SV.NoTexture
+		PLATE_RIGHT = SV.NoTexture
+		PLATE_LEFT = SV.NoTexture
+	else
+		PLATE_TOP = self.media.topArt
+		PLATE_BOTTOM = self.media.bottomArt
+		PLATE_RIGHT = self.media.rightArt
+		PLATE_LEFT = self.media.leftArt
+	end
+
+	if (db.comboPoints and (SV.class == 'ROGUE' or SV.class == 'DRUID')) then
+		self.UseCombo = true
+		self:RegisterEvent("UNIT_COMBO_POINTS")
+	else
+		self.UseCombo = false
+		self:UnregisterEvent("UNIT_COMBO_POINTS")
+	end
+
+	if (NPFindHealers) then
+		self:RegisterEvent("UPDATE_BATTLEFIELD_SCORE")
+	else
+		self:UnregisterEvent("UPDATE_BATTLEFIELD_SCORE")
+	end
+end
+
+function MOD:CombatToggle(noToggle)
+	if(NPCombatHide) then
+		self:RegisterEvent("PLAYER_REGEN_DISABLED")
+		self:RegisterEvent("PLAYER_REGEN_ENABLED")
+		if(not noToggle) then
+			SetCVar("nameplateShowEnemies", 0)
+		end
+	else
+		self:UnregisterEvent("PLAYER_REGEN_DISABLED")
+		self:UnregisterEvent("PLAYER_REGEN_ENABLED")
+		if(not noToggle) then
+			SetCVar("nameplateShowEnemies", 1)
+		end
+	end
+end
+
+function MOD:ReLoad()
+	self:UpdateAllPlates();
+end
+
+function MOD:Load()
+	--SV.SpecialFX:Register("platepoint", [[Spells\Arcane_missile_lvl1.m2]], -12, 48, 12, -48, 0.25, 0, 0)
+	SV.SpecialFX:Register("platepoint", [[Spells\Arrow_state_animated.m2]], -12, 12, 12, -50, 0.75, 0, 0.1)
+	--SV.SpecialFX:Register("platepoint", [[Spells\Cast_arcane_01.m2]], -12, 48, 12, -48, 0.25, 0, 0)
+	--SV.SpecialFX:Register("platepoint", [[Spells\Cast_arcane_01.m2]], -12, 48, 12, -48, 0.25, 0, 0)
+	--SV.SpecialFX:Register("platepoint", [[Spells\Shadow_precast_uber_hand.m2]],  -12, 22, 12, -22, 0.23, -0.1, 0.1)
+	SV.SpecialFX:SetFXFrame(NPGlow, "platepoint", true)
+	NPGlow.FX:SetParent(SV.Screen)
+	NPGlow.FX:SetFrameStrata("BACKGROUND")
+	NPGlow.FX:SetFrameLevel(0)
+	NPGlow.FX:Hide()
+	self:UpdateLocals()
+	self:RegisterEvent("PLAYER_ENTERING_WORLD")
+	self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
+	self:RegisterEvent("UNIT_AURA")
+	self:RegisterEvent("PLAYER_TARGET_CHANGED")
+	self:RegisterEvent("UPDATE_MOUSEOVER_UNIT")
+	self:RegisterEvent("NAME_PLATE_CREATED")
+	self:RegisterEvent("NAME_PLATE_UNIT_ADDED")
+	--WorldFrame:HookScript('OnUpdate', WorldFrameUpdateHook)
+	self:CombatToggle(true)
+	SV.Events:On("PLAYER_ROLE_CHANGED", PlayerRoleUpdate, true)
+end
diff --git a/SVUI_NamePlates/SVUI_NamePlates.lua b/SVUI_NamePlates/SVUI_NamePlates.lua
new file mode 100644
index 0000000..191974b
--- /dev/null
+++ b/SVUI_NamePlates/SVUI_NamePlates.lua
@@ -0,0 +1,214 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+credit: Elv.       NamePlatess was parently nameplates.lua adapted from ElvUI #
+##############################################################################
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack    = _G.unpack;
+local select    = _G.select;
+local pairs     = _G.pairs;
+local ipairs    = _G.ipairs;
+local type      = _G.type;
+local error     = _G.error;
+local pcall     = _G.pcall;
+local tostring  = _G.tostring;
+local tonumber  = _G.tonumber;
+local tinsert   = _G.tinsert;
+local string    = _G.string;
+local math      = _G.math;
+local bit       = _G.bit;
+local table     = _G.table;
+--[[ STRING METHODS ]]--
+local lower, upper = string.lower, string.upper;
+local find, format, split = string.find, string.format, string.split;
+local match, gmatch, gsub = string.match, string.gmatch, string.gsub;
+--[[ MATH METHODS ]]--
+local floor, ceil = math.floor, math.ceil;  -- Basic
+--[[ BINARY METHODS ]]--
+local band, bor = bit.band, bit.bor;
+--[[ TABLE METHODS ]]--
+local tremove, tcopy, twipe, tsort, tconcat = table.remove, table.copy, table.wipe, table.sort, table.concat;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.NamePlates;
+if(not MOD) then return end;
+
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+--[[
+##########################################################
+LOCAL VARS
+##########################################################
+]]--
+local PlateRegistry, VisiblePlates = {}, {};
+local _hook_NamePlateDriverMixin, PlateForge, PlateUpdate;
+local CURRENT_TARGET_NAME;
+local TARGET_CHECKS = 0;
+local PLATE_TOP = MOD.media.topArt;
+local PLATE_BOTTOM = MOD.media.bottomArt;
+local PLATE_RIGHT = MOD.media.rightArt;
+local PLATE_LEFT = MOD.media.leftArt;
+local NPBarTex = [[Interface\BUTTONS\WHITE8X8]];
+--[[
+##########################################################
+UTILITY FRAMES
+##########################################################
+]]--
+local NPGrip = _G.SVUI_PlateParentFrame
+local NPGlow = _G.SVUI_PlateGlowFrame
+--[[
+##########################################################
+PLATE UPDATE HANDLERS
+##########################################################
+]]--
+function _hook_NamePlateDriverMixin(self, event, ...)
+	if event == "NAME_PLATE_CREATED" then
+		local frame = ...;
+		if(not PlateRegistry[frame]) then
+			PlateForge(frame)
+		else
+			PlateUpdate(frame)
+		end
+	elseif event == "NAME_PLATE_UNIT_ADDED" then
+		local namePlateUnitToken = ...;
+		local frame = C_NamePlate.GetNamePlateForUnit(namePlateUnitToken);
+		if(not PlateRegistry[frame]) then
+			PlateForge(frame)
+		else
+			PlateUpdate(frame)
+		end
+	elseif event == "NAME_PLATE_UNIT_REMOVED" then
+		local namePlateUnitToken = ...;
+		local frame = C_NamePlate.GetNamePlateForUnit(namePlateUnitToken);
+		PlateUpdate(frame)
+	elseif event == "PLAYER_TARGET_CHANGED" then
+		-- DO STUFF
+	elseif event == "DISPLAY_SIZE_CHANGED" then
+		-- DO STUFF
+	elseif event == "RAID_TARGET_UPDATE" then
+		-- DO STUFF
+	elseif ( event == "UNIT_FACTION" ) then
+		-- DO STUFF
+	end
+end
+
+function PlateUpdate(source)
+	local plate = source.UnitFrame;
+	if(not plate) then return end;
+	plate.healthBar:SetStatusBarTexture(NPBarTex)
+	plate.castBar:SetStatusBarTexture(NPBarTex)
+	plate.name:SetFontObject(SVUI_Font_NamePlate)
+	plate.name:SetTextColor(1, 1, 1)
+end
+
+function PlateForge(source)
+	local plate = source.UnitFrame;
+	if(not plate) then return end;
+
+	plate.healthBar:SetStyle("Frame", "Bar")
+	plate.castBar:SetStyle("Frame", 'Bar')
+
+	VisiblePlates[plate] = true
+	PlateRegistry[source] = true;
+	PlateUpdate(source)
+end
+--[[
+##########################################################
+EVENTS
+##########################################################
+]]--
+function MOD:PLAYER_REGEN_DISABLED()
+	SetCVar("nameplateShowEnemies", 1)
+end
+
+function MOD:PLAYER_REGEN_ENABLED()
+	SetCVar("nameplateShowEnemies", 0)
+end
+
+function MOD:PLAYER_TARGET_CHANGED()
+	-- NPGlow:Hide()
+	-- if(NPGlow.FX:IsShown()) then
+	-- 	NPGlow.FX:Hide()
+	-- end
+	if(UnitExists("target")) then
+		CURRENT_TARGET_NAME = UnitName("target");
+		TARGET_CHECKS = 1;
+	else
+		CURRENT_TARGET_NAME = nil;
+		TARGET_CHECKS = 0;
+	end
+end
+--[[
+##########################################################
+UPDATE AND BUILD
+##########################################################
+]]--
+function MOD:UpdateLocals()
+	local db = SV.db.NamePlates
+	if not db then return end
+
+	NPBarTex = LSM:Fetch("statusbar", db.barTexture);
+
+	if(not db.themed) then
+		PLATE_TOP = SV.NoTexture
+		PLATE_BOTTOM = SV.NoTexture
+		PLATE_RIGHT = SV.NoTexture
+		PLATE_LEFT = SV.NoTexture
+	else
+		PLATE_TOP = self.media.topArt
+		PLATE_BOTTOM = self.media.bottomArt
+		PLATE_RIGHT = self.media.rightArt
+		PLATE_LEFT = self.media.leftArt
+	end
+end
+
+function MOD:CombatToggle(noToggle)
+	if(NPCombatHide) then
+		self:RegisterEvent("PLAYER_REGEN_DISABLED")
+		self:RegisterEvent("PLAYER_REGEN_ENABLED")
+		if(not noToggle) then
+			SetCVar("nameplateShowEnemies", 0)
+		end
+	else
+		self:UnregisterEvent("PLAYER_REGEN_DISABLED")
+		self:UnregisterEvent("PLAYER_REGEN_ENABLED")
+		if(not noToggle) then
+			SetCVar("nameplateShowEnemies", 1)
+		end
+	end
+end
+
+function MOD:ReLoad()
+	self:UpdateAllPlates();
+end
+
+function MOD:Load()
+	SV:FontManager(SystemFont_NamePlate, "platename")
+	--SV.SpecialFX:Register("platepoint", [[Spells\Arrow_state_animated.m2]], -12, 12, 12, -50, 0.75, 0, 0.1)
+	--SV.SpecialFX:SetFXFrame(NPGlow, "platepoint", true)
+	-- NPGlow.FX:SetParent(SV.Screen)
+	-- NPGlow.FX:SetFrameStrata("BACKGROUND")
+	-- NPGlow.FX:SetFrameLevel(0)
+	-- NPGlow.FX:Hide()
+	self:UpdateLocals()
+	self:RegisterEvent("PLAYER_ENTERING_WORLD")
+	self:RegisterEvent("PLAYER_TARGET_CHANGED")
+	NamePlateDriverFrame:HookScript("OnEvent", _hook_NamePlateDriverMixin)
+
+	if (ClassNameplateManaBarFrame) then
+		ClassNameplateManaBarFrame:SetStyle("Frame", "Bar")
+		ClassNameplateManaBarFrame:SetStatusBarTexture(SV.media.statusbar.glow)
+	end
+
+	self:CombatToggle(true)
+end
diff --git a/SVUI_NamePlates/SVUI_NamePlates.toc b/SVUI_NamePlates/SVUI_NamePlates.toc
new file mode 100644
index 0000000..6667719
--- /dev/null
+++ b/SVUI_NamePlates/SVUI_NamePlates.toc
@@ -0,0 +1,16 @@
+## Interface: 70000
+## Author: Failcoder
+## Version: 1.3.5
+## Title: |cffFF9900SuperVillain UI: |r|cffFFEF00NamePlates|r
+## Notes: NamePlates Plugin for [|cff9911FFSVUI|r].
+## OptionalDeps: LibSharedMedia-3.0
+## RequiredDeps: SVUI_!Core
+## X-SVUIName: NamePlates
+## X-SVUISchema: NamePlates
+## X-Email: munglunch@gmail.com
+## X-Website: http://www.supervillainui.com
+## X-Donate: PayPal:munglunch@gmail.com
+## X-License: MIT
+## X-Category: Interface Enhancements
+
+SVUI_NamePlates.xml
diff --git a/SVUI_NamePlates/SVUI_NamePlates.xml b/SVUI_NamePlates/SVUI_NamePlates.xml
new file mode 100644
index 0000000..d3b8e47
--- /dev/null
+++ b/SVUI_NamePlates/SVUI_NamePlates.xml
@@ -0,0 +1,109 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+    <Font name="SVUI_Font_NamePlate" font="Fonts\skurri.ttf" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="9"/>
+        </FontHeight>
+    </Font>
+    <Font name="SVUI_Font_NamePlate_Aura" font="Fonts\skurri.ttf" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="9"/>
+        </FontHeight>
+    </Font>
+    <Font name="SVUI_Font_NamePlate_Number" font="Fonts\skurri.ttf" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="9"/>
+        </FontHeight>
+    </Font>
+
+	<Frame name="SVUI_PlateParentFrame" frameStrata="BACKGROUND" hidden="true">
+        <Scripts>
+            <OnLoad>
+                self:SetParent(_G['WorldFrame'])
+            </OnLoad>
+        </Scripts>
+    </Frame>
+
+    <Frame name="SVUI_PlateGlowFrame" frameStrata="BACKGROUND" hidden="true">
+        <Backdrop bgFile="Interface\BUTTONS\WHITE8X8" edgeFile="Interface\AddOns\SVUI_!Core\assets\borders\SHADOW">
+            <EdgeSize val="2" />
+            <TileSize val="0" />
+            <BackgroundInsets left="2" right="2" top="2" bottom="2" />
+            <Color r="0" g="0" b="0" a="0" />
+            <BorderColor r="0" g="0" b="0" a="0" />
+        </Backdrop>
+    	<Scripts>
+            <OnLoad>
+            	self:SetParent(_G['WorldFrame'])
+				self:SetScale(2.5)
+            </OnLoad>
+        </Scripts>
+    </Frame>
+
+    <Frame name="SVUI_StyleTemplate_Nameplate" virtual="true">
+        <Attributes>
+            <Attribute name="panelID" type="string" value="nameplate" />
+            <Attribute name="panelPadding" type="number" value="2" />
+            <Attribute name="panelColor" type="string" value="transparent" />
+            <Attribute name="panelGradient" type="boolean" value="false" />
+            <Attribute name="panelTexUpdate" type="boolean" value="false" />
+            <Attribute name="panelSkipUpdate" type="boolean" value="false" />
+            <Attribute name="panelOffset" type="number" value="1" />
+        </Attributes>
+        <Backdrop bgFile="Interface\BUTTONS\WHITE8X8" edgeFile="Interface\BUTTONS\WHITE8X8" tile="false">
+            <EdgeSize val="1" />
+            <TileSize val="0" />
+            <BackgroundInsets left="1" right="1" top="1" bottom="1" />
+            <Color r="0" g="0" b="0" a="0.8" />
+            <BorderColor r="0" g="0" b="0" a="1" />
+        </Backdrop>
+        <Layers>
+            <Layer level="BACKGROUND" textureSubLevel="-7">
+                <Texture parentKey="Top" file="Interface\AddOns\SVUI_NamePlates\assets\PLATE-TOP">
+                    <Anchors>
+                        <Anchor point="BOTTOMLEFT" relativePoint="TOPLEFT" />
+                        <Anchor point="BOTTOMRIGHT" relativePoint="TOPRIGHT" />
+                    </Anchors>
+                    <Size>
+                        <AbsDimension y="22" />
+                    </Size>
+                    <Color r="1" g="1" b="0" a="0.25" />
+                </Texture>
+                <Texture parentKey="Bottom" file="Interface\AddOns\SVUI_NamePlates\assets\PLATE-BOTTOM">
+                    <Anchors>
+                        <Anchor point="TOPLEFT" relativePoint="BOTTOMLEFT" />
+                        <Anchor point="TOPRIGHT" relativePoint="BOTTOMRIGHT" />
+                    </Anchors>
+                    <Size>
+                        <AbsDimension y="32" />
+                    </Size>
+                    <Color r="1" g="1" b="0" a="0.25" />
+                </Texture>
+            </Layer>
+        </Layers>
+        <Frames>
+            <Frame parentKey="Shadow" inherits="SVUI_ShadowTemplate" />
+        </Frames>
+    </Frame>
+
+    <Script file="Loader.lua"/>
+    <Script file='SVUI_NamePlates.lua'/>
+    <!-- <Script file='components\healers.lua'/> -->
+</Ui>
diff --git a/SVUI_NamePlates/assets/COMBO-POINT.blp b/SVUI_NamePlates/assets/COMBO-POINT.blp
new file mode 100644
index 0000000..f226600
Binary files /dev/null and b/SVUI_NamePlates/assets/COMBO-POINT.blp differ
diff --git a/SVUI_NamePlates/assets/PLATE-BOTTOM.blp b/SVUI_NamePlates/assets/PLATE-BOTTOM.blp
new file mode 100644
index 0000000..bd9a901
Binary files /dev/null and b/SVUI_NamePlates/assets/PLATE-BOTTOM.blp differ
diff --git a/SVUI_NamePlates/assets/PLATE-LEFT.blp b/SVUI_NamePlates/assets/PLATE-LEFT.blp
new file mode 100644
index 0000000..7e50514
Binary files /dev/null and b/SVUI_NamePlates/assets/PLATE-LEFT.blp differ
diff --git a/SVUI_NamePlates/assets/PLATE-RIGHT.blp b/SVUI_NamePlates/assets/PLATE-RIGHT.blp
new file mode 100644
index 0000000..f19b684
Binary files /dev/null and b/SVUI_NamePlates/assets/PLATE-RIGHT.blp differ
diff --git a/SVUI_NamePlates/assets/PLATE-ROLES.blp b/SVUI_NamePlates/assets/PLATE-ROLES.blp
new file mode 100644
index 0000000..278428e
Binary files /dev/null and b/SVUI_NamePlates/assets/PLATE-ROLES.blp differ
diff --git a/SVUI_NamePlates/assets/PLATE-TOP.blp b/SVUI_NamePlates/assets/PLATE-TOP.blp
new file mode 100644
index 0000000..f703b72
Binary files /dev/null and b/SVUI_NamePlates/assets/PLATE-TOP.blp differ
diff --git a/SVUI_NamePlates/components/healers.lua b/SVUI_NamePlates/components/healers.lua
new file mode 100644
index 0000000..a3269d1
--- /dev/null
+++ b/SVUI_NamePlates/components/healers.lua
@@ -0,0 +1,152 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack    = _G.unpack;
+local select    = _G.select;
+local pairs     = _G.pairs;
+local ipairs    = _G.ipairs;
+local type      = _G.type;
+local error     = _G.error;
+local pcall     = _G.pcall;
+local tostring  = _G.tostring;
+local tonumber  = _G.tonumber;
+local tinsert 	= _G.tinsert;
+local string 	= _G.string;
+local math 		= _G.math;
+local table 	= _G.table;
+--[[ STRING METHODS ]]--
+local format = string.format;
+--[[ MATH METHODS ]]--
+local abs, ceil, floor, round = math.abs, math.ceil, math.floor, math.round;
+--[[ TABLE METHODS ]]--
+local tremove, twipe = table.remove, table.wipe;
+--[[ BINARY METHODS ]]--
+local band, bor = bit.band, bit.bor;
+--BLIZZARD API
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local MOD = SV.NamePlates;
+--[[
+##########################################################
+LOCALS
+##########################################################
+]]--
+local HEALER_ROSTER = {};
+local HEALER_SPECS = {
+	["Druid"] = { ["Restoration"] = true, },
+	["Paladin"] = { ["Holy"] = true, },
+	["Priest"] = { ["Discipline"] = true, ["Holy"] = true, },
+	["Shaman"] = { ["Restoration"] = true, },
+	["Monk"] = { ["Mistweaver"] = true, },
+}
+local HEALER_SPELLS = {
+	[47540] = "PRIEST", -- Penance
+	[88625] = "PRIEST", -- Holy Word: Chastise
+	[88684] = "PRIEST", -- Holy Word: Serenity
+	[88685] = "PRIEST", -- Holy Word: Sanctuary
+	[89485] = "PRIEST", -- Inner Focus
+	[10060] = "PRIEST", -- Power Infusion
+	[33206] = "PRIEST", -- Pain Suppression
+	[62618] = "PRIEST", -- Power Word: Barrier
+	[724]   = "PRIEST",   -- Lightwell
+	[14751] = "PRIEST", -- Chakra
+	[34861] = "PRIEST", -- Circle of Healing
+	[47788] = "PRIEST", -- Guardian Spirit
+	[18562] = "DRUID", -- Swiftmend
+	[17116] = "DRUID", -- Nature's Swiftness
+	[48438] = "DRUID", -- Wild Growth
+	[33891] = "DRUID", -- Tree of Life
+	[974]   = "SHAMAN", -- Earth Shield
+	[17116] = "SHAMAN", -- Nature's Swiftness
+	[16190] = "SHAMAN", -- Mana Tide Totem
+	[61295] = "SHAMAN", -- Riptide
+	[20473] = "PALADIN", -- Holy Shock
+	[31842] = "PALADIN", -- Divine Favor
+	[53563] = "PALADIN", -- Beacon of Light
+	[31821] = "PALADIN", -- Aura Mastery
+	[85222] = "PALADIN", -- Light of Dawn
+	[115175] = "MONK", -- Soothing Mist
+	[115294] = "MONK", -- Mana Tea
+	[115310] = "MONK", -- Revival
+	[116670] = "MONK", -- Uplift
+	[116680] = "MONK", -- Thunder Focus Tea
+	[116849] = "MONK", -- Life Cocoon
+	[116995] = "MONK", -- Surging mist
+	[119611] = "MONK", -- Renewing mist
+	[132120] = "MONK", -- Envelopping Mist
+}
+--[[
+##########################################################
+HELPER FUNCTIONS
+##########################################################
+]]--
+local function IsHealer(name)
+	if(name) then
+		local role = HEALER_ROSTER[name]
+		if(not role) then
+			RequestBattlefieldScoreData()
+		else
+			return true;
+		end
+	end
+	return false;
+end
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+function MOD:UpdateHealerPlate(plate, name, spellID)
+	if(HEALER_SPELLS[spellID] and (not HEALER_ROSTER[name])) then
+		HEALER_ROSTER[name] = true;
+	end
+	plate.isHealer = IsHealer(name);
+end
+
+do
+	local NextUpdate = 0
+	function MOD:UPDATE_BATTLEFIELD_SCORE()
+		local now = GetTime()
+		if(now > NextUpdate) then
+			NextUpdate = now + 3;
+		else
+			return
+		end
+
+		local hasChanges = false;
+		local scoreCount = GetNumBattlefieldScores();
+
+		if(scoreCount > 0) then
+			for i = 1, scoreCount do
+				local name, _, _, _, _, faction, _, class, _, _, _, _, _, _, _, talentSpec = GetBattlefieldScore(i)
+				if(name and class and HEALER_SPECS[class] and talentSpec) then
+					local role = HEALER_SPECS[class][talentSpec]
+					if(role) then
+						HEALER_ROSTER[name] = true
+						hasChanges = true
+					elseif(HEALER_ROSTER[name]) then
+						HEALER_ROSTER[name] = nil
+						hasChanges = true
+					end
+				end
+			end
+			if hasChanges then
+				TidyPlates:RequestDelegateUpdate()
+			end
+		end
+	end
+end
diff --git a/SVUI_PKG.toc b/SVUI_PKG.toc
new file mode 100644
index 0000000..4ec6946
--- /dev/null
+++ b/SVUI_PKG.toc
@@ -0,0 +1,8 @@
+## Interface: 70000
+## Author: Failcoder
+## Version: 1.3.5
+## Title: |cffFF9900 |r
+## X-Email: munglunch@gmail.com
+## X-Donate: PayPal:munglunch@gmail.com
+## X-License: MIT
+## X-Category: Interface Enhancements
diff --git a/SVUI_QuestTracker/LICENSE.txt b/SVUI_QuestTracker/LICENSE.txt
new file mode 100644
index 0000000..05ceba8
--- /dev/null
+++ b/SVUI_QuestTracker/LICENSE.txt
@@ -0,0 +1,31 @@
+
+The MIT License
+
+Copyright (c) 2010, Failcoder (Steve Jackson)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy
+of this software and associated documentation files (the "Software"), to
+deal
+in the Software without restriction, including without limitation the
+rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/SVUI_QuestTracker/Loader.lua b/SVUI_QuestTracker/Loader.lua
new file mode 100644
index 0000000..ea997d7
--- /dev/null
+++ b/SVUI_QuestTracker/Loader.lua
@@ -0,0 +1,137 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+
+local SV = _G["SVUI"];
+local L = SV.L
+local MOD = SV:NewModule(...);
+local Schema = MOD.Schema;
+
+MOD.media = {}
+MOD.media.dockIcon = [[Interface\AddOns\SVUI_QuestTracker\assets\DOCK-ICON-QUESTS]];
+MOD.media.buttonArt = [[Interface\AddOns\SVUI_QuestTracker\assets\QUEST-BUTTON-ART]];
+MOD.media.completeIcon = [[Interface\AddOns\SVUI_QuestTracker\assets\QUEST-COMPLETE-ICON]];
+MOD.media.incompleteIcon = [[Interface\AddOns\SVUI_QuestTracker\assets\QUEST-INCOMPLETE-ICON]];
+
+SV.defaults[Schema] = {
+	["rowHeight"] = 0,
+	["itemBarDirection"] = 'VERTICAL',
+	["itemButtonSize"] = 28,
+	["itemButtonsPerRow"] = 5,
+};
+
+SV:AssignMedia("font", "questdialog", "SVUI Default Font", 12, "OUTLINE");
+SV:AssignMedia("font", "questheader", "SVUI Caps Font", 16, "OUTLINE");
+SV:AssignMedia("font", "questnumber", "SVUI Number Font", 11, "OUTLINE");
+SV:AssignMedia("globalfont", "questdialog", "SVUI_Font_Quest");
+SV:AssignMedia("globalfont", "questheader", "SVUI_Font_Quest_Header");
+SV:AssignMedia("globalfont", "questnumber", "SVUI_Font_Quest_Number");
+
+
+function MOD:LoadOptions()
+	local questFonts = {
+		["questdialog"] = {
+			order = 1,
+			name = "Quest Tracker Dialog",
+			desc = "Default font used in the quest tracker"
+		},
+		["questheader"] = {
+			order = 2,
+			name = "Quest Tracker Titles",
+			desc = "Font used in the quest tracker for listing headers."
+		},
+		["questnumber"] = {
+			order = 3,
+			name = "Quest Tracker Numbers",
+			desc = "Font used in the quest tracker to display numeric values."
+		},
+	};
+
+	SV:GenerateFontOptionGroup("QuestTracker", 6, "Fonts used in the SVUI Quest Tracker.", questFonts)
+
+	SV.Options.args[Schema] = {
+		type = "group",
+		name = Schema,
+		args = {
+			generalGroup = {
+				order = 1,
+				type = "group",
+				name = "General",
+				guiInline = true,
+				args = {
+					rowHeight = {
+						order = 1,
+						type = 'range',
+						name = L["Row Height (minimum adjusted by font size)"],
+						desc = L["Setting this to 0 (zero) will force an automatic size"],
+						min = 0,
+						max = 50,
+						step = 1,
+						width = "full",
+						get = function(a)return SV.db[Schema][a[#a]] end,
+						set = function(a,b)
+							local c = SV.media.shared.font.questdialog.size;
+							local d = c + 4;
+							if((b > 0) and (b < d)) then
+								b = d;
+							end
+							MOD:ChangeDBVar(b,a[#a]);
+							MOD:UpdateSetup();
+						end
+					},
+				}
+			},
+			itemsGroup = {
+				order = 2,
+				type = "group",
+				name = "Quest Items",
+				guiInline = true,
+				get = function(a)return SV.db[Schema][a[#a]] end,
+				set = function(a,b)
+					MOD:ChangeDBVar(b,a[#a]);
+					MOD:UpdateLocals();
+				end,
+				args = {
+					itemBarDirection = {
+						order = 1,
+						type = 'select',
+						name = L["Bar Direction"],
+						values = {
+							['VERTICAL'] = L['Vertical'],
+							['HORIZONTAL'] = L['Horizontal']
+						},
+					},
+					itemButtonSize = {
+						order = 2,
+						type = 'range',
+						name = L["Button Size"],
+						min = 10,
+						max = 100,
+						step = 1,
+						width = "full",
+					},
+					itemButtonsPerRow = {
+						order = 3,
+						type = 'range',
+						name = L["Buttons Per Row"],
+						desc = L["This will only take effect if you have moved the item bar away from the dock."],
+						min = 1,
+						max = 20,
+						step = 1,
+						width = "full",
+					},
+				}
+			}
+		}
+	}
+end
diff --git a/SVUI_QuestTracker/SVUI_QuestTracker.lua b/SVUI_QuestTracker/SVUI_QuestTracker.lua
new file mode 100644
index 0000000..22b0426
--- /dev/null
+++ b/SVUI_QuestTracker/SVUI_QuestTracker.lua
@@ -0,0 +1,494 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local pairs     = _G.pairs;
+--BLIZZARD API
+local CreateFrame           = _G.CreateFrame;
+local GetTime               = _G.GetTime;
+local PERCENTAGE_STRING     = _G.PERCENTAGE_STRING;
+local GetTimeStringFromSeconds = _G.GetTimeStringFromSeconds;
+local GetQuestProgressBarPercent = _G.GetQuestProgressBarPercent;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local MOD = SV.QuestTracker;
+if(not MOD) then return end;
+MOD.DOCK_IS_FADED = false;
+--[[
+##########################################################
+LOCALS
+##########################################################
+]]--
+local ROW_WIDTH = 300;
+local ROW_HEIGHT = 24;
+local INNER_HEIGHT = ROW_HEIGHT - 4;
+local LARGE_ROW_HEIGHT = ROW_HEIGHT * 2;
+local LARGE_INNER_HEIGHT = LARGE_ROW_HEIGHT - 4;
+--local OBJ_ICON_ACTIVE = [[Interface\COMMON\Indicator-Yellow]];
+local OBJ_ICON_COMPLETE = [[Interface\COMMON\Indicator-Green]];
+local OBJ_ICON_INCOMPLETE = [[Interface\COMMON\Indicator-Gray]];
+--[[
+##########################################################
+OBJECTIVE SCRIPT HANDLERS
+##########################################################
+]]--
+local OBJECTIVE_StartProgress = function(self, ...)
+	local questID, finished = ...
+
+	local status = self:GetStatus();
+	status:FadeIn();
+	status.Bar.questID = questID;
+	status.Bar.finished = finished;
+	status.Bar:SetMinMaxValues(0, 100);
+	local percent = 100;
+	if(not finished) then
+		percent = GetQuestProgressBarPercent(questID);
+	end
+	status.Bar:SetValue(percent);
+	status.Label:SetFormattedText(PERCENTAGE_STRING, percent);
+	self:RegisterEvent("QUEST_LOG_UPDATE")
+end
+
+local OBJECTIVE_StopProgress = function(self)
+	if(not self.Status) then return end
+	local status = self.Status;
+	status:SetAlpha(0);
+	status.Bar:SetValue(0);
+	status.Label:SetText('');
+	self:UnregisterEvent("QUEST_LOG_UPDATE")
+end
+
+local OBJECTIVE_UpdateProgress = function(self)
+	if(not self.Status) then
+		self:UnregisterEvent("QUEST_LOG_UPDATE")
+		return
+	end
+	local status = self.Status;
+	local percent = 100;
+	if(not status.Bar.finished) then
+		percent = GetQuestProgressBarPercent(status.Bar.questID);
+	end
+	status.Bar:SetValue(percent);
+	status.Label:SetFormattedText(PERCENTAGE_STRING, percent);
+end
+
+local OBJECTIVE_StartTimer = function(self, ...)
+	local duration, elapsed = ...
+	local timeNow = GetTime();
+	local startTime = timeNow - elapsed;
+	local timeRemaining = duration - startTime;
+
+	local status = self:GetStatus();
+	status:FadeIn();
+	status.Bar.duration = duration or 1;
+	status.Bar.startTime = startTime;
+	status.Bar:SetMinMaxValues(0, status.Bar.duration);
+	status.Bar:SetValue(timeRemaining);
+	status.Label:SetText(GetTimeStringFromSeconds(duration, nil, true));
+	status.Label:SetTextColor(MOD:GetTimerTextColor(duration, duration - timeRemaining));
+
+	self:SetScript("OnUpdate", self.UpdateTimer);
+end
+
+local OBJECTIVE_StopTimer = function(self)
+	if(not self.Status) then return end
+	local status = self.Status;
+	status:SetAlpha(0);
+	status.Bar.duration = 1;
+	status.Bar.startTime = 0;
+	status.Bar:SetMinMaxValues(0, status.Bar.duration);
+	status.Bar:SetValue(0);
+	status.Label:SetText('');
+	status.Label:SetTextColor(1,1,1);
+
+	self:SetScript("OnUpdate", nil);
+end
+
+local OBJECTIVE_UpdateTimer = function(self)
+	if(not self.Status) then
+		self:SetScript("OnUpdate", nil);
+		return
+	end
+	local status = self.Status;
+	local timeNow = GetTime();
+	local timeRemaining = status.Bar.duration - (timeNow - status.Bar.startTime);
+	status.Bar:SetValue(timeRemaining);
+	if(timeRemaining < 0) then
+		-- hold at 0 for a moment
+		if(timeRemaining > -1) then
+			timeRemaining = 0;
+		else
+			self:SetAlpha(0);
+			status.Bar.duration = 1;
+			status.Bar.startTime = 0;
+			status.Bar:SetMinMaxValues(0, status.Bar.duration);
+			status.Bar:SetValue(0);
+			status.Label:SetText('');
+			status.Label:SetTextColor(1,1,1);
+			self:SetScript("OnUpdate", nil);
+		end
+	end
+	local r,g,b = MOD:GetTimerTextColor(status.Bar.duration, status.Bar.duration - timeRemaining)
+	status.Label:SetText(GetTimeStringFromSeconds(timeRemaining, nil, true));
+	status.Label:SetTextColor(r,g,b);
+end
+
+local OBJECTIVE_GetStatus = function(self)
+	if(not self.Status) then
+		local status = CreateFrame("Frame", nil, self)
+		status:SetPoint("TOPLEFT", self.Icon, "TOPRIGHT", 4, 0);
+		status:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", 0, 0);
+
+		status.Bar = CreateFrame("StatusBar", nil, status);
+		status.Bar:SetPoint("TOPLEFT", status, "TOPLEFT", 4, -2);
+		status.Bar:SetPoint("BOTTOMRIGHT", status, "BOTTOMRIGHT", -4, 2);
+		status.Bar:SetStatusBarTexture(SV.media.statusbar.default)
+		status.Bar:SetStatusBarColor(0.15,0.5,1) --1,0.15,0.08
+		status.Bar:SetMinMaxValues(0, 1)
+		status.Bar:SetValue(0)
+
+		local bgFrame = CreateFrame("Frame", nil, status.Bar)
+		bgFrame:InsetPoints(status.Bar, -2, -2)
+		bgFrame:SetFrameLevel(bgFrame:GetFrameLevel() - 1)
+
+		bgFrame.bg = bgFrame:CreateTexture(nil, "BACKGROUND")
+		bgFrame.bg:SetAllPoints(bgFrame)
+		bgFrame.bg:SetTexture(SV.media.statusbar.default)
+	  	bgFrame.bg:SetVertexColor(0,0,0,0.5)
+
+		local borderB = bgFrame:CreateTexture(nil,"OVERLAY")
+		borderB:SetColorTexture(0,0,0)
+		borderB:SetPoint("BOTTOMLEFT")
+		borderB:SetPoint("BOTTOMRIGHT")
+		borderB:SetHeight(2)
+
+		local borderT = bgFrame:CreateTexture(nil,"OVERLAY")
+		borderT:SetColorTexture(0,0,0)
+		borderT:SetPoint("TOPLEFT")
+		borderT:SetPoint("TOPRIGHT")
+		borderT:SetHeight(2)
+
+		local borderL = bgFrame:CreateTexture(nil,"OVERLAY")
+		borderL:SetColorTexture(0,0,0)
+		borderL:SetPoint("TOPLEFT")
+		borderL:SetPoint("BOTTOMLEFT")
+		borderL:SetWidth(2)
+
+		local borderR = bgFrame:CreateTexture(nil,"OVERLAY")
+		borderR:SetColorTexture(0,0,0)
+		borderR:SetPoint("TOPRIGHT")
+		borderR:SetPoint("BOTTOMRIGHT")
+		borderR:SetWidth(2)
+
+		status.Label = status.Bar:CreateFontString(nil,"OVERLAY");
+		status.Label:InsetPoints(status.Bar);
+		status.Label:SetFontObject(SVUI_Font_Quest_Number)
+		status.Label:SetTextColor(1,1,1)
+		status.Label:SetText('')
+
+		status:SetAlpha(0);
+
+		self.Status = status;
+
+		self:SetScript("OnEvent", self.UpdateProgress);
+
+		return status;
+	end
+
+	return self.Status;
+end
+--[[
+##########################################################
+OBJECTIVE HEADER METHODS
+##########################################################
+]]--
+local OBJECTIVE_HEADER_Reset = function(self, lite)
+	for x = 1, #self.Rows do
+		local objective = self.Rows[x]
+		if(objective) then
+			if(not objective:IsShown()) then
+				objective:Show()
+			end
+			objective.Text:SetText('');
+			objective.Icon:SetTexture("");
+			objective:StopTimer();
+			objective:StopProgress();
+			objective:SetHeight(1);
+			if(not lite) then
+				objective:SetAlpha(0);
+			end
+		end
+	end
+	self:SetHeight(1);
+end
+
+local OBJECTIVE_HEADER_Get = function(self, index)
+	if(not self.Rows[index]) then
+		local yOffset = (index * (ROW_HEIGHT)) - ROW_HEIGHT;
+
+		local objective = CreateFrame("Frame", nil, self);
+		objective:SetPoint("TOPLEFT", self, "TOPLEFT", 22, -yOffset);
+		objective:SetPoint("TOPRIGHT", self, "TOPRIGHT", 0, -yOffset);
+		objective:SetHeight(ROW_HEIGHT);
+
+		objective.Icon = objective:CreateTexture(nil,"OVERLAY");
+		objective.Icon:SetPoint("TOPLEFT", objective, "TOPLEFT", 4, -2);
+		objective.Icon:SetSize(INNER_HEIGHT,INNER_HEIGHT);
+		objective.Icon:SetTexture(OBJ_ICON_INCOMPLETE);
+
+		objective.Text = objective:CreateFontString(nil,"OVERLAY");
+		objective.Text:SetPoint("TOPLEFT", objective, "TOPLEFT", 20 + 6, -2);
+		objective.Text:SetPoint("TOPRIGHT", objective, "TOPRIGHT", 0, -2);
+		objective.Text:SetHeight(INNER_HEIGHT);
+		objective.Text:SetFontObject(SVUI_Font_Quest);
+		objective.Text:SetJustifyH('LEFT')
+		objective.Text:SetTextColor(0.6,0.6,0.6);
+		objective.Text:SetText('');
+
+		objective.StartProgress = OBJECTIVE_StartProgress;
+		objective.StopProgress = OBJECTIVE_StopProgress;
+		objective.UpdateProgress = OBJECTIVE_UpdateProgress;
+		objective.StartTimer = OBJECTIVE_StartTimer;
+		objective.StopTimer = OBJECTIVE_StopTimer;
+		objective.UpdateTimer = OBJECTIVE_UpdateTimer;
+		objective.GetStatus = OBJECTIVE_GetStatus;
+
+		self.Rows[index] = objective;
+		return objective;
+	end
+
+	return self.Rows[index];
+end
+
+local OBJECTIVE_HEADER_SetInfo = function(self, index, ...)
+	index = index + 1;
+	local description, completed, failed = ...
+	local objective = self:Get(index);
+
+	if(failed) then
+		objective.Text:SetTextColor(1,0,0)
+		objective.Icon:SetTexture(OBJ_ICON_INCOMPLETE)
+	elseif(completed) then
+		objective.Text:SetTextColor(0.1,0.9,0.1)
+		objective.Icon:SetTexture(OBJ_ICON_COMPLETE)
+	else
+		objective.Text:SetTextColor(0.6,0.6,0.6)
+		objective.Icon:SetTexture(OBJ_ICON_INCOMPLETE)
+	end
+	objective.Text:SetText(description);
+	objective:SetHeight(INNER_HEIGHT);
+	objective:FadeIn();
+
+	return index;
+end
+
+local OBJECTIVE_HEADER_SetTimer = function(self, index, ...)
+	index = index + 1;
+
+	local objective = self:Get(index);
+	objective.Text:SetText('')
+	objective:SetHeight(INNER_HEIGHT);
+	objective:FadeIn();
+
+	objective:StartTimer(...)
+
+	return index;
+end
+
+local OBJECTIVE_HEADER_SetProgress = function(self, index, ...)
+	index = index + 1;
+
+	local objective = self:Get(index);
+	objective.Text:SetText('')
+	objective:SetHeight(INNER_HEIGHT);
+	objective:FadeIn();
+
+	objective:StartProgress(...)
+
+	return index;
+end
+--[[
+##########################################################
+OBJECTIVE CONSTRUCTOR
+##########################################################
+]]--
+function MOD:NewObjectiveHeader()
+	local header = CreateFrame("Frame", nil, self);
+	header.Rows = {};
+
+	header.Reset = OBJECTIVE_HEADER_Reset;
+	header.Get = OBJECTIVE_HEADER_Get;
+	header.SetInfo = OBJECTIVE_HEADER_SetInfo;
+	header.SetTimer = OBJECTIVE_HEADER_SetTimer;
+	header.SetProgress = OBJECTIVE_HEADER_SetProgress;
+
+	return header;
+end
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+function MOD:GetTimerTextColor(duration, elapsed)
+	local yellowPercent = .66
+	local redPercent = .33
+
+	local percentageLeft = 1 - ( elapsed / duration )
+	if(percentageLeft > yellowPercent) then
+		return 1, 1, 1;
+	elseif(percentageLeft > redPercent) then
+		local blueOffset = (percentageLeft - redPercent) / (yellowPercent - redPercent);
+		return 1, 1, blueOffset;
+	else
+		local greenOffset = percentageLeft / redPercent;
+		return 1, greenOffset, 0;
+	end
+end
+
+function MOD:UpdateDimensions()
+	local totalHeight = 1;
+	local scrollHeight = MOD.Docklet.ScrollFrame:GetHeight();
+	local scrollWidth = MOD.Docklet.ScrollFrame:GetWidth();
+
+	for headerName, headerFrame in pairs(MOD.Headers) do
+		if(headerName == 'Active' or headerName == 'Popups') then
+			totalHeight = totalHeight - headerFrame:GetHeight()
+		else
+			totalHeight = totalHeight + headerFrame:GetHeight()
+		end
+		headerFrame:SetWidth(scrollWidth)
+	end
+
+	MOD.Docklet.ScrollFrame.MaxVal = totalHeight;
+	MOD.Docklet.ScrollFrame.ScrollBar:SetMinMaxValues(1, totalHeight);
+	--MOD.Docklet.ScrollFrame.ScrollBar:SetHeight(scrollHeight);
+	MOD.Docklet.ScrollFrame.ScrollChild:SetWidth(scrollWidth);
+	MOD.Docklet.ScrollFrame.ScrollChild:SetHeight(totalHeight);
+	SV.Events:Trigger("QUEST_LAYOUT_UPDATED");
+end
+
+local function ExpandQuestTracker(location)
+	if(not location or (location ~= MOD.Docklet.Parent.Bar.Data.Location)) then return end
+	SV.Timers:ExecuteTimer(MOD.UpdateDimensions, 0.2)
+end
+
+local function PostFadeInCallback(location)
+	if(not location or (location ~= MOD.Docklet.Parent.Bar.Data.Location)) then return end
+	MOD.DOCK_IS_FADED = false;
+	--print(MOD.DOCK_IS_FADED)
+end
+
+local function PostFadeOutCallback(location)
+	if(not location or (location ~= MOD.Docklet.Parent.Bar.Data.Location)) then return end
+	MOD.DOCK_IS_FADED = true;
+	--print(MOD.DOCK_IS_FADED)
+end
+
+function MOD:UpdateSetup()
+	for headerName, headerFrame in pairs(MOD.Headers) do
+		if(headerFrame.Refresh) then
+			headerFrame:Refresh()
+		end
+	end
+end
+
+function MOD:UpdateLocals()
+	ROW_WIDTH = self.Docklet.ScrollFrame:GetWidth();
+	local baseWidth = SV.db.QuestTracker.rowHeight;
+	local calculated = SV.media.shared.font.questdialog.size + 4;
+	ROW_HEIGHT = (baseWidth < calculated) and calculated or baseWidth;
+	INNER_HEIGHT = ROW_HEIGHT - 4;
+	LARGE_ROW_HEIGHT = ROW_HEIGHT * 2;
+	LARGE_INNER_HEIGHT = LARGE_ROW_HEIGHT - 4;
+	SV.Events:Trigger("QUEST_UPVALUES_UPDATED", ROW_WIDTH, ROW_HEIGHT, INNER_HEIGHT, LARGE_ROW_HEIGHT, LARGE_INNER_HEIGHT);
+end
+
+function MOD:ReLoad()
+	-- DO STUFF
+	self:UpdateDimensions()
+end
+
+function MOD:Load()
+	self.Headers = {}
+	self.Docklet = SV.Dock:NewDocklet("BottomRight", "SVUI_QuestTracker", "Quest Tracker", MOD.media.dockIcon);
+
+	self:InitializePopups()
+	self:InitializeActive()
+
+	local scrollFrame = CreateFrame("ScrollFrame", "SVUI_QuestTrackerScrollFrame", self.Docklet);
+	scrollFrame:SetPoint("TOPLEFT", self.Headers["Active"], "BOTTOMLEFT", 4, -2);
+	scrollFrame:SetPoint("BOTTOMRIGHT", self.Docklet, "BOTTOMRIGHT", -30, 2);
+	scrollFrame:EnableMouseWheel(true);
+	scrollFrame.MaxVal = 420;
+
+	local scrollBar = CreateFrame("Slider", "SVUI_QuestTrackerScrollFrameScrollBar", scrollFrame);
+	--scrollBar:SetHeight(scrollFrame:GetHeight());
+	scrollBar:SetWidth(18);
+	scrollBar:SetPoint("TOPRIGHT", self.Headers["Active"], "BOTTOMRIGHT", -4, 2);
+	scrollBar:SetPoint("BOTTOMRIGHT", self.Docklet, "BOTTOMRIGHT", -4, 2);
+	scrollBar:SetFrameLevel(6)
+	scrollBar:SetOrientation("VERTICAL");
+	scrollBar:SetValueStep(5);
+	scrollBar:SetMinMaxValues(1, 420);
+	scrollBar:SetValue(1);
+	scrollBar:SetScript("OnValueChanged", function(self, argValue)
+		_G.SVUI_QuestTrackerScrollFrame:SetVerticalScroll(argValue)
+	end)
+	SV.API:Set("ScrollBar", scrollBar)
+
+	local scrollChild = CreateFrame("Frame", "SVUI_QuestTrackerScrollFrameScrollChild", scrollFrame);
+	scrollChild:SetWidth(scrollFrame:GetWidth());
+	scrollChild:SetClampedToScreen(false)
+	scrollChild:SetHeight(500)
+	scrollChild:SetPoint("BOTTOMRIGHT", scrollFrame, "BOTTOMRIGHT", -2, 0)
+	scrollChild:SetFrameLevel(scrollFrame:GetFrameLevel() + 1)
+
+	scrollFrame:SetScrollChild(scrollChild);
+	scrollFrame.ScrollBar = scrollBar;
+	scrollFrame.ScrollChild = scrollChild;
+	scrollFrame:SetScript("OnMouseWheel", function(self, delta)
+		local scroll = self:GetVerticalScroll();
+		local value = (scroll - (20  *  delta));
+		if value < -1 then
+			value = 0
+		end
+		if value > self.MaxVal then
+			value = self.MaxVal
+		end
+		self:SetVerticalScroll(value)
+		self.ScrollBar:SetValue(value)
+	end)
+
+	self.Docklet.ScrollFrame = scrollFrame;
+	self:UpdateLocals();
+
+	self.ClosestQuest = 0;
+	self.CurrentQuest = 0;
+
+	self:InitializeScenarios()
+	--self:InitializeQuestItem()
+	self:InitializeBonuses()
+	self:InitializeQuests()
+	self:InitializeAchievements()
+
+	self:UpdateDimensions();
+	self.Docklet:Show();
+
+	ObjectiveTrackerFrame:UnregisterAllEvents();
+	ObjectiveTrackerFrame:SetParent(SV.Hidden);
+
+	self.Headers["Popups"]:Refresh()
+
+	SV.Events:On("DOCK_EXPANDED", ExpandQuestTracker, true);
+	SV.Events:On("DOCK_FADE_IN", PostFadeInCallback, true);
+	SV.Events:On("DOCK_FADE_OUT", PostFadeOutCallback, true);
+end
diff --git a/SVUI_QuestTracker/SVUI_QuestTracker.toc b/SVUI_QuestTracker/SVUI_QuestTracker.toc
new file mode 100644
index 0000000..c13b7a7
--- /dev/null
+++ b/SVUI_QuestTracker/SVUI_QuestTracker.toc
@@ -0,0 +1,16 @@
+## Interface: 70000
+## Author: Failcoder
+## Version: 1.3.5
+## Title: |cffFF9900SuperVillain UI: |r|cffFFEF00QuestTracker|r
+## Notes: QuestTracker Plugin for [|cff9911FFSVUI|r].
+## OptionalDeps: LibSharedMedia-3.0
+## RequiredDeps: SVUI_!Core
+## X-SVUIName: QuestTracker
+## X-SVUISchema: QuestTracker
+## X-Email: munglunch@gmail.com
+## X-Website: http://www.supervillainui.com
+## X-Donate: PayPal:munglunch@gmail.com
+## X-License: MIT
+## X-Category: Interface Enhancements
+
+SVUI_QuestTracker.xml
diff --git a/SVUI_QuestTracker/SVUI_QuestTracker.xml b/SVUI_QuestTracker/SVUI_QuestTracker.xml
new file mode 100644
index 0000000..2688d4a
--- /dev/null
+++ b/SVUI_QuestTracker/SVUI_QuestTracker.xml
@@ -0,0 +1,51 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+    <Font name="SVUI_Font_Quest" font="Fonts\ARIALN.TTF" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="12"/>
+        </FontHeight>
+    </Font>
+    <Font name="SVUI_Font_Quest_Header" font="Fonts\skurri.ttf" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="16"/>
+        </FontHeight>
+    </Font>
+    <Font name="SVUI_Font_Quest_Number" font="Fonts\MORPHEUS.ttf" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="11"/>
+        </FontHeight>
+    </Font>
+
+    <Frame name="SVUI_QuestItemBar" parent="UIParent">
+        <Size x="32" y="160"/>
+        <Anchors>
+            <Anchor point="BOTTOMRIGHT" x="-250" y="60"/>
+        </Anchors>
+    </Frame>
+
+    <Script file="Loader.lua"/>
+    <Script file='SVUI_QuestTracker.lua'/>
+    <Script file='components\popups.lua'/>
+    <Script file='components\active.lua'/>
+    <Script file='components\scenario.lua'/>
+    <Script file='components\quests.lua'/>
+    <Script file='components\bonus.lua'/>
+    <Script file='components\achievements.lua'/>
+</Ui>
diff --git a/SVUI_QuestTracker/assets/DOCK-ICON-QUESTS.blp b/SVUI_QuestTracker/assets/DOCK-ICON-QUESTS.blp
new file mode 100644
index 0000000..0b7ee68
Binary files /dev/null and b/SVUI_QuestTracker/assets/DOCK-ICON-QUESTS.blp differ
diff --git a/SVUI_QuestTracker/assets/QUEST-BUTTON-ART.blp b/SVUI_QuestTracker/assets/QUEST-BUTTON-ART.blp
new file mode 100644
index 0000000..d8172f1
Binary files /dev/null and b/SVUI_QuestTracker/assets/QUEST-BUTTON-ART.blp differ
diff --git a/SVUI_QuestTracker/assets/QUEST-COMPLETE-ICON.blp b/SVUI_QuestTracker/assets/QUEST-COMPLETE-ICON.blp
new file mode 100644
index 0000000..625db95
Binary files /dev/null and b/SVUI_QuestTracker/assets/QUEST-COMPLETE-ICON.blp differ
diff --git a/SVUI_QuestTracker/assets/QUEST-INCOMPLETE-ICON.blp b/SVUI_QuestTracker/assets/QUEST-INCOMPLETE-ICON.blp
new file mode 100644
index 0000000..b883f51
Binary files /dev/null and b/SVUI_QuestTracker/assets/QUEST-INCOMPLETE-ICON.blp differ
diff --git a/SVUI_QuestTracker/components/achievements.lua b/SVUI_QuestTracker/components/achievements.lua
new file mode 100644
index 0000000..781766b
--- /dev/null
+++ b/SVUI_QuestTracker/components/achievements.lua
@@ -0,0 +1,389 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack    = _G.unpack;
+local select    = _G.select;
+local pairs     = _G.pairs;
+local ipairs    = _G.ipairs;
+local type      = _G.type;
+local error     = _G.error;
+local pcall     = _G.pcall;
+local tostring  = _G.tostring;
+local tonumber  = _G.tonumber;
+local tinsert 	= _G.tinsert;
+local string 	= _G.string;
+local math 		= _G.math;
+local table 	= _G.table;
+local band 		= _G.bit.band;
+--[[ STRING METHODS ]]--
+local format = string.format;
+--[[ MATH METHODS ]]--
+local abs, ceil, floor, round = math.abs, math.ceil, math.floor, math.round;
+--[[ TABLE METHODS ]]--
+local tremove, twipe = table.remove, table.wipe;
+--BLIZZARD API
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+local GameTooltip           = _G.GameTooltip;
+local hooksecurefunc        = _G.hooksecurefunc;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local MOD = SV.QuestTracker;
+--[[
+##########################################################
+LOCALS
+##########################################################
+]]--
+local ROW_WIDTH = 300;
+local ROW_HEIGHT = 20;
+local QUEST_ROW_HEIGHT = ROW_HEIGHT + 2;
+local INNER_HEIGHT = ROW_HEIGHT - 4;
+local LARGE_ROW_HEIGHT = ROW_HEIGHT * 2;
+local LARGE_INNER_HEIGHT = LARGE_ROW_HEIGHT - 4;
+
+local NO_ICON = SV.NoTexture;
+local OBJ_ICON_ACTIVE = [[Interface\COMMON\Indicator-Yellow]];
+local OBJ_ICON_COMPLETE = [[Interface\COMMON\Indicator-Green]];
+local OBJ_ICON_INCOMPLETE = [[Interface\COMMON\Indicator-Gray]];
+local LINE_ACHIEVEMENT_ICON = [[Interface\ICONS\Achievement_General]];
+local MAX_OBJECTIVES_SHOWN = 8;
+--[[
+##########################################################
+SCRIPT HANDLERS
+##########################################################
+]]--
+local RowButton_OnEnter = function(self, ...)
+	if(MOD.DOCK_IS_FADED) then return end
+	GameTooltip:SetOwner(self, "ANCHOR_BOTTOMLEFT", 0, ROW_HEIGHT)
+	GameTooltip:ClearLines()
+	GameTooltip:AddDoubleLine("[Left-Click]", "View this in the achievements window.", 0, 1, 0, 1, 1, 1)
+	GameTooltip:AddLine(" ")
+	GameTooltip:AddDoubleLine("[Right-Click]", "Remove this achievement from the tracker.", 0, 1, 0, 1, 1, 1)
+	GameTooltip:Show()
+end
+
+local RowButton_OnLeave = function(self, ...)
+	GameTooltip:Hide()
+end
+
+local ViewButton_OnClick = function(self, button)
+	local achievementID = self:GetID();
+	if(achievementID and (achievementID ~= 0)) then
+		if(IsModifiedClick("CHATLINK") and ChatEdit_GetActiveWindow()) then
+			local achievementLink = GetAchievementLink(achievementID);
+			if(achievementLink) then
+				ChatEdit_InsertLink(achievementLink);
+			end
+		else
+			CloseDropDownMenus();
+			if(not AchievementFrame ) then
+				AchievementFrame_LoadUI();
+			end
+			if(IsModifiedClick("QUESTWATCHTOGGLE") or (button and button == "RightButton")) then
+				AchievementObjectiveTracker_UntrackAchievement(self, achievementID);
+			elseif(not AchievementFrame:IsShown()) then
+				AchievementFrame_ToggleAchievementFrame();
+				AchievementFrame_SelectAchievement(achievementID);
+			else
+				if(AchievementFrameAchievements.selection ~= achievementID) then
+					AchievementFrame_SelectAchievement(achievementID);
+				else
+					AchievementFrame_ToggleAchievementFrame();
+				end
+			end
+		end
+	end
+end
+
+local BadgeButton_OnClick = function(self, button)
+	local achievementID = self.Link:GetID();
+	if(achievementID and (achievementID ~= 0)) then
+		if(IsModifiedClick("CHATLINK") and ChatEdit_GetActiveWindow()) then
+			local achievementLink = GetAchievementLink(achievementID);
+			if(achievementLink) then
+				ChatEdit_InsertLink(achievementLink);
+			end
+		else
+			CloseDropDownMenus();
+			if(not AchievementFrame ) then
+				AchievementFrame_LoadUI();
+			end
+			if(IsModifiedClick("QUESTWATCHTOGGLE") or (button and button == "RightButton")) then
+				AchievementObjectiveTracker_UntrackAchievement(self.Link, achievementID);
+			elseif(not AchievementFrame:IsShown()) then
+				AchievementFrame_ToggleAchievementFrame();
+				AchievementFrame_SelectAchievement(achievementID);
+			else
+				if(AchievementFrameAchievements.selection ~= achievementID) then
+					AchievementFrame_SelectAchievement(achievementID);
+				else
+					AchievementFrame_ToggleAchievementFrame();
+				end
+			end
+		end
+	end
+end
+--[[
+##########################################################
+TRACKER FUNCTIONS
+##########################################################
+]]--
+local GetAchievementRow = function(self, index)
+	if(not self.Rows[index]) then
+		local previousFrame = self.Rows[#self.Rows]
+		local index = #self.Rows + 1;
+		local yOffset = -3;
+
+		local anchorFrame;
+		if(previousFrame and previousFrame.Objectives) then
+			anchorFrame = previousFrame.Objectives;
+			yOffset = -6;
+		else
+			anchorFrame = self.Header;
+		end
+
+		local row = CreateFrame("Frame", nil, self)
+		row:SetPoint("TOPLEFT", anchorFrame, "BOTTOMLEFT", 0, yOffset);
+		row:SetPoint("TOPRIGHT", anchorFrame, "BOTTOMRIGHT", 0, yOffset);
+		row:SetHeight(QUEST_ROW_HEIGHT);
+
+		row.Badge = CreateFrame("Frame", nil, row)
+		row.Badge:SetPoint("TOPLEFT", row, "TOPLEFT", 0, 0);
+		row.Badge:SetSize(QUEST_ROW_HEIGHT, QUEST_ROW_HEIGHT);
+		--row.Badge:SetStyle("Frame", "Lite");
+
+		row.Badge.Icon = row.Badge:CreateTexture(nil,"OVERLAY")
+		row.Badge.Icon:SetAllPoints(row.Badge);
+		row.Badge.Icon:SetTexture(LINE_ACHIEVEMENT_ICON)
+		row.Badge.Icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+
+		row.Badge.Button = CreateFrame("Button", nil, row.Badge)
+		row.Badge.Button:SetAllPoints(row.Badge);
+		row.Badge.Button:SetStyle("LiteButton")
+		row.Badge.Button:SetID(0)
+		row.Badge.Button.Icon = row.Badge.Icon;
+		row.Badge.Button:RegisterForClicks("LeftButtonUp", "RightButtonUp")
+		row.Badge.Button:SetScript("OnClick", BadgeButton_OnClick)
+		row.Badge.Button:SetScript("OnEnter", RowButton_OnEnter)
+		row.Badge.Button:SetScript("OnLeave", RowButton_OnLeave)
+
+		row.Header = CreateFrame("Frame", nil, row)
+		row.Header:SetPoint("TOPLEFT", row, "TOPLEFT", (QUEST_ROW_HEIGHT + 6), 0);
+		row.Header:SetPoint("TOPRIGHT", row, "TOPRIGHT", -2, 0);
+		row.Header:SetHeight(QUEST_ROW_HEIGHT);
+
+		row.Header.Text = row.Header:CreateFontString(nil,"OVERLAY")
+		row.Header.Text:SetFontObject(SVUI_Font_Quest);
+		row.Header.Text:SetJustifyH('LEFT')
+		row.Header.Text:SetTextColor(1,1,0)
+		row.Header.Text:SetText('')
+		row.Header.Text:SetPoint("TOPLEFT", row.Header, "TOPLEFT", 4, 0);
+		row.Header.Text:SetPoint("BOTTOMRIGHT", row.Header, "BOTTOMRIGHT", 0, 0);
+
+		row.Button = CreateFrame("Button", nil, row.Header);
+		row.Button:SetPoint("TOPLEFT", row, "TOPLEFT", (QUEST_ROW_HEIGHT + 6), 0);
+		row.Button:SetPoint("TOPRIGHT", row, "TOPRIGHT", -2, 0);
+		row.Button:SetHeight(INNER_HEIGHT + 2);
+		row.Button:SetStyle("LiteButton")
+		row.Button:SetID(0)
+		row.Button:RegisterForClicks("LeftButtonUp", "RightButtonUp")
+		row.Button:SetScript("OnClick", ViewButton_OnClick)
+		row.Button:SetScript("OnEnter", RowButton_OnEnter)
+		row.Button:SetScript("OnLeave", RowButton_OnLeave)
+
+		row.Badge.Button.Link = row.Button
+
+		row.Objectives = MOD.NewObjectiveHeader(row);
+		row.Objectives:SetPoint("TOPLEFT", row, "BOTTOMLEFT", 0, 0);
+		row.Objectives:SetPoint("TOPRIGHT", row, "BOTTOMRIGHT", 0, 0);
+		row.Objectives:SetHeight(1);
+
+		row.RowID = 0;
+		self.Rows[index] = row;
+		return row;
+	end
+
+	return self.Rows[index];
+end
+
+local SetAchievementRow = function(self, index, title, details, icon, achievementID)
+	index = index + 1;
+	icon = icon or LINE_ACHIEVEMENT_ICON;
+
+	local fill_height = 0;
+	local shown_objectives = 0;
+	local objective_rows = 0;
+
+	local row = self:Get(index);
+	row.RowID = achievementID
+	row.Header.Text:SetText(title)
+	row.Badge.Icon:SetTexture(icon);
+	row.Badge:SetAlpha(1);
+	row.Button:Enable();
+	row.Button:SetID(achievementID);
+	row:SetHeight(ROW_HEIGHT);
+	row:FadeIn();
+	row.Header:FadeIn();
+
+	local objective_block = row.Objectives;
+	local subCount = GetAchievementNumCriteria(achievementID);
+
+	for i = 1, subCount do
+		local description, category, completed, quantity, totalQuantity, _, flags, assetID, quantityString, criteriaID, eligible, duration, elapsed = GetAchievementCriteriaInfo(achievementID, i);
+		if(completed or (shown_objectives > MAX_OBJECTIVES_SHOWN and not completed)) then
+			--DO NOTHING
+		elseif(shown_objectives == MAX_OBJECTIVES_SHOWN and subCount > (MAX_OBJECTIVES_SHOWN + 1)) then
+			shown_objectives = shown_objectives + 1;
+		else
+			if(description and band(flags, EVALUATION_TREE_FLAG_PROGRESS_BAR) == EVALUATION_TREE_FLAG_PROGRESS_BAR) then
+				if(string.find(quantityString:lower(), "interface\\moneyframe")) then
+					description = quantityString.."\n"..description;
+				else
+					description = string.gsub(quantityString, " / ", "/").." "..description;
+				end
+			else
+				if(category == CRITERIA_TYPE_ACHIEVEMENT and assetID) then
+					_, description = GetAchievementInfo(assetID);
+				end
+			end
+
+			if(description and description ~= '') then
+				shown_objectives = shown_objectives + 1;
+
+				fill_height = fill_height + (ROW_HEIGHT + 2);
+				objective_rows = objective_block:SetInfo(objective_rows, description, completed)
+				if(duration and elapsed and elapsed < duration) then
+					fill_height = fill_height + (ROW_HEIGHT + 2);
+					objective_rows = objective_block:SetTimer(objective_rows, duration, elapsed);
+				end
+			end
+		end
+	end
+
+	if(objective_rows > 0) then
+		objective_block:SetHeight(fill_height);
+		objective_block:FadeIn();
+	end
+
+	fill_height = fill_height + (ROW_HEIGHT + 2);
+
+	return index, fill_height;
+end
+
+local RefreshAchievements = function(self, event, ...)
+	local list = { GetTrackedAchievements() };
+	local fill_height = 0;
+	local rows = 0;
+
+	if(#list > 0) then
+		for i = 1, #list do
+			local achievementID = list[i];
+			local _, title, _, completed, _, _, _, details, _, icon, _, _, wasEarnedByMe = GetAchievementInfo(achievementID);
+			if(not wasEarnedByMe) then
+				local add_height = 0;
+				rows, add_height = self:Set(rows, title, details, icon, achievementID)
+				fill_height = fill_height + add_height
+			end
+		end
+	end
+
+	if(rows == 0 or (fill_height <= 1)) then
+		self:SetHeight(1);
+		self.Header.Text:SetText('');
+		self.Header:SetAlpha(0);
+		self:SetAlpha(0);
+	else
+		self:SetHeight(fill_height + 2);
+		self.Header.Text:SetText(TRACKER_HEADER_ACHIEVEMENTS);
+		self:FadeIn();
+		self.Header:FadeIn();
+	end
+end
+
+local ResetAchievementBlock = function(self)
+	for x = 1, #self.Rows do
+		local row = self.Rows[x]
+		if(row) then
+			row.RowID = 0;
+			row.Header.Text:SetText('');
+			row.Header:SetAlpha(0);
+			row.Button:Disable();
+			row.Button:SetID(0);
+			row.Badge.Icon:SetTexture(NO_ICON);
+			row.Badge:SetAlpha(0);
+			row:SetHeight(1);
+			row:SetAlpha(0);
+			row.Objectives:Reset();
+		end
+	end
+end
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+function MOD:UpdateAchievements(event, ...)
+	self.Headers["Achievements"]:Reset()
+	self.Headers["Achievements"]:Refresh(event, ...)
+	self:UpdateDimensions();
+end
+
+local function UpdateAchievementLocals(...)
+	ROW_WIDTH, ROW_HEIGHT, INNER_HEIGHT, LARGE_ROW_HEIGHT, LARGE_INNER_HEIGHT = ...;
+	QUEST_ROW_HEIGHT = ROW_HEIGHT + 2;
+end
+
+function MOD:InitializeAchievements()
+	local scrollChild = self.Docklet.ScrollFrame.ScrollChild;
+
+    local achievements = CreateFrame("Frame", nil, scrollChild)
+    achievements:SetWidth(ROW_WIDTH);
+	achievements:SetHeight(ROW_HEIGHT);
+	achievements:SetPoint("TOPLEFT", self.Headers["Quests"], "BOTTOMLEFT", 0, -12);
+
+	achievements.Header = CreateFrame("Frame", nil, achievements)
+	achievements.Header:SetPoint("TOPLEFT", achievements, "TOPLEFT", 2, -2);
+	achievements.Header:SetPoint("TOPRIGHT", achievements, "TOPRIGHT", -2, -2);
+	achievements.Header:SetHeight(INNER_HEIGHT);
+
+	achievements.Header.Text = achievements.Header:CreateFontString(nil,"OVERLAY")
+	achievements.Header.Text:SetPoint("TOPLEFT", achievements.Header, "TOPLEFT", 2, 0);
+	achievements.Header.Text:SetPoint("BOTTOMLEFT", achievements.Header, "BOTTOMLEFT", 2, 0);
+	achievements.Header.Text:SetFontObject(SVUI_Font_Quest_Header);
+	achievements.Header.Text:SetJustifyH('LEFT')
+	achievements.Header.Text:SetTextColor(0.28,0.75,1)
+	achievements.Header.Text:SetText(TRACKER_HEADER_ACHIEVEMENTS)
+
+	achievements.Header.Divider = achievements.Header:CreateTexture(nil, 'BACKGROUND');
+	achievements.Header.Divider:SetPoint("TOPLEFT", achievements.Header.Text, "TOPRIGHT", -10, 0);
+	achievements.Header.Divider:SetPoint("BOTTOMRIGHT", achievements.Header, "BOTTOMRIGHT", 0, 0);
+	achievements.Header.Divider:SetTexture([[Interface\AddOns\SVUI_!Core\assets\textures\DROPDOWN-DIVIDER]]);
+
+	achievements.Rows = {};
+
+	achievements.Get = GetAchievementRow;
+	achievements.Set = SetAchievementRow;
+	achievements.Refresh = RefreshAchievements;
+	achievements.Reset = ResetAchievementBlock;
+
+	self.Headers["Achievements"] = achievements;
+
+	self:RegisterEvent("TRACKED_ACHIEVEMENT_UPDATE", self.UpdateAchievements);
+	self:RegisterEvent("TRACKED_ACHIEVEMENT_LIST_CHANGED", self.UpdateAchievements);
+
+	self.Headers["Achievements"]:Refresh()
+
+	SV.Events:On("QUEST_UPVALUES_UPDATED", UpdateAchievementLocals, true);
+end
diff --git a/SVUI_QuestTracker/components/active.lua b/SVUI_QuestTracker/components/active.lua
new file mode 100644
index 0000000..cfbe772
--- /dev/null
+++ b/SVUI_QuestTracker/components/active.lua
@@ -0,0 +1,433 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack    = _G.unpack;
+local select    = _G.select;
+local type      = _G.type;
+--BLIZZARD API
+local CreateFrame           			= _G.CreateFrame;
+local GameTooltip           			= _G.GameTooltip;
+local IsShiftKeyDown        			= _G.IsShiftKeyDown;
+local IsModifiedClick       			= _G.IsModifiedClick;
+local GetQuestLink  							= _G.GetQuestLink;
+local GetQuestLogTitle  					= _G.GetQuestLogTitle;
+local GetQuestWatchInfo  					= _G.GetQuestWatchInfo;
+local GetQuestWatchIndex  				= _G.GetQuestWatchIndex;
+local ShowQuestComplete  					= _G.ShowQuestComplete;
+local RemoveQuestWatch  					= _G.RemoveQuestWatch;
+local IsQuestComplete  						= _G.IsQuestComplete;
+local GetSuperTrackedQuestID			= _G.GetSuperTrackedQuestID;
+local GetQuestLogIndexByID  			= _G.GetQuestLogIndexByID;
+local GetQuestObjectiveInfo				= _G.GetQuestObjectiveInfo;
+local GetQuestLogIsAutoComplete  	= _G.GetQuestLogIsAutoComplete;
+local GetQuestDifficultyColor  		= _G.GetQuestDifficultyColor;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local MOD = SV.QuestTracker;
+--[[
+##########################################################
+LOCALS
+##########################################################
+]]--
+local ROW_WIDTH = 300;
+local ROW_HEIGHT = 24;
+local INNER_HEIGHT = ROW_HEIGHT - 4;
+local LARGE_ROW_HEIGHT = ROW_HEIGHT * 2;
+local LARGE_INNER_HEIGHT = LARGE_ROW_HEIGHT - 4;
+local DEFAULT_COLOR = {r = 1, g = 0.68, b = 0.1}
+--[[
+##########################################################
+SCRIPT HANDLERS
+##########################################################
+]]--
+-- local ObjectiveTimer_OnUpdate = function(self, elapsed)
+-- 	local statusbar = self.Timer.Bar
+-- 	local timeNow = GetTime();
+-- 	local timeRemaining = statusbar.duration - (timeNow - statusbar.startTime);
+-- 	statusbar:SetValue(timeRemaining);
+-- 	if(timeRemaining < 0) then
+-- 		-- hold at 0 for a moment
+-- 		if(timeRemaining > -1) then
+-- 			timeRemaining = 0;
+-- 		else
+-- 			self:StopTimer();
+-- 		end
+-- 	end
+-- 	local r,g,b = MOD:GetTimerTextColor(statusbar.duration, statusbar.duration - timeRemaining)
+-- 	statusbar.Label:SetText(GetTimeStringFromSeconds(timeRemaining, nil, true));
+-- 	statusbar.Label:SetTextColor(r,g,b);
+-- end
+--
+-- local ObjectiveProgressBar_OnEvent = function(self, event, ...)
+-- 	local statusbar = self.Progress.Bar;
+-- 	local percent = 100;
+-- 	if(not statusbar.finished) then
+-- 		percent = GetQuestProgressBarPercent(statusbar.questID);
+-- 	end
+-- 	statusbar:SetValue(percent);
+-- 	statusbar.Label:SetFormattedText(PERCENTAGE_STRING, percent);
+-- end
+
+local ActiveButton_OnEnter = function(self)
+	if(MOD.DOCK_IS_FADED) then return end
+	GameTooltip:SetOwner(self, "ANCHOR_BOTTOMLEFT", 0, ROW_HEIGHT)
+	GameTooltip:ClearLines()
+	GameTooltip:AddDoubleLine("[Left-Click]", "View the log entry for this quest.", 0, 1, 0, 1, 1, 1)
+	GameTooltip:AddLine(" ")
+	GameTooltip:AddDoubleLine("[Right-Click]", "Remove this quest from the tracker.", 0, 1, 0, 1, 1, 1)
+	GameTooltip:AddLine(" ")
+	GameTooltip:AddDoubleLine("[SHIFT+Click]", "Show this quest on the map.", 0, 1, 0, 1, 1, 1)
+	GameTooltip:Show()
+end
+
+local ActiveButton_OnLeave = function()
+	GameTooltip:Hide()
+end
+
+local ActiveButton_OnClick = function()
+	MOD.Headers["Active"]:Unset();
+end
+
+local ViewButton_OnClick = function(self, button)
+	local questIndex = self.LogID;
+	if(questIndex and (questIndex ~= 0)) then
+		local questID = select(8, GetQuestLogTitle(questIndex));
+		if(IsModifiedClick("CHATLINK") and ChatEdit_GetActiveWindow()) then
+			local questLink = GetQuestLink(questIndex);
+			if(questLink) then
+				ChatEdit_InsertLink(questLink);
+			end
+		elseif(questID and IsShiftKeyDown()) then
+			QuestMapFrame_OpenToQuestDetails(questID);
+		elseif(questID and button ~= "RightButton") then
+			CloseDropDownMenus();
+			if(IsQuestComplete(questID) and GetQuestLogIsAutoComplete(questIndex)) then
+				AutoQuestPopupTracker_RemovePopUp(questID);
+				ShowQuestComplete(questIndex);
+			else
+				QuestLogPopupDetailFrame_Show(questIndex);
+			end
+		elseif(questID) then
+			local superTrackedQuestID = GetSuperTrackedQuestID();
+			RemoveQuestWatch(questIndex);
+			if(questID == superTrackedQuestID) then
+				QuestSuperTracking_OnQuestUntracked();
+			end
+		end
+	end
+end
+
+local CloseButton_OnEnter = function(self)
+    self:SetBackdropBorderColor(0.1, 0.8, 0.8)
+end
+
+local CloseButton_OnLeave = function(self)
+    self:SetBackdropBorderColor(0,0,0,1)
+end
+--[[
+##########################################################
+TRACKER FUNCTIONS
+##########################################################
+]]--
+local UnsetActiveData = function(self, bypass)
+	local block = self.Block;
+	block:SetHeight(1);
+	block.Header.Text:SetText('');
+	block.Header.Level:SetText('');
+	block.Badge.Icon:SetTexture("");
+	block.Button.LogID = 0;
+	self.ActiveQuestID = 0;
+	MOD.ActiveQuestID = self.ActiveQuestID;
+	MOD.CurrentQuest = 0;
+	block.Objectives:Reset();
+	block:SetAlpha(0);
+	self:SetAlpha(0);
+	self:SetHeight(1);
+	-- if(MOD.QuestItem and MOD.QuestItem:IsShown()) then
+	-- 	MOD.QuestItem.CurrentQuest = 0;
+	-- 	MOD.QuestItem.Artwork:SetTexture("");
+	-- 	MOD.QuestItem:ClearUsage();
+	-- end
+	if(block.Badge.StopTracking) then
+		block.Badge:StopTracking()
+	end
+	if(not bypass and MOD.Headers["Quests"]) then
+		MOD:UpdateObjectives('FORCED_UPDATE')
+	end
+end
+
+local SetActiveData = function(self, title, level, icon, questID, questLogIndex, numObjectives, duration, elapsed, isComplete, itemLink)
+	if(not questID) then return end
+	self.ActiveQuestID = questID;
+	MOD.ActiveQuestID = self.ActiveQuestID;
+	local fill_height = 0;
+	local objective_rows = 0;
+	local block = self.Block;
+
+	local color = DEFAULT_COLOR
+	if(level and type(level) == 'number') then
+		color = GetQuestDifficultyColor(level);
+	end
+	block.Header.Level:SetTextColor(color.r, color.g, color.b);
+	block.Header.Level:SetText(level);
+	block.Header.Text:SetText(title);
+
+	block.Button.LogID = questLogIndex;
+
+	MOD.CurrentQuest = questLogIndex;
+
+	local objective_block = block.Objectives;
+	objective_block:Reset();
+	for i = 1, numObjectives do
+		local description, category, completed = GetQuestObjectiveInfo(questID, i, false);
+		if(not completed) then isComplete = false end
+		if(duration and elapsed and (elapsed < duration)) then
+			objective_rows = objective_block:SetTimer(objective_rows, duration, elapsed);
+			fill_height = fill_height + (INNER_HEIGHT + 2);
+		elseif(description and description ~= '') then
+			objective_rows = objective_block:SetInfo(objective_rows, description, completed);
+			fill_height = fill_height + (INNER_HEIGHT + 2);
+		end
+	end
+
+	if(objective_rows > 0) then
+		objective_block:SetHeight(fill_height);
+		objective_block:FadeIn();
+	end
+	fill_height = fill_height + (LARGE_INNER_HEIGHT + 8);
+	local padding = block.Details:GetHeight()
+	block:SetHeight(fill_height + padding);
+
+	MOD.Docklet.ScrollFrame.ScrollBar:SetValue(0);
+
+	if(isComplete) then
+		icon = MOD.media.completeIcon;
+	else
+		icon = icon or MOD.media.incompleteIcon;
+	end
+	block.Badge.Icon:SetTexture(icon);
+	-- if(itemLink) then
+	-- 	local iName, _, _, _ = GetItemInfo(itemLink);
+	-- 	block.Badge.Button.macrotext = '/use '..iName;
+	-- 	if(InCombatLockdown()) then
+ --            block.Badge.Button:RegisterEvent('PLAYER_REGEN_ENABLED')
+ --        else
+ --            block.Badge.Button:SetAttribute('item', block.Badge.Button.macrotext)
+ --        end
+	-- end
+
+	if(block.Badge.StartTracking) then
+		block.Badge:StartTracking(questID)
+	end
+
+	self:RefreshHeight()
+end
+
+local RefreshActiveHeight = function(self)
+	if(self.ActiveQuestID == 0) then
+		self:Unset()
+	else
+		self:FadeIn();
+		self.Block:FadeIn();
+		local height = self.Block:GetHeight()
+		self:SetHeight(height)
+	end
+end
+
+local RefreshActiveObjective = function(self, event, ...)
+	-- print('<-----ACTIVE')
+	-- print(event)
+	-- print(...)
+	if(event) then
+		if(event == 'ACTIVE_QUEST_LOADED') then
+			self.ActiveQuestID = 0;
+			self:Set(...)
+		elseif(event == 'SUPER_TRACKED_QUEST_CHANGED') then
+			local questID = ...;
+			if(questID and questID ~= self.ActiveQuestID) then
+				local questLogIndex = GetQuestLogIndexByID(questID)
+				if(questLogIndex) then
+					local questWatchIndex = GetQuestWatchIndex(questLogIndex)
+					if(questWatchIndex) then
+						local title, level, suggestedGroup = GetQuestLogTitle(questLogIndex)
+						local questID, _, questLogIndex, numObjectives, requiredMoney, completed, startEvent, isAutoComplete, duration, elapsed, questType, isTask, isStory, isOnMap, hasLocalPOI = GetQuestWatchInfo(questWatchIndex);
+						self:Set(title, level, nil, questID, questLogIndex, numObjectives, duration, elapsed, hasLocalPOI)
+					end
+				end
+			end
+		elseif(event == 'FORCED_UPDATE') then
+			local questID = self.ActiveQuestID;
+			if(questID and questID ~= 0) then
+				local questLogIndex = GetQuestLogIndexByID(questID)
+				if(questLogIndex) then
+					local questWatchIndex = GetQuestWatchIndex(questLogIndex)
+					if(questWatchIndex) then
+						local title, level, suggestedGroup = GetQuestLogTitle(questLogIndex)
+						local questID, _, questLogIndex, numObjectives, requiredMoney, completed, startEvent, isAutoComplete, duration, elapsed, questType, isTask, isStory, isOnMap, hasLocalPOI = GetQuestWatchInfo(questWatchIndex);
+						self:Set(title, level, nil, questID, questLogIndex, numObjectives, duration, elapsed, hasLocalPOI)
+					end
+				end
+			end
+		end
+	end
+end
+
+local MacroButton_OnEvent = function(self, event)
+    if(event == 'PLAYER_REGEN_ENABLED') then
+        self:SetAttribute('macrotext', self.macrotext)
+        self:UnregisterEvent(event)
+    end
+end
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+function MOD:CheckActiveQuest(questID, ...)
+	if(questID and self.Headers["Active"].ActiveQuestID == questID) then
+		self.Headers["Active"]:Unset(true);
+	else
+		local currentQuestIndex = self.CurrentQuest;
+		if(currentQuestIndex and (currentQuestIndex ~= 0)) then
+			local questLogIndex = select(5, ...);
+			if(questLogIndex and (questLogIndex == currentQuestIndex)) then
+				self.Headers["Active"]:Set(...);
+				return true;
+			end
+		end
+	end
+	return false;
+end
+
+function MOD:UpdateActiveObjective(event, ...)
+	self.Headers["Active"]:Refresh(event, ...)
+	self:UpdateDimensions();
+end
+
+local function UpdateActiveLocals(...)
+	ROW_WIDTH, ROW_HEIGHT, INNER_HEIGHT, LARGE_ROW_HEIGHT, LARGE_INNER_HEIGHT = ...;
+end
+
+function MOD:InitializeActive()
+	local active = CreateFrame("Frame", nil, self.Docklet)
+    active:SetPoint("TOPLEFT", self.Docklet, "TOPLEFT");
+    active:SetPoint("TOPRIGHT", self.Docklet, "TOPRIGHT");
+    active:SetHeight(1);
+
+	local block = CreateFrame("Frame", nil, active)
+	block:SetPoint("TOPLEFT", active, "TOPLEFT", 2, -4);
+	block:SetPoint("TOPRIGHT", active, "TOPRIGHT", -2, -4);
+	block:SetHeight(LARGE_INNER_HEIGHT);
+
+	block.Button = CreateFrame("Button", nil, block)
+	block.Button:SetPoint("TOPLEFT", block, "TOPLEFT", 0, 0);
+	block.Button:SetPoint("BOTTOMRIGHT", block, "BOTTOMRIGHT", 0, 8);
+	block.Button:SetStyle("DockButton", "Transparent")
+	--block.Button:SetBackdropBorderColor(0, 0.9, 0, 0.5)
+	block.Button.LogID = 0
+	block.Button.Parent = active;
+	block.Button:SetScript("OnClick", ViewButton_OnClick)
+	block.Button:SetScript("OnEnter", ActiveButton_OnEnter)
+	block.Button:SetScript("OnLeave", ActiveButton_OnLeave)
+
+	block.CloseButton = CreateFrame("Button", nil, block.Button, "UIPanelCloseButton")
+	block.CloseButton:RemoveTextures()
+	block.CloseButton:SetStyle("Button", -7, -7, "red")
+	block.CloseButton:SetFrameLevel(block.Button:GetFrameLevel() + 4)
+	block.CloseButton:SetNormalTexture(SV.media.icon.close)
+  	block.CloseButton:HookScript("OnEnter", CloseButton_OnEnter)
+  	block.CloseButton:HookScript("OnLeave", CloseButton_OnLeave)
+	block.CloseButton:SetPoint("TOPRIGHT", block.Button, "TOPRIGHT", 4, 4);
+	block.CloseButton:RegisterForClicks("LeftButtonUp", "RightButtonUp")
+	block.CloseButton.Parent = active;
+	block.CloseButton:SetScript("OnClick", ActiveButton_OnClick)
+
+	block.Badge = CreateFrame("Frame", nil, block.Button)
+	block.Badge:SetPoint("TOPLEFT", block.Button, "TOPLEFT", 4, -4);
+	block.Badge:SetSize((LARGE_INNER_HEIGHT - 4), (LARGE_INNER_HEIGHT - 4));
+	block.Badge:SetStyle("!_Frame", "Inset")
+
+	block.Badge.Icon = block.Badge:CreateTexture(nil,"OVERLAY")
+	block.Badge.Icon:InsetPoints(block.Badge);
+	block.Badge.Icon:SetTexture(MOD.media.incompleteIcon)
+	block.Badge.Icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+
+	-- block.Badge.Button = CreateFrame("Button", nil, UIParent, "SecureActionButtonTemplate")
+	-- local bX,bY = block.Badge:GetCenter()
+	-- block.Badge.Button:SetPoint("CENTER", UIParent, "CENTER", bX,bY);
+	-- block.Badge.Button:SetStyle("LiteButton")
+	-- block.Badge.Button.LogID = 0
+	-- block.Badge.Button:SetFrameLevel(999);
+	-- block.Badge.Button.Icon = block.Badge.Icon;
+	-- block.Badge.Button:SetAttribute("type", "macro")
+	-- block.Badge.Button:SetScript('OnEvent', MacroButton_OnEvent);
+
+	block.Header = CreateFrame("Frame", nil, block)
+	block.Header:SetPoint("TOPLEFT", block.Badge, "TOPRIGHT", 4, 0);
+	block.Header:SetPoint("TOPRIGHT", block.Button, "TOPRIGHT", -24, -4);
+	block.Header:SetHeight(INNER_HEIGHT - 2);
+	block.Header:SetStyle("Frame")
+
+	block.Header.Level = block.Header:CreateFontString(nil,"OVERLAY")
+	block.Header.Level:SetFontObject(SVUI_Font_Quest);
+	block.Header.Level:SetJustifyH('LEFT')
+	block.Header.Level:SetText('')
+	block.Header.Level:SetPoint("TOPLEFT", block.Header, "TOPLEFT", 4, 0);
+	block.Header.Level:SetPoint("BOTTOMLEFT", block.Header, "BOTTOMLEFT", 4, 0);
+
+	block.Header.Text = block.Header:CreateFontString(nil,"OVERLAY")
+	block.Header.Text:SetFontObject(SVUI_Font_Quest);
+	block.Header.Text:SetJustifyH('LEFT')
+	block.Header.Text:SetTextColor(1,1,0)
+	block.Header.Text:SetText('')
+	block.Header.Text:SetPoint("TOPLEFT", block.Header.Level, "TOPRIGHT", 4, 0);
+	block.Header.Text:SetPoint("BOTTOMRIGHT", block.Header, "BOTTOMRIGHT", 0, 0);
+
+	block.Details = CreateFrame("Frame", nil, block.Header)
+	block.Details:SetPoint("TOPLEFT", block.Header, "BOTTOMLEFT", 0, -2);
+	block.Details:SetPoint("TOPRIGHT", block.Header, "BOTTOMRIGHT", 0, -2);
+
+	if(SV.AddQuestCompass) then
+		block.Details:SetHeight(INNER_HEIGHT - 4);
+		SV:AddQuestCompass(block, block.Badge)
+		block.Badge.Compass.Range:ClearAllPoints()
+		block.Badge.Compass.Range:SetPoint("TOPLEFT", block.Details, "TOPLEFT", 4, 0);
+		block.Badge.Compass.Range:SetPoint("BOTTOMLEFT", block.Details, "BOTTOMLEFT", 4, 0);
+		block.Badge.Compass.Range:SetJustifyH("LEFT");
+	else
+		block.Details:SetHeight(1);
+	end
+
+	block.Objectives = MOD.NewObjectiveHeader(block);
+	block.Objectives:SetPoint("TOPLEFT", block.Details, "BOTTOMLEFT", 0, -2);
+	block.Objectives:SetPoint("TOPRIGHT", block.Details, "BOTTOMRIGHT", 0, -2);
+	block.Objectives:SetHeight(1);
+
+	active.Block = block;
+
+	active.ActiveQuestID = 0;
+	active.Set = SetActiveData;
+	active.Unset = UnsetActiveData;
+	active.Refresh = RefreshActiveObjective;
+	active.RefreshHeight = RefreshActiveHeight;
+
+	self.Headers["Active"] = active;
+
+	self.Headers["Active"]:RefreshHeight()
+
+	self.ActiveQuestID = self.Headers["Active"].ActiveQuestID;
+
+	self:RegisterEvent("SUPER_TRACKED_QUEST_CHANGED", self.UpdateActiveObjective);
+
+	SV.Events:On("QUEST_UPVALUES_UPDATED", UpdateActiveLocals, true);
+end
diff --git a/SVUI_QuestTracker/components/bonus.lua b/SVUI_QuestTracker/components/bonus.lua
new file mode 100644
index 0000000..af9e1ad
--- /dev/null
+++ b/SVUI_QuestTracker/components/bonus.lua
@@ -0,0 +1,455 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack    = _G.unpack;
+local select    = _G.select;
+local pairs     = _G.pairs;
+local ipairs    = _G.ipairs;
+local type      = _G.type;
+local error     = _G.error;
+local pcall     = _G.pcall;
+local tostring  = _G.tostring;
+local tonumber  = _G.tonumber;
+local tinsert 	= _G.tinsert;
+local tDeleteItem = _G.tDeleteItem;
+local string 	= _G.string;
+local math 		= _G.math;
+local table 	= _G.table;
+--[[ STRING METHODS ]]--
+local format = string.format;
+--[[ MATH METHODS ]]--
+local abs, ceil, floor, round = math.abs, math.ceil, math.floor, math.round;
+--[[ TABLE METHODS ]]--
+local tremove, twipe = table.remove, table.wipe;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local MOD = SV.QuestTracker;
+--[[
+##########################################################
+LOCALS
+##########################################################
+]]--
+local ROW_WIDTH = 300;
+local ROW_HEIGHT = 24;
+local INNER_HEIGHT = ROW_HEIGHT - 4;
+local LARGE_ROW_HEIGHT = ROW_HEIGHT * 2;
+local LARGE_INNER_HEIGHT = LARGE_ROW_HEIGHT - 4;
+local OBJ_ICON_ACTIVE = [[Interface\COMMON\Indicator-Yellow]];
+local OBJ_ICON_COMPLETE = [[Interface\COMMON\Indicator-Green]];
+local OBJ_ICON_INCOMPLETE = [[Interface\COMMON\Indicator-Gray]];
+local CACHED_BONUS_DATA = {};
+local COMPLETED_BONUS_DATA = {};
+--[[
+##########################################################
+DATA CACHE HANDLERS
+##########################################################
+]]--
+local function CacheBonusData(questID, xp, money)
+	if(not questID or (questID and questID <= 0)) then return; end
+
+	local data = {};
+	data.objectives = {};
+	local isInArea, isOnMap, numObjectives = GetTaskInfo(questID);
+	local iscomplete = true;
+
+	if(numObjectives and (type(numObjectives) == "number") and numObjectives > 0) then
+		for objectiveIndex = 1, numObjectives do
+			local text, objectiveType, finished = GetQuestObjectiveInfo(questID, objectiveIndex, true);
+			if not finished then iscomplete = false end
+			tinsert(data.objectives, text);
+			data.objectiveType = objectiveType;
+		end
+	end
+
+	data.rewards = {};
+	if(not xp) then
+		xp = GetQuestLogRewardXP(questID);
+	end
+	if(xp > 0 and UnitLevel("player") < MAX_PLAYER_LEVEL) then
+		local t = {};
+		t.label = xp;
+		t.texture = "Interface\\Icons\\XP_Icon";
+		t.count = 0;
+		t.font = "NumberFontNormal";
+		tinsert(data.rewards, t);
+	end
+
+	local numCurrencies = GetNumQuestLogRewardCurrencies(questID);
+	for i = 1, numCurrencies do
+		local name, texture, count = GetQuestLogRewardCurrencyInfo(i, questID);
+		local t = {};
+		t.label = name;
+		t.texture = texture;
+		t.count = count;
+		t.font = "GameFontHighlightSmall";
+		tinsert(data.rewards, t);
+	end
+
+	local numItems = GetNumQuestLogRewards(questID);
+	for i = 1, numItems do
+		local name, texture, count, quality, isUsable = GetQuestLogRewardInfo(i, questID);
+		local t = {};
+		t.label = name;
+		t.texture = texture;
+		t.count = count;
+		t.font = "GameFontHighlightSmall";
+		tinsert(data.rewards, t);
+	end
+
+	if(not money) then
+		money = GetQuestLogRewardMoney(questID);
+	end
+	if(money > 0) then
+		local t = {};
+		t.label = GetMoneyString(money);
+		t.texture = "Interface\\Icons\\inv_misc_coin_01";
+		t.count = 0;
+		t.font = "GameFontHighlight";
+		tinsert(data.rewards, t);
+	end
+	CACHED_BONUS_DATA[questID] = data;
+
+	if(iscomplete or #data.rewards <= 0) then
+		CACHED_BONUS_DATA[questID] = nil;
+		COMPLETED_BONUS_DATA[questID] = true;
+		PlaySound("UI_Scenario_Stage_End");
+	end
+end
+
+local function GetBonusCache()
+	local cache = GetTasksTable();
+	for questID, data in pairs(CACHED_BONUS_DATA) do
+		if(questID > 0) then
+			local found = false;
+			for i = 1, #cache do
+				if(cache[i] == questID) then
+					found = true;
+					break;
+				end
+			end
+			if(not found) then
+				tinsert(cache, questID);
+			end
+		end
+	end
+	return cache;
+end
+
+local function GetCachedTaskInfo(questID)
+	if(CACHED_BONUS_DATA[questID]) then
+		return true, true, #CACHED_BONUS_DATA[questID].objectives;
+	else
+		return GetTaskInfo(questID);
+	end
+end
+
+local function GetCachedQuestObjectiveInfo(questID, objectiveIndex)
+	if(CACHED_BONUS_DATA[questID]) then
+		return CACHED_BONUS_DATA[questID].objectives[objectiveIndex], CACHED_BONUS_DATA[questID].objectiveType, true;
+	else
+		return GetQuestObjectiveInfo(questID, objectiveIndex, false);
+	end
+end
+
+local function GetScenarioBonusStep(index)
+	local cachedObjectives = C_Scenario.GetSupersededObjectives();
+	for i = 1, #cachedObjectives do
+		local pairs = cachedObjectives[i];
+		local k,v = unpack(pairs);
+		if(v == index) then
+			return k;
+		end
+	end
+end
+--[[
+##########################################################
+TRACKER FUNCTIONS
+##########################################################
+]]--
+local GetBonusRow = function(self, index)
+	if(not self.Rows[index]) then
+		local previousFrame = self.Rows[#self.Rows]
+		local index = #self.Rows + 1;
+		local yOffset = 0;
+
+		local row = CreateFrame("Frame", nil, self)
+		if(previousFrame and previousFrame.Objectives) then
+			row:SetPoint("TOPLEFT", previousFrame.Objectives, "BOTTOMLEFT", 0, -6);
+			row:SetPoint("TOPRIGHT", previousFrame.Objectives, "BOTTOMRIGHT", 0, -6);
+		else
+			row:SetPoint("TOPLEFT", self, "TOPLEFT", 0, 0);
+			row:SetPoint("TOPRIGHT", self, "TOPRIGHT", 0, 0);
+		end
+		row:SetHeight(ROW_HEIGHT);
+
+		row.Header = CreateFrame("Frame", nil, row)
+		row.Header:SetPoint("TOPLEFT", row, "TOPLEFT", 2, -2);
+		row.Header:SetPoint("TOPRIGHT", row, "TOPRIGHT", -2, -2);
+		row.Header:SetHeight(INNER_HEIGHT);
+
+		row.Header.Text = row.Header:CreateFontString(nil,"OVERLAY")
+		row.Header.Text:SetFontObject(SVUI_Font_Quest_Header);
+		row.Header.Text:SetJustifyH('LEFT')
+		row.Header.Text:SetTextColor(0.2,0.75,1)
+		row.Header.Text:SetText('')
+		row.Header.Text:SetPoint("TOPLEFT", row.Header, "TOPLEFT", 0, 0);
+		row.Header.Text:SetPoint("BOTTOMRIGHT", row.Header, "BOTTOMRIGHT", 0, 0);
+
+		row.Objectives = MOD.NewObjectiveHeader(row);
+		row.Objectives:SetPoint("TOPLEFT", row, "BOTTOMLEFT", 0, 0);
+		row.Objectives:SetPoint("TOPRIGHT", row, "BOTTOMRIGHT", 0, 0);
+		row.Objectives:SetHeight(1);
+
+		row.RowID = 0;
+
+		self.Rows[index] = row;
+
+		return row;
+	end
+
+	return self.Rows[index];
+end
+
+local SetCriteriaRow = function(self, index, bonusStepIndex, subCount, hasFailed)
+	index = index + 1
+	local objective_rows = 0;
+	local fill_height = 0;
+	local iscomplete = true;
+
+	local row = self:Get(index);
+	row.RowID = 0
+	row.Header.Text:SetText(TRACKER_HEADER_BONUS_OBJECTIVES)
+	row:SetHeight(ROW_HEIGHT);
+	row:SetAlpha(1);
+
+	local objective_block = row.Objectives;
+	objective_block:Reset()
+
+	for i = 1, subCount do
+		local text, category, completed, quantity, totalQuantity, flags, assetID, quantityString, criteriaID, duration, elapsed, failed = C_Scenario.GetCriteriaInfoByStep(bonusStepIndex, i);
+		if(text and text ~= '') then
+			if not completed then iscomplete = false end
+			objective_rows = objective_block:SetInfo(objective_rows, text, completed, failed);
+			fill_height = fill_height + (INNER_HEIGHT + 2);
+			if(duration > 0 and elapsed <= duration and not (failed or completed)) then
+				objective_rows = objective_block:SetTimer(objective_rows, duration, elapsed);
+				fill_height = fill_height + (INNER_HEIGHT + 2);
+			end
+		end
+	end
+
+	if(hasFailed) then
+		row.Header.Text:SetTextColor(1,0,0)
+	elseif(iscomplete) then
+		row.Header.Text:SetTextColor(0.1,0.9,0.1)
+	else
+		row.Header.Text:SetTextColor(1,1,1)
+	end
+
+	if(objective_rows > 0) then
+		objective_block:SetHeight(fill_height);
+	end
+
+	fill_height = fill_height + (ROW_HEIGHT + 2);
+
+	return index, fill_height;
+end
+
+local SetBonusRow = function(self, index, questID, subCount)
+	index = index + 1
+	local objective_rows = 0;
+	local fill_height = 0;
+	local iscomplete = true;
+	local row = self:Get(index);
+	local objective_block = row.Objectives;
+
+	for i = 1, subCount do
+		local text, category, objective_completed = GetCachedQuestObjectiveInfo(questID, i);
+		if not objective_completed then iscomplete = false end
+		if(text and text ~= '') then
+			objective_rows = objective_block:SetInfo(objective_rows, text, objective_completed);
+			fill_height = fill_height + (INNER_HEIGHT + 2);
+		end
+		if(category and category == 'progressbar') then
+			objective_rows = objective_block:SetProgress(objective_rows, questID, objective_completed);
+			fill_height = fill_height + (INNER_HEIGHT + 2);
+		end
+	end
+
+	if(not iscomplete) then
+		row.RowID = questID
+		row.Header.Text:SetText(TRACKER_HEADER_BONUS_OBJECTIVES)
+		row:SetHeight(ROW_HEIGHT);
+		row:FadeIn();
+
+		if(objective_rows > 0) then
+			objective_block:SetHeight(fill_height);
+		end
+
+		fill_height = fill_height + (ROW_HEIGHT + 2);
+
+		return index, fill_height;
+	else
+		CACHED_BONUS_DATA[questID] = nil;
+		COMPLETED_BONUS_DATA[questID] = true;
+		PlaySoundKitID(45142);
+		return index, 0;
+	end
+end
+
+local UpdateBonusObjectives = function(self)
+	local fill_height = 0;
+	local rows = 0;
+
+	if(C_Scenario.IsInScenario()) then
+		local tblBonusSteps = C_Scenario.GetBonusSteps();
+		local cachedToRemove = {};
+		for i = 1, #tblBonusSteps do
+			local bonusStepIndex = tblBonusSteps[i];
+			local cachedIndex = GetScenarioBonusStep(bonusStepIndex);
+			if(cachedIndex) then
+				local name, description, numCriteria, stepFailed, isBonusStep, isForCurrentStepOnly = C_Scenario.GetStepInfo(bonusStepIndex);
+				local completed = true;
+				for criteriaIndex = 1, numCriteria do
+					local criteriaString, criteriaType, criteriaCompleted, quantity, totalQuantity, flags, assetID, quantityString, criteriaID, duration, elapsed, criteriaFailed = C_Scenario.GetCriteriaInfoByStep(bonusStepIndex, criteriaIndex);
+					if(criteriaString) then
+						if(not criteriaCompleted) then
+							completed = false;
+							break;
+						end
+					end
+				end
+				if(not completed) then
+					tinsert(cachedToRemove, cachedIndex);
+				end
+			end
+		end
+		for i = 1, #cachedToRemove do
+			tDeleteItem(tblBonusSteps, cachedToRemove[i]);
+		end
+
+		for i = 1, #tblBonusSteps do
+			local bonusStepIndex = tblBonusSteps[i];
+			local name, description, numCriteria, stepFailed, isBonusStep, isForCurrentStepOnly = C_Scenario.GetStepInfo(bonusStepIndex);
+			local add_height = 0;
+			rows, add_height = self:SetCriteria(rows, bonusStepIndex, numCriteria, stepFailed)
+			fill_height = fill_height + add_height;
+		end
+	else
+		local cache = GetBonusCache();
+		for i = 1, #cache do
+			local questID = cache[i];
+			local completedData = COMPLETED_BONUS_DATA[questID];
+			if(not completedData) then
+				local existingTask = CACHED_BONUS_DATA[questID];
+				local isInArea, isOnMap, numObjectives = GetCachedTaskInfo(questID);
+				if(isInArea or (isOnMap and existingTask)) then
+					local add_height = 0;
+					rows, add_height = self:SetBonus(rows, questID, numObjectives)
+					fill_height = fill_height + add_height;
+				end
+			end
+		end
+	end
+
+	if(rows == 0 or (fill_height <= 1)) then
+		self:SetHeight(1);
+		self:SetAlpha(0);
+		self:Reset();
+	else
+		self:SetHeight(fill_height + 2);
+		self:FadeIn();
+	end
+end
+
+local RefreshBonusObjectives = function(self, event, ...)
+	-- print('BONUS-------->')
+	-- print(event)
+	-- print(...)
+	if(event == "CRITERIA_COMPLETE") then
+		local id = ...;
+		if(id > 0) then
+			local tblBonusSteps = C_Scenario.GetBonusSteps();
+			for i = 1, #tblBonusSteps do
+				local bonusStepIndex = tblBonusSteps[i];
+				local _, _, numCriteria = C_Scenario.GetStepInfo(bonusStepIndex);
+				for criteriaIndex = 1, numCriteria do
+					local _, _, _, _, _, _, _, _, criteriaID = C_Scenario.GetCriteriaInfoByStep(bonusStepIndex, criteriaIndex);
+					if(id == criteriaID) then
+						local questID = C_Scenario.GetBonusStepRewardQuestID(bonusStepIndex);
+						if(questID ~= 0) then
+							CacheBonusData(questID);
+							return;
+						end
+					end
+				end
+			end
+		end
+	end
+	self:UpdateAll();
+end
+
+local ResetBonusBlock = function(self)
+	for x = 1, #self.Rows do
+		local row = self.Rows[x]
+		if(row) then
+			row.RowID = 0;
+			row.Header.Text:SetText('');
+			row:SetHeight(1);
+			row:SetAlpha(0);
+			row.Objectives:Reset();
+		end
+	end
+end
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+function MOD:UpdateBonusObjective(event, ...)
+	self.Headers["Bonus"]:Reset()
+	self.Headers["Bonus"]:Refresh(event, ...)
+	self:UpdateDimensions();
+end
+
+function MOD:CacheBonusObjective(event, ...)
+	CacheBonusData(...)
+end
+
+local function UpdateBonusLocals(...)
+	ROW_WIDTH, ROW_HEIGHT, INNER_HEIGHT, LARGE_ROW_HEIGHT, LARGE_INNER_HEIGHT = ...;
+end
+
+function MOD:InitializeBonuses()
+	local scrollChild = self.Docklet.ScrollFrame.ScrollChild;
+	local bonus = CreateFrame("Frame", nil, scrollChild)
+	bonus:SetWidth(ROW_WIDTH);
+	bonus:SetHeight(1);
+	bonus:SetPoint("TOPLEFT", self.Headers["Scenario"], "BOTTOMLEFT", 0, -4);
+
+	bonus.Rows = {};
+
+	bonus.Get = GetBonusRow;
+	bonus.SetBonus = SetBonusRow;
+	bonus.SetCriteria = SetCriteriaRow;
+	bonus.Refresh = RefreshBonusObjectives;
+	bonus.Reset = ResetBonusBlock;
+	bonus.UpdateAll = UpdateBonusObjectives;
+
+	self.Headers["Bonus"] = bonus
+
+	self:RegisterEvent("CRITERIA_COMPLETE", self.UpdateBonusObjective);
+	SV.Events:On("QUEST_UPVALUES_UPDATED", UpdateBonusLocals, true);
+end
diff --git a/SVUI_QuestTracker/components/button.lua b/SVUI_QuestTracker/components/button.lua
new file mode 100644
index 0000000..abd021b
--- /dev/null
+++ b/SVUI_QuestTracker/components/button.lua
@@ -0,0 +1,146 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+
+QUEST TRACKER BUTTON:
+
+Originally "ExtraQuestButton" by p3lim,
+modified/minimally re-written for SVUI by Failcoder
+
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack    = _G.unpack;
+local select    = _G.select;
+local pairs     = _G.pairs;
+local ipairs    = _G.ipairs;
+local type      = _G.type;
+local error     = _G.error;
+local pcall     = _G.pcall;
+local tostring  = _G.tostring;
+local tonumber  = _G.tonumber;
+local tinsert 	= _G.tinsert;
+local string 	= _G.string;
+local math 		= _G.math;
+local table 	= _G.table;
+--[[ STRING METHODS ]]--
+local format = string.format;
+--[[ MATH METHODS ]]--
+local abs, ceil, floor, round = math.abs, math.ceil, math.floor, math.round;
+--[[ TABLE METHODS ]]--
+local tremove, twipe = table.remove, table.wipe;
+
+local C_Timer 				= _G.C_Timer;
+local GetNumQuestWatches  	= _G.GetNumQuestWatches;
+local GetQuestWatchInfo  	= _G.GetQuestWatchInfo;
+local QuestHasPOIInfo  	= _G.QuestHasPOIInfo;
+local GetQuestLogSpecialItemInfo  	= _G.GetQuestLogSpecialItemInfo;
+local GetCurrentMapAreaID  	= _G.GetCurrentMapAreaID;
+local GetDistanceSqToQuest  	= _G.GetDistanceSqToQuest;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local MOD = SV.QuestTracker;
+--[[
+##########################################################
+LOCALS
+##########################################################
+]]--
+local QuestInZone = {
+	[14108] = 541,
+	[13998] = 11,
+	[25798] = 61,
+	[25799] = 61,
+	[25112] = 161,
+	[25111] = 161,
+	[24735] = 201,
+};
+--[[
+##########################################################
+BUTTON INTERNALS
+##########################################################
+]]--
+local ticker;
+local UpdateButton = function(self)
+	local numItems = 0
+	local shortestDistance = 62500
+	local closestQuestLink, closestQuestTexture
+	local activeQuestLink, activeQuestTexture
+
+	for index = 1, GetNumQuestWatches() do
+		local questID, _, questIndex, _, _, isComplete = GetQuestWatchInfo(index)
+		if(questID and QuestHasPOIInfo(questID)) then
+			local link, texture, _, showCompleted = GetQuestLogSpecialItemInfo(questIndex)
+			if(link) then
+				local areaID = QuestInZone[questID]
+				if questIndex == MOD.CurrentQuest then
+					activeQuestLink = link
+					activeQuestTexture = texture
+				end
+				if(areaID and areaID == GetCurrentMapAreaID()) then
+					closestQuestLink = link
+					closestQuestTexture = texture
+				elseif(not isComplete or (isComplete and showCompleted)) then
+					local distanceSq, onContinent = GetDistanceSqToQuest(questIndex)
+					if(onContinent and distanceSq < shortestDistance) then
+						shortestDistance = distanceSq
+						closestQuestLink = link
+						closestQuestTexture = texture
+					end
+				end
+
+				numItems = numItems + 1
+			end
+		end
+	end
+
+	if(closestQuestLink) then
+		self:SetUsage(closestQuestLink, closestQuestTexture);
+	elseif(activeQuestLink) then
+		self:SetUsage(activeQuestLink, activeQuestTexture);
+	end
+
+	if(numItems > 0 and not ticker) then
+		ticker = C_Timer.NewTicker(30, function()
+			self:Update()
+		end)
+	elseif(numItems == 0 and ticker) then
+		ticker:Cancel()
+		ticker = nil
+	end
+end
+--[[
+##########################################################
+PACKAGE CALL
+##########################################################
+]]--
+function MOD:InitializeQuestItem()
+	SVUI_QuestItemBar:SetParent(SV.Screen)
+	SVUI_QuestItemBar:SetPoint("BOTTOM", SV.Screen, "BOTTOM", 0, 250)
+	SVUI_QuestItemBar:SetSize(40,40)
+
+	SV:NewAnchor(SVUI_QuestItemBar, L["Quest Item Button"])
+
+	local questitem = SV:CreateSecureButton("item", "SVUI_QuestItemBar", "SVUI_QuestAutoItemButton", UpdateButton);
+	questitem.ArtFile = MOD.media.buttonArt;
+	questitem.blacklist[113191] = true
+	questitem.blacklist[110799] = true
+	questitem.blacklist[109164] = true
+	questitem:RegisterEvent('UPDATE_EXTRA_ACTIONBAR')
+	questitem:RegisterEvent('BAG_UPDATE_COOLDOWN')
+	questitem:RegisterEvent('BAG_UPDATE_DELAYED')
+	questitem:RegisterEvent('WORLD_MAP_UPDATE')
+	questitem:RegisterEvent('QUEST_LOG_UPDATE')
+	questitem:RegisterEvent('QUEST_POI_UPDATE')
+
+	self.QuestItem = questitem
+end
\ No newline at end of file
diff --git a/SVUI_QuestTracker/components/popups.lua b/SVUI_QuestTracker/components/popups.lua
new file mode 100644
index 0000000..826ce86
--- /dev/null
+++ b/SVUI_QuestTracker/components/popups.lua
@@ -0,0 +1,230 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack    = _G.unpack;
+local select    = _G.select;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local MOD = SV.QuestTracker;
+--[[
+##########################################################
+LOCALS
+##########################################################
+]]--
+local ROW_WIDTH = 300;
+local ROW_HEIGHT = 24;
+local INNER_HEIGHT = ROW_HEIGHT - 4;
+local LARGE_ROW_HEIGHT = ROW_HEIGHT * 2;
+local LARGE_INNER_HEIGHT = LARGE_ROW_HEIGHT - 4;
+--[[
+##########################################################
+SCRIPT HANDLERS
+##########################################################
+]]--
+local PopUpButton_OnClick = function(self)
+	local questIndex = self:GetID();
+	if(questIndex and (questIndex ~= 0) and self.PopUpType) then
+		local questID = select(8, GetQuestLogTitle(questIndex));
+		if(self.PopUpType == "OFFER") then
+			ShowQuestOffer(questIndex);
+		else
+			ShowQuestComplete(questIndex);
+		end
+		MOD.Headers["Popups"]:RemovePopup(questID)
+	end
+end
+--[[
+##########################################################
+TRACKER FUNCTIONS
+##########################################################
+]]--
+local GetPopUpRow = function(self, index)
+	if(not self.Rows[index]) then
+		local previousFrame = self.Rows[#self.Rows]
+		index = #self.Rows + 1;
+		local row = CreateFrame("Frame", nil, self)
+		if(previousFrame) then
+			row:SetPoint("TOPLEFT", previousFrame, "BOTTOMLEFT", 0, -2);
+			row:SetPoint("TOPRIGHT", previousFrame, "BOTTOMRIGHT", 0, -2);
+		else
+			row:SetPoint("TOPLEFT", self, "TOPLEFT", 0, -2);
+			row:SetPoint("TOPRIGHT", self, "TOPRIGHT", 0, -2);
+		end
+		row:SetHeight(LARGE_ROW_HEIGHT);
+		row.Button = CreateFrame("Button", nil, row)
+		row.Button:SetPoint("TOPLEFT", row, "TOPLEFT", 0, 0);
+		row.Button:SetPoint("BOTTOMRIGHT", row, "BOTTOMRIGHT", 0, 0);
+		row.Button:SetStyle("Button")
+		row.Button:SetPanelColor('yellow')
+		row.Button:SetID(0)
+		row.Button.PopUpType = nil;
+		row.Button:SetScript("OnClick", PopUpButton_OnClick)
+		row.Badge = CreateFrame("Frame", nil, row.Button)
+		row.Badge:SetPoint("TOPLEFT", row.Button, "TOPLEFT", 4, -4);
+		row.Badge:SetSize((LARGE_INNER_HEIGHT - 4), (LARGE_INNER_HEIGHT - 4));
+		row.Badge:SetStyle("!_Frame", "Icon")
+		row.Badge.Icon = row.Badge:CreateTexture(nil,"OVERLAY")
+		row.Badge.Icon:InsetPoints(row.Badge);
+		row.Badge.Icon:SetTexture(MOD.media.incompleteIcon)
+		row.Badge.Icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+		row.Header = CreateFrame("Frame", nil, row.Button)
+		row.Header:SetPoint("TOPLEFT", row.Badge, "TOPRIGHT", 4, -1);
+		row.Header:SetPoint("BOTTOMRIGHT", row.Button, "BOTTOMRIGHT", -5, 5);
+		row.Header:SetStyle("Frame")
+		row.Header.Text = row.Header:CreateFontString(nil,"OVERLAY")
+		row.Header.Text:SetFontObject(SVUI_Font_Quest);
+		row.Header.Text:SetJustifyH('LEFT')
+		row.Header.Text:SetTextColor(1,1,0)
+		row.Header.Text:SetText('')
+		row.Header.Text:SetPoint("TOPLEFT", row.Header, "TOPLEFT", 0, 0);
+		row.Header.Text:SetPoint("BOTTOMRIGHT", row.Header, "BOTTOMRIGHT", 0, 0);
+		row.RowID = 0;
+		self.Rows[index] = row;
+		return row;
+	end
+
+	return self.Rows[index];
+end
+
+local SetPopupRow = function(self, index, title, popUpType, questID, questLogIndex)
+	index = index + 1;
+	local icon = (popUpType == 'COMPLETED') and MOD.media.completeIcon or MOD.media.incompleteIcon
+	local row = self:GetPopup(index);
+	row.RowID = questID
+	row.Header:SetAlpha(1);
+	row.Header.Text:SetText(title)
+	row.Badge.Icon:SetTexture(icon);
+	row.Badge:SetAlpha(1);
+	row.Button:Enable();
+	row.Button.PopUpType = popUpType;
+	row.Button:SetID(questLogIndex);
+	row:SetHeight(LARGE_ROW_HEIGHT);
+	row:FadeIn();
+
+	local fill_height = LARGE_ROW_HEIGHT + 6;
+
+	return index, fill_height;
+end
+
+local RefreshPopupObjective = function(self)
+	local rows = 0;
+	local add_height;
+	local fill_height = 0;
+	for i = 1, GetNumAutoQuestPopUps() do
+		local questID, popUpType = GetAutoQuestPopUp(i);
+		if(questID) then
+			local questLogIndex = GetQuestLogIndexByID(questID);
+			local title = GetQuestLogTitle(questLogIndex);
+			if(title and title ~= '') then
+				rows, add_height = self:SetPopup(rows, title, popUpType, questID, questLogIndex);
+				add_height = add_height or 0;
+				fill_height = fill_height + add_height
+			end
+		end
+	end
+
+	if(rows == 0 or (fill_height <= 1)) then
+		self.CurrentHeight = 1;
+		self:SetAlpha(0);
+	else
+		self.CurrentHeight = (fill_height + 2);
+		self:FadeIn();
+	end
+end
+
+local ResetPopupBlock = function(self)
+	for x = 1, #self.Rows do
+		local row = self.Rows[x]
+		if(row) then
+			row.RowID = 0;
+			row.Header.Text:SetText('');
+			row.Header:SetAlpha(0);
+			row.Button:SetID(0);
+			row.Button:Disable();
+			row.Badge:SetAlpha(0);
+			row.Badge.Icon:SetTexture("");
+			row:SetHeight(1);
+			row:SetAlpha(0);
+		end
+	end
+end
+
+local AddAutoPopUp = function(self, questID, popUpType, noCheck)
+	local checkPassed = true;
+	if(not noCheck) then
+		checkPassed = AddAutoQuestPopUp(questID, popUpType)
+	end
+	if(checkPassed) then
+		self:Reset()
+		self:Refresh();
+		MOD:UpdateDimensions();
+		PlaySound("UI_AutoQuestComplete")
+		self:SetHeight(self.CurrentHeight)
+	end
+end
+
+local RemoveAutoPopUp = function(self, questID, noRemove)
+	if(not noRemove) then
+		RemoveAutoQuestPopUp(questID);
+	end
+	self:Reset();
+	self:Refresh();
+	self:SetHeight(1);
+	MOD:UpdateDimensions();
+end
+
+local _hook_AddAutoPopUpQuests = function(questID, popUpType)
+	MOD.Headers["Popups"]:AddPopup(questID, popUpType, true)
+end
+
+local _hook_RemoveAutoPopUpQuests = function(questID)
+	MOD.Headers["Popups"]:RemovePopup(questID, true)
+end
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+
+function MOD:UpdatePopupQuests(event, ...)
+	local questID = ...;
+	self.Headers["Popups"]:AddPopup(questID, "COMPLETE");
+end
+
+local function UpdatePopupLocals(...)
+	ROW_WIDTH, ROW_HEIGHT, INNER_HEIGHT, LARGE_ROW_HEIGHT, LARGE_INNER_HEIGHT = ...;
+end
+
+function MOD:InitializePopups()
+	local popups = CreateFrame("Frame", nil, self.Docklet)
+	popups:SetPoint("BOTTOMLEFT", self.Docklet, "TOPLEFT");
+    popups:SetPoint("BOTTOMRIGHT", self.Docklet, "TOPRIGHT");
+    popups:SetHeight(1);
+	popups.Rows = {};
+
+	popups.GetPopup = GetPopUpRow;
+	popups.SetPopup = SetPopupRow;
+	popups.AddPopup = AddAutoPopUp;
+	popups.RemovePopup = RemoveAutoPopUp;
+	popups.Reset = ResetPopupBlock;
+	popups.Refresh = RefreshPopupObjective;
+
+	self.Headers["Popups"] = popups;
+
+	self:RegisterEvent("QUEST_AUTOCOMPLETE", self.UpdatePopupQuests);
+
+	hooksecurefunc("AutoQuestPopupTracker_AddPopUp", _hook_AddAutoPopUpQuests);
+	hooksecurefunc("AutoQuestPopupTracker_RemovePopUp", _hook_RemoveAutoPopUpQuests);
+
+	SV.Events:On("QUEST_UPVALUES_UPDATED", UpdatePopupLocals, true);
+end
diff --git a/SVUI_QuestTracker/components/quests.lua b/SVUI_QuestTracker/components/quests.lua
new file mode 100644
index 0000000..cda99a6
--- /dev/null
+++ b/SVUI_QuestTracker/components/quests.lua
@@ -0,0 +1,1277 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack    = _G.unpack;
+local select    = _G.select;
+local pairs     = _G.pairs;
+local ipairs    = _G.ipairs;
+local type      = _G.type;
+local error     = _G.error;
+local pcall     = _G.pcall;
+local tostring  = _G.tostring;
+local tonumber  = _G.tonumber;
+local tinsert 	= _G.tinsert;
+local string 	= _G.string;
+local math 		= _G.math;
+local table 	= _G.table;
+local tinsert   = _G.tinsert;
+local tremove   = _G.tremove;
+local wipe      = _G.wipe;
+--[[ STRING METHODS ]]--
+local format = string.format;
+--[[ MATH METHODS ]]--
+local abs, ceil, floor, round, maxNum = math.abs, math.ceil, math.floor, math.round, math.max;
+--[[ TABLE METHODS ]]--
+local tsort, tcopy = table.sort, table.copy;
+--BLIZZARD API
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+local GameTooltip           = _G.GameTooltip;
+local hooksecurefunc        = _G.hooksecurefunc;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local MOD = SV.QuestTracker;
+--[[
+##########################################################
+LOCALS
+##########################################################
+]]--
+local ITEM_BUTTON_SIZE = 28;
+local ITEMS_PER_ROW = 5;
+local ROW_WIDTH = 300;
+local ROW_HEIGHT = 20;
+local QUEST_ROW_HEIGHT = ROW_HEIGHT + 2;
+local INNER_HEIGHT = ROW_HEIGHT - 4;
+local LARGE_ROW_HEIGHT = ROW_HEIGHT * 2;
+local LARGE_INNER_HEIGHT = LARGE_ROW_HEIGHT - 4;
+local OBJ_ICON_ACTIVE = [[Interface\COMMON\Indicator-Yellow]];
+local OBJ_ICON_COMPLETE = [[Interface\COMMON\Indicator-Green]];
+local OBJ_ICON_INCOMPLETE = [[Interface\COMMON\Indicator-Gray]];
+
+local CACHED_QUESTS = {};
+local QUESTS_BY_LOCATION = {};
+local QUEST_HEADER_MAP = {};
+local USED_QUESTIDS = {};
+local TICKERS, ACTIVE_ITEMS, SWAP_ITEMS = {}, {}, {};
+local CURRENT_MAP_ID = 0;
+local WORLDMAP_UPDATE = false;
+
+local DEFAULT_COLOR = {r = 1, g = 0.68, b = 0.1}
+
+local QuestInZone = {
+	[14108] = 541,
+	[13998] = 11,
+	[25798] = 61,
+	[25799] = 61,
+	[25112] = 161,
+	[25111] = 161,
+	[24735] = 201,
+};
+local ItemBlacklist = {
+	[113191] = true,
+	[110799] = true,
+	[109164] = true,
+};
+--[[
+##########################################################
+ITEM BAR/BUTTON CONSTRUCT
+##########################################################
+]]--
+local ItemBar = _G["SVUI_QuestItemBar"];
+ItemBar.Buttons = {};
+
+local ItemBar_OnEvent = function(self, event)
+    if(event == 'PLAYER_REGEN_ENABLED' and self.needsUpdate) then
+        self:Update()
+        self:UnregisterEvent("PLAYER_REGEN_ENABLED")
+    end
+end
+ItemBar:SetScript('OnEvent', ItemBar_OnEvent);
+
+local CreateQuestItemButton;
+do
+    --[[ HANDLERS ]]--
+
+    local Button_UpdateCooldown = function(self)
+        if(self:IsShown() and self.itemID) then
+            local start, duration, enable = GetItemCooldown(self.itemID)
+            if((start and start > 0) and (duration and duration > 0)) then
+                self.Cooldown:SetCooldown(start, duration)
+                self.Cooldown:Show()
+            else
+                self.Cooldown:Hide()
+            end
+        end
+    end
+
+    local Button_OnEnter = function(self)
+			if(self.itemID and (not MOD.DOCK_IS_FADED)) then
+          GameTooltip:SetOwner(self, 'ANCHOR_LEFT')
+          GameTooltip:SetHyperlink(self.itemLink)
+      end
+    end
+
+    local Button_OnLeave = function(self)
+    	GameTooltip_Hide()
+    end
+
+    local Button_OnEvent = function(self, event)
+        if(event == 'BAG_UPDATE_COOLDOWN') then
+            self:UpdateCooldown()
+        elseif(event == 'PLAYER_REGEN_ENABLED') then
+            self:SetAttribute('item', self.attribute)
+            self:UnregisterEvent(event)
+            self:UpdateCooldown()
+        --else
+            --self:Update()
+        end
+    end
+
+    local Button_SetItem = function(self, itemLink, texture, completed)
+	    	if(completed) then self:ClearUsage() return end
+        if(itemLink) then
+            if(ACTIVE_ITEMS[itemLink] or ((itemLink == self.itemLink) and self:IsShown())) then
+                return
+            end
+            ACTIVE_ITEMS[itemLink] = self:GetID();
+            self.Icon:SetTexture(texture)
+            self.itemID, self.itemName = string.match(itemLink, '|Hitem:(.-):.-|h%[(.+)%]|h')
+            self.itemLink = itemLink
+
+            if(ItemBlacklist[self.itemID]) then
+                return
+            end
+            self:FadeIn()
+        end
+
+        if(InCombatLockdown()) then
+			self.attribute = self.itemName
+            self:RegisterEvent('PLAYER_REGEN_ENABLED')
+        else
+            self:SetAttribute('item', self.itemName)
+            self:UpdateCooldown()
+        end
+
+        return true
+    end
+
+    local Button_ClearItem = function(self)
+		self.attribute = nil;
+        if(InCombatLockdown()) then
+            self:RegisterEvent('PLAYER_REGEN_ENABLED');
+        else
+            self:SetAttribute('item', nil)
+        end
+    end
+
+    local Button_UpdateItem = function(self)
+		local numItems = 0
+		local shortestDistance = 62500
+		local closestQuestLink, closestQuestTexture
+		local activeQuestLink, activeQuestTexture
+
+		for index = 1, GetNumQuestWatches() do
+			local questID, _, questIndex, _, _, isComplete = GetQuestWatchInfo(index)
+			if(questID and QuestHasPOIInfo(questID)) then
+				local link, texture, _, showCompleted = GetQuestLogSpecialItemInfo(questIndex)
+				if(link) then
+					local areaID = QuestInZone[questID]
+					if questIndex == MOD.CurrentQuest then
+						activeQuestLink = link
+						activeQuestTexture = texture
+					end
+					if(areaID and areaID == GetCurrentMapAreaID()) then
+						closestQuestLink = link
+						closestQuestTexture = texture
+					elseif(not isComplete or (isComplete and showCompleted)) then
+						local distanceSq, onContinent = GetDistanceSqToQuest(questIndex)
+						if(onContinent and distanceSq < shortestDistance) then
+							shortestDistance = distanceSq
+							closestQuestLink = link
+							closestQuestTexture = texture
+						end
+					end
+
+					numItems = numItems + 1
+				end
+			end
+		end
+
+		if(closestQuestLink) then
+			self:SetUsage(closestQuestLink, closestQuestTexture);
+		elseif(activeQuestLink) then
+			self:SetUsage(activeQuestLink, activeQuestTexture);
+		end
+
+		local name = self:GetName();
+		if(numItems > 0 and not TICKERS[name]) then
+			TICKERS[name] = C_Timer.NewTicker(30, function()
+				self:Update()
+			end)
+		elseif(numItems == 0 and TICKERS[name]) then
+			TICKERS[name]:Cancel()
+			TICKERS[name] = nil
+		end
+	end
+
+    --[[ METHOD ]]--
+
+    CreateQuestItemButton = function(index)
+    	local buttonName = "SVUI_QuestButton" .. index
+		local itembutton = CreateFrame('Button', buttonName, UIParent, 'SecureActionButtonTemplate, SecureHandlerStateTemplate, SecureHandlerAttributeTemplate');
+		itembutton:SetAlpha(0);
+		itembutton:SetStyle("!_ActionSlot");
+			--itembutton:SetBackdropBorderColor(0.1, 0.1, 0.1)
+		itembutton:SetSize(ITEM_BUTTON_SIZE, ITEM_BUTTON_SIZE);
+		itembutton:SetID(index);
+		itembutton.___overflow = false;
+		itembutton.SetUsage = Button_SetItem;
+		itembutton.ClearUsage = Button_ClearItem;
+		itembutton.Update = Button_UpdateItem;
+		itembutton.UpdateCooldown = Button_UpdateCooldown;
+
+		local Icon = itembutton:CreateTexture('$parentIcon', 'BACKGROUND')
+		Icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+		Icon:SetAllPoints()
+		itembutton.Icon = Icon
+
+		local Cooldown = CreateFrame('Cooldown', '$parentCooldown', itembutton, 'CooldownFrameTemplate')
+		Cooldown:ClearAllPoints()
+		Cooldown:SetPoint('TOPRIGHT', -2, -3)
+		Cooldown:SetPoint('BOTTOMLEFT', 2, 1)
+		Cooldown:Hide()
+		itembutton.Cooldown = Cooldown
+
+		--RegisterStateDriver(itembutton, 'visible', '[petbattle] hide; show')
+		itembutton:SetAttribute('type', 'item');
+		itembutton:SetAttribute('_onattributechanged', [[
+		  if(name == 'item') then
+		      if(value and not self:IsShown()) then
+		          self:Show()
+		          self:SetAlpha(1)
+		      elseif(not value) then
+		      	self:SetAlpha(0)
+		          self:Hide()
+		      end
+		  end
+		]]);
+
+		itembutton:SetScript('OnEnter', Button_OnEnter);
+		itembutton:SetScript('OnLeave', Button_OnLeave);
+		itembutton:SetScript('OnEvent', Button_OnEvent);
+
+		itembutton:RegisterEvent('UPDATE_EXTRA_ACTIONBAR');
+		itembutton:RegisterEvent('BAG_UPDATE_COOLDOWN');
+		itembutton:RegisterEvent('BAG_UPDATE_DELAYED');
+		itembutton:RegisterEvent('WORLD_MAP_UPDATE');
+		itembutton:RegisterEvent('QUEST_LOG_UPDATE');
+		itembutton:RegisterEvent('QUEST_POI_UPDATE');
+
+		SV:ManageVisibility(itembutton)
+
+		return itembutton
+    end
+
+    function ItemBar:SetQuestItem(itemLink, texture, completed)
+    	if(not itemLink) then return end
+    	local savedIndex = ACTIVE_ITEMS[itemLink]
+    	if(savedIndex and self.Buttons[savedIndex]) then
+    		self.Buttons[savedIndex]:SetUsage(itemLink, texture, completed)
+    	else
+			local maxIndex = #self.Buttons;
+			for i = 1, maxIndex do
+				if(not self.Buttons[i]:GetAttribute('item')) then
+		    		self.Buttons[i]:SetUsage(itemLink, texture, completed)
+		    		return
+		    	end
+			end
+
+			local index = maxIndex + 1
+			self.Buttons[index] = CreateQuestItemButton(index)
+			self.Buttons[index]:SetUsage(itemLink, texture, completed)
+		end
+	end
+end
+
+function ItemBar:Reset()
+	local maxIndex = #self.Buttons;
+	for i = 1, maxIndex do
+		local button = self.Buttons[i];
+		button:ClearUsage();
+	end
+end
+
+local function HideItemBarButtons()
+	local maxIndex = #ItemBar.Buttons;
+	for i = 1, maxIndex do
+		local button = ItemBar.Buttons[i];
+		button:FadeOut(0.1, 1, 0, true);
+	end
+	ItemBar:FadeOut(0.1, 1, 0, true);
+end
+
+local function ShowItemBarButtons()
+	ItemBar:FadeIn();
+	local maxIndex = #ItemBar.Buttons;
+	for link, index in pairs(ACTIVE_ITEMS) do
+		local button = ItemBar.Buttons[index];
+		button:FadeIn();
+	end
+	MOD.Headers["Quests"]:Reset();
+	MOD.Headers["Quests"]:Refresh();
+end
+
+function ItemBar:Update()
+	if(InCombatLockdown()) then
+		self:RegisterEvent("PLAYER_REGEN_ENABLED")
+		self.needsUpdate = true
+		return
+	end
+	wipe(ACTIVE_ITEMS);
+	local maxIndex = #self.Buttons;
+	local firstButton = self.Buttons[1];
+	local itemLink = firstButton.itemLink;
+
+	if(itemLink) then
+		ACTIVE_ITEMS[itemLink] = 1
+	end
+
+	local dockletLocation = MOD.Docklet.Parent.Bar.Data.Location;
+	local isHorizontal = (SV.db.QuestTracker.itemBarDirection == 'HORIZONTAL');
+	local anchor1 = isHorizontal and "LEFT" or "TOP";
+	local anchor2 = isHorizontal and "RIGHT" or "BOTTOM";
+	local switch1 = isHorizontal and "BOTTOM" or "RIGHT";
+	local switch2 = isHorizontal and "TOP" or "LEFT";
+	local xOff = isHorizontal and 2 or 0;
+	local yOff = isHorizontal and 0 or -2;
+	local xChange = isHorizontal and 0 or -2;
+	local yChange = isHorizontal and 2 or 0;
+
+	local itemScale = ITEM_BUTTON_SIZE + 2;
+	if(self.Grip and (not self.Grip:HasMoved())) then
+		local dockWidth,dockHeight = MOD.Docklet:GetSize()
+		ITEMS_PER_ROW = isHorizontal and (dockWidth / itemScale) or (dockHeight / itemScale);
+	end
+
+	firstButton:ClearAllPoints();
+	firstButton:SetSize(ITEM_BUTTON_SIZE, ITEM_BUTTON_SIZE);
+
+	if(dockletLocation:find('Left')) then
+		anchor1 = isHorizontal and "RIGHT" or "TOP";
+		anchor2 = isHorizontal and "LEFT" or "BOTTOM";
+		switch1 = isHorizontal and "BOTTOM" or "LEFT";
+		switch2 = isHorizontal and "TOP" or "RIGHT";
+		xOff = isHorizontal and -2 or 0;
+		xChange = isHorizontal and 0 or 2;
+	end
+
+	if(dockletLocation:find('Top')) then
+		if(not isHorizontal) then
+			anchor1 = "BOTTOM";
+			anchor2 = "TOP";
+			yOff = 2;
+		else
+			switch1 = "TOP";
+			switch2 = "BOTTOM";
+			yChange = -2;
+		end
+	end
+
+	if(isHorizontal) then
+		firstButton:SetPoint(anchor1, self, anchor1, 0, 0);
+		if(SV.Tooltip and (not self.tipanchorchecked) and SV.Tooltip.Holder and SV.Tooltip.Holder.Grip and (not SV.Tooltip.Holder.Grip:HasMoved())) then
+			SV.Tooltip.DefaultPadding = 56
+			self.tipanchorchecked = true
+		end
+	else
+		firstButton:SetPoint(anchor2, self, anchor2, 0, 0);
+	end
+
+	local lastButton, totalShown, button = firstButton, 1;
+
+	for i = 2, maxIndex do
+		button = self.Buttons[i];
+		itemLink = button.itemLink;
+
+		button:ClearAllPoints();
+		button:SetSize(ITEM_BUTTON_SIZE, ITEM_BUTTON_SIZE);
+		if(button:IsShown()) then
+			totalShown = totalShown + 1;
+			if(totalShown == (ITEMS_PER_ROW + 1)) then
+				totalShown = 1;
+				local lastRowButton = self.Buttons[i - ITEMS_PER_ROW];
+				if(lastRowButton) then
+					button:SetPoint(switch1, lastRowButton, switch2, xChange, yChange)
+				else
+					button:SetPoint(switch1, firstButton, switch2, xChange, yChange)
+				end
+			else
+				button:SetPoint(anchor2, lastButton, anchor1, xOff, -yOff)
+			end
+			button:FadeIn();
+			lastButton = button
+
+			if(itemLink) then
+				ACTIVE_ITEMS[itemLink] = i
+			else
+				button:ClearUsage()
+			end
+		end
+	end
+
+	self.needsUpdate = nil
+end
+--[[
+##########################################################
+QUEST CACHING
+##########################################################
+]]--
+local function CacheQuestHeaders()
+	wipe(QUEST_HEADER_MAP)
+
+	local currentHeader = "Misc";
+	local numEntries, numQuests = GetNumQuestLogEntries();
+
+	for i = 1, numEntries do
+		local title, _, _, isHeader, _, _, _, questID = GetQuestLogTitle(i);
+		if(isHeader) then
+			currentHeader = title;
+		else
+			QUEST_HEADER_MAP[questID] = currentHeader
+		end
+	end
+end
+
+local function UpdateCachedQuests(needsSorting)
+	local s = 62500;
+	local c = 0;
+	local li = 0;
+	local HeadersCached = false;
+
+	wipe(QUESTS_BY_LOCATION)
+
+	for i = 1, GetNumQuestWatches() do
+		local questID, _, questLogIndex, numObjectives, _, completed, _, _, duration, elapsed, questType, isTask, isStory, isOnMap, hasLocalPOI = GetQuestWatchInfo(i);
+		if(questID) then  -- and (not USED_QUESTIDS[questID])
+			local distanceSq, onContinent = GetDistanceSqToQuest(questLogIndex)
+			local title, level, suggestedGroup, isHeader, isCollapsed, isComplete, frequency, questID, startEvent, displayQuestID, isOnMap, hasLocalPOI, isTask, isStory = GetQuestLogTitle(questLogIndex)
+			local link, texture, _, showCompleted = GetQuestLogSpecialItemInfo(questLogIndex)
+			if(not CACHED_QUESTS[questID]) then
+				CACHED_QUESTS[questID] = {i, title, level, texture, questID, questLogIndex, numObjectives, duration, elapsed, completed, questType, link};
+			else
+				CACHED_QUESTS[questID][1] = i;	            -- args: quest watch index
+				CACHED_QUESTS[questID][2] = title;	        -- args: quest title
+				CACHED_QUESTS[questID][3] = level;	        -- args: quest level
+				CACHED_QUESTS[questID][4] = texture;	    -- args: quest item icon
+				CACHED_QUESTS[questID][5] = questID;	    -- args: quest id
+				CACHED_QUESTS[questID][6] = questLogIndex;	-- args: quest log index
+				CACHED_QUESTS[questID][7] = numObjectives;	-- args: quest objective count
+				CACHED_QUESTS[questID][8] = duration;		-- args: quest timer duration
+				CACHED_QUESTS[questID][9] = elapsed;		-- args: quest timer elapsed
+				CACHED_QUESTS[questID][10] = completed;		-- args: quest is completed
+				CACHED_QUESTS[questID][11] = questType;	    -- args: quest type
+				CACHED_QUESTS[questID][12] = link;	        -- args: quest item link
+			end
+
+			if(questID == MOD.ActiveQuestID) then
+				MOD:UpdateActiveObjective('FORCED_UPDATE')
+			end
+
+			if(not QUEST_HEADER_MAP[questID] and (not HeadersCached)) then
+				CacheQuestHeaders()
+				HeadersCached = true
+			end
+
+			local header = QUEST_HEADER_MAP[questID] or "Misc"
+
+			tinsert(QUESTS_BY_LOCATION, {distanceSq, header, questID});
+		end
+	end
+
+	tsort(QUESTS_BY_LOCATION, function(a,b)
+		if(a[2] and b[2]) then
+			return a[2] < b[2]
+		else
+			return false
+		end
+	end);
+
+	tsort(QUESTS_BY_LOCATION, function(a,b)
+		if(a[1] and b[1]) then
+			return a[1] < b[1]
+		else
+			return false
+		end
+	end);
+end
+
+local function UpdateCachedDistance()
+	local s = 62500;
+	wipe(QUESTS_BY_LOCATION)
+	local HeadersCached = false;
+	for questID,questData in pairs(CACHED_QUESTS) do
+		local questLogIndex = questData[6];
+		local distanceSq, onContinent = GetDistanceSqToQuest(questLogIndex)
+		if(not QUEST_HEADER_MAP[questID] and (not HeadersCached)) then
+			CacheQuestHeaders()
+			HeadersCached = true
+		end
+		local header = QUEST_HEADER_MAP[questID] or "Misc"
+		tinsert(QUESTS_BY_LOCATION, {distanceSq, header, questID});
+	end
+
+	tsort(QUESTS_BY_LOCATION, function(a,b)
+		if(a[2] and b[2]) then
+			return a[2] < b[2]
+		else
+			return false
+		end
+	end);
+
+	tsort(QUESTS_BY_LOCATION, function(a,b)
+		if(a[1] and b[1]) then
+			return a[1] < b[1]
+		else
+			return false
+		end
+	end);
+end
+
+local function AddCachedQuest(questLogIndex)
+	local HeadersCached = false;
+	if(questLogIndex) then  -- and (not USED_QUESTIDS[questID])
+		local i = GetQuestWatchIndex(questLogIndex)
+		if(i) then
+			local distanceSq, onContinent = GetDistanceSqToQuest(questLogIndex)
+			local questID, _, _, numObjectives, _, completed, _, _, duration, elapsed, questType, isTask, isStory, isOnMap, hasLocalPOI = GetQuestWatchInfo(i);
+
+			if(not CACHED_QUESTS[questID]) then
+				local title, level, suggestedGroup = GetQuestLogTitle(questLogIndex)
+				local link, texture, _, showCompleted = GetQuestLogSpecialItemInfo(questLogIndex)
+				local mapID, floorNumber = 0,0
+				if(not WorldMapFrame:IsShown()) then
+					mapID, floorNumber = GetQuestWorldMapAreaID(questID)
+				else
+					WORLDMAP_UPDATE = true;
+				end
+
+				CACHED_QUESTS[questID] = {i, title, level, texture, questID, questLogIndex, numObjectives, duration, elapsed, completed, questType, link};
+
+				if(not QUEST_HEADER_MAP[questID] and (not HeadersCached)) then
+					CacheQuestHeaders()
+					HeadersCached = true
+				end
+				local header = QUEST_HEADER_MAP[questID] or "Misc"
+				tinsert(QUESTS_BY_LOCATION, {distanceSq, header, questID});
+
+				tsort(QUESTS_BY_LOCATION, function(a,b)
+					if(a[2] and b[2]) then
+						return a[2] < b[2]
+					else
+						return false
+					end
+				end);
+
+				tsort(QUESTS_BY_LOCATION, function(a,b)
+					if(a[1] and b[1]) then
+						return a[1] < b[1]
+					else
+						return false
+					end
+				end);
+			end
+
+			return questID;
+		end
+	end
+
+	return false;
+end
+--[[
+##########################################################
+SCRIPT HANDLERS
+##########################################################
+]]--
+local BadgeButton_OnEnter = function(self, ...)
+	if(MOD.DOCK_IS_FADED) then return end
+	GameTooltip:SetOwner(self, "ANCHOR_BOTTOMLEFT", 0, ROW_HEIGHT)
+	GameTooltip:ClearLines()
+	GameTooltip:AddLine("Click to track this quest.")
+	GameTooltip:Show()
+end
+
+local RowButton_OnEnter = function(self, ...)
+	if(MOD.DOCK_IS_FADED) then return end
+	GameTooltip:SetOwner(self, "ANCHOR_BOTTOMLEFT", 0, ROW_HEIGHT)
+	GameTooltip:ClearLines()
+	GameTooltip:AddDoubleLine("[Left-Click]", "View the log entry for this quest.", 0, 1, 0, 1, 1, 1)
+	GameTooltip:AddLine(" ")
+	GameTooltip:AddDoubleLine("[Right-Click]", "Remove this quest from the tracker.", 0, 1, 0, 1, 1, 1)
+	GameTooltip:AddLine(" ")
+	GameTooltip:AddDoubleLine("[SHIFT+Click]", "Show this quest on the map.", 0, 1, 0, 1, 1, 1)
+	GameTooltip:Show()
+end
+
+local AnyButton_OnLeave = function(self, ...)
+	GameTooltip:Hide()
+end
+
+local TimerBar_OnUpdate = function(self, elapsed)
+	local statusbar = self.Timer.Bar
+	local timeNow = GetTime();
+	local timeRemaining = statusbar.duration - (timeNow - statusbar.startTime);
+	statusbar:SetValue(timeRemaining);
+	if(timeRemaining < 0) then
+		-- hold at 0 for a moment
+		if(timeRemaining > -1) then
+			timeRemaining = 0;
+		else
+			self:StopTimer();
+		end
+	end
+	local r,g,b = MOD:GetTimerTextColor(statusbar.duration, statusbar.duration - timeRemaining)
+	self.Timer.TimeLeft:SetText(GetTimeStringFromSeconds(timeRemaining, nil, true));
+	self.Timer.TimeLeft:SetTextColor(r,g,b);
+end
+
+local ActiveButton_OnClick = function(self, button)
+	local rowIndex = self:GetID();
+	if(rowIndex and (rowIndex ~= 0)) then
+		local questID, _, questLogIndex, numObjectives, requiredMoney, completed, startEvent, isAutoComplete, duration, elapsed, questType, isTask, isStory, isOnMap, hasLocalPOI = GetQuestWatchInfo(rowIndex);
+		if(questID) then
+			local title, level, suggestedGroup, isHeader, isCollapsed, isComplete, frequency, questID, startEvent, displayQuestID, isOnMap, hasLocalPOI, isTask, isStory = GetQuestLogTitle(questLogIndex)
+			local icon = self.Icon:GetTexture()
+			local itemLink, texture, _, showCompleted = GetQuestLogSpecialItemInfo(questLogIndex)
+			SetSuperTrackedQuestID(questID);
+			MOD.Headers["Active"]:Set(title, level, icon, questID, questLogIndex, numObjectives, duration, elapsed, isComplete, itemLink);
+		end
+	end
+end
+
+local ViewButton_OnClick = function(self, button)
+	local questIndex = self:GetID();
+	if(questIndex and (questIndex ~= 0)) then
+		local questID = select(8, GetQuestLogTitle(questIndex));
+		if(IsModifiedClick("CHATLINK") and ChatEdit_GetActiveWindow()) then
+			local questLink = GetQuestLink(questIndex);
+			if(questLink) then
+				ChatEdit_InsertLink(questLink);
+			end
+		elseif(questID and IsShiftKeyDown()) then
+			QuestMapFrame_OpenToQuestDetails(questID);
+		elseif(questID and button ~= "RightButton") then
+			CloseDropDownMenus();
+			if(IsQuestComplete(questID) and GetQuestLogIsAutoComplete(questIndex)) then
+				AutoQuestPopupTracker_RemovePopUp(questID);
+				ShowQuestComplete(questIndex);
+			else
+				QuestLogPopupDetailFrame_Show(questIndex);
+			end
+		elseif(questID) then
+			local superTrackedQuestID = GetSuperTrackedQuestID();
+			RemoveQuestWatch(questIndex);
+			if(questID == superTrackedQuestID) then
+				QuestSuperTracking_OnQuestUntracked();
+			end
+		end
+	end
+end
+--[[
+##########################################################
+TRACKER FUNCTIONS
+##########################################################
+]]--
+local StartTimer = function(self, duration, elapsed)
+	local timeNow = GetTime();
+	local startTime = timeNow - elapsed;
+	local timeRemaining = duration - startTime;
+
+	self.Timer:SetHeight(INNER_HEIGHT);
+	self.Timer:FadeIn();
+	self.Timer.Bar.duration = duration or 1;
+	self.Timer.Bar.startTime = startTime;
+	self.Timer.Bar:SetMinMaxValues(0, self.Timer.Bar.duration);
+	self.Timer.Bar:SetValue(timeRemaining);
+	self.Timer.TimeLeft:SetText(GetTimeStringFromSeconds(duration, nil, true));
+	self.Timer.TimeLeft:SetTextColor(MOD:GetTimerTextColor(duration, duration - timeRemaining));
+
+	self:SetScript("OnUpdate", TimerBar_OnUpdate);
+end
+
+local StopTimer = function(self)
+	self.Timer:SetHeight(1);
+	self.Timer:SetAlpha(0);
+	self.Timer.Bar.duration = 1;
+	self.Timer.Bar.startTime = 0;
+	self.Timer.Bar:SetMinMaxValues(0, self.Timer.Bar.duration);
+	self.Timer.Bar:SetValue(0);
+	self.Timer.TimeLeft:SetText('');
+	self.Timer.TimeLeft:SetTextColor(1,1,1);
+
+	self:SetScript("OnUpdate", nil);
+end
+
+local GetQuestRow = function(self, index)
+	if(not self.Rows[index]) then
+		local previousFrame = self.Rows[#self.Rows]
+		local index = #self.Rows + 1;
+		local yOffset = -3;
+
+		local anchorFrame;
+		if(previousFrame and previousFrame.Objectives) then
+			anchorFrame = previousFrame.Objectives;
+			yOffset = -6;
+		else
+			anchorFrame = self.Header;
+		end
+
+		local row = CreateFrame("Frame", nil, self)
+		row:SetPoint("TOPLEFT", anchorFrame, "BOTTOMLEFT", 0, yOffset);
+		row:SetPoint("TOPRIGHT", anchorFrame, "BOTTOMRIGHT", 0, yOffset);
+		row:SetHeight(QUEST_ROW_HEIGHT);
+
+		row.Badge = CreateFrame("Frame", nil, row)
+		row.Badge:SetPoint("TOPLEFT", row, "TOPLEFT", 0, 0);
+		row.Badge:SetSize(QUEST_ROW_HEIGHT, QUEST_ROW_HEIGHT);
+		--row.Badge:SetStyle("Frame", "Lite")
+
+		row.Badge.Icon = row.Badge:CreateTexture(nil,"OVERLAY")
+		row.Badge.Icon:SetAllPoints(row.Badge);
+		row.Badge.Icon:SetTexture(MOD.media.incompleteIcon)
+		row.Badge.Icon:SetTexCoord(0.05, 0.95, 0.05, 0.95)
+
+		row.Badge.Button = CreateFrame("Button", nil, row.Badge)
+		row.Badge.Button:SetAllPoints(row.Badge);
+		row.Badge.Button:SetStyle("LiteButton")
+		row.Badge.Button:SetID(0)
+		row.Badge.Button.Icon = row.Badge.Icon;
+		row.Badge.Button:RegisterForClicks("LeftButtonUp", "RightButtonUp")
+		row.Badge.Button:SetScript("OnClick", ActiveButton_OnClick)
+		row.Badge.Button:SetScript("OnEnter", BadgeButton_OnEnter)
+		row.Badge.Button:SetScript("OnLeave", AnyButton_OnLeave)
+
+		row.Header = CreateFrame("Frame", nil, row)
+		row.Header:SetPoint("TOPLEFT", row, "TOPLEFT", (QUEST_ROW_HEIGHT + 6), 0);
+		row.Header:SetPoint("TOPRIGHT", row, "TOPRIGHT", -2, 0);
+		row.Header:SetHeight(INNER_HEIGHT);
+
+		row.Header.Level = row.Header:CreateFontString(nil,"OVERLAY")
+		row.Header.Level:SetFontObject(SVUI_Font_Quest_Number);
+		row.Header.Level:SetJustifyH('RIGHT')
+		row.Header.Level:SetText('')
+		row.Header.Level:SetPoint("TOPRIGHT", row.Header, "TOPRIGHT", -4, 0);
+		row.Header.Level:SetPoint("BOTTOMRIGHT", row.Header, "BOTTOMRIGHT", -4, 0);
+
+		row.Header.Text = row.Header:CreateFontString(nil,"OVERLAY")
+		row.Header.Text:SetFontObject(SVUI_Font_Quest);
+		row.Header.Text:SetJustifyH('LEFT')
+		row.Header.Text:SetTextColor(1,1,0)
+		row.Header.Text:SetText('')
+		row.Header.Text:SetPoint("TOPLEFT", row.Header, "TOPLEFT", 4, 0);
+		row.Header.Text:SetPoint("BOTTOMRIGHT", row.Header.Level, "BOTTOMLEFT", 0, 0);
+
+		row.Header.Zone = row:CreateFontString(nil,"OVERLAY")
+		row.Header.Zone:SetAllPoints(row);
+		row.Header.Zone:SetFontObject(SVUI_Font_Quest);
+		row.Header.Zone:SetJustifyH('LEFT')
+		row.Header.Zone:SetTextColor(0.75,0.25,1)
+		row.Header.Zone:SetText("")
+
+		row.Button = CreateFrame("Button", nil, row.Header)
+		row.Button:SetPoint("TOPLEFT", row, "TOPLEFT", (QUEST_ROW_HEIGHT + 6), 0);
+		row.Button:SetPoint("TOPRIGHT", row, "TOPRIGHT", -2, 0);
+		row.Button:SetHeight(INNER_HEIGHT + 2);
+		row.Button:SetStyle("LiteButton")
+		row.Button:SetID(0)
+		row.Button:RegisterForClicks("LeftButtonUp", "RightButtonUp")
+		row.Button:SetScript("OnClick", ViewButton_OnClick);
+		row.Button:SetScript("OnEnter", RowButton_OnEnter)
+		row.Button:SetScript("OnLeave", AnyButton_OnLeave)
+
+		row.Timer = CreateFrame("Frame", nil, row)
+		row.Timer:SetPoint("TOPLEFT", row, "BOTTOMLEFT", 0, 4);
+		row.Timer:SetPoint("TOPRIGHT", row, "BOTTOMRIGHT", 0, 4);
+		row.Timer:SetHeight(INNER_HEIGHT);
+
+		row.Timer.Bar = CreateFrame("StatusBar", nil, row.Timer);
+		row.Timer.Bar:SetPoint("TOPLEFT", row.Timer, "TOPLEFT", 4, -2);
+		row.Timer.Bar:SetPoint("BOTTOMRIGHT", row.Timer, "BOTTOMRIGHT", -4, 2);
+		row.Timer.Bar:SetStatusBarTexture(SV.media.statusbar.default)
+		row.Timer.Bar:SetStatusBarColor(0.5,0,1) --1,0.15,0.08
+		row.Timer.Bar:SetMinMaxValues(0, 1)
+		row.Timer.Bar:SetValue(0)
+
+		local bgFrame = CreateFrame("Frame", nil, row.Timer.Bar)
+		bgFrame:InsetPoints(row.Timer.Bar, -2, -2)
+		bgFrame:SetFrameLevel(bgFrame:GetFrameLevel() - 1)
+
+		bgFrame.bg = bgFrame:CreateTexture(nil, "BACKGROUND")
+		bgFrame.bg:SetAllPoints(bgFrame)
+		bgFrame.bg:SetTexture(SV.media.statusbar.default)
+	  	bgFrame.bg:SetVertexColor(0,0,0,0.5)
+
+		local borderB = bgFrame:CreateTexture(nil,"OVERLAY")
+		borderB:SetColorTexture(0,0,0)
+		borderB:SetPoint("BOTTOMLEFT")
+		borderB:SetPoint("BOTTOMRIGHT")
+		borderB:SetHeight(2)
+
+		local borderT = bgFrame:CreateTexture(nil,"OVERLAY")
+		borderT:SetColorTexture(0,0,0)
+		borderT:SetPoint("TOPLEFT")
+		borderT:SetPoint("TOPRIGHT")
+		borderT:SetHeight(2)
+
+		local borderL = bgFrame:CreateTexture(nil,"OVERLAY")
+		borderL:SetColorTexture(0,0,0)
+		borderL:SetPoint("TOPLEFT")
+		borderL:SetPoint("BOTTOMLEFT")
+		borderL:SetWidth(2)
+
+		local borderR = bgFrame:CreateTexture(nil,"OVERLAY")
+		borderR:SetColorTexture(0,0,0)
+		borderR:SetPoint("TOPRIGHT")
+		borderR:SetPoint("BOTTOMRIGHT")
+		borderR:SetWidth(2)
+
+		row.Timer.TimeLeft = row.Timer.Bar:CreateFontString(nil,"OVERLAY");
+		row.Timer.TimeLeft:InsetPoints(row.Timer.Bar);
+		row.Timer.TimeLeft:SetFontObject(SVUI_Font_Quest_Number);
+		row.Timer.TimeLeft:SetTextColor(1,1,1)
+		row.Timer.TimeLeft:SetText('')
+
+		row.Timer:SetHeight(1);
+		row.Timer:SetAlpha(0);
+
+		row.StartTimer = StartTimer;
+		row.StopTimer = StopTimer;
+
+		row.Objectives = MOD.NewObjectiveHeader(row);
+		row.Objectives:SetPoint("TOPLEFT", row.Timer, "BOTTOMLEFT", 0, 0);
+		row.Objectives:SetPoint("TOPRIGHT", row.Timer, "BOTTOMRIGHT", 0, 0);
+		row.Objectives:SetHeight(1);
+
+		row.RowID = 0;
+		self.Rows[index] = row;
+		return row;
+	end
+
+	return self.Rows[index];
+end
+
+local SetQuestRow = function(self, index, watchIndex, title, level, icon, questID, questLogIndex, subCount, duration, elapsed, completed, questType)
+	if(not watchIndex) then
+		return index,0
+	end
+	index = index or #self.Rows
+	index = index + 1;
+
+	local fill_height = 0;
+	local iscomplete = true;
+	local objective_rows = 0;
+	local row = self:Get(index);
+
+	if(not icon) then
+		icon = completed and MOD.media.completeIcon or MOD.media.incompleteIcon
+	end
+	local color = DEFAULT_COLOR
+	if(level and type(level) == 'number') then
+		color = GetQuestDifficultyColor(level);
+	end
+
+	row.Header:SetAlpha(1);
+	row.Header.Zone:SetText('')
+	row.Header.Level:SetTextColor(color.r, color.g, color.b)
+	row.Header.Level:SetText(level)
+	row.Header.Text:SetTextColor(color.r, color.g, color.b)
+	row.Header.Text:SetText(title)
+	row.Badge.Icon:SetTexture(icon);
+	row.Badge.Button:Enable();
+	row.Badge.Button:SetID(watchIndex);
+	row.Badge:SetAlpha(1);
+	row.Button:SetAlpha(1);
+	row.Button:Enable();
+	row.Button:SetID(questLogIndex);
+	row:SetHeight(QUEST_ROW_HEIGHT);
+	row:FadeIn();
+
+	local objective_block = row.Objectives;
+	objective_block:Reset();
+
+	for i = 1, subCount do
+		local description, category, objective_completed = GetQuestLogLeaderBoard(i, questLogIndex);
+		-- local description, category, objective_completed = GetQuestObjectiveInfo(questID, i, false);
+		if not objective_completed then iscomplete = false end
+		if(description) then
+			fill_height = fill_height + (INNER_HEIGHT + 4);
+			objective_rows = objective_block:SetInfo(objective_rows, description, objective_completed);
+		end
+	end
+
+	if(duration) then
+		if(elapsed and elapsed < duration) then
+			fill_height = fill_height + (INNER_HEIGHT + 4);
+			row:StartTimer(duration, elapsed)
+		end
+	end
+
+	if(objective_rows > 0) then
+		objective_block:SetHeight(fill_height);
+		objective_block:FadeIn();
+	end
+
+	fill_height = fill_height + (QUEST_ROW_HEIGHT + 6);
+
+	return index, fill_height;
+end
+
+local SetZoneHeader = function(self, index, zoneName)
+	index = index + 1;
+	local row = self:Get(index);
+	row.Header.Level:SetText('');
+	row.Header.Text:SetText('');
+	row.Badge.Icon:SetTexture("");
+	row.Badge.Button:SetID(0);
+	row.Badge:SetAlpha(0);
+	row.Button:SetID(0);
+	row.Button:Disable();
+	row.Button:SetAlpha(0);
+	row.Badge.Button:Disable();
+	row.Header.Zone:SetTextColor(1,0.31,0.1)
+	row.Header.Zone:SetText(zoneName);
+	row:SetHeight(ROW_HEIGHT);
+	row:SetAlpha(1);
+
+	local objective_block = row.Objectives;
+	objective_block:Reset();
+	return index, zoneName;
+end
+
+local RefreshQuests = function(self, event, ...)
+	local rows = 0;
+	local fill_height = 0;
+	local zone = 0;
+
+	for i = 1, #QUESTS_BY_LOCATION do
+		local zoneName = QUESTS_BY_LOCATION[i][2]
+		local questID = QUESTS_BY_LOCATION[i][3]
+		local quest = CACHED_QUESTS[questID]
+		if(quest) then
+			if(quest[2] and quest[2] ~= '') then
+				local add_height = 0;
+				if(zone ~= zoneName) then
+					rows, zone = self:SetZone(rows, zoneName);
+					fill_height = fill_height + QUEST_ROW_HEIGHT;
+				end
+				rows, add_height = self:Set(rows, unpack(quest))
+				fill_height = fill_height + add_height;
+				if(quest[12]) then
+					ItemBar:SetQuestItem(quest[12], quest[4], quest[10])
+				end
+			end
+		end
+	end
+
+	if(rows == 0 or (fill_height <= 1)) then
+		self:SetHeight(1);
+		self:SetAlpha(0);
+	else
+		self:SetHeight(fill_height + 2);
+		self:FadeIn();
+	end
+
+	ItemBar:Update()
+end
+
+local AddOneQuest = function(self, questID)
+	local rows = 0;
+	if(questID) then
+		local fill_height = self:GetHeight();
+		local quest = CACHED_QUESTS[questID];
+		if(quest[2] and quest[2] ~= '') then
+			local add_height = 0;
+			rows, add_height = self:Set(rows, unpack(quest))
+			fill_height = fill_height + add_height;
+			if(quest[12]) then
+				ItemBar:SetQuestItem(quest[12], quest[4], quest[10])
+			end
+		end
+
+		self:SetHeight(fill_height + 2);
+	end
+
+	ItemBar:Update()
+end
+
+local ResetQuestBlock = function(self)
+	for x = 1, #self.Rows do
+		local row = self.Rows[x]
+		if(row) then
+			row.Header.Text:SetText('');
+			row.Header:SetAlpha(0);
+			row.Header.Zone:SetText('');
+			row.Button:SetID(0);
+			row.Button:Disable();
+			row.Badge.Button:SetID(0);
+			row.Badge.Icon:SetTexture("");
+			row.Badge:SetAlpha(0);
+			row.Badge.Button:Disable();
+			row:SetHeight(1);
+			row:SetAlpha(0);
+			row.Objectives:Reset();
+		end
+	end
+	UpdateCachedQuests();
+end
+
+local LiteResetQuestBlock = function(self)
+	for x = 1, #self.Rows do
+		local row = self.Rows[x]
+		if(row) then
+			row.Objectives:Reset(true);
+		end
+	end
+end
+
+local _hook_WorldMapFrameOnHide = function()
+	if(not WORLDMAP_UPDATE) then return end
+	MOD.Headers["Quests"]:Reset()
+	MOD.Headers["Quests"]:Refresh()
+	MOD:UpdateDimensions();
+end
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+function MOD:UpdateObjectives(event, ...)
+	if(event == "ZONE_CHANGED_NEW_AREA") then
+		if(not WorldMapFrame:IsShown() and GetCVarBool("questPOI")) then
+			SetMapToCurrentZone();
+			CURRENT_MAP_ID = GetCurrentMapAreaID();
+			UpdateCachedDistance();
+			self.Headers["Quests"]:LiteReset()
+			self.Headers["Quests"]:Refresh(event, ...)
+		end
+	elseif(event == "ZONE_CHANGED") then
+		local inMicroDungeon = IsPlayerInMicroDungeon();
+		if(inMicroDungeon ~= self.inMicroDungeon) then
+			if(not WorldMapFrame:IsShown() and GetCVarBool("questPOI")) then
+				SetMapToCurrentZone();
+				CURRENT_MAP_ID = GetCurrentMapAreaID();
+				UpdateCachedDistance();
+				self.Headers["Quests"]:LiteReset()
+				self.Headers["Quests"]:Refresh(event, ...)
+			end
+			self.inMicroDungeon = inMicroDungeon;
+		end
+	else
+		if(event == "QUEST_ACCEPTED" or event == "QUEST_WATCH_LIST_CHANGED") then
+			local questLogIndex, questID, isTracked;
+			if(event == "QUEST_ACCEPTED") then
+				questLogIndex, questID = ...;
+				if(AUTO_QUEST_WATCH == "1") then
+					AddQuestWatch(questLogIndex);
+					QuestSuperTracking_OnQuestTracked(questID);
+				end
+				local addedQuest = AddCachedQuest(questLogIndex)
+				if(addedQuest) then
+					self.Headers["Quests"]:AddQuest(addedQuest)
+					self:UpdateDimensions();
+				end
+			elseif(event == "QUEST_WATCH_LIST_CHANGED") then
+				questID, isTracked = ...;
+				if(questID) then
+					local questLogIndex = GetQuestLogIndexByID(questID)
+					if(isTracked) then
+						local addedQuest = AddCachedQuest(questLogIndex)
+						self.Headers["Quests"]:AddQuest(addedQuest)
+					else
+						CACHED_QUESTS[questID] = nil;
+						self:CheckActiveQuest(questID);
+						self.Headers["Quests"]:Reset();
+						self.Headers["Quests"]:Refresh(event, ...)
+					end
+					self:UpdateDimensions();
+				end
+			end
+		elseif(event == "QUEST_TURNED_IN") then
+			local questID, XP, Money = ...
+			if(IsQuestTask(questID)) then
+				self:CacheBonusObjective(event, ...);
+			end
+			self:CheckActiveQuest(questID);
+			if(CACHED_QUESTS[questID]) then
+				CACHED_QUESTS[questID] = nil;
+				ItemBar:Reset();
+				self.Headers["Quests"]:Reset();
+				self.Headers["Quests"]:Refresh(event, ...);
+				self:UpdateDimensions();
+			end
+		elseif(event == "QUEST_LOG_UPDATE") then
+			self.Headers["Quests"]:Reset();
+			self.Headers["Quests"]:Refresh(event, ...)
+			self:UpdateBonusObjective(event, ...);
+			self:UpdateDimensions();
+		else
+			self:UpdateBonusObjective(event, ...)
+		end
+	end
+end
+
+local function ReAnchorItemBar()
+	if(InCombatLockdown()) then return end
+	local dockletLocation = MOD.Docklet.Parent.Bar.Data.Location;
+	local isHorizontal = (SV.db.QuestTracker.itemBarDirection == 'HORIZONTAL');
+	local anchor1 = isHorizontal and "LEFT" or "RIGHT";
+	local anchor2 = "LEFT";
+	local xOff = isHorizontal and 0 or -4;
+	local yOff = isHorizontal and 4 or 0;
+
+	if(dockletLocation:find('Left')) then
+		anchor1 = isHorizontal and "RIGHT" or "LEFT";
+		anchor2 = "RIGHT";
+		xOff = isHorizontal and 0 or 4;
+	end
+
+	local prefix1 = isHorizontal and "BOTTOM" or "TOP";
+	local prefix2 = "TOP";
+
+	if(dockletLocation:find('Top')) then
+		prefix1 = isHorizontal and "TOP" or "BOTTOM";
+		prefix2 = "BOTTOM";
+		yOff = -4;
+	end
+
+	anchor1 = prefix1 .. anchor1;
+	anchor2 = prefix2 .. anchor2;
+
+	local parentWindow = MOD.Docklet.Parent.Window;
+	ItemBar:ClearAllPoints();
+	ItemBar:SetSecurePoint(anchor1, parentWindow, anchor2, xOff, yOff);
+
+	if(isHorizontal) then
+		ItemBar:SetWidth(parentWindow:GetWidth());
+		ItemBar:SetHeight(32);
+	else
+		ItemBar:SetWidth(32);
+		ItemBar:SetHeight(parentWindow:GetHeight());
+	end
+end
+
+local function UpdateQuestLocals(...)
+	ROW_WIDTH, ROW_HEIGHT, INNER_HEIGHT, LARGE_ROW_HEIGHT, LARGE_INNER_HEIGHT = ...;
+	QUEST_ROW_HEIGHT = ROW_HEIGHT + 2;
+	ITEM_BUTTON_SIZE = SV.db.QuestTracker.itemButtonSize;
+	ITEMS_PER_ROW = SV.db.QuestTracker.itemButtonsPerRow;
+	ReAnchorItemBar();
+	ItemBar:Update()
+end
+
+local function PostMoveCallback(buttonName)
+	if(not buttonName or (buttonName ~= MOD.Docklet.Button:GetName())) then return end
+	if(ItemBar.Grip and (not ItemBar.Grip:HasMoved())) then
+		ReAnchorItemBar()
+	end
+	MOD.QuestItemTimer = SV.Timers:ExecuteTimer(ShowItemBarButtons, 1.2);
+	ShowItemBarButtons();
+end
+
+local function PostShowCallback(location, windowName)
+	if(not location or (location ~= MOD.Docklet.Parent.Bar.Data.Location)) then return end
+	if(not windowName or (windowName ~= MOD.Docklet:GetName())) then return end
+	MOD.QuestItemTimer = SV.Timers:ExecuteTimer(ShowItemBarButtons, 1.2);
+	ShowItemBarButtons();
+end
+
+local function PostHideCallback(location, windowName)
+	if(not location or (location ~= MOD.Docklet.Parent.Bar.Data.Location)) then return end
+	if(not windowName or (windowName ~= MOD.Docklet:GetName())) then return end
+	if(MOD.QuestItemTimer) then
+		SV.Timers:RemoveTimer(MOD.QuestItemTimer)
+		MOD.QuestItemTimer = nil
+	end
+	HideItemBarButtons();
+end
+
+function MOD:InitializeQuests()
+	ReAnchorItemBar()
+	SV:NewAnchor(ItemBar, L["Quest Items"]);
+	ITEM_BUTTON_SIZE = SV.db.QuestTracker.itemButtonSize;
+	ITEMS_PER_ROW = SV.db.QuestTracker.itemButtonsPerRow;
+	for i = 1, 5 do
+		ItemBar.Buttons[i] = CreateQuestItemButton(i)
+	end
+
+	SV.Events:On("DOCKLET_MOVED", PostMoveCallback, true);
+	SV.Events:On("DOCKLET_SHOWN", PostShowCallback, true);
+	SV.Events:On("DOCKLET_HIDDEN", PostHideCallback, true);
+
+	local scrollChild = self.Docklet.ScrollFrame.ScrollChild;
+	local quests = CreateFrame("Frame", nil, scrollChild)
+	quests:SetWidth(ROW_WIDTH);
+	quests:SetHeight(ROW_HEIGHT);
+	quests:SetPoint("TOPLEFT", self.Headers["Bonus"], "BOTTOMLEFT", 0, -4);
+	--quests:SetStyle()
+
+	quests.Header = CreateFrame("Frame", nil, quests)
+	quests.Header:SetPoint("TOPLEFT", quests, "TOPLEFT", 2, -2);
+	quests.Header:SetPoint("TOPRIGHT", quests, "TOPRIGHT", -2, -2);
+	quests.Header:SetHeight(INNER_HEIGHT);
+
+	quests.Header.Text = quests.Header:CreateFontString(nil,"OVERLAY")
+	quests.Header.Text:SetPoint("TOPLEFT", quests.Header, "TOPLEFT", 2, 0);
+	quests.Header.Text:SetPoint("BOTTOMLEFT", quests.Header, "BOTTOMLEFT", 2, 0);
+	quests.Header.Text:SetFontObject(SVUI_Font_Quest_Header);
+	quests.Header.Text:SetJustifyH('LEFT')
+	quests.Header.Text:SetTextColor(0.28,0.75,1)
+	quests.Header.Text:SetText(TRACKER_HEADER_QUESTS)
+
+	quests.Header.Divider = quests.Header:CreateTexture(nil, 'BACKGROUND');
+	quests.Header.Divider:SetPoint("TOPLEFT", quests.Header.Text, "TOPRIGHT", -10, 0);
+	quests.Header.Divider:SetPoint("BOTTOMRIGHT", quests.Header, "BOTTOMRIGHT", 0, 0);
+	quests.Header.Divider:SetTexture([[Interface\AddOns\SVUI_!Core\assets\textures\DROPDOWN-DIVIDER]]);
+
+	quests.Rows = {};
+
+	quests.Get = GetQuestRow;
+	quests.Set = SetQuestRow;
+	quests.SetZone = SetZoneHeader;
+	quests.Refresh = RefreshQuests;
+	quests.AddQuest = AddOneQuest;
+	quests.Reset = ResetQuestBlock;
+	quests.LiteReset = LiteResetQuestBlock;
+
+	self.Headers["Quests"] = quests;
+
+	self:RegisterEvent("QUEST_LOG_UPDATE", self.UpdateObjectives);
+	self:RegisterEvent("QUEST_WATCH_LIST_CHANGED", self.UpdateObjectives);
+	self:RegisterEvent("QUEST_ACCEPTED", self.UpdateObjectives);
+	self:RegisterEvent("QUEST_POI_UPDATE", self.UpdateObjectives);
+	self:RegisterEvent("QUEST_TURNED_IN", self.UpdateObjectives);
+
+	self:RegisterEvent("ZONE_CHANGED_NEW_AREA", self.UpdateObjectives);
+	self:RegisterEvent("ZONE_CHANGED", self.UpdateObjectives);
+
+	--ItemBar:Reset();
+	CacheQuestHeaders()
+	self.Headers["Quests"]:Reset()
+	self.Headers["Quests"]:Refresh()
+
+	WorldMapFrame:HookScript("OnHide", _hook_WorldMapFrameOnHide)
+	ItemBar:Show()
+	SV.Events:On("QUEST_LAYOUT_UPDATED", ReAnchorItemBar, true);
+	SV.Events:On("QUEST_UPVALUES_UPDATED", UpdateQuestLocals, true);
+end
diff --git a/SVUI_QuestTracker/components/scenario.lua b/SVUI_QuestTracker/components/scenario.lua
new file mode 100644
index 0000000..ab55370
--- /dev/null
+++ b/SVUI_QuestTracker/components/scenario.lua
@@ -0,0 +1,475 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack    = _G.unpack;
+local select    = _G.select;
+local pairs     = _G.pairs;
+local ipairs    = _G.ipairs;
+local type      = _G.type;
+local error     = _G.error;
+local pcall     = _G.pcall;
+local tostring  = _G.tostring;
+local tonumber  = _G.tonumber;
+local tinsert 	= _G.tinsert;
+local string 	= _G.string;
+local math 		= _G.math;
+local table 	= _G.table;
+--[[ STRING METHODS ]]--
+local format = string.format;
+--[[ MATH METHODS ]]--
+local abs, ceil, floor, round = math.abs, math.ceil, math.floor, math.round;
+--[[ TABLE METHODS ]]--
+local tremove, twipe = table.remove, table.wipe;
+--BLIZZARD API
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+local GameTooltip           = _G.GameTooltip;
+local hooksecurefunc        = _G.hooksecurefunc;
+local IsAltKeyDown          = _G.IsAltKeyDown;
+local IsShiftKeyDown        = _G.IsShiftKeyDown;
+local IsControlKeyDown      = _G.IsControlKeyDown;
+local IsModifiedClick       = _G.IsModifiedClick;
+local PlaySound             = _G.PlaySound;
+local PlaySoundKitID        = _G.PlaySoundKitID;
+local GetTime               = _G.GetTime;
+local C_Scenario            = _G.C_Scenario;
+local GetWorldElapsedTimers = _G.GetWorldElapsedTimers;
+local GetInstanceInfo 		= _G.GetInstanceInfo;
+local GetWorldElapsedTime 	= _G.GetWorldElapsedTime;
+local GetTimeStringFromSeconds	= _G.GetTimeStringFromSeconds;
+local GetChallengeModeMapTimes 	= _G.GetChallengeModeMapTimes;
+local GENERIC_FRACTION_STRING 	= _G.GENERIC_FRACTION_STRING;
+local CHALLENGE_MEDAL_GOLD   	= _G.CHALLENGE_MEDAL_GOLD;
+local CHALLENGE_MEDAL_SILVER    = _G.CHALLENGE_MEDAL_SILVER;
+local CHALLENGE_MEDAL_TEXTURES  = _G.CHALLENGE_MEDAL_TEXTURES;
+local CHALLENGES_TIMER_NO_MEDAL = _G.CHALLENGES_TIMER_NO_MEDAL;
+local LE_WORLD_ELAPSED_TIMER_TYPE_CHALLENGE_MODE = _G.LE_WORLD_ELAPSED_TIMER_TYPE_CHALLENGE_MODE;
+local LE_WORLD_ELAPSED_TIMER_TYPE_PROVING_GROUND = _G.LE_WORLD_ELAPSED_TIMER_TYPE_PROVING_GROUND;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local MOD = SV.QuestTracker;
+--[[
+##########################################################
+LOCALS
+##########################################################
+]]--
+local ROW_WIDTH = 300;
+local ROW_HEIGHT = 24;
+local INNER_HEIGHT = ROW_HEIGHT - 4;
+local LARGE_ROW_HEIGHT = ROW_HEIGHT * 2;
+local LARGE_INNER_HEIGHT = LARGE_ROW_HEIGHT - 4;
+local LINE_FAILED_ICON = [[Interface\ICONS\Ability_Blackhand_Marked4Death]];
+local LINE_SCENARIO_ICON = [[Interface\ICONS\Icon_Scenarios]];
+local LINE_CHALLENGE_ICON = [[Interface\ICONS\Achievement_ChallengeMode_Platinum]];
+--[[
+##########################################################
+SCRIPT HANDLERS
+##########################################################
+]]--
+local TimerBar_OnUpdate = function(self, elapsed)
+	local statusbar = self.Bar
+    statusbar.elapsed = statusbar.elapsed + elapsed;
+    local currentTime = statusbar.duration - statusbar.elapsed
+    local timeString = GetTimeStringFromSeconds(currentTime)
+    local r,g,b = MOD:GetTimerTextColor(statusbar.duration, statusbar.elapsed)
+    if(statusbar.elapsed <= statusbar.duration) then
+        statusbar:SetValue(currentTime);
+        statusbar.TimeLeft:SetText(timeString);
+        statusbar.TimeLeft:SetTextColor(r,g,b);
+    else
+    	self:StopTimer()
+    end
+end
+--[[
+##########################################################
+TRACKER FUNCTIONS
+##########################################################
+]]--
+local SetScenarioData = function(self, title, stageName, currentStage, numStages, stageDescription, numObjectives)
+	local objective_rows = 0;
+	local fill_height = 0;
+	local block = self.Block;
+
+	block.HasData = true;
+	if(currentStage ~= 0) then
+		block.Header.Stage:SetText("Stage " .. currentStage)
+	else
+		block.Header.Stage:SetText('')
+	end
+	block.Header.Text:SetText(title)
+	block.Icon:SetTexture(LINE_SCENARIO_ICON)
+
+	local objective_block = block.Objectives;
+	for i = 1, numObjectives do
+		local description, criteriaType, completed, quantity, totalQuantity, flags, assetID, quantityString, criteriaID, duration, elapsed, failed = C_Scenario.GetCriteriaInfo(i);
+		if(duration > 0 and elapsed <= duration and not (failed or completed)) then
+			objective_rows = objective_block:SetTimer(objective_rows, duration, elapsed);
+			fill_height = fill_height + (INNER_HEIGHT + 2);
+		end
+		if(description and description ~= '') then
+			objective_rows = objective_block:SetInfo(objective_rows, description, completed, failed);
+			fill_height = fill_height + (INNER_HEIGHT + 2);
+		end
+	end
+
+	local timerHeight = self.Timer:GetHeight()
+
+	if(objective_rows > 0) then
+		objective_block:SetHeight(fill_height);
+		objective_block:FadeIn();
+	end
+
+	fill_height = fill_height + (LARGE_ROW_HEIGHT + 2) + timerHeight;
+	block:SetHeight(fill_height);
+
+	MOD.Docklet.ScrollFrame.ScrollBar:SetValue(0)
+end
+
+local UnsetScenarioData = function(self)
+	local block = self.Block;
+	block:SetHeight(1);
+	block.Header.Text:SetText('');
+	block.Header.Stage:SetText('');
+	block.Icon:SetTexture(LINE_SCENARIO_ICON);
+	block.HasData = false;
+	block.Objectives:Reset()
+	self:SetHeight(1);
+	self:SetAlpha(0);
+end
+
+local RefreshScenarioHeight = function(self)
+	if(not self.Block.HasData) then
+		self:Unset();
+	else
+		local h1 = self.Timer:GetHeight()
+		local h2 = self.Block:GetHeight()
+		self:SetHeight(h1 + h2 + 2);
+		self:FadeIn();
+	end
+end
+--[[
+##########################################################
+TIMER FUNCTIONS
+##########################################################
+]]--
+local MEDAL_TIMES = {};
+local LAST_MEDAL;
+
+local StartTimer = function(self, elapsed, duration, medalIndex, currWave, maxWave)
+	self:SetHeight(INNER_HEIGHT);
+	self:FadeIn();
+	self.Bar.duration = duration or 1;
+	self.Bar.elapsed = elapsed or 0;
+	self.Bar:SetMinMaxValues(0, self.Bar.duration);
+	self.Bar:SetValue(self.Bar.elapsed);
+	self:SetScript("OnUpdate", TimerBar_OnUpdate);
+	local blockHeight = MOD.Headers["Scenario"].Block:GetHeight();
+	MOD.Headers["Scenario"].Block:SetHeight(blockHeight + INNER_HEIGHT + 4);
+
+	if (medalIndex < 4) then
+		self.Bar.Wave:SetFormattedText(GENERIC_FRACTION_STRING, currWave, maxWave);
+	else
+		self.Bar.Wave:SetText(currWave);
+	end
+end
+
+local StopTimer = function(self)
+	local timerHeight = self:GetHeight();
+	self:SetHeight(1);
+	self:SetAlpha(0);
+	self.Bar.duration = 1;
+	self.Bar.elapsed = 0;
+	self.Bar:SetMinMaxValues(0, self.Bar.duration);
+	self.Bar:SetValue(0);
+	self:SetScript("OnUpdate", nil);
+	local blockHeight = MOD.Headers["Scenario"].Block:GetHeight();
+	MOD.Headers["Scenario"].Block:SetHeight((blockHeight - timerHeight) + 1);
+end
+
+local SetChallengeMedals = function(self, elapsedTime, ...)
+	self:SetHeight(INNER_HEIGHT);
+	local blockHeight = MOD.Headers["Scenario"].Block:GetHeight();
+	MOD.Headers["Scenario"].Block:SetHeight(blockHeight + INNER_HEIGHT + 4);
+	self:FadeIn();
+	self.Bar:SetMinMaxValues(0, elapsedTime);
+	self.Bar:SetValue(elapsedTime);
+
+	for i = 1, select("#", ...) do
+		MEDAL_TIMES[i] = select(i, ...);
+	end
+	LAST_MEDAL = nil;
+	self:UpdateMedals(elapsedTime);
+	self:UpdateMedals(elapsedTime);
+end
+
+local UpdateChallengeMedals = function(self, elapsedTime)
+	local prevMedalTime = 0;
+	for i = #MEDAL_TIMES, 1, -1 do
+		local currentMedalTime = MEDAL_TIMES[i];
+		if ( elapsedTime < currentMedalTime ) then
+			self.Bar:SetMinMaxValues(0, currentMedalTime - prevMedalTime);
+			self.Bar.medalTime = currentMedalTime;
+			if(CHALLENGE_MEDAL_TEXTURES[i]) then
+				self.Icon:SetTexture(CHALLENGE_MEDAL_TEXTURES[i]);
+			end
+			if(LAST_MEDAL and LAST_MEDAL ~= i) then
+				if(LAST_MEDAL == CHALLENGE_MEDAL_GOLD) then
+					PlaySound("UI_Challenges_MedalExpires_GoldtoSilver");
+				elseif(LAST_MEDAL == CHALLENGE_MEDAL_SILVER) then
+					PlaySound("UI_Challenges_MedalExpires_SilvertoBronze");
+				else
+					PlaySound("UI_Challenges_MedalExpires");
+				end
+			end
+			LAST_MEDAL = i;
+			return;
+		else
+			prevMedalTime = currentMedalTime;
+		end
+	end
+
+	self.Bar.TimeLeft:SetText(CHALLENGES_TIMER_NO_MEDAL);
+	self.Bar:SetValue(0);
+	self.Bar.medalTime = nil;
+	self:SetHeight(1)
+	self.Icon:SetTexture(LINE_FAILED_ICON);
+
+	if(LAST_MEDAL and LAST_MEDAL ~= 0) then
+		PlaySound("UI_Challenges_MedalExpires");
+	end
+
+	LAST_MEDAL = 0;
+end
+
+
+local UpdateChallengeTimer = function(self, elapsedTime)
+	local statusBar = self.Bar;
+	if ( statusBar.medalTime ) then
+		local timeLeft = statusBar.medalTime - elapsedTime;
+		if (timeLeft == 10) then
+			if (not statusBar.playedSound) then
+				PlaySoundKitID(34154);
+				statusBar.playedSound = true;
+			end
+		else
+			statusBar.playedSound = false;
+		end
+		if(timeLeft < 0) then
+			self:UpdateMedals(elapsedTime);
+		else
+			statusBar:SetValue(timeLeft);
+			statusBar.TimeLeft:SetText(GetTimeStringFromSeconds(timeLeft));
+		end
+	end
+end
+
+local UpdateAllTimers = function(self, ...)
+	local timeLeftFound
+	for i = 1, select("#", ...) do
+		local timerID = select(i, ...);
+		local _, elapsedTime, type = GetWorldElapsedTime(timerID);
+		if ( type == LE_WORLD_ELAPSED_TIMER_TYPE_CHALLENGE_MODE) then
+			local _, _, _, _, _, _, _, mapID = GetInstanceInfo();
+			if ( mapID ) then
+				self:SetMedals(elapsedTime, GetChallengeModeMapTimes(mapID));
+				return;
+			end
+		elseif ( type == LE_WORLD_ELAPSED_TIMER_TYPE_PROVING_GROUND ) then
+			local diffID, currWave, maxWave, duration = C_Scenario.GetProvingGroundsInfo()
+			if (duration > 0) then
+				self:StartTimer(elapsedTime, duration, diffID, currWave, maxWave)
+				return;
+			end
+		end
+	end
+	--self:StopTimer()
+end
+
+local RefreshScenarioObjective = function(self, event, ...)
+	if(C_Scenario.IsInScenario()) then
+		if(event == "PLAYER_ENTERING_WORLD") then
+			self.Timer:UpdateTimers(GetWorldElapsedTimers());
+		elseif(event == "WORLD_STATE_TIMER_START") then
+			self.Timer:UpdateTimers(...)
+		elseif(event == "WORLD_STATE_TIMER_STOP") then
+			self.Timer:StopTimer()
+		elseif(event == "PROVING_GROUNDS_SCORE_UPDATE") then
+			local score = ...
+			self.Block.Header.Score:SetText(score);
+		elseif(event == "SCENARIO_COMPLETED" or event == 'SCENARIO_UPDATE' or event == 'SCENARIO_CRITERIA_UPDATE') then
+			if(event == "SCENARIO_COMPLETED") then
+				self.Timer:StopTimer()
+			else
+				self.Block.Objectives:Reset()
+				local title, currentStage, numStages, flags, _, _, _, xp, money = C_Scenario.GetInfo();
+				if(title) then
+					local stageName, stageDescription, numObjectives = C_Scenario.GetStepInfo();
+					-- local inChallengeMode = bit.band(flags, SCENARIO_FLAG_CHALLENGE_MODE) == SCENARIO_FLAG_CHALLENGE_MODE;
+					-- local inProvingGrounds = bit.band(flags, SCENARIO_FLAG_PROVING_GROUNDS) == SCENARIO_FLAG_PROVING_GROUNDS;
+					-- local dungeonDisplay = bit.band(flags, SCENARIO_FLAG_USE_DUNGEON_DISPLAY) == SCENARIO_FLAG_USE_DUNGEON_DISPLAY;
+					local scenariocompleted = currentStage > numStages;
+					if(not scenariocompleted) then
+						self:Set(title, stageName, currentStage, numStages, stageDescription, numObjectives)
+						if(currentStage > 1) then
+							PlaySound("UI_Scenario_Stage_End");
+						end
+					else
+						self.Timer:StopTimer()
+						self.Block.HasData = false
+					end
+				end
+			end
+		end
+	else
+		self.Timer:StopTimer()
+		self.Block.HasData = false
+	end
+
+	self:RefreshHeight()
+end
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+function MOD:UpdateScenarioObjective(event, ...)
+	self.Headers["Scenario"]:Refresh(event, ...)
+	self:UpdateDimensions();
+end
+
+local function UpdateScenarioLocals(...)
+	ROW_WIDTH, ROW_HEIGHT, INNER_HEIGHT, LARGE_ROW_HEIGHT, LARGE_INNER_HEIGHT = ...;
+end
+
+function MOD:InitializeScenarios()
+	local scrollChild = self.Docklet.ScrollFrame.ScrollChild;
+
+	local scenario = CreateFrame("Frame", nil, scrollChild)
+	scenario:SetHeight(ROW_HEIGHT);
+	scenario:SetPoint("TOPLEFT", scrollChild, "TOPLEFT", 0, 0);
+	scenario:SetPoint("TOPRIGHT", scrollChild, "TOPRIGHT", 0, 0);
+
+	scenario.Set = SetScenarioData;
+	scenario.Unset = UnsetScenarioData;
+	scenario.Refresh = RefreshScenarioObjective;
+	scenario.RefreshHeight = RefreshScenarioHeight;
+
+	local block = CreateFrame("Frame", nil, scenario)
+	block:SetPoint("TOPLEFT", scenario, "TOPLEFT", 2, -2);
+	block:SetPoint("TOPRIGHT", scenario, "TOPRIGHT", -2, -2);
+	block:SetHeight(1);
+	block:SetStyle("Frame", "Lite");
+
+	block.Badge = CreateFrame("Frame", nil, block)
+	block.Badge:SetPoint("TOPLEFT", block, "TOPLEFT", 4, -4);
+	block.Badge:SetSize((LARGE_INNER_HEIGHT - 4), (LARGE_INNER_HEIGHT - 4));
+	block.Badge:SetStyle("!_Frame", "Inset")
+
+	block.Icon = block.Badge:CreateTexture(nil,"OVERLAY")
+	block.Icon:InsetPoints(block.Badge);
+	block.Icon:SetTexture(LINE_SCENARIO_ICON)
+	block.Icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+
+	block.Header = CreateFrame("Frame", nil, block)
+	block.Header:SetPoint("TOPLEFT", block.Badge, "TOPRIGHT", 4, -1);
+	block.Header:SetPoint("TOPRIGHT", block, "TOPRIGHT", -4, 0);
+	block.Header:SetHeight(INNER_HEIGHT);
+	block.Header:SetStyle("Frame")
+
+	block.Header.Stage = block.Header:CreateFontString(nil,"OVERLAY")
+	block.Header.Stage:SetFontObject(SVUI_Font_Quest);
+	block.Header.Stage:SetJustifyH('LEFT')
+	block.Header.Stage:SetText('')
+	block.Header.Stage:SetPoint("TOPLEFT", block.Header, "TOPLEFT", 4, 0);
+	block.Header.Stage:SetPoint("BOTTOMLEFT", block.Header, "BOTTOMLEFT", 4, 0);
+
+	block.Header.Score = block.Header:CreateFontString(nil,"OVERLAY")
+	block.Header.Score:SetFontObject(SVUI_Font_Quest);
+	block.Header.Score:SetJustifyH('RIGHT')
+	block.Header.Score:SetTextColor(1,1,0)
+	block.Header.Score:SetText('')
+	block.Header.Score:SetPoint("TOPRIGHT", block.Header, "TOPRIGHT", -2, 0);
+	block.Header.Score:SetPoint("BOTTOMRIGHT", block.Header, "BOTTOMRIGHT", -2, 0);
+
+	block.Header.Text = block.Header:CreateFontString(nil,"OVERLAY")
+	block.Header.Text:SetFontObject(SVUI_Font_Quest);
+	block.Header.Text:SetTextColor(1,1,0)
+	block.Header.Text:SetText('')
+	block.Header.Text:SetPoint("TOPLEFT", block.Header.Stage, "TOPRIGHT", 4, 0);
+	block.Header.Text:SetPoint("BOTTOMRIGHT", block.Header.Score, "BOTTOMRIGHT", 0, 0);
+
+	local timer = CreateFrame("Frame", nil, block.Header)
+	timer:SetPoint("TOPLEFT", block.Header, "BOTTOMLEFT", 4, -4);
+	timer:SetPoint("TOPRIGHT", block.Header, "BOTTOMRIGHT", -4, -4);
+	timer:SetHeight(INNER_HEIGHT);
+	timer:SetStyle("!_Frame", "Bar");
+
+	timer.StartTimer = StartTimer;
+	timer.StopTimer = StopTimer;
+	timer.UpdateTimers = UpdateAllTimers;
+	timer.SetMedals = SetChallengeMedals;
+	timer.UpdateMedals = UpdateChallengeMedals;
+	timer.UpdateChallenges = UpdateChallengeTimer;
+
+	timer.Bar = CreateFrame("StatusBar", nil, timer);
+	timer.Bar:SetAllPoints(timer);
+	timer.Bar:SetStatusBarTexture(SV.media.statusbar.default)
+	timer.Bar:SetStatusBarColor(0.5,0,1) --1,0.15,0.08
+	timer.Bar:SetMinMaxValues(0, 1)
+	timer.Bar:SetValue(0)
+
+	timer.Bar.Wave = timer.Bar:CreateFontString(nil,"OVERLAY")
+	timer.Bar.Wave:SetPoint("TOPLEFT", timer.Bar, "TOPLEFT", 4, 0);
+	timer.Bar.Wave:SetPoint("BOTTOMLEFT", timer.Bar, "BOTTOMLEFT", 4, 0);
+	timer.Bar.Wave:SetFontObject(SVUI_Font_Quest);
+	timer.Bar.Wave:SetJustifyH('LEFT')
+	timer.Bar.Wave:SetTextColor(1,1,0)
+	timer.Bar.Wave:SetText('')
+
+	timer.Bar.TimeLeft = timer.Bar:CreateFontString(nil,"OVERLAY");
+	timer.Bar.TimeLeft:SetPoint("TOPLEFT", timer.Bar.Wave, "TOPRIGHT", 4, 0);
+	timer.Bar.TimeLeft:SetPoint("BOTTOMRIGHT", timer.Bar, "BOTTOMRIGHT", 0, 0);
+	timer.Bar.TimeLeft:SetFontObject(SVUI_Font_Quest_Number);
+	timer.Bar.TimeLeft:SetTextColor(1,1,1)
+	timer.Bar.TimeLeft:SetText('')
+
+	timer.Icon = block.Icon;
+	timer:SetHeight(1);
+	timer:SetAlpha(0)
+
+	block.Objectives = MOD.NewObjectiveHeader(block);
+	block.Objectives:SetPoint("TOPLEFT", timer, "BOTTOMLEFT", -4, -4);
+	block.Objectives:SetPoint("TOPRIGHT", timer, "BOTTOMRIGHT", 4, -4);
+	block.Objectives:SetHeight(1);
+
+	block.HasData = false;
+
+	scenario.Timer = timer;
+	scenario.Block = block;
+
+	self.Headers["Scenario"] = scenario;
+
+	self.Headers["Scenario"]:RefreshHeight()
+
+	self:RegisterEvent("PLAYER_ENTERING_WORLD", self.UpdateScenarioObjective);
+	self:RegisterEvent("PROVING_GROUNDS_SCORE_UPDATE", self.UpdateScenarioObjective);
+	self:RegisterEvent("WORLD_STATE_TIMER_START", self.UpdateScenarioObjective);
+	self:RegisterEvent("WORLD_STATE_TIMER_STOP", self.UpdateScenarioObjective);
+	self:RegisterEvent("SCENARIO_UPDATE", self.UpdateScenarioObjective);
+	self:RegisterEvent("SCENARIO_CRITERIA_UPDATE", self.UpdateScenarioObjective);
+	self:RegisterEvent("SCENARIO_COMPLETED", self.UpdateScenarioObjective);
+
+	SV.Events:On("QUEST_UPVALUES_UPDATED", UpdateScenarioLocals, true);
+end
diff --git a/SVUI_Skins/License.txt b/SVUI_Skins/License.txt
new file mode 100644
index 0000000..05ceba8
--- /dev/null
+++ b/SVUI_Skins/License.txt
@@ -0,0 +1,31 @@
+
+The MIT License
+
+Copyright (c) 2010, Failcoder (Steve Jackson)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy
+of this software and associated documentation files (the "Software"), to
+deal
+in the Software without restriction, including without limitation the
+rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/SVUI_Skins/Loader.lua b/SVUI_Skins/Loader.lua
new file mode 100644
index 0000000..83a62ae
--- /dev/null
+++ b/SVUI_Skins/Loader.lua
@@ -0,0 +1,523 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+
+local SV = _G["SVUI"];
+local L = SV.L
+local MOD = SV:NewModule(...);
+local Schema = MOD.Schema;
+
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+if(LSM) then
+	LSM:Register("background", "SVUI Model BG 2", [[Interface\TALENTFRAME\DeathKnightBlood-TopLeft]]);
+	LSM:Register("background", "SVUI Model BG 3", [[Interface\TALENTFRAME\DeathKnightFrost-TopLeft]]);
+	LSM:Register("background", "SVUI Model BG 4", [[Interface\TALENTFRAME\DeathKnightUnholy-TopLeft]]);
+	LSM:Register("background", "SVUI Model BG 5", [[Interface\TALENTFRAME\DruidBalance-TopLeft]]);
+	LSM:Register("background", "SVUI Model BG 6", [[Interface\TALENTFRAME\DruidFeralCombat-TopLeft]]);
+	LSM:Register("background", "SVUI Model BG 7", [[Interface\TALENTFRAME\DruidRestoration-TopLeft]]);
+	LSM:Register("background", "SVUI Model BG 8", [[Interface\TALENTFRAME\HunterBeastMastery-TopLeft]]);
+	LSM:Register("background", "SVUI Model BG 9", [[Interface\TALENTFRAME\HunterMarksmanship-TopLeft]]);
+	LSM:Register("background", "SVUI Model BG 10", [[Interface\TALENTFRAME\HunterPetCunning-TopLeft]]);
+	LSM:Register("background", "SVUI Model BG 11", [[Interface\TALENTFRAME\HunterPetFerocity-TopLeft]]);
+	LSM:Register("background", "SVUI Model BG 12", [[Interface\TALENTFRAME\HunterPetTenacity-TopLeft]]);
+	LSM:Register("background", "SVUI Model BG 13", [[Interface\TALENTFRAME\HunterSurvival-TopLeft]]);
+	LSM:Register("background", "SVUI Model BG 14", [[Interface\TALENTFRAME\MageArcane-TopLeft]]);
+	LSM:Register("background", "SVUI Model BG 15", [[Interface\TALENTFRAME\MageFire-TopLeft]]);
+	LSM:Register("background", "SVUI Model BG 16", [[Interface\TALENTFRAME\MageFrost-TopLeft]]);
+	LSM:Register("background", "SVUI Model BG 17", [[Interface\TALENTFRAME\PALADINCOMBAT-TOPLEFT]]);
+	LSM:Register("background", "SVUI Model BG 18", [[Interface\TALENTFRAME\PALADINHOLY-TOPLEFT]]);
+	LSM:Register("background", "SVUI Model BG 19", [[Interface\TALENTFRAME\PALADINPROTECTION-TOPLEFT]]);
+	LSM:Register("background", "SVUI Model BG 20", [[Interface\TALENTFRAME\PriestDiscipline-TopLeft]]);
+	LSM:Register("background", "SVUI Model BG 21", [[Interface\TALENTFRAME\PriestHoly-TopLeft]]);
+	LSM:Register("background", "SVUI Model BG 22", [[Interface\TALENTFRAME\PriestShadow-TopLeft]]);
+	LSM:Register("background", "SVUI Model BG 23", [[Interface\TALENTFRAME\RogueAssassination-TopLeft]]);
+	LSM:Register("background", "SVUI Model BG 24", [[Interface\TALENTFRAME\RogueCombat-TopLeft]]);
+	LSM:Register("background", "SVUI Model BG 25", [[Interface\TALENTFRAME\RogueSubtlety-TopLeft]]);
+	LSM:Register("background", "SVUI Model BG 26", [[Interface\TALENTFRAME\ShamanElementalCombat-TopLeft]]);
+	LSM:Register("background", "SVUI Model BG 27", [[Interface\TALENTFRAME\ShamanEnhancement-TopLeft]]);
+	LSM:Register("background", "SVUI Model BG 28", [[Interface\TALENTFRAME\ShamanRestoration-TopLeft]]);
+	LSM:Register("background", "SVUI Model BG 29", [[Interface\TALENTFRAME\WarlockCurses-TopLeft]]);
+	LSM:Register("background", "SVUI Model BG 30", [[Interface\TALENTFRAME\WarlockDestruction-TopLeft]]);
+	LSM:Register("background", "SVUI Model BG 31", [[Interface\TALENTFRAME\WarlockSummoning-TopLeft]]);
+	LSM:Register("background", "SVUI Model BG 32", [[Interface\TALENTFRAME\WarriorArm-TopLeft]]);
+	LSM:Register("background", "SVUI Model BG 33", [[Interface\TALENTFRAME\WarriorArms-TopLeft]]);
+	LSM:Register("background", "SVUI Model BG 34", [[Interface\TALENTFRAME\WarriorFury-TopLeft]]);
+	LSM:Register("background", "SVUI Model BG 35", [[Interface\TALENTFRAME\WarriorProtection-TopLeft]]);
+end
+
+SV.defaults[Schema] = {
+	["enable"] = true,
+	["enableAddonDock"] = true,
+	["blizzard"] = {
+		["enable"] = true,
+		["bags"] = true,
+		["bmah"] = true,
+		["chat"] = true,
+		["reforge"] = true,
+		["calendar"] = true,
+		["achievement"] = true,
+		["lfguild"] = true,
+		["inspect"] = true,
+		["binding"] = true,
+		["gbank"] = true,
+		["archaeology"] = true,
+		["guildcontrol"] = true,
+		["gossip"] = true,
+		["guild"] = true,
+		["tradeskill"] = true,
+		["raid"] = false,
+		["talent"] = true,
+		["auctionhouse"] = true,
+		["barber"] = true,
+		["macro"] = true,
+		["debug"] = true,
+		["trainer"] = true,
+		["socket"] = true,
+		["loot"] = true,
+		["alertframes"] = true,
+		["bgscore"] = true,
+		["merchant"] = true,
+		["mail"] = true,
+		["help"] = true,
+		["trade"] = true,
+		["gossip"] = true,
+		["greeting"] = true,
+		["worldmap"] = true,
+		["taxi"] = true,
+		["quest"] = true,
+		["petition"] = true,
+		["dressingroom"] = true,
+		["pvp"] = true,
+		["lfg"] = true,
+		["nonraid"] = true,
+		["friends"] = true,
+		["spellbook"] = true,
+		["character"] = true,
+		["misc"] = true,
+		["tabard"] = true,
+		["guildregistrar"] = true,
+		["timemanager"] = true,
+		["encounterjournal"] = true,
+		["voidstorage"] = true,
+		["transmogrify"] = true,
+		["stable"] = true,
+		["bgmap"] = true,
+		["mounts"] = true,
+		["petbattleui"] = true,
+		["losscontrol"] = true,
+		["itemUpgrade"] = true,
+		["talkingHead"] = true,
+	},
+	["addons"] = {
+		["enable"] = true,
+		['ACP'] = true,
+		['AdiBags'] = true,
+		['Altoholic'] = true,
+		['AtlasLoot'] = true,
+		['AuctionLite'] = true,
+		['alDamageMeter'] = true,
+		['BigWigs'] = true,
+		['Bugsack'] = true,
+		['Clique'] = true,
+		['Cooline'] = true,
+		['Details'] = true,
+		['DBM'] = true,
+		['DXE'] = true,
+		['LightHeaded'] = true,
+		['MasterPlan'] = true,
+		['Mogit'] = true,
+		['Omen'] = true,
+		['Outfitter'] = true,
+		['Postal'] = true,
+		['Quartz'] = true,
+		['Recount'] = true,
+		['SexyCooldown'] = true,
+		['Skada'] = true,
+		['Storyline'] = true,
+		['TinyDPS'] = true,
+		['TomTom'] = true,
+		['TradeSkillDW'] = true,
+		['VEM'] = true,
+		['ZygorGuidesViewer'] = true,
+	},
+};
+
+local function AddonConfigOptions()
+	local t = {};
+	for addonName,_ in pairs(SV.db[Schema].addons) do
+		t[addonName] = {
+			type = "toggle",
+			name = addonName,
+			desc = L["Addon Styling"],
+			get = function(key) return MOD:IsAddonReady(key[#key]) end,
+			set = function(key,value) MOD:ChangeDBVar(value, key[#key], "addons"); SV:StaticPopup_Show("RL_CLIENT") end,
+		}
+	end
+	return t;
+end
+
+function MOD:LoadOptions()
+	SV.Options.args.Dock.args.AddonDocklets = {
+		order = 13,
+		type = "group",
+		name = L["Docked Addons"],
+		guiInline = true,
+		args = {
+			enableAddonDock = {
+				type = "toggle",
+				order = 1,
+				width = "full",
+				name = "Enable Docking",
+				get = function() return SV.db[Schema].enableAddonDock end,
+				set = function(a,value) SV.db[Schema].enableAddonDock = value; MOD:RegisterAddonDocklets() end,
+			},
+			DockletMain = {
+				type = "select",
+				order = 2,
+				name = "Primary Docklet",
+				desc = "Select an addon to occupy the primary docklet window",
+				disabled = function() return not SV.db[Schema].enableAddonDock end,
+				values = function() return MOD:GetDockables() end,
+				get = function() return SV.private.Docks.Embed1 end,
+				set = function(a,value) SV.private.Docks.Embed1 = value; MOD:RegisterAddonDocklets() end,
+			},
+			DockletSplit = {
+				type = "select",
+				order = 3,
+				name = "Secondary Docklet",
+				desc = "Select another addon",
+				disabled = function() return not SV.db[Schema].enableAddonDock end,
+				values = function() return MOD:GetDockables(true) end,
+				get = function() return SV.private.Docks.Embed2 end,
+				set = function(a,value) SV.private.Docks.Embed2 = value; MOD:RegisterAddonDocklets() end,
+			}
+		}
+	};
+
+	SV.Options.args[Schema] = {
+		type = 'group',
+		name = Schema,
+		args = {
+			blizzardEnable = {
+			    order = 2,
+				name = "Standard UI Styling",
+			    type = "toggle",
+			    get = function(key) return SV.db[Schema].blizzard.enable end,
+			    set = function(key,value) SV.db[Schema].blizzard.enable = value; SV:StaticPopup_Show("RL_CLIENT") end
+			},
+			addonEnable = {
+			    order = 3,
+				name = "Addon Styling",
+			    type = "toggle",
+			    get = function(key) return SV.db[Schema].addons.enable end,
+			    set = function(key,value) SV.db[Schema].addons.enable = value; SV:StaticPopup_Show("RL_CLIENT") end
+			},
+			addons = {
+				order = 4,
+				type = "group",
+				name = "Addon Styling",
+				get = function(key) return SV.db[Schema].addons[key[#key]] end,
+				set = function(key,value) SV.db[Schema].addons[key[#key]] = value; SV:StaticPopup_Show("RL_CLIENT")end,
+				disabled = function() return not SV.db[Schema].addons.enable end,
+				guiInline = true,
+				args = AddonConfigOptions()
+			},
+			blizzard = {
+				order = 300,
+				type = "group",
+				name = "Individual Mods",
+				get = function(key) return SV.db[Schema].blizzard[key[#key]] end,
+				set = function(key,value) SV.db[Schema].blizzard[key[#key]] = value; SV:StaticPopup_Show("RL_CLIENT") end,
+				disabled = function() return not SV.db[Schema].blizzard.enable end,
+				guiInline = true,
+				args = {
+					bmah = {
+						type = "toggle",
+						name = L["Black Market AH"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					chat = {
+						type = "toggle",
+						name = L["Chat Menus"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					transmogrify = {
+						type = "toggle",
+						name = L["Transmogrify Frame"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					encounterjournal = {
+						type = "toggle",
+						name = L["Encounter Journal"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					reforge = {
+						type = "toggle",
+						name = L["Reforge Frame"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					calendar = {
+						type = "toggle",
+						name = L["Calendar Frame"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					achievement = {
+						type = "toggle",
+						name = L["Achievement Frame"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					lfguild = {
+						type = "toggle",
+						name = L["LF Guild Frame"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					inspect = {
+						type = "toggle",
+						name = L["Inspect Frame"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					binding = {
+						type = "toggle",
+						name = L["KeyBinding Frame"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					gbank = {
+						type = "toggle",
+						name = L["Guild Bank"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					archaeology = {
+						type = "toggle",
+						name = L["Archaeology Frame"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					guildcontrol = {
+						type = "toggle",
+						name = L["Guild Control Frame"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					guild = {
+						type = "toggle",
+						name = L["Guild Frame"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					tradeskill = {
+						type = "toggle",
+						name = L["TradeSkill Frame"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					raid = {
+						type = "toggle",
+						name = L["Raid Frame"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					talent = {
+						type = "toggle",
+						name = L["Talent Frame"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					auctionhouse = {
+						type = "toggle",
+						name = L["Auction Frame"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					timemanager = {
+						type = "toggle",
+						name = L["Time Manager"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					barber = {
+						type = "toggle",
+						name = L["Barbershop Frame"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					macro = {
+						type = "toggle",
+						name = L["Macro Frame"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					debug = {
+						type = "toggle",
+						name = L["Debug Tools"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					trainer = {
+						type = "toggle",
+						name = L["Trainer Frame"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					socket = {
+						type = "toggle",
+						name = L["Socket Frame"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					alertframes = {
+						type = "toggle",
+						name = L["Alert Frames"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					loot = {
+						type = "toggle",
+						name = L["Loot Frames"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					bgscore = {
+						type = "toggle",
+						name = L["BG Score"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					merchant = {
+						type = "toggle",
+						name = L["Merchant Frame"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					mail = {
+						type = "toggle",
+						name = L["Mail Frame"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					help = {
+						type = "toggle",
+						name = L["Help Frame"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					trade = {
+						type = "toggle",
+						name = L["Trade Frame"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					gossip = {
+						type = "toggle",
+						name = L["Gossip Frame"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					greeting = {
+						type = "toggle",
+						name = L["Greeting Frame"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					worldmap = {
+						type = "toggle",
+						name = L["World Map"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					taxi = {
+						type = "toggle",
+						name = L["Taxi Frame"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					lfg = {
+						type = "toggle",
+						name = L["LFG Frame"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					mounts = {
+						type = "toggle",
+						name = L["Collections"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					quest = {
+						type = "toggle",
+						name = L["Quest Frames"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					petition = {
+						type = "toggle",
+						name = L["Petition Frame"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					dressingroom = {
+						type = "toggle",
+						name = L["Dressing Room"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					pvp = {
+						type = "toggle",
+						name = L["PvP Frames"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					nonraid = {
+						type = "toggle",
+						name = L["Non-Raid Frame"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					friends = {
+						type = "toggle",
+						name = L["Friends"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					spellbook = {
+						type = "toggle",
+						name = L["Spellbook"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					character = {
+						type = "toggle",
+						name = L["Character Frame"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					misc = {
+						type = "toggle",
+						name = L["Misc Frames"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					tabard = {
+						type = "toggle",
+						name = L["Tabard Frame"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					guildregistrar = {
+						type = "toggle",
+						name = L["Guild Registrar"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					bags = {
+						type = "toggle",
+						name = L["Bags"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					stable = {
+						type = "toggle",
+						name = L["Stable"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					bgmap = {
+						type = "toggle",
+						name = L["BG Map"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					petbattleui = {
+						type = "toggle",
+						name = L["Pet Battle"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					losscontrol = {
+						type = "toggle",
+						name = L["Loss Control"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					voidstorage = {
+						type = "toggle",
+						name = L["Void Storage"],
+						desc = L["TOGGLEART_DESC"]
+					},
+					itemUpgrade = {
+						type = "toggle",
+						name = L["Item Upgrade"],
+						desc = L["TOGGLEART_DESC"]
+					}
+				}
+			}
+		}
+	}
+end
diff --git a/SVUI_Skins/SVUI_Skins.lua b/SVUI_Skins/SVUI_Skins.lua
new file mode 100644
index 0000000..8cea6a5
--- /dev/null
+++ b/SVUI_Skins/SVUI_Skins.lua
@@ -0,0 +1,369 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local type 		= _G.type;
+local tostring 	= _G.tostring;
+local print 	= _G.print;
+local pcall 	= _G.pcall;
+local tinsert 	= _G.tinsert;
+local string 	= _G.string;
+local math 		= _G.math;
+local table 	= _G.table;
+--[[ STRING METHODS ]]--
+local format,find = string.format, string.find;
+--[[ MATH METHODS ]]--
+local floor = math.floor;
+--[[ TABLE METHODS ]]--
+local twipe, tcopy = table.wipe, table.copy;
+local IsAddOnLoaded = _G.IsAddOnLoaded;
+local LoadAddOn = _G.LoadAddOn;
+--BLIZZARD API
+local InCombatLockdown      = _G.InCombatLockdown;
+local CreateFrame           = _G.CreateFrame;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G["SVUI"];
+local L = SV.L
+local MOD = SV.Skins;
+if(not MOD) then return end;
+local NewHook = hooksecurefunc;
+local Schema = MOD.Schema;
+local VERSION = MOD.Version;
+--[[
+##########################################################
+CORE DATA
+##########################################################
+]]--
+MOD.AddOnQueue = {};
+MOD.AddOnEvents = {};
+MOD.CustomQueue = {};
+MOD.EventListeners = {};
+MOD.OnLoadAddons = {};
+MOD.SkinnedAddons = {};
+MOD.Debugging = false;
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+local charming = {"Spiffy", "Pimped Out", "Fancy", "Awesome", "Bad Ass", "Sparkly", "Gorgeous", "Handsome", "Shiny"}
+local styleMessage = '|cffFFAA00[Skinned]|r |cff00FF77%s|r Is Now %s!'
+
+local function ListSkinnedAddons(msg, prefix)
+	for style,_ in pairs(MOD.SkinnedAddons) do
+		local verb = charming[math.random(1,#charming)]
+		SV:AddonMessage(styleMessage:format(style, verb))
+	end
+end
+
+function MOD:LoadAlert(MainText, Function)
+	self.Alert.Text:SetText(MainText)
+	self.Alert.Accept:SetScript('OnClick', Function)
+	self.Alert:Show()
+end
+
+function MOD:Style(style, fn, ...)
+	local pass, catch = pcall(fn, ...)
+	--self.Debugging = true
+	if(catch and self.Debugging) then
+		SV:HandleError("SKINS", style, catch);
+		return
+	end
+	if(pass and (not style:find("Blizzard")) and not self.SkinnedAddons[style]) then
+		self.SkinnedAddons[style] = true
+		self.AddOnQueue[style] = nil
+	end
+	self.Debugging = false
+end
+
+function MOD:IsAddonReady(addon, ...)
+	if not SV.db.Skins.addons then return end
+	for i = 1, select('#', ...) do
+		local a = select(i, ...)
+		if not a then break end
+		if not IsAddOnLoaded(a) then return false end
+	end
+
+	return SV.db.Skins.addons[addon]
+end
+
+function MOD:SaveAddonStyle(addon, fn, force, passive, ...)
+	self:DefineEventFunction("PLAYER_ENTERING_WORLD", addon)
+	if(passive) then
+		self:DefineEventFunction("ADDON_LOADED", addon)
+	end
+	for i=1, select("#",...) do
+		local event = select(i,...)
+		if(event) then
+			self:DefineEventFunction(event, addon)
+		end
+	end
+	if(SV.defaults.Skins.addons and SV.defaults.Skins.addons[addon] == nil) then
+		SV.defaults.Skins.addons[addon] = true
+	end
+
+	if force then
+		fn()
+	else
+		self.AddOnQueue[addon] = fn
+	end
+end
+
+function MOD:SaveBlizzardStyle(addon, fn, force)
+	if force then
+		if(not IsAddOnLoaded(addon)) then
+			LoadAddOn(addon)
+		end
+		fn()
+	else
+		self.OnLoadAddons[addon] = fn
+	end
+end
+
+function MOD:SaveCustomStyle(fn)
+	tinsert(MOD.CustomQueue, fn)
+end
+
+function MOD:DefineEventFunction(addonEvent, addon)
+	if(not addon) then return end
+	if(not self.EventListeners[addonEvent]) then
+		self.EventListeners[addonEvent] = {}
+	end
+	self.EventListeners[addonEvent][addon] = true
+	if(not self[addonEvent]) then
+		self[addonEvent] = function(self, event, ...)
+			for name,fn in pairs(self.AddOnQueue) do
+				if self:IsAddonReady(name) and self.EventListeners[event] and self.EventListeners[event][name] then
+					self:Style(name, fn, event, ...)
+				end
+			end
+		end
+		self:RegisterEvent(addonEvent);
+	end
+end
+
+function MOD:SafeEventRemoval(addon, event)
+	if not self.EventListeners[event] then return end
+	if not self.EventListeners[event][addon] then return end
+	self.EventListeners[event][addon] = nil;
+	local defined = false;
+	for name,_ in pairs(self.EventListeners[event]) do
+		if name then
+			defined = true;
+			break
+		end
+	end
+	if not defined then
+		self:UnregisterEvent(event)
+	end
+end
+
+function MOD:PLAYER_ENTERING_WORLD(event, ...)
+	for addonName,fn in pairs(self.OnLoadAddons) do
+		if(IsAddOnLoaded(addonName)) then
+			--print(addonName)
+			--self.Debugging = true
+			self:Style(addonName, fn, event, ...)
+			self.OnLoadAddons[addonName] = nil
+		end
+	end
+
+	for _,fn in pairs(self.CustomQueue)do
+		--print(_)
+		fn(event, ...)
+	end
+
+	twipe(self.CustomQueue)
+
+	local listener = self.EventListeners[event]
+	for addonName,fn in pairs(self.AddOnQueue)do
+		if(SV.db.Skins.addons[addonName] == nil) then
+			SV.db.Skins.addons[addonName] = true
+		end
+		if(listener[addonName] and self:IsAddonReady(addonName)) then
+			self:Style(addonName, fn, event, ...)
+		end
+	end
+
+	SV.Events:Trigger("REQUEST_TEMPLATE_UPDATED");
+end
+
+function MOD:ADDON_LOADED(event, addon)
+	--print(addon)
+	local needsUpdate = false
+	for name, fn in pairs(self.OnLoadAddons) do
+		if(addon:find(name)) then
+			--self.Debugging = true
+			self:Style(name, fn, event, addon)
+			self.OnLoadAddons[name] = nil
+			needsUpdate = true
+		end
+	end
+
+	local listener = self.EventListeners[event]
+	if(listener) then
+		for name, fn in pairs(self.AddOnQueue) do
+			if(listener[name] and self:IsAddonReady(name)) then
+				self:Style(name, fn, event, addon)
+				needsUpdate = true
+			end
+		end
+	end
+
+	-- if(addon == 'SVUI_!Options') then
+	-- 	self:Style(addon, MOD.StyleSVUIOptions)
+	-- end
+
+	if(needsUpdate) then
+		SV.Events:Trigger("REQUEST_TEMPLATE_UPDATED");
+	end
+end
+--[[
+##########################################################
+CUSTOM HANDLERS
+##########################################################
+]]--
+local AddonDockletToggle = function(self)
+	if(not MOD.Docklet:IsShown()) then
+		MOD.Docklet:Show()
+	end
+	if(not MOD.Docklet.Dock1:IsShown()) then
+		MOD.Docklet.Dock1:Show()
+	end
+	if(not MOD.Docklet.Dock2:IsShown()) then
+		MOD.Docklet.Dock2:Show()
+	end
+end
+
+local ShowSubDocklet = function(self)
+	local frame  = self.FrameLink
+	if(frame and frame.Show) then
+		if(InCombatLockdown() and (frame.IsProtected and frame:IsProtected())) then return end
+		if(not frame:IsShown()) then
+			frame:Show()
+		end
+	end
+end
+
+local HideSubDocklet = function(self)
+	local frame  = self.FrameLink
+	if(frame and frame.Hide) then
+		if(InCombatLockdown() and (frame.IsProtected and frame:IsProtected())) then return end
+		if(frame:IsShown()) then
+			frame:Hide()
+		end
+	end
+end
+
+local function DockExpandDocklet(location)
+	if(not location or (location ~= MOD.Docklet.Parent.Bar.Data.Location)) then return end
+	MOD.Docklet:UpdateEmbeds()
+end
+
+local function DockFadeInDocklet(location)
+	if(not location or (location ~= MOD.Docklet.Parent.Bar.Data.Location)) then return end
+	local active = MOD.Docklet.Button.ActiveDocklet
+	if(active) then
+		MOD.Docklet.Dock1:Show()
+		MOD.Docklet.Dock2:Show()
+	end
+end
+
+local function DockFadeOutDocklet(location)
+	if(not location or (location ~= MOD.Docklet.Parent.Bar.Data.Location)) then return end
+	local active = MOD.Docklet.Button.ActiveDocklet
+	if(active) then
+		MOD.Docklet.Dock1:Hide()
+		MOD.Docklet.Dock2:Hide()
+	end
+end
+--[[
+##########################################################
+BUILD FUNCTION
+##########################################################
+]]--
+function MOD:ReLoad()
+	self:RegisterAddonDocklets()
+end
+
+function MOD:Load()
+	SV.private.Docks = SV.private.Docks or {"None", "None"}
+
+	local alert = CreateFrame('Frame', nil, UIParent);
+	alert:SetStyle("!_Frame", 'Transparent');
+	alert:SetSize(250, 70);
+	alert:SetPoint('CENTER', UIParent, 'CENTER');
+	alert:SetFrameStrata('DIALOG');
+	alert.Text = alert:CreateFontString(nil, "OVERLAY");
+	alert.Text:SetFont(SV.media.font.dialog, 12);
+	alert.Text:SetPoint('TOP', alert, 'TOP', 0, -10);
+	alert.Accept = CreateFrame('Button', nil, alert);
+	alert.Accept:SetSize(70, 25);
+	alert.Accept:SetPoint('RIGHT', alert, 'BOTTOM', -10, 20);
+	alert.Accept.Text = alert.Accept:CreateFontString(nil, "OVERLAY");
+	alert.Accept.Text:SetFont(SV.media.font.dialog, 10);
+	alert.Accept.Text:SetPoint('CENTER');
+	alert.Accept.Text:SetText(_G.YES);
+	alert.Close = CreateFrame('Button', nil, alert);
+	alert.Close:SetSize(70, 25);
+	alert.Close:SetPoint('LEFT', alert, 'BOTTOM', 10, 20);
+	alert.Close:SetScript('OnClick', function(this) this:GetParent():Hide() end);
+	alert.Close.Text = alert.Close:CreateFontString(nil, "OVERLAY");
+	alert.Close.Text:SetFont(SV.media.font.dialog, 10);
+	alert.Close.Text:SetPoint('CENTER');
+	alert.Close.Text:SetText(_G.NO);
+	alert.Accept:SetStyle("Button");
+	alert.Close:SetStyle("Button");
+	alert:Hide();
+
+	self.Alert = alert;
+
+	self.Docklet = SV.Dock:NewDocklet("BottomRight", "SVUI_SkinsDock", "Addon Docklet", [[Interface\AddOns\SVUI_Skins\artwork\DOCK-ICON-ADDON]]);
+	--self.Docklet:SetVisibilityCallbacks(false, false);
+	self.Docklet:SetClickCallbacks(AddonDockletToggle, false, self.GetAddonDockMenu);
+
+	--SV.Dock.BottomRight.Bar.Button.GetDockOptions = self.GetAddonDockMenu;
+
+	local dockWidth = self.Docklet:GetWidth()
+
+	self.Docklet.Dock1 = CreateFrame("Frame", "SVUI_SkinsDockAddon1", self.Docklet);
+	self.Docklet.Dock1:SetPoint('TOPLEFT', self.Docklet, 'TOPLEFT', -1, 0);
+	self.Docklet.Dock1:SetPoint('BOTTOMLEFT', self.Docklet, 'BOTTOMLEFT', -1, -1);
+	self.Docklet.Dock1:SetWidth(dockWidth);
+	self.Docklet.Dock1:SetScript('OnShow', ShowSubDocklet);
+	self.Docklet.Dock1:SetScript('OnHide', HideSubDocklet);
+
+	self.Docklet.Dock2 = CreateFrame("Frame", "SVUI_SkinsDockAddon2", self.Docklet);
+	self.Docklet.Dock2:SetPoint('TOPLEFT', self.Docklet.Dock1, 'TOPRIGHT', 0, 0);
+	self.Docklet.Dock2:SetPoint('BOTTOMRIGHT', self.Docklet, 'BOTTOMRIGHT', 1, -1);
+	self.Docklet.Dock2:SetWidth(dockWidth * 0.5);
+	self.Docklet.Dock2:SetScript('OnShow', ShowSubDocklet);
+	self.Docklet.Dock2:SetScript('OnHide', HideSubDocklet);
+
+	self:SetEmbedHandlers()
+
+	self.Docklet:Hide()
+
+	self:RegisterAddonDocklets()
+
+	self:RegisterEvent("PLAYER_ENTERING_WORLD");
+	self:RegisterEvent("ADDON_LOADED");
+
+	SV:AddSlashCommand("skinned", "List all addons skinned by SVUI", ListSkinnedAddons);
+
+	SV.Events:On("DOCK_FADE_IN", DockFadeInDocklet, true);
+	SV.Events:On("DOCK_FADE_OUT", DockFadeOutDocklet, true);
+	SV.Events:On("DOCK_EXPANDED", DockExpandDocklet, true);
+end
diff --git a/SVUI_Skins/SVUI_Skins.toc b/SVUI_Skins/SVUI_Skins.toc
new file mode 100644
index 0000000..e156ea8
--- /dev/null
+++ b/SVUI_Skins/SVUI_Skins.toc
@@ -0,0 +1,18 @@
+## Interface: 70000
+## Author: Failcoder, Azilroka, Sortokk
+## Version: 1.3.5
+## Title: |cffFF9900SuperVillain UI: |r|cffFFEF00Skins|r
+## Notes: SVUI [|cff9911FFSkins System and AddOn Frames|r].
+## SavedVariables: SVUIUI_STYLE_GLOBAL
+## SavedVariablesPerCharacter: SVUIUI_STYLE_PROFILE, SVUIUI_STYLE_PRIVATE
+## RequiredDeps: SVUI_!Core
+## OptionalDeps: LibSharedMedia-3.0
+## X-SVUIName: Skins
+## X-SVUISchema: Skins
+## X-Email: munglunch@gmail.com
+## X-Website: http://www.supervillainui.com
+## X-Donate: PayPal:munglunch@gmail.com
+## X-License: MIT
+## X-Category: Interface Enhancements
+
+SVUI_Skins.xml
diff --git a/SVUI_Skins/SVUI_Skins.xml b/SVUI_Skins/SVUI_Skins.xml
new file mode 100644
index 0000000..06846b4
--- /dev/null
+++ b/SVUI_Skins/SVUI_Skins.xml
@@ -0,0 +1,5 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+	<Script file='Loader.lua'/>
+	<Script file='SVUI_Skins.lua'/>
+	<Include file='components\_load.xml'/>
+</Ui>
\ No newline at end of file
diff --git a/SVUI_Skins/artwork/Arch-Progress-Bg.blp b/SVUI_Skins/artwork/Arch-Progress-Bg.blp
new file mode 100644
index 0000000..f687762
Binary files /dev/null and b/SVUI_Skins/artwork/Arch-Progress-Bg.blp differ
diff --git a/SVUI_Skins/artwork/Arch-Progress-Fill.blp b/SVUI_Skins/artwork/Arch-Progress-Fill.blp
new file mode 100644
index 0000000..74b84c2
Binary files /dev/null and b/SVUI_Skins/artwork/Arch-Progress-Fill.blp differ
diff --git a/SVUI_Skins/artwork/ArcheologyToast.blp b/SVUI_Skins/artwork/ArcheologyToast.blp
new file mode 100644
index 0000000..17a6c92
Binary files /dev/null and b/SVUI_Skins/artwork/ArcheologyToast.blp differ
diff --git a/SVUI_Skins/artwork/DOCK-ICON-ADDON.blp b/SVUI_Skins/artwork/DOCK-ICON-ADDON.blp
new file mode 100644
index 0000000..c38f93a
Binary files /dev/null and b/SVUI_Skins/artwork/DOCK-ICON-ADDON.blp differ
diff --git a/SVUI_Skins/artwork/FAVORITE-STAR.blp b/SVUI_Skins/artwork/FAVORITE-STAR.blp
new file mode 100644
index 0000000..8c89657
Binary files /dev/null and b/SVUI_Skins/artwork/FAVORITE-STAR.blp differ
diff --git a/SVUI_Skins/artwork/FOLLOWER-LEVEL.blp b/SVUI_Skins/artwork/FOLLOWER-LEVEL.blp
new file mode 100644
index 0000000..0c646b4
Binary files /dev/null and b/SVUI_Skins/artwork/FOLLOWER-LEVEL.blp differ
diff --git a/SVUI_Skins/artwork/FOLLOWER-RING.blp b/SVUI_Skins/artwork/FOLLOWER-RING.blp
new file mode 100644
index 0000000..9a7ade9
Binary files /dev/null and b/SVUI_Skins/artwork/FOLLOWER-RING.blp differ
diff --git a/SVUI_Skins/artwork/UI-LFG-ICON-ROLES.blp b/SVUI_Skins/artwork/UI-LFG-ICON-ROLES.blp
new file mode 100644
index 0000000..82a7726
Binary files /dev/null and b/SVUI_Skins/artwork/UI-LFG-ICON-ROLES.blp differ
diff --git a/SVUI_Skins/artwork/UI-LFG-ICONS-ROLEBACKGROUNDS.blp b/SVUI_Skins/artwork/UI-LFG-ICONS-ROLEBACKGROUNDS.blp
new file mode 100644
index 0000000..607f5da
Binary files /dev/null and b/SVUI_Skins/artwork/UI-LFG-ICONS-ROLEBACKGROUNDS.blp differ
diff --git a/SVUI_Skins/components/_load.xml b/SVUI_Skins/components/_load.xml
new file mode 100644
index 0000000..39e3923
--- /dev/null
+++ b/SVUI_Skins/components/_load.xml
@@ -0,0 +1,6 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+	<Script file='docklet.lua'/>
+	<Script file='atlas.lua'/>
+	<Include file='blizzard\_load.xml'/>
+	<Include file='addons\_load.xml'/>
+</Ui>
\ No newline at end of file
diff --git a/SVUI_Skins/components/addons/ACP.lua b/SVUI_Skins/components/addons/ACP.lua
new file mode 100644
index 0000000..2770e87
--- /dev/null
+++ b/SVUI_Skins/components/addons/ACP.lua
@@ -0,0 +1,96 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+ACP
+##########################################################
+]]--
+local function cbResize(self,elapsed)
+	self.timeLapse = self.timeLapse + elapsed
+	if(self.timeLapse < 2) then
+		return
+	else
+		self.timeLapse = 0
+	end
+	for i=1,20,1 do
+		local d=_G["ACP_AddonListEntry"..i.."Enabled"]
+		local e=_G["ACP_AddonListEntry"..i.."Collapse"]
+		local f=_G["ACP_AddonListEntry"..i.."Security"]
+		local g=""
+		if g=="" then
+			d:SetPoint("LEFT",5,0)
+			if e:IsShown()then
+				d:SetWidth(26)
+				d:SetHeight(26)
+			else
+				d:SetPoint("LEFT",15,0)
+				d:SetWidth(20)
+				d:SetHeight(20)
+			end
+		end
+		if f:IsShown()then
+			d:SetPoint("LEFT",5,0)
+			d:SetWidth(26)
+			d:SetHeight(26)
+		end
+	end
+end
+
+local function StyleACP()
+	assert(ACP_AddonList, "AddOn Not Loaded")
+
+	SV.API:Set("Frame", ACP_AddonList)
+	SV.API:Set("Frame", ACP_AddonList_ScrollFrame)
+	local h={"ACP_AddonListSetButton","ACP_AddonListDisableAll","ACP_AddonListEnableAll","ACP_AddonList_ReloadUI","ACP_AddonListBottomClose"}
+	for i,j in pairs(h)do _G[j]:SetStyle("Button")end
+	for c=1,20 do _G["ACP_AddonListEntry"..c.."LoadNow"]:SetStyle("Button")end
+	SV.API:Set("CloseButton", ACP_AddonListCloseButton)
+	for c=1,20,1 do
+		local k=_G["ACP_AddonList"]
+		k.timeLapse = 0
+		k:SetScript("OnUpdate",cbResize)
+	end
+	for c=1,20 do
+		_G["ACP_AddonListEntry"..c.."Enabled"]:SetStyle("CheckButton")
+	end
+	ACP_AddonList_NoRecurse:SetStyle("CheckButton")
+	SV.API:Set("ScrollBar", ACP_AddonList_ScrollFrameScrollBar)
+	SV.API:Set("DropDown", ACP_AddonListSortDropDown)
+	ACP_AddonListSortDropDown:SetWidth(130)
+	ACP_AddonList_ScrollFrame:SetWidth(590)
+	ACP_AddonList_ScrollFrame:SetHeight(412)
+	ACP_AddonList:SetHeight(502)
+	ACP_AddonListEntry1:SetPoint("TOPLEFT",ACP_AddonList,"TOPLEFT",47,-62)
+	ACP_AddonList_ScrollFrame:SetPoint("TOPLEFT",ACP_AddonList,"TOPLEFT",20,-53)
+	ACP_AddonListCloseButton:SetPoint("TOPRIGHT",ACP_AddonList,"TOPRIGHT",4,5)
+	ACP_AddonListSetButton:SetPoint("BOTTOMLEFT",ACP_AddonList,"BOTTOMLEFT",20,8)
+	ACP_AddonListSetButton:SetHeight(25)
+	ACP_AddonListDisableAll:SetPoint("BOTTOMLEFT",ACP_AddonList,"BOTTOMLEFT",90,8)
+	ACP_AddonListDisableAll:SetHeight(25)
+	ACP_AddonListEnableAll:SetPoint("BOTTOMLEFT",ACP_AddonList,"BOTTOMLEFT",175,8)
+	ACP_AddonListEnableAll:SetHeight(25)
+	ACP_AddonList_ReloadUI:SetPoint("BOTTOMRIGHT",ACP_AddonList,"BOTTOMRIGHT",-160,8)
+	ACP_AddonListBottomClose:SetPoint("BOTTOMRIGHT",ACP_AddonList,"BOTTOMRIGHT",-50,8)
+	ACP_AddonListBottomClose:SetHeight(25)ACP_AddonList:SetParent(UIParent)
+end
+
+MOD:SaveAddonStyle("ACP", StyleACP)
\ No newline at end of file
diff --git a/SVUI_Skins/components/addons/Ace3.lua b/SVUI_Skins/components/addons/Ace3.lua
new file mode 100644
index 0000000..b88773e
--- /dev/null
+++ b/SVUI_Skins/components/addons/Ace3.lua
@@ -0,0 +1,268 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+--[[
+##########################################################
+HELPERS
+##########################################################
+]]--
+local RegisterAsWidget, RegisterAsContainer;
+
+local ProxyLSMType = {
+	["LSM30_Font"] = true,
+	["LSM30_Sound"] = true,
+	["LSM30_Border"] = true,
+	["LSM30_Background"] = true,
+	["LSM30_Statusbar"] = true
+}
+
+local ProxyType = {
+	["InlineGroup"] = true,
+	["TreeGroup"] = true,
+	["TabGroup"] = true,
+	["SimpleGroup"] = true,
+	["DropdownGroup"] = true
+}
+
+local function Widget_OnEnter(b)
+	b:SetBackdropBorderColor(0.1, 0.8, 0.8)
+end
+
+local function Widget_OnLeave(b)
+	b:SetBackdropBorderColor(0,0,0,1)
+end
+
+local function Widget_ScrollStyle(frame, arg)
+	return SV.API:Set("ScrollBar", frame)
+end
+
+local function Widget_ButtonStyle(frame, strip, bypass)
+	if frame.Left then frame.Left:SetAlpha(0) end
+	if frame.Middle then frame.Middle:SetAlpha(0) end
+	if frame.Right then frame.Right:SetAlpha(0) end
+	if frame.SetNormalTexture then frame:SetNormalTexture("") end
+	if frame.SetHighlightTexture then frame:SetHighlightTexture(0,0,0,0) end
+	if frame.SetPushedTexture then frame:SetPushedTexture(0,0,0,0) end
+	if frame.SetDisabledTexture then frame:SetDisabledTexture("") end
+	if strip then frame:RemoveTextures() end
+	if not bypass then
+		frame:SetStyle("Button")
+	end
+end
+
+local function Widget_PaginationStyle(...)
+	SV.API:Set("PageButton", ...)
+end
+
+local function SetAdjustedStyle(this, xTopleft, yTopleft, xBottomright, yBottomright)
+	if(not this or (this and this.Panel)) then return end
+	this:RemoveTextures()
+	this:SetStyle("Frame", "Transparent")
+	this.Panel:SetPoint("TOPLEFT", this, "TOPLEFT", xTopleft, yTopleft)
+	this.Panel:SetPoint("BOTTOMRIGHT", this, "BOTTOMRIGHT", xBottomright, yBottomright)
+end
+
+local NOOP = SV.fubar
+
+local WidgetButton_OnClick = function(self)
+	local obj = self.obj;
+	if(obj and obj.pullout and obj.pullout.frame) then
+		SV.API:Set("Frame", obj.pullout.frame, "Default", true)
+	end
+end
+
+local WidgetDropButton_OnClick = function(self)
+	local obj = self.obj;
+	local widgetFrame = obj.dropdown
+	if(widgetFrame) then
+    	widgetFrame:SetWidth(220)
+		widgetFrame:SetStyle("Frame", "Default")
+	end
+end
+--[[
+##########################################################
+AceGUI MOD
+##########################################################
+]]--
+local function StyleAceGUI(event, addon)
+	local AceGUI = LibStub("AceGUI-3.0", true)
+
+	assert(AceGUI and (AceGUI.RegisterAsContainer ~= RegisterAsContainer or AceGUI.RegisterAsWidget ~= RegisterAsWidget), "Addon Not Loaded")
+
+	local regWidget = AceGUI.RegisterAsWidget;
+	local regContainer = AceGUI.RegisterAsContainer;
+
+	RegisterAsWidget = function(self, widget)
+
+		local widgetType = widget.type;
+		-- print("RegisterAsWidget: " .. widgetType);
+		if(widgetType == "MultiLineEditBox") then
+			local widgetFrame = widget.frame;
+			SV.API:Set("!_Frame", widgetFrame, "Default", true)
+			SV.API:Set("Frame", widget.scrollBG, "Lite", true)
+			Widget_ButtonStyle(widget.button)
+			SV.API:Set("ScrollBar", widget.scrollBar)
+			widget.scrollBar:SetPoint("RIGHT", widgetFrame, "RIGHT", -4)
+			widget.scrollBG:SetPoint("TOPRIGHT", widget.scrollBar, "TOPLEFT", -2, 19)
+			widget.scrollBG:SetPoint("BOTTOMLEFT", widget.button, "TOPLEFT")
+			widget.scrollFrame:SetPoint("BOTTOMRIGHT", widget.scrollBG, "BOTTOMRIGHT", -4, 8)
+
+		elseif(widgetType == "CheckBox") then
+			widget.checkbg:Die()
+			widget.highlight:Die()
+			if not widget.styledCheckBG then
+				widget.styledCheckBG = CreateFrame("Frame", nil, widget.frame)
+				widget.styledCheckBG:InsetPoints(widget.check)
+				SV.API:Set("!_Frame", widget.styledCheckBG, "CheckButton")
+			end
+			widget.check:SetParent(widget.styledCheckBG)
+
+		elseif(widgetType == "Dropdown") then
+			local widgetDropdown = widget.dropdown;
+			local widgetButton = widget.button;
+
+			widgetDropdown:RemoveTextures()
+			widgetButton:ClearAllPoints()
+			widgetButton:SetPoint("RIGHT", widgetDropdown, "RIGHT", -20, 0)
+			widgetButton:SetFrameLevel(widgetButton:GetFrameLevel() + 1)
+			Widget_PaginationStyle(widgetButton, true)
+
+			SetAdjustedStyle(widgetDropdown, 20, -2, -20, 2)
+
+			widgetButton:SetParent(widgetDropdown.Panel)
+			widget.text:SetParent(widgetDropdown.Panel)
+			widgetButton:HookScript("OnClick", WidgetButton_OnClick)
+
+		elseif(widgetType == "EditBox") then
+			local widgetEditbox = widget.editbox;
+			SV.API:Set("EditBox", widgetEditbox, nil, 15, 2, -2)
+
+		elseif(widgetType == "Button") then
+			local widgetFrame = widget.frame;
+			Widget_ButtonStyle(widgetFrame, true)
+			widget.text:SetParent(widgetFrame.Panel)
+
+		elseif(widgetType == "Slider") then
+			local widgetSlider = widget.slider;
+			local widgetEditbox = widget.editbox;
+
+			SV.API:Set("!_Frame", widgetSlider, "Bar")
+
+			widgetSlider:SetHeight(20)
+			widgetSlider:SetThumbTexture("Interface\\Buttons\\UI-ScrollBar-Knob")
+			widgetSlider:GetThumbTexture():SetVertexColor(0.8, 0.8, 0.8)
+
+			widgetEditbox:SetHeight(15)
+			widgetEditbox:SetPoint("TOP", widgetSlider, "BOTTOM", 0, -1)
+
+			widget.lowtext:SetPoint("TOPLEFT", widgetSlider, "BOTTOMLEFT", 2, -2)
+			widget.hightext:SetPoint("TOPRIGHT", widgetSlider, "BOTTOMRIGHT", -2, -2)
+
+		elseif(ProxyLSMType[widgetType]) then
+			local widgetFrame = widget.frame;
+			local dropButton = widgetFrame.dropButton;
+
+			widgetFrame:RemoveTextures()
+			Widget_PaginationStyle(dropButton, true)
+			widgetFrame.text:ClearAllPoints()
+			widgetFrame.text:SetPoint("RIGHT", dropButton, "LEFT", -2, 0)
+			dropButton:ClearAllPoints()
+			dropButton:SetPoint("RIGHT", widgetFrame, "RIGHT", -10, -6)
+			if(not widgetFrame.Panel) then
+				if(widgetType == "LSM30_Sound") then
+					SetAdjustedStyle(widgetFrame, 20, -17, 2, -2)
+					widget.soundbutton:SetParent(widgetFrame.Panel)
+					widget.soundbutton:ClearAllPoints()
+					widget.soundbutton:SetPoint("LEFT", widgetFrame.Panel, "LEFT", 2, 0)
+				elseif(widgetType == "LSM30_Statusbar") then
+					SetAdjustedStyle(widgetFrame, 20, -17, 2, -2)
+					widget.bar:SetParent(widgetFrame.Panel)
+					widget.bar:InsetPoints()
+				elseif(widgetType == "LSM30_Border" or widgetType == "LSM30_Background") then
+					SetAdjustedStyle(widgetFrame, 42, -17, 2, -2)
+				else
+					SetAdjustedStyle(widgetFrame, 20, -17, 2, -2)
+				end
+				widgetFrame.Panel:SetPoint("BOTTOMRIGHT", dropButton, "BOTTOMRIGHT", 2, -2)
+			end
+			dropButton:SetParent(widgetFrame.Panel)
+			widgetFrame.text:SetParent(widgetFrame.Panel)
+		end
+		return regWidget(self, widget)
+	end
+
+	AceGUI.RegisterAsWidget = RegisterAsWidget
+
+	RegisterAsContainer = function(self, widget)
+		local widgetType = widget.type;
+		-- print("RegisterAsContainer: " .. widgetType);
+		local widgetParent = widget.content:GetParent()
+		if widgetType == "ScrollFrame" then
+			SV.API:Set("ScrollBar", widget.scrollBar)
+		elseif widgetType == "Frame" then
+			for i = 1, widgetParent:GetNumChildren()do
+				local childFrame = select(i, widgetParent:GetChildren())
+				if childFrame:GetObjectType() == "Button" and childFrame:GetText() then
+					Widget_ButtonStyle(childFrame)
+				else
+					childFrame:RemoveTextures()
+				end
+			end
+			SV.API:Set("Window", widgetParent)
+		elseif(ProxyType[widgetType]) then
+
+			if widget.treeframe then
+				SV.API:Set("Frame", widget.treeframe, "Transparent")
+				widgetParent:SetPoint("TOPLEFT", widget.treeframe, "TOPRIGHT", 1, 0)
+				local oldFunc = widget.CreateButton;
+				widget.CreateButton = function(self)
+					local newButton = oldFunc(self)
+					newButton.toggle:RemoveTextures()
+					newButton.toggle.SetNormalTexture = NOOP;
+					newButton.toggle.SetPushedTexture = NOOP;
+					newButton.toggle:SetStyle("Button")
+					newButton.toggleText = newButton.toggle:CreateFontString(nil, "OVERLAY")
+					newButton.toggleText:SetFont([[Interface\AddOns\SVUI_!Core\assets\fonts\Default.ttf]], 19)
+					newButton.toggleText:SetPoint("CENTER")
+					newButton.toggleText:SetText("*")
+					return newButton
+				end
+			elseif(not widgetParent.Panel) then
+				SV.API:Set("Frame", widgetParent, "Lite")
+			end
+
+			if(widgetType == "TabGroup") then
+				local oldFunc = widget.CreateTab;
+				widget.CreateTab = function(self, arg)
+					local newTab = oldFunc(self, arg)
+					newTab:RemoveTextures()
+					return newTab
+				end
+			end
+
+			if widget.scrollbar then
+				SV.API:Set("ScrollBar", widget.scrollBar)
+			end
+		end
+		return regContainer(self, widget)
+	end
+
+	AceGUI.RegisterAsContainer = RegisterAsContainer
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+--MOD:SaveAddonStyle("SVUI_ConfigOMatic", StyleAceGUI, nil, true)
+MOD:SaveAddonStyle("AceGUI", StyleAceGUI, nil, true)
\ No newline at end of file
diff --git a/SVUI_Skins/components/addons/AdiBags.lua b/SVUI_Skins/components/addons/AdiBags.lua
new file mode 100644
index 0000000..483d0a5
--- /dev/null
+++ b/SVUI_Skins/components/addons/AdiBags.lua
@@ -0,0 +1,63 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local string 	= _G.string;
+--[[ STRING METHODS ]]--
+local format = string.format;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+ADIBAGS
+##########################################################
+]]--
+local function StyleAdiBags(event)
+	local AdiBags = LibStub('AceAddon-3.0'):GetAddon('AdiBags')
+	assert(AdiBags, "AddOn Not Loaded")
+	--hooksecurefunc(AdiBags, 'HookBagFrameCreation', function(self) print(self) end)
+
+	local function SkinFrame(frame)
+		local region = frame.HeaderRightRegion
+		frame:SetStyle("Frame", 'Transparent')
+		_G[frame:GetName()..'Bags']:SetStyle("Frame", "Default")
+		for i = 1, 3 do
+			region.widgets[i].widget:SetStyle("Button")
+		end
+	end
+
+	if event == 'PLAYER_ENTERING_WORLD' then
+		SV.Timers:ExecuteTimer(function()
+			if not AdiBagsContainer1 then ToggleBackpack() ToggleBackpack() end
+			if AdiBagsContainer1 then
+				SkinFrame(AdiBagsContainer1)
+				AdiBagsContainer1SearchBox:SetStyle("Editbox")
+				AdiBagsContainer1SearchBox:SetPoint('TOPRIGHT', AdiBagsSimpleLayeredRegion2, 'TOPRIGHT', -75, -1)
+			end
+		end, 1)
+	elseif event == 'BANKFRAME_OPENED' then
+		SV.Timers:ExecuteTimer(function()
+			if AdiBagsContainer2 then
+				SkinFrame(AdiBagsContainer2)
+				MOD:SafeEventRemoval("AdiBags", event)
+			end
+		end, 1)
+	end
+end
+
+MOD:SaveAddonStyle("AdiBags", StyleAdiBags, nil, nil, 'BANKFRAME_OPENED')
\ No newline at end of file
diff --git a/SVUI_Skins/components/addons/Altoholic.lua b/SVUI_Skins/components/addons/Altoholic.lua
new file mode 100644
index 0000000..ab557ee
--- /dev/null
+++ b/SVUI_Skins/components/addons/Altoholic.lua
@@ -0,0 +1,282 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local string 	= _G.string;
+--[[ STRING METHODS ]]--
+local format = string.format;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+ALTOHOLIC
+##########################################################
+]]--
+local function ColorAltoBorder(self)
+	if self.border then
+		local Backdrop = self.backdrop or self.Backdrop
+		if not Backdrop then return end
+		local r, g, b = self.border:GetVertexColor()
+		Backdrop:SetBackdropBorderColor(r, g, b, 1)
+	end
+end
+
+local function ApplyTextureStyle(self)
+	if not self then return end
+	self:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+	local parent = self:GetParent()
+	if(parent) then
+		self:InsetPoints(parent, 1, 1)
+	end
+end
+
+local AltoholicFrameStyled = false;
+
+local function StyleAltoholic(event, addon)
+	assert(AltoholicFrame, "AddOn Not Loaded")
+
+	if not AltoholicFrameStyled then
+		SV.API:Set("Tooltip", AltoTooltip)
+
+		AltoholicFramePortrait:Die()
+
+		SV.API:Set("Frame", AltoholicFrame, "Window2")
+		SV.API:Set("Frame", AltoMsgBox)
+		SV.API:Set("Button", AltoMsgBoxYesButton)
+		SV.API:Set("Button", AltoMsgBoxNoButton)
+		SV.API:Set("CloseButton", AltoholicFrameCloseButton)
+		SV.API:Set("EditBox", AltoholicFrame_SearchEditBox, 175, 15)
+		SV.API:Set("Button", AltoholicFrame_ResetButton)
+		SV.API:Set("Button", AltoholicFrame_SearchButton)
+
+		AltoholicFrameTab1:SetPoint("TOPLEFT", AltoholicFrame, "BOTTOMLEFT", -5, 2)
+		AltoholicFrame_ResetButton:SetPoint("TOPLEFT", AltoholicFrame, "TOPLEFT", 25, -77)
+		AltoholicFrame_SearchEditBox:SetPoint("TOPLEFT", AltoholicFrame, "TOPLEFT", 37, -56)
+		AltoholicFrame_ResetButton:SetSize(85, 24)
+		AltoholicFrame_SearchButton:SetSize(85, 24)
+		AltoholicFrameStyled = true
+	end
+
+	if IsAddOnLoaded("Altoholic_Summary") then
+		SV.API:Set("Frame", AltoholicFrameSummary)
+		SV.API:Set("Frame", AltoholicFrameBagUsage)
+		SV.API:Set("Frame", AltoholicFrameSkills)
+		SV.API:Set("Frame", AltoholicFrameActivity)
+		SV.API:Set("ScrollBar", AltoholicFrameSummaryScrollFrameScrollBar)
+		SV.API:Set("ScrollBar", AltoholicFrameBagUsageScrollFrameScrollBar)
+		SV.API:Set("ScrollBar", AltoholicFrameSkillsScrollFrameScrollBar)
+		SV.API:Set("ScrollBar", AltoholicFrameActivityScrollFrameScrollBar)
+		SV.API:Set("DropDown", AltoholicTabSummary_SelectLocation, 200)
+
+		if(AltoholicFrameSummaryScrollFrame) then
+			AltoholicFrameSummaryScrollFrame:RemoveTextures(true)
+		end
+
+		if(AltoholicFrameBagUsageScrollFrame) then
+			AltoholicFrameBagUsageScrollFrame:RemoveTextures(true)
+		end
+
+		if(AltoholicFrameSkillsScrollFrame) then
+			AltoholicFrameSkillsScrollFrame:RemoveTextures(true)
+		end
+
+		if(AltoholicFrameActivityScrollFrame) then
+			AltoholicFrameActivityScrollFrame:RemoveTextures(true)
+		end
+
+		SV.API:Set("Button", AltoholicTabSummary_RequestSharing)
+		ApplyTextureStyle(AltoholicTabSummary_RequestSharingIconTexture)
+		SV.API:Set("Button", AltoholicTabSummary_Options)
+		ApplyTextureStyle(AltoholicTabSummary_OptionsIconTexture)
+		SV.API:Set("Button", AltoholicTabSummary_OptionsDataStore)
+		ApplyTextureStyle(AltoholicTabSummary_OptionsDataStoreIconTexture)
+
+		for i = 1, 5 do
+			SV.API:Set("Button", _G["AltoholicTabSummaryMenuItem"..i], true)
+		end
+		for i = 1, 8 do
+			SV.API:Set("Button", _G["AltoholicTabSummary_Sort"..i], true)
+		end
+		for i = 1, 7 do
+			SV.API:Set("Tab", _G["AltoholicFrameTab"..i], true)
+		end
+	end
+
+	if IsAddOnLoaded("Altoholic_Characters") then
+		SV.API:Set("Frame", AltoholicFrameContainers)
+		SV.API:Set("Frame", AltoholicFrameRecipes)
+		SV.API:Set("Frame", AltoholicFrameQuests)
+		SV.API:Set("Frame", AltoholicFrameGlyphs)
+		SV.API:Set("Frame", AltoholicFrameMail)
+		SV.API:Set("Frame", AltoholicFrameSpellbook)
+		SV.API:Set("Frame", AltoholicFramePets)
+		SV.API:Set("Frame", AltoholicFrameAuctions)
+		SV.API:Set("ScrollBar", AltoholicFrameContainersScrollFrameScrollBar)
+		SV.API:Set("ScrollBar", AltoholicFrameQuestsScrollFrameScrollBar)
+		SV.API:Set("ScrollBar", AltoholicFrameRecipesScrollFrameScrollBar)
+		SV.API:Set("DropDown", AltoholicFrameTalents_SelectMember)
+		SV.API:Set("DropDown", AltoholicTabCharacters_SelectRealm)
+		SV.API:Set("PageButton", AltoholicFrameSpellbookPrevPage)
+		SV.API:Set("PageButton", AltoholicFrameSpellbookNextPage)
+		SV.API:Set("PageButton", AltoholicFramePetsNormalPrevPage)
+		SV.API:Set("PageButton", AltoholicFramePetsNormalNextPage)
+		SV.API:Set("Button", AltoholicTabCharacters_Sort1)
+		SV.API:Set("Button", AltoholicTabCharacters_Sort2)
+		SV.API:Set("Button", AltoholicTabCharacters_Sort3)
+		AltoholicFrameContainersScrollFrame:RemoveTextures(true)
+		AltoholicFrameQuestsScrollFrame:RemoveTextures(true)
+		AltoholicFrameRecipesScrollFrame:RemoveTextures(true)
+
+		local Buttons = {
+			'AltoholicTabCharacters_Characters',
+			'AltoholicTabCharacters_CharactersIcon',
+			'AltoholicTabCharacters_BagsIcon',
+			'AltoholicTabCharacters_QuestsIcon',
+			'AltoholicTabCharacters_TalentsIcon',
+			'AltoholicTabCharacters_AuctionIcon',
+			'AltoholicTabCharacters_MailIcon',
+			'AltoholicTabCharacters_SpellbookIcon',
+			'AltoholicTabCharacters_ProfessionsIcon',
+		}
+
+		for _, object in pairs(Buttons) do
+			ApplyTextureStyle(_G[object..'IconTexture'])
+			ApplyTextureStyle(_G[object])
+		end
+
+		for i = 1, 7 do
+			for j = 1, 14 do
+				SV.API:Set("ItemButton", _G["AltoholicFrameContainersEntry"..i.."Item"..j])
+				_G["AltoholicFrameContainersEntry"..i.."Item"..j]:HookScript('OnShow', ColorAltoBorder)
+			end
+		end
+	end
+
+	if IsAddOnLoaded("Altoholic_Achievements") then
+		SV.API:Set("!_Frame", AltoholicFrameAchievements)
+		AltoholicFrameAchievementsScrollFrame:RemoveTextures(true)
+		AltoholicAchievementsMenuScrollFrame:RemoveTextures(true)
+		SV.API:Set("ScrollBar", AltoholicFrameAchievementsScrollFrameScrollBar)
+		SV.API:Set("ScrollBar", AltoholicAchievementsMenuScrollFrameScrollBar)
+		SV.API:Set("DropDown", AltoholicTabAchievements_SelectRealm)
+		AltoholicTabAchievements_SelectRealm:SetPoint("TOPLEFT", AltoholicFrame, "TOPLEFT", 205, -57)
+
+		for i = 1, 15 do
+			SV.API:Set("Button", _G["AltoholicTabAchievementsMenuItem"..i], true)
+		end
+
+		for i = 1, 8 do
+			for j = 1, 10 do
+				SV.API:Set("!_Frame", _G["AltoholicFrameAchievementsEntry"..i.."Item"..j])
+				local Backdrop = _G["AltoholicFrameAchievementsEntry"..i.."Item"..j].backdrop or _G["AltoholicFrameAchievementsEntry"..i.."Item"..j].Backdrop
+				ApplyTextureStyle(_G["AltoholicFrameAchievementsEntry"..i.."Item"..j..'_Background'])
+				_G["AltoholicFrameAchievementsEntry"..i.."Item"..j..'_Background']:SetInside(Backdrop)
+			end
+		end
+	end
+
+	if IsAddOnLoaded("Altoholic_Agenda") then
+		SV.API:Set("Frame", AltoholicFrameCalendarScrollFrame)
+		SV.API:Set("Frame", AltoholicTabAgendaMenuItem1)
+		SV.API:Set("ScrollBar", AltoholicFrameCalendarScrollFrameScrollBar)
+		SV.API:Set("PageButton", AltoholicFrameCalendar_NextMonth)
+		SV.API:Set("PageButton", AltoholicFrameCalendar_PrevMonth)
+		SV.API:Set("Button", AltoholicTabAgendaMenuItem1, true)
+
+		for i = 1, 14 do
+			SV.API:Set("Frame", _G["AltoholicFrameCalendarEntry"..i])
+		end
+	end
+
+	if IsAddOnLoaded("Altoholic_Grids") then
+		AltoholicFrameGridsScrollFrame:RemoveTextures(true)
+		SV.API:Set("!_Frame", AltoholicFrameGrids)
+		SV.API:Set("ScrollBar", AltoholicFrameGridsScrollFrameScrollBar)
+		SV.API:Set("DropDown", AltoholicTabGrids_SelectRealm)
+		SV.API:Set("DropDown", AltoholicTabGrids_SelectView)
+
+		for i = 1, 8 do
+			for j = 1, 10 do
+				SV.API:Set("!_Frame", _G["AltoholicFrameGridsEntry"..i.."Item"..j])
+				_G["AltoholicFrameGridsEntry"..i.."Item"..j]:HookScript('OnShow', ColorAltoBorder)
+			end
+		end
+
+		AltoholicFrameGrids:HookScript('OnUpdate', function()
+			for i = 1, 10 do
+				for j = 1, 10 do
+					if _G["AltoholicFrameGridsEntry"..i.."Item"..j.."_Background"] then
+						_G["AltoholicFrameGridsEntry"..i.."Item"..j.."_Background"]:SetTexCoord(.08, .92, .08, .82)
+					end
+				end
+			end
+		end)
+
+	end
+
+	if IsAddOnLoaded("Altoholic_Guild") then
+		SV.API:Set("Frame", AltoholicFrameGuildMembers)
+		SV.API:Set("Frame", AltoholicFrameGuildBank)
+		SV.API:Set("ScrollBar", AltoholicFrameGuildMembersScrollFrameScrollBar)
+		AltoholicFrameGuildMembersScrollFrame:RemoveTextures(true)
+
+		for i = 1, 2 do
+			SV.API:Set("Button", _G["AltoholicTabGuildMenuItem"..i])
+		end
+
+		for i = 1, 7 do
+			for j = 1, 14 do
+				SV.API:Set("ItemButton", _G["AltoholicFrameGuildBankEntry"..i.."Item"..j])
+			end
+		end
+
+		for i = 1, 19 do
+			SV.API:Set("ItemButton", _G["AltoholicFrameGuildMembersItem"..i])
+		end
+
+		for i = 1, 5 do
+			SV.API:Set("Button", _G["AltoholicTabGuild_Sort"..i])
+		end
+	end
+
+	if IsAddOnLoaded("Altoholic_Search") then
+		SV.API:Set("!_Frame", AltoholicFrameSearch)
+		AltoholicFrameSearchScrollFrame:RemoveTextures(true)
+		AltoholicSearchMenuScrollFrame:RemoveTextures(true)
+		SV.API:Set("ScrollBar", AltoholicFrameSearchScrollFrameScrollBar)
+		SV.API:Set("ScrollBar", AltoholicSearchMenuScrollFrameScrollBar)
+		SV.API:Set("DropDown", AltoholicTabSearch_SelectRarity)
+		SV.API:Set("DropDown", AltoholicTabSearch_SelectSlot)
+		SV.API:Set("DropDown", AltoholicTabSearch_SelectLocation)
+		AltoholicTabSearch_SelectRarity:SetSize(125, 32)
+		AltoholicTabSearch_SelectSlot:SetSize(125, 32)
+		AltoholicTabSearch_SelectLocation:SetSize(175, 32)
+		SV.API:Set("EditBox", _G["AltoholicTabSearch_MinLevel"])
+		SV.API:Set("EditBox", _G["AltoholicTabSearch_MaxLevel"])
+
+		for i = 1, 15 do
+			SV.API:Set("Button", _G["AltoholicTabSearchMenuItem"..i])
+		end
+
+		for i = 1, 8 do
+			SV.API:Set("Button", _G["AltoholicTabSearch_Sort"..i])
+		end
+	end
+end
+
+MOD:SaveAddonStyle("Altoholic", StyleAltoholic, false, true)
diff --git a/SVUI_Skins/components/addons/AtlasLoot.lua b/SVUI_Skins/components/addons/AtlasLoot.lua
new file mode 100644
index 0000000..69ef3cc
--- /dev/null
+++ b/SVUI_Skins/components/addons/AtlasLoot.lua
@@ -0,0 +1,214 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+ATLASLOOT
+##########################################################
+]]--
+local timeLapse = 0;
+local nineisthere = {"AtlasLootCompareFrameSortButton_7","AtlasLootCompareFrameSortButton_8","AtlasLootCompareFrameSortButton_9"}
+local StripAllTextures = {"AtlasLootDefaultFrame","AtlasLootDefaultFrame_ScrollFrame","AtlasLootItemsFrame","AtlasLootPanel","AtlasLootCompareFrame","AtlasLootCompareFrame_ScrollFrameMainFilterScrollChildFrame","AtlasLootCompareFrame_ScrollFrameItemFrame","AtlasLootCompareFrame_ScrollFrameMainFilter","AtlasLootCompareFrameSortButton_Name","AtlasLootCompareFrameSortButton_Rarity","AtlasLootCompareFrameSortButton_1","AtlasLootCompareFrameSortButton_2","AtlasLootCompareFrameSortButton_3","AtlasLootCompareFrameSortButton_4","AtlasLootCompareFrameSortButton_5","AtlasLootCompareFrameSortButton_6"}
+
+local SetTemplateDefault = {"AtlasLootCompareFrameSortButton_Name","AtlasLootCompareFrameSortButton_Rarity","AtlasLootCompareFrameSortButton_1","AtlasLootCompareFrameSortButton_2","AtlasLootCompareFrameSortButton_3","AtlasLootCompareFrameSortButton_4","AtlasLootCompareFrameSortButton_5","AtlasLootCompareFrameSortButton_6"}
+
+local buttons = {"AtlasLoot_AtlasInfoFrame_ToggleALButton","AtlasLootPanelSearch_SearchButton","AtlasLootDefaultFrame_CompareFrame","AtlasLootPanelSearch_ClearButton","AtlasLootPanelSearch_LastResultButton","AtlasLoot10Man25ManSwitch","AtlasLootItemsFrame_BACK","AtlasLootCompareFrameSearch_ClearButton","AtlasLootCompareFrameSearch_SearchButton","AtlasLootCompareFrame_WishlistButton","AtlasLootCompareFrame_CloseButton2"}
+
+local function AL_OnShow(self, event, ...)
+	AtlasLootPanel:SetPoint("TOP", AtlasLootDefaultFrame, "BOTTOM", 0, -1)
+	AtlasLootQuickLooksButton:SetPoint("BOTTOM", AtlasLootItemsFrame, "BOTTOM", 53, 33)
+	AtlasLootPanelSearch_Box:ClearAllPoints()
+	AtlasLootPanelSearch_Box:SetPoint("TOP", AtlasLoot_PanelButton_7, "BOTTOM", 80, -10)
+	AtlasLootPanelSearch_SearchButton:SetPoint("LEFT", AtlasLootPanelSearch_Box, "RIGHT", 5, 0)
+	AtlasLootPanelSearch_SelectModuel:SetPoint("LEFT", AtlasLootPanelSearch_SearchButton, "RIGHT", 5, 0)
+	AtlasLootPanelSearch_ClearButton:SetPoint("LEFT", AtlasLootPanelSearch_SelectModuel, "RIGHT", 5, 0)
+	AtlasLootPanelSearch_LastResultButton:SetPoint("LEFT", AtlasLootPanelSearch_ClearButton, "RIGHT", 5, 0)
+	AtlasLoot10Man25ManSwitch:SetPoint("BOTTOM", AtlasLootItemsFrame, "BOTTOM", -130, 4)
+	if AtlasLoot_PanelButton_2 then AtlasLoot_PanelButton_2:SetPoint("LEFT", AtlasLoot_PanelButton_1, "RIGHT", 1, 0) end
+	if AtlasLoot_PanelButton_3 then AtlasLoot_PanelButton_3:SetPoint("LEFT", AtlasLoot_PanelButton_2, "RIGHT", 1, 0) end
+	if AtlasLoot_PanelButton_4 then AtlasLoot_PanelButton_4:SetPoint("LEFT", AtlasLoot_PanelButton_3, "RIGHT", 1, 0) end
+	if AtlasLoot_PanelButton_5 then AtlasLoot_PanelButton_5:SetPoint("LEFT", AtlasLoot_PanelButton_4, "RIGHT", 1, 0) end
+	if AtlasLoot_PanelButton_6 then AtlasLoot_PanelButton_6:SetPoint("LEFT", AtlasLoot_PanelButton_5, "RIGHT", 1, 0) end
+	if AtlasLoot_PanelButton_8 then AtlasLoot_PanelButton_8:SetPoint("LEFT", AtlasLoot_PanelButton_7, "RIGHT", 1, 0) end
+	if AtlasLoot_PanelButton_9 then AtlasLoot_PanelButton_9:SetPoint("LEFT", AtlasLoot_PanelButton_8, "RIGHT", 1, 0) end
+	if AtlasLoot_PanelButton_10 then AtlasLoot_PanelButton_10:SetPoint("LEFT", AtlasLoot_PanelButton_9, "RIGHT", 1, 0) end
+	if AtlasLoot_PanelButton_11 then AtlasLoot_PanelButton_11:SetPoint("LEFT", AtlasLoot_PanelButton_10, "RIGHT", 1, 0) end
+	if AtlasLoot_PanelButton_12 then AtlasLoot_PanelButton_12:SetPoint("LEFT", AtlasLoot_PanelButton_11, "RIGHT", 1, 0) end
+	AtlasLootCompareFrameSortButton_Rarity:SetPoint("LEFT", AtlasLootCompareFrameSortButton_Name, "RIGHT", 1, 0)
+	AtlasLootCompareFrameSortButton_Rarity:SetWidth(80)
+	AtlasLootCompareFrameSortButton_Name:SetWidth(80)
+	AtlasLootCompareFrameSortButton_1:SetPoint("LEFT", AtlasLootCompareFrameSortButton_Rarity, "RIGHT", 1, 0)
+	AtlasLootCompareFrameSortButton_2:SetPoint("LEFT", AtlasLootCompareFrameSortButton_1, "RIGHT", 1, 0)
+	AtlasLootCompareFrameSortButton_3:SetPoint("LEFT", AtlasLootCompareFrameSortButton_2, "RIGHT", 1, 0)
+	AtlasLootCompareFrameSortButton_4:SetPoint("LEFT", AtlasLootCompareFrameSortButton_3, "RIGHT", 1, 0)
+	AtlasLootCompareFrameSortButton_5:SetPoint("LEFT", AtlasLootCompareFrameSortButton_4, "RIGHT", 1, 0)
+	AtlasLootCompareFrameSortButton_6:SetPoint("LEFT", AtlasLootCompareFrameSortButton_5, "RIGHT", 1, 0)
+	AtlasLootCompareFrame_CloseButton2:SetPoint("BOTTOMRIGHT", AtlasLootCompareFrame, "BOTTOMRIGHT", -7, 10)
+	AtlasLootCompareFrame_WishlistButton:SetPoint("RIGHT", AtlasLootCompareFrame_CloseButton2, "LEFT", -1, 0)
+	AtlasLootCompareFrameSearch_SearchButton:SetPoint("LEFT", AtlasLootCompareFrameSearch_Box, "RIGHT", 5, 0)
+	AtlasLootCompareFrameSearch_SelectModuel:SetPoint("LEFT", AtlasLootCompareFrameSearch_SearchButton, "RIGHT", 5, 0)
+	AtlasLootDefaultFrame_CloseButton:ClearAllPoints()
+	AtlasLootDefaultFrame_CloseButton:SetPoint("TOPRIGHT", AtlasLootDefaultFrame, "TOPRIGHT", -5 -2)
+	AtlasLootDefaultFrame:SetFrameLevel(0)
+	AtlasLootItemsFrame:SetFrameLevel(AtlasLootDefaultFrame:GetFrameLevel()+1)
+	for i = 1, 30 do if _G["AtlasLootDefaultFrame_ScrollLine"..i] then _G["AtlasLootDefaultFrame_ScrollLine"..i]:SetFrameLevel(AtlasLootDefaultFrame:GetFrameLevel()+1)end end
+
+	if(AtlasLootDefaultFrame_PackageSelect) then
+		AtlasLootDefaultFrame_PackageSelect:SetFrameLevel(AtlasLootDefaultFrame:GetFrameLevel()+1)
+	end
+	AtlasLootDefaultFrame_InstanceSelect:SetFrameLevel(AtlasLootDefaultFrame:GetFrameLevel()+1)
+	AtlasLoot_AtlasInfoFrame_ToggleALButton:SetFrameLevel(AtlasLootDefaultFrame:GetFrameLevel()+1)
+	AtlasLootDefaultFrame_CompareFrame:SetFrameLevel(AtlasLootDefaultFrame:GetFrameLevel()+1)
+	AtlasLootPanelSearch_Box:SetHeight(16)
+	AtlasLootPanel:SetWidth(921)
+end
+
+local function Nine_IsThere(self, elapsed)
+	self.timeLapse = self.timeLapse + elapsed
+	if(self.timeLapse < 2) then
+		return
+	else
+		self.timeLapse = 0
+	end
+	for i = 1, 9 do local f = _G["AtlasLootCompareFrameSortButton_"..i]f:SetWidth(44.44)end
+	for _, object in pairs(nineisthere) do SV.API:Set("Frame", _G[object]) end
+	AtlasLootCompareFrameSortButton_7:SetPoint("LEFT", AtlasLootCompareFrameSortButton_6, "RIGHT", 1, 0)
+	AtlasLootCompareFrameSortButton_8:SetPoint("LEFT", AtlasLootCompareFrameSortButton_7, "RIGHT", 1, 0)
+	AtlasLootCompareFrameSortButton_9:SetPoint("LEFT", AtlasLootCompareFrameSortButton_8, "RIGHT", 1, 0)
+end
+
+local function Compare_OnShow(self, event, ...)
+	for i = 1, 6 do _G["AtlasLootCompareFrameSortButton_"..i]:SetWidth(40)end
+	local Nine = AtlasLootCompareFrameSortButton_9
+	if Nine ~= nil then
+		Nine.timeLapse = 0
+		Nine:SetScript("OnUpdate", Nine_IsThere)
+	end
+end
+
+local _hook_ALPanel = function(self,_,parent,_,_,_,breaker)
+	if not breaker then
+		self:ClearAllPoints()
+		self:SetPoint("TOP",parent,"BOTTOM",0,-1,true)
+	end
+end
+
+local _hook_OnUpdate = function(self, elapsed)
+	self.timeLapse = self.timeLapse + elapsed
+	if(self.timeLapse < 2) then
+		return
+	else
+		self.timeLapse = 0
+	end
+	self:SetWidth(AtlasLootDefaultFrame:GetWidth())
+end
+
+
+local function StyleAtlasLoot(event, addon)
+	assert(AtlasLootPanel, "AddOn Not Loaded")
+
+	for _, object in pairs(StripAllTextures) do _G[object]:RemoveTextures()end
+	for _, object in pairs(SetTemplateDefault) do SV.API:Set("Frame", _G[object], "Default")end
+	for _, button in pairs(buttons) do _G[button]:SetStyle("Button")end
+
+	-- Manipulate the main frames
+	SV.API:Set("Frame", _G["AtlasLootDefaultFrame"], "Window2");
+	SV.API:Set("!_Frame", _G["AtlasLootItemsFrame"], "Inset");
+	SV.API:Set("Frame", _G["AtlasLootPanel"], "Default");
+	hooksecurefunc(_G["AtlasLootPanel"], "SetPoint", _hook_ALPanel);
+
+	_G["AtlasLootPanel"]:SetPoint("TOP",_G["AtlasLootDefaultFrame"],"BOTTOM",0,-1);
+	-- Back to the rest
+	SV.API:Set("Frame", _G["AtlasLootCompareFrame"], "Transparent");
+	if AtlasLoot_PanelButton_1 then AtlasLoot_PanelButton_1:SetStyle("Button") end
+	if AtlasLoot_PanelButton_2 then AtlasLoot_PanelButton_2:SetStyle("Button") end
+	if AtlasLoot_PanelButton_3 then AtlasLoot_PanelButton_3:SetStyle("Button") end
+	if AtlasLoot_PanelButton_4 then AtlasLoot_PanelButton_4:SetStyle("Button") end
+	if AtlasLoot_PanelButton_5 then AtlasLoot_PanelButton_5:SetStyle("Button") end
+	if AtlasLoot_PanelButton_6 then AtlasLoot_PanelButton_6:SetStyle("Button") end
+	if AtlasLoot_PanelButton_7 then AtlasLoot_PanelButton_7:SetStyle("Button") end
+	if AtlasLoot_PanelButton_8 then AtlasLoot_PanelButton_8:SetStyle("Button") end
+	if AtlasLoot_PanelButton_9 then AtlasLoot_PanelButton_9:SetStyle("Button") end
+	if AtlasLoot_PanelButton_10 then AtlasLoot_PanelButton_10:SetStyle("Button") end
+	if AtlasLoot_PanelButton_11 then AtlasLoot_PanelButton_11:SetStyle("Button") end
+	if AtlasLoot_PanelButton_12 then AtlasLoot_PanelButton_12:SetStyle("Button") end
+
+	for i = 1, 15 do local f = _G["AtlasLootCompareFrameMainFilterButton"..i]f:RemoveTextures() end
+
+	SV.API:Set("CloseButton", AtlasLootDefaultFrame_CloseButton)
+	SV.API:Set("CloseButton", AtlasLootCompareFrame_CloseButton)
+	SV.API:Set("CloseButton", AtlasLootCompareFrame_CloseButton_Wishlist)
+	SV.API:Set("PageButton", AtlasLootQuickLooksButton)
+	SV.API:Set("PageButton", AtlasLootItemsFrame_NEXT)
+	AtlasLootItemsFrame_NEXT:SetWidth(25)
+	AtlasLootItemsFrame_NEXT:SetHeight(25)
+	SV.API:Set("PageButton", AtlasLootItemsFrame_PREV)
+	AtlasLootItemsFrame_PREV:SetWidth(25)
+	AtlasLootItemsFrame_PREV:SetHeight(25)
+	SV.API:Set("PageButton", AtlasLootPanelSearch_SelectModuel)
+	SV.API:Set("PageButton", AtlasLootCompareFrameSearch_SelectModuel)
+
+	if(AtlasLootDefaultFrame_PackageSelect) then
+		SV.API:Set("DropDown", AtlasLootDefaultFrame_PackageSelect)
+		AtlasLootDefaultFrame_PackageSelect:SetWidth(240)
+		AtlasLootDefaultFrame_PackageSelect:SetPoint("TOPLEFT", AtlasLootDefaultFrame, "TOPLEFT", 50, -50)
+	end
+
+	SV.API:Set("DropDown", AtlasLootDefaultFrame_ModuleSelect,240)
+	SV.API:Set("DropDown", AtlasLootDefaultFrame_InstanceSelect,240)
+
+	SV.API:Set("DropDown", AtlasLootCompareFrameSearch_StatsListDropDown)
+	AtlasLootCompareFrameSearch_StatsListDropDown:SetWidth(240)
+	SV.API:Set("DropDown", AtlasLootCompareFrame_WishlistDropDown)
+	AtlasLootCompareFrame_WishlistDropDown:SetWidth(240)
+	AtlasLootPanelSearch_Box:SetStyle("Editbox")
+	AtlasLootCompareFrameSearch_Box:SetStyle("Editbox")
+
+	if AtlasLootFilterCheck then
+		AtlasLootFilterCheck:SetStyle("CheckButton")
+	end
+	if AtlasLootItemsFrame_Heroic then
+		AtlasLootItemsFrame_Heroic:SetStyle("CheckButton")
+	end
+	if AtlasLootCompareFrameSearch_FilterCheck then AtlasLootCompareFrameSearch_FilterCheck:SetStyle("CheckButton")
+	end
+	if AtlasLootItemsFrame_RaidFinder then
+		AtlasLootItemsFrame_RaidFinder:SetStyle("CheckButton")
+	end
+	if AtlasLootItemsFrame_Thunderforged then
+		AtlasLootItemsFrame_Thunderforged:SetStyle("CheckButton")
+	end
+
+	AtlasLootPanel.Titel:SetTextColor(23/255, 132/255, 209/255)
+	AtlasLootPanel.Titel:SetPoint("BOTTOM", AtlasLootPanel.TitelBg, "BOTTOM", 0, 40)
+	SV.API:Set("ScrollBar", AtlasLootCompareFrame_ScrollFrameItemFrameScrollBar)
+	SV.API:Set("ScrollBar", AtlasLootCompareFrame_WishlistScrollFrameScrollBar)
+	AtlasLootDefaultFrame:HookScript("OnShow", AL_OnShow)
+	AtlasLootCompareFrame:HookScript("OnShow", Compare_OnShow)
+	AtlasLootPanel.timeLapse = 0;
+
+	--AtlasLootPanel:HookScript("OnUpdate", _hook_OnUpdate)
+
+	if(AtlasLootTooltip:GetName() ~= "GameTooltip") then
+		SV.API:Set("Tooltip", AtlasLootTooltip)
+	end
+end
+MOD:SaveAddonStyle("AtlasLoot", StyleAtlasLoot, nil, true)
\ No newline at end of file
diff --git a/SVUI_Skins/components/addons/AuctionLite.lua b/SVUI_Skins/components/addons/AuctionLite.lua
new file mode 100644
index 0000000..c51c81b
--- /dev/null
+++ b/SVUI_Skins/components/addons/AuctionLite.lua
@@ -0,0 +1,77 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local string 	= _G.string;
+--[[ STRING METHODS ]]--
+local format = string.format;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G["SVUI"];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+AUCTIONLITE
+##########################################################
+]]--
+local function BGHelper(parent)
+  parent.bg = CreateFrame("Frame", nil, parent)
+  parent.bg:SetStyle("!_Frame", "Inset")
+  parent.bg:SetPoint("TOPLEFT", parent, "TOPLEFT", 16, -103)
+  parent.bg:SetPoint("BOTTOMRIGHT", AuctionFrame, "BOTTOMRIGHT", -8, 36)
+  parent.bg:SetFrameLevel(parent.bg:GetFrameLevel() - 1)
+end
+
+local function StyleAuctionLite(event, ...)
+  assert(AuctionFrameTab4, "AddOn Not Loaded")
+  if(not event or (event and event == 'PLAYER_ENTERING_WORLD')) then return; end
+
+  BuyName:SetStyle("Editbox")
+  BuyQuantity:SetStyle("Editbox")
+  SellStacks:SetStyle("Editbox")
+  SellSize:SetStyle("Editbox")
+  SellBidPriceGold:SetStyle("Editbox")
+  SellBidPriceSilver:SetStyle("Editbox")
+  SellBidPriceCopper:SetStyle("Editbox")
+  SellBuyoutPriceGold:SetStyle("Editbox")
+  SellBuyoutPriceSilver:SetStyle("Editbox")
+  SellBuyoutPriceCopper:SetStyle("Editbox")
+
+  BuySearchButton:SetStyle("Button")
+  BuyBidButton:SetStyle("Button")
+  BuyBuyoutButton:SetStyle("Button")
+  BuyCancelSearchButton:SetStyle("Button")
+  BuyCancelAuctionButton:SetStyle("Button")
+  BuyScanButton:SetStyle("Button")
+  SellCreateAuctionButton:SetStyle("Button")
+
+  SV.API:Set("PageButton", BuyAdvancedButton)
+  SV.API:Set("PageButton", SellRememberButton)
+
+  SV.API:Set("Tab", AuctionFrameTab4)
+  SV.API:Set("Tab", AuctionFrameTab5)
+
+  if(_G["AuctionFrameBuy"]) then
+    BGHelper(_G["AuctionFrameBuy"])
+  end
+  if(_G["AuctionFrameSell"]) then
+    BGHelper(_G["AuctionFrameSell"])
+  end
+
+  MOD:SafeEventRemoval("AuctionLite", event)
+end
+
+MOD:SaveAddonStyle("AuctionLite", StyleAuctionLite, nil, nil, "AUCTION_HOUSE_SHOW")
\ No newline at end of file
diff --git a/SVUI_Skins/components/addons/BigWigs.lua b/SVUI_Skins/components/addons/BigWigs.lua
new file mode 100644
index 0000000..17e8c11
--- /dev/null
+++ b/SVUI_Skins/components/addons/BigWigs.lua
@@ -0,0 +1,136 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G["SVUI"];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+BIGWIGS
+##########################################################
+]]--
+local FreeBG
+local BigWigsLoaded
+
+local function freestyle(bar)
+	if not FreeBG then FreeBG = {} end
+	local bg = bar:Get("bigwigs:elvui:barbg")
+	if bg then
+		bg:ClearAllPoints()
+		bg:SetParent(SV.Screen)
+		bg:Hide()
+		FreeBG[#FreeBG + 1] = bg
+	end
+
+	local ibg = bar:Get("bigwigs:elvui:iconbg")
+	if ibg then
+		ibg:ClearAllPoints()
+		ibg:SetParent(SV.Screen)
+		ibg:Hide()
+		FreeBG[#FreeBG + 1] = ibg
+	end
+	bar.candyBarIconFrame.SetWidth = bar.candyBarIconFrame.OldSetWidth
+	bar.candyBarBar.SetPoint = bar.candyBarBar.OldSetPoint
+	bar.candyBarIconFrame:ClearAllPoints()
+	bar.candyBarIconFrame:SetPoint("TOPLEFT")
+	bar.candyBarIconFrame:SetPoint("BOTTOMLEFT")
+	bar.candyBarIconFrame:SetTexCoord(0.1,0.9,0.1,0.9)
+	bar.candyBarBar:ClearAllPoints()
+	bar.candyBarBar:SetPoint("TOPRIGHT")
+	bar.candyBarBar:SetPoint("BOTTOMRIGHT")
+	bar.candyBarBackground:SetAllPoints()
+	bar.candyBarDuration:ClearAllPoints()
+	bar.candyBarDuration:SetPoint("RIGHT", bar.candyBarBar, "RIGHT", -2, 0)
+	bar.candyBarLabel:ClearAllPoints()
+	bar.candyBarLabel:SetPoint("LEFT", bar.candyBarBar, "LEFT", 2, 0)
+	bar.candyBarLabel:SetPoint("RIGHT", bar.candyBarBar, "RIGHT", -2, 0)
+end
+
+local function applystyle(bar)
+	if not FreeBG then FreeBG = {} end
+	bar:SetHeight(20)
+	local bg = nil
+	if #FreeBG > 0 then
+		bg = tremove(FreeBG)
+	else
+		bg = CreateFrame("Frame")
+	end
+	bg:SetStyle("!_Frame", 'Transparent', true)
+	bg:SetParent(bar)
+	bg:WrapPoints(bar)
+	bg:SetFrameLevel(bar:GetFrameLevel() - 1)
+	bg:SetFrameStrata(bar:GetFrameStrata())
+	bg:Show()
+	bar:Set("bigwigs:elvui:barbg", bg)
+	local ibg = nil
+	if bar.candyBarIconFrame:GetTexture() then
+		if #FreeBG > 0 then
+			ibg = tremove(FreeBG)
+		else
+			ibg = CreateFrame("Frame")
+		end
+		ibg:SetParent(bar)
+		ibg:SetStyle("!_Frame", 'Transparent', true)
+		ibg:SetBackdropColor(0, 0, 0, 0)
+		ibg:WrapPoints(bar.candyBarIconFrame)
+		ibg:SetFrameLevel(bar:GetFrameLevel() - 1)
+		ibg:SetFrameStrata(bar:GetFrameStrata())
+		ibg:Show()
+		bar:Set("bigwigs:elvui:iconbg", ibg)
+	end
+	bar.candyBarLabel:SetJustifyH("LEFT")
+	bar.candyBarLabel:ClearAllPoints()
+	bar.candyBarDuration:SetJustifyH("RIGHT")
+	bar.candyBarDuration:ClearAllPoints()
+	bar.candyBarLabel:SetPoint("LEFT", bar, "LEFT", 4, 0)
+	bar.candyBarDuration:SetPoint("RIGHT", bar, "RIGHT", -4, 0)
+	bar.candyBarBar:ClearAllPoints()
+	bar.candyBarBar:SetAllPoints(bar)
+	bar.candyBarBar.OldSetPoint = bar.candyBarBar.SetPoint
+	bar.candyBarBar.SetPoint = SV.fubar
+	bar.candyBarIconFrame.OldSetWidth = bar.candyBarIconFrame.SetWidth
+	bar.candyBarIconFrame.SetWidth = SV.fubar
+	bar.candyBarIconFrame:ClearAllPoints()
+	bar.candyBarIconFrame:SetPoint("BOTTOMRIGHT", bar, "BOTTOMLEFT", -1, 0)
+	bar.candyBarIconFrame:SetSize(20, 20)
+	bar.candyBarIconFrame:SetTexCoord(0.1,0.9,0.1,0.9)
+end
+
+local function StyleBigWigs(event, addon)
+	assert(BigWigs, "AddOn Not Loaded")
+	if (IsAddOnLoaded('BigWigs_Plugins') or event == "ADDON_LOADED" and addon == 'BigWigs_Plugins') then
+		local styleName = SV.NameID
+		local BigWigsBars = BigWigs:GetPlugin('Bars')
+		if BigWigsLoaded then return end
+		BigWigsLoaded = true
+		BigWigsBars:RegisterBarStyle(styleName, {
+			apiVersion = 1,
+			version = 1,
+			GetSpacing = function(bar)
+				return 4
+			end,
+			ApplyStyle = applystyle,
+			BarStopped = freestyle,
+			GetStyleName = function() return styleName end,
+		})
+		BigWigsBars:SetBarStyle(styleName)
+		MOD:SafeEventRemoval("BigWigs", "ADDON_LOADED")
+		MOD:SafeEventRemoval("BigWigs", "PLAYER_ENTERING_WORLD")
+	end
+end
+
+MOD:SaveAddonStyle("BigWigs", StyleBigWigs, nil, true)
\ No newline at end of file
diff --git a/SVUI_Skins/components/addons/Bugsack.lua b/SVUI_Skins/components/addons/Bugsack.lua
new file mode 100644
index 0000000..2259bf5
--- /dev/null
+++ b/SVUI_Skins/components/addons/Bugsack.lua
@@ -0,0 +1,47 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local string 	= _G.string;
+--[[ STRING METHODS ]]--
+local format = string.format;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+BUGSACK
+##########################################################
+]]--
+local function StyleBugSack(event, addon)
+	assert(BugSack, "AddOn Not Loaded")
+	hooksecurefunc(BugSack, "OpenSack", function()
+		if BugSackFrame.Panel then return end
+		BugSackFrame:RemoveTextures()
+		BugSackFrame:SetStyle("Frame", 'Transparent')
+		SV.API:Set("Tab", BugSackTabAll)
+		BugSackTabAll:SetPoint("TOPLEFT", BugSackFrame, "BOTTOMLEFT", 0, 1)
+		SV.API:Set("Tab", BugSackTabSession)
+		SV.API:Set("Tab", BugSackTabLast)
+		BugSackNextButton:SetStyle("Button")
+		BugSackSendButton:SetStyle("Button")
+		BugSackPrevButton:SetStyle("Button")
+		SV.API:Set("ScrollBar", BugSackScrollScrollBar)
+	end)
+end
+
+MOD:SaveAddonStyle("Bugsack", StyleBugSack)
\ No newline at end of file
diff --git a/SVUI_Skins/components/addons/Clique.lua b/SVUI_Skins/components/addons/Clique.lua
new file mode 100644
index 0000000..2b4b8a4
--- /dev/null
+++ b/SVUI_Skins/components/addons/Clique.lua
@@ -0,0 +1,141 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local string 	= _G.string;
+--[[ STRING METHODS ]]--
+local format = string.format;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+CLIQUE
+##########################################################
+]]--
+local CliqueFrames = {
+	"CliqueDialog",
+	"CliqueConfig",
+	"CliqueConfigPage1",
+	"CliqueConfigPage2",
+	"CliqueClickGrabber",
+	"CliqueScrollFrame"
+}
+
+local CliqueButtons = {
+	"CliqueConfigPage1ButtonSpell",
+	"CliqueConfigPage1ButtonOther",
+	"CliqueConfigPage1ButtonOptions",
+	"CliqueConfigPage2ButtonBinding",
+	"CliqueDialogButtonAccept",
+	"CliqueDialogButtonBinding",
+	"CliqueConfigPage2ButtonSave",
+	"CliqueConfigPage2ButtonCancel",
+	"CliqueSpellTab",
+}
+
+local CliqueStripped = {
+	"CliqueConfigPage1Column1",
+	"CliqueConfigPage1Column2",
+	"CliqueConfigPage1_VSlider",
+	"CliqueSpellTab",
+	"CliqueConfigPage1ButtonSpell",
+	"CliqueConfigPage1ButtonOther",
+	"CliqueConfigPage1ButtonOptions",
+	"CliqueConfigPage2ButtonBinding",
+	"CliqueDialogButtonAccept",
+	"CliqueDialogButtonBinding",
+	"CliqueConfigPage2ButtonSave",
+	"CliqueConfigPage2ButtonCancel",
+}
+
+local CliqueConfigPage1_OnShow = function(self)
+	for i = 1, 12 do
+		if _G["CliqueRow"..i] then
+			_G["CliqueRow"..i.."Icon"]:SetTexCoord(0.1,0.9,0.1,0.9);
+			_G["CliqueRow"..i.."Bind"]:ClearAllPoints()
+			if _G["CliqueRow"..i] == CliqueRow1 then
+				_G["CliqueRow"..i.."Bind"]:SetPoint("RIGHT", _G["CliqueRow"..i], 8,0)
+			else
+				_G["CliqueRow"..i.."Bind"]:SetPoint("RIGHT", _G["CliqueRow"..i], -9,0)
+			end
+			_G["CliqueRow"..i]:GetHighlightTexture():SetDesaturated(true)
+		end
+	end
+	CliqueRow1:ClearAllPoints()
+	CliqueRow1:SetPoint("TOPLEFT",5,-(CliqueConfigPage1Column1:GetHeight() +3))
+end
+
+local function StyleClique()
+	assert(CliqueDialog, "AddOn Not Loaded")
+
+	for _, gName in pairs(CliqueFrames) do
+		local frame = _G[gName]
+		if(frame) then
+			SV.API:Set("Frame", frame, "Transparent")
+			if(gName == "CliqueConfig") then
+				frame.Panel:SetPoint("TOPLEFT",0,0)
+				frame.Panel:SetPoint("BOTTOMRIGHT",0,-5)
+			elseif(gName == "CliqueClickGrabber" or gName == "CliqueScrollFrame") then
+				frame.Panel:SetPoint("TOPLEFT",4,0)
+				frame.Panel:SetPoint("BOTTOMRIGHT",-2,4)
+			else
+				frame.Panel:SetPoint("TOPLEFT",0,0)
+				frame.Panel:SetPoint("BOTTOMRIGHT",2,0)
+			end
+		end
+	end
+
+	for _, gName in pairs(CliqueStripped) do
+		local frame = _G[gName]
+		if(frame) then
+			frame:RemoveTextures(true)
+		end
+	end
+
+	for _, gName in pairs(CliqueButtons) do
+		local button = _G[gName]
+		if(button) then
+			button:SetStyle("Button")
+		end
+	end
+
+	SV.API:Set("CloseButton", CliqueDialog.CloseButton)
+
+	CliqueConfigPage1:SetScript("OnShow", CliqueConfigPage1_OnShow)
+
+	CliqueDialog:SetSize(CliqueDialog:GetWidth()-1, CliqueDialog:GetHeight()-1)
+
+	CliqueConfigPage1ButtonSpell:ClearAllPoints()
+	CliqueConfigPage1ButtonSpell:SetPoint("TOPLEFT", CliqueConfigPage1,"BOTTOMLEFT",0,-4)
+
+	CliqueConfigPage1ButtonOptions:ClearAllPoints()
+	CliqueConfigPage1ButtonOptions:SetPoint("TOPRIGHT", CliqueConfigPage1,"BOTTOMRIGHT",2,-4)
+
+	CliqueConfigPage2ButtonSave:ClearAllPoints()
+	CliqueConfigPage2ButtonSave:SetPoint("TOPLEFT", CliqueConfigPage2,"BOTTOMLEFT",0,-4)
+
+	CliqueConfigPage2ButtonCancel:ClearAllPoints()
+	CliqueConfigPage2ButtonCancel:SetPoint("TOPRIGHT", CliqueConfigPage2,"BOTTOMRIGHT",2,-4)
+
+	CliqueSpellTab:GetRegions():SetSize(.1,.1)
+	CliqueSpellTab:GetNormalTexture():SetTexCoord(0.1,0.9,0.1,0.9)
+	CliqueSpellTab:GetNormalTexture():ClearAllPoints()
+	CliqueSpellTab:GetNormalTexture():InsetPoints()
+end
+
+MOD:SaveAddonStyle("Clique", StyleClique)
\ No newline at end of file
diff --git a/SVUI_Skins/components/addons/Cooline.lua b/SVUI_Skins/components/addons/Cooline.lua
new file mode 100644
index 0000000..3101fa4
--- /dev/null
+++ b/SVUI_Skins/components/addons/Cooline.lua
@@ -0,0 +1,51 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local string 	= _G.string;
+--[[ STRING METHODS ]]--
+local format = string.format;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+COOLINE
+##########################################################
+]]--
+local function StyleCoolLine()
+	assert(CoolLineDB, "AddOn Not Loaded")
+
+	CoolLineDB.bgcolor = { r = 0, g = 0, b = 0, a = 0, }
+	CoolLineDB.border = "None"
+	CoolLine.updatelook()
+
+	if(not CoolLine.Panel) then
+		SV.API:Set("Frame", CoolLine, "Transparent")
+	end
+
+	SV:ManageVisibility(CoolLine)
+
+	if MOD:IsAddonReady("CoolLine_Anchored") then
+		if(not CoolLineDB.vertical and (SV.ActionBars and SV.ActionBars.MainAnchor)) then
+			CoolLine:ClearAllPoints()
+			CoolLine:SetPoint('BOTTOMRIGHT', SV.ActionBars.MainAnchor, 'TOPRIGHT', 0, 4)
+			CoolLine:SetPoint("BOTTOMLEFT", SV.ActionBars.MainAnchor, "TOPLEFT", 0, 4)
+		end
+	end
+end
+MOD:SaveAddonStyle("CoolLine", StyleCoolLine)
\ No newline at end of file
diff --git a/SVUI_Skins/components/addons/DBM.lua b/SVUI_Skins/components/addons/DBM.lua
new file mode 100644
index 0000000..a51acdf
--- /dev/null
+++ b/SVUI_Skins/components/addons/DBM.lua
@@ -0,0 +1,232 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local string 	= _G.string;
+local gsub 		= string.gsub;
+--[[ STRING METHODS ]]--
+local format = string.format;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+DBM
+##########################################################
+]]--
+local function StyleBars(self)
+	for bar in self:GetBarIterator() do
+		if not bar.injected then
+			bar.ApplyStyle = function()
+				local frame = bar.frame
+				local tbar = _G[frame:GetName()..'Bar']
+				local spark = _G[frame:GetName()..'BarSpark']
+				local texture = _G[frame:GetName()..'BarTexture']
+				local icon1 = _G[frame:GetName()..'BarIcon1']
+				local icon2 = _G[frame:GetName()..'BarIcon2']
+				local name = _G[frame:GetName()..'BarName']
+				local timer = _G[frame:GetName()..'BarTimer']
+
+				if not icon1.overlay then
+					icon1.overlay = CreateFrame('Frame', '$parentIcon1Overlay', tbar)
+					icon1.overlay:SetSize(28,28)
+					icon1.overlay:SetStyle("Frame", "Button")
+					icon1.overlay:SetFrameLevel(0)
+					icon1.overlay:SetPoint('BOTTOMRIGHT', frame, 'BOTTOMLEFT', -4, 0)
+				end
+
+				if not icon2.overlay then
+					icon2.overlay = CreateFrame('Frame', '$parentIcon2Overlay', tbar)
+					icon2.overlay:SetSize(28,28)
+					icon2.overlay:SetStyle("Frame", "Button")
+					icon2.overlay:SetFrameLevel(0)
+					icon2.overlay:SetPoint('BOTTOMLEFT', frame, 'BOTTOMRIGHT', 4, 0)
+				end
+
+				if bar.color then
+					tbar:SetStatusBarColor(bar.color.r, bar.color.g, bar.color.b)
+				else
+					tbar:SetStatusBarColor(bar.owner.options.StartColorR, bar.owner.options.StartColorG, bar.owner.options.StartColorB)
+				end
+
+				local sharedWidth = bar.owner.options.Width
+				local sharedScale = bar.owner.options.Scale
+				if bar.enlarged then
+					sharedWidth = bar.owner.options.HugeWidth
+					sharedScale = bar.owner.options.HugeScale
+				end
+
+				frame:SetWidth(sharedWidth)
+				frame:SetHeight(28)
+				frame:SetScale(sharedScale)
+
+				spark:SetAlpha(0)
+				spark:SetTexture("")
+
+				icon1:SetTexCoord(0.1,0.9,0.1,0.9)
+				icon1:ClearAllPoints()
+				icon1:SetAllPoints(icon1.overlay)
+
+				icon2:SetTexCoord(0.1,0.9,0.1,0.9)
+				icon2:ClearAllPoints()
+				icon2:SetAllPoints(icon2.overlay)
+
+				texture:SetTexture(SV.media.statusbar.default)
+				tbar:SetWidth(sharedWidth)
+				tbar:SetHeight(10)
+				tbar:SetPoint('BOTTOMLEFT', frame, 'BOTTOMLEFT', 0, 0)
+				tbar:SetStyle("Frame", "Bar")
+
+				name:ClearAllPoints()
+				name:SetHeight(8)
+				name:SetWidth(sharedWidth)
+				name:SetJustifyH('LEFT')
+				name:SetShadowColor(0, 0, 0, 0)
+				name:SetPoint('TOPLEFT', frame, 'TOPLEFT', 0, 0)
+				name:SetFont(SV.media.font.default, 12, 'OUTLINE')
+				name:SetTextColor(bar.owner.options.TextColorR, bar.owner.options.TextColorG, bar.owner.options.TextColorB)
+
+				timer:ClearAllPoints()
+				timer:SetJustifyH('RIGHT')
+				timer:SetShadowColor(0, 0, 0, 0)
+				timer:SetPoint('TOPRIGHT', frame, 'TOPRIGHT', 0, 0)
+				timer:SetFont(SV.media.font.default, 12, 'OUTLINE')
+				timer:SetTextColor(bar.owner.options.TextColorR, bar.owner.options.TextColorG, bar.owner.options.TextColorB)
+
+				if bar.owner.options.IconLeft then icon1:Show() icon1.overlay:Show() else icon1:Hide() icon1.overlay:Hide() end
+				if bar.owner.options.IconRight then icon2:Show() icon2.overlay:Show() else icon2:Hide() icon2.overlay:Hide() end
+
+				bar.owner.options.BarYOffset = 8
+				bar.owner.options.HugeBarYOffset = 8
+
+				tbar:SetAlpha(1)
+				frame:SetAlpha(1)
+				texture:SetAlpha(1)
+				frame:Show()
+				bar:Update(0)
+				bar.injected = true
+			end
+			bar:ApplyStyle()
+		end
+	end
+end
+
+local StyleBossTitle = function()
+	local anchor = DBMBossHealthDropdown:GetParent()
+	if not anchor.styled then
+		local header = {anchor:GetRegions()}
+		if header[1]:IsObjectType('FontString') then
+			header[1]:SetFontObject(SVUI_Font_Default)
+			header[1]:SetTextColor(1, 1, 1)
+			header[1]:SetShadowColor(0, 0, 0, 0)
+			anchor.styled = true
+		end
+		header = nil
+	end
+	anchor = nil
+end
+
+local StyleBoss = function()
+	local count = 1
+	while _G[format('DBM_BossHealth_Bar_%d', count)] do
+		local bar = _G[format('DBM_BossHealth_Bar_%d', count)]
+		local background = _G[bar:GetName()..'BarBorder']
+		local progress = _G[bar:GetName()..'Bar']
+		local name = _G[bar:GetName()..'BarName']
+		local timer = _G[bar:GetName()..'BarTimer']
+		local prev = _G[format('DBM_BossHealth_Bar_%d', count-1)]
+		local _, anch, _ ,_, _ = bar:GetPoint()
+		bar:ClearAllPoints()
+		if count == 1 then
+			if(DBM_SavedOptions and DBM_SavedOptions.HealthFrameGrowUp) then
+				bar:SetPoint('BOTTOM', anch, 'TOP' , 0 , 12)
+			else
+				bar:SetPoint('TOP', anch, 'BOTTOM' , 0, -22)
+			end
+		else
+			if(DBM_SavedOptions and DBM_SavedOptions.HealthFrameGrowUp) then
+				bar:SetPoint('TOPLEFT', prev, 'TOPLEFT', 0, 22 + 4)
+			else
+				bar:SetPoint('TOPLEFT', prev, 'TOPLEFT', 0, -(22 + 4))
+			end
+		end
+		bar:SetStyle("!_Frame", 'Transparent')
+		background:SetNormalTexture(nil)
+		progress:SetStatusBarTexture(SV.media.statusbar.default)
+		progress:ClearAllPoints()
+		progress:InsetPoints(bar)
+		name:ClearAllPoints()
+		name:SetJustifyH('LEFT')
+		name:SetShadowColor(0, 0, 0, 0)
+		timer:ClearAllPoints()
+		timer:SetJustifyH('RIGHT')
+		timer:SetShadowColor(0, 0, 0, 0)
+		bar:SetHeight(22)
+		name:SetPoint('LEFT', bar, 'LEFT', 4, 0)
+		timer:SetPoint('RIGHT', bar, 'RIGHT', -4, 0)
+		name:SetFontObject(SpellFont_Small)
+		timer:SetFontObject(SVUI_Font_Default)
+		count = count + 1
+	end
+end
+
+local RangeSet, InfoSet, HooksSet, NoticeSet;
+local function StyleDBM(event, addon)
+	assert(DBM, "AddOn Not Loaded")
+
+	if(DBT and (DBM.BossHealth) and (not HooksSet)) then
+		hooksecurefunc(DBT, 'CreateBar', StyleBars)
+		hooksecurefunc(DBM.BossHealth, 'Show', StyleBossTitle)
+		hooksecurefunc(DBM.BossHealth, 'AddBoss', StyleBoss)
+		hooksecurefunc(DBM.BossHealth, 'UpdateSettings', StyleBoss)
+		HooksSet = true
+	end
+
+	if((not RangeSet) and DBMRangeCheck and (not DBM_SavedOptions['DontShowRangeFrame'])) then
+		DBM.RangeCheck:Show()
+		DBM.RangeCheck:Hide()
+		DBMRangeCheck:HookScript('OnShow', function(self) self:SetStyle("!_Frame", 'Transparent') end)
+		DBMRangeCheckRadar:SetStyle("!_Frame", 'Transparent')
+		RangeSet = true
+	end
+
+	if((not InfoSet) and DBMInfoFrame and (not DBM_SavedOptions['DontShowInfoFrame'])) then
+		DBM.InfoFrame:Show(5, 'test')
+		DBM.InfoFrame:Hide()
+		DBMInfoFrame:HookScript('OnShow', function(self) self:SetStyle("!_Frame", 'Transparent') end)
+		InfoSet = true
+	end
+
+	if(RaidNotice_AddMessage and (not NoticeSet)) then
+		local RaidNotice_AddMessage_ = RaidNotice_AddMessage
+		RaidNotice_AddMessage = function(noticeFrame, textString, colorInfo)
+			if textString:find(' |T') then
+				textString = gsub(textString,'(:12:12)',':18:18:0:0:64:64:5:59:5:59')
+			end
+			return RaidNotice_AddMessage_(noticeFrame, textString, colorInfo)
+		end
+		NoticeSet = true
+	end
+
+	if(RangeSet and InfoSet and HooksSet and NoticeSet) then
+		MOD:SafeEventRemoval("DBM", event)
+		MOD:SafeEventRemoval("DBM-GUI", event)
+	end
+end
+
+MOD:SaveAddonStyle("DBM", StyleDBM, false, true)
+--MOD:SaveAddonStyle("DBM-GUI", StyleDBM, false, true)
\ No newline at end of file
diff --git a/SVUI_Skins/components/addons/DXE.lua b/SVUI_Skins/components/addons/DXE.lua
new file mode 100644
index 0000000..3387d7d
--- /dev/null
+++ b/SVUI_Skins/components/addons/DXE.lua
@@ -0,0 +1,124 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local string 	= _G.string;
+--[[ STRING METHODS ]]--
+local format = string.format;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+local playerName = UnitName("player");
+local playerRealm = GetRealmName();
+local playerKey = ("%s - %s"):format(playerName, playerRealm)
+--[[
+##########################################################
+DXE
+##########################################################
+]]--
+local function StyleDXEBar(bar)
+	bar:SetStyle("!_Frame", "Transparent")
+	bar.bg:SetTexture("")
+	bar.border.Show = SV.fubar
+	bar.border:Hide()
+	bar.statusbar:SetStatusBarTexture(SV.media.statusbar.default)
+	bar.statusbar:ClearAllPoints()
+	bar.statusbar:InsetPoints()
+	bar.righticon:SetStyle("!_Frame", "Default")
+	bar.righticon.border.Show = SV.fubar
+	bar.righticon.border:Hide()
+	bar.righticon:ClearAllPoints()
+	bar.righticon:SetPoint("LEFT", bar, "RIGHT", 2, 0)
+	bar.righticon.t:SetTexCoord(0.1,0.9,0.1,0.9)
+	bar.righticon.t:ClearAllPoints()
+	bar.righticon.t:InsetPoints()
+	bar.righticon.t:SetDrawLayer("ARTWORK")
+	bar.lefticon:SetStyle("!_Frame", "Default")
+	bar.lefticon.border.Show = SV.fubar
+	bar.lefticon.border:Hide()
+	bar.lefticon:ClearAllPoints()
+	bar.lefticon:SetPoint("RIGHT", bar, "LEFT", -2, 0)
+	bar.lefticon.t:SetTexCoord(0.1,0.9,0.1,0.9)
+	bar.lefticon.t:ClearAllPoints()
+	bar.lefticon.t:InsetPoints()
+	bar.lefticon.t:SetDrawLayer("ARTWORK")
+end
+
+local function RefreshDXEBars(frame)
+	if frame.refreshing then return end
+	frame.refreshing = true
+	local i = 1
+	while _G["DXEAlertBar"..i] do
+		local bar = _G["DXEAlertBar"..i]
+		if not bar.styled then
+			bar:SetScale(1)
+			bar.SetScale = SV.fubar
+			StyleDXEBar(bar)
+			bar.styled = true
+		end
+		i = i + 1
+	end
+	frame.refreshing = false
+end
+
+LoadAddOn("DXE")
+
+local function StyleDXE()
+	assert(DXE, "AddOn Not Loaded")
+
+	DXE.LayoutHealthWatchers_ = DXE.LayoutHealthWatchers
+	DXE.LayoutHealthWatchers = function(frame)
+		DXE:LayoutHealthWatchers_()
+		for i,hw in ipairs(frame.HW) do
+			if hw:IsShown() then
+				hw:SetStyle("!_Frame", "Transparent")
+				hw.border.Show = SV.fubar
+				hw.border:Hide()
+				hw.healthbar:SetStatusBarTexture(SV.media.statusbar.default)
+			end
+		end
+	end
+
+	local DXEAlerts = DXE:GetModule("Alerts")
+	local frame = CreateFrame("Frame")
+
+	frame.elapsed = 1
+	frame:SetScript("OnUpdate", function(frame,elapsed)
+		frame.elapsed = frame.elapsed + elapsed
+		if(frame.elapsed >= 1) then
+			RefreshDXEBars(DXEAlerts)
+			frame.elapsed = 0
+		end
+	end)
+
+	hooksecurefunc(DXEAlerts, "Simple", RefreshDXEBars)
+	hooksecurefunc(DXEAlerts, "RefreshBars", RefreshDXEBars)
+	DXE:LayoutHealthWatchers()
+	DXE.Alerts:RefreshBars()
+
+	if not DXEDB then DXEDB = {} end
+	if not DXEDB["profiles"] then DXEDB["profiles"] = {} end
+	if not DXEDB["profiles"][playerKey] then DXEDB["profiles"][playerKey] = {} end
+	if not DXEDB["profiles"][playerKey]["Globals"] then DXEDB["profiles"][playerKey]["Globals"] = {} end
+
+	DXEDB["profiles"][playerKey]["Globals"]["BackgroundTexture"] = [[Interface\BUTTONS\WHITE8X8]]
+	DXEDB["profiles"][playerKey]["Globals"]["BarTexture"] = SV.media.statusbar.default
+	DXEDB["profiles"][playerKey]["Globals"]["Border"] = "None"
+	DXEDB["profiles"][playerKey]["Globals"]["Font"] = SV.media.font.dialog
+	DXEDB["profiles"][playerKey]["Globals"]["TimerFont"] = SV.media.font.dialog
+end
+MOD:SaveAddonStyle("DXE", StyleDXE)
diff --git a/SVUI_Skins/components/addons/Details.lua b/SVUI_Skins/components/addons/Details.lua
new file mode 100644
index 0000000..17212ad
--- /dev/null
+++ b/SVUI_Skins/components/addons/Details.lua
@@ -0,0 +1,45 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+local ipairs  = _G.ipairs;
+local pairs   = _G.pairs;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+STYLE (IN DEVELOPMENT)
+##########################################################
+]]--
+local function StyleDetails()
+	assert(_G._detalhes, "AddOn Not Loaded");
+
+	for i=1, 10 do
+		local baseframe = _G['DetailsBaseFrame'..i];
+
+		if(baseframe) then
+			local bgframe = _G['Details_WindowFrame'..i];
+			baseframe:RemoveTextures();
+			if(bgframe) then
+				bgframe:RemoveTextures();
+				bgframe:SetStyle("Frame", "Transparent");
+			else
+				baseframe:SetStyle("Frame", "Transparent");
+			end
+		end
+	end
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveAddonStyle("Details", StyleDetails)
diff --git a/SVUI_Skins/components/addons/LightHeaded.lua b/SVUI_Skins/components/addons/LightHeaded.lua
new file mode 100644
index 0000000..67a6544
--- /dev/null
+++ b/SVUI_Skins/components/addons/LightHeaded.lua
@@ -0,0 +1,93 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local string 	= _G.string;
+--[[ STRING METHODS ]]--
+local format = string.format;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+LIGHTHEADED
+##########################################################
+]]--
+local timeLapse = 0;
+
+local function DoDis(self, elapsed)
+	self.timeLapse = self.timeLapse + elapsed
+	if(self.timeLapse < 2) then
+		return
+	else
+		self.timeLapse = 0
+	end
+	QuestNPCModel:ClearAllPoints()
+	QuestNPCModel:SetPoint("TOPLEFT", LightHeadedFrame, "TOPRIGHT", 5, -10)
+	QuestNPCModel:SetAlpha(0.85)
+	LightHeadedFrame:SetPoint("LEFT", QuestLogFrame, "RIGHT", 2, 0)
+end
+
+local function StyleLightHeaded()
+	assert(LightHeadedFrame, "AddOn Not Loaded")
+
+	local lhframe 	= _G["LightHeadedFrame"]
+	local lhsub 	= _G["LightHeadedFrameSub"]
+	local lhopts 	= _G["LightHeaded_Panel"]
+
+	SV.API:Set("Frame", LightHeadedFrame)
+	SV.API:Set("Frame", LightHeadedFrameSub)
+	SV.API:Set("Frame", LightHeadedSearchBox)
+	SV.API:Set("Tooltip", LightHeadedTooltip)
+	LightHeadedScrollFrame:RemoveTextures()
+
+	lhframe.close:Hide()
+	SV.API:Set("CloseButton", lhframe.close)
+	lhframe.handle:Hide()
+
+	SV.API:Set("PageButton", lhsub.prev)
+	SV.API:Set("PageButton", lhsub.next)
+	lhsub.prev:SetWidth(16)
+	lhsub.prev:SetHeight(16)
+	lhsub.next:SetWidth(16)
+	lhsub.next:SetHeight(16)
+	lhsub.prev:SetPoint("RIGHT", lhsub.page, "LEFT", -25, 0)
+	lhsub.next:SetPoint("LEFT", lhsub.page, "RIGHT", 25, 0)
+	SV.API:Set("ScrollBar", LightHeadedScrollFrameScrollBar, 5)
+	lhsub.title:SetTextColor(23/255, 132/255, 209/255)
+
+	lhframe.timeLapse = 0;
+	lhframe:SetScript("OnUpdate", DoDis)
+
+	if lhopts:IsVisible() then
+		for i = 1, 9 do
+			local cbox = _G["LightHeaded_Panel_Toggle"..i]
+			cbox:SetStyle("CheckButton")
+		end
+		local buttons = {
+			"LightHeaded_Panel_Button1",
+			"LightHeaded_Panel_Button2",
+		}
+
+		for _, button in pairs(buttons) do
+			_G[button]:SetStyle("Button")
+		end
+
+		LightHeaded_Panel_Button2:Disable()
+	end
+end
+MOD:SaveAddonStyle("Lightheaded", StyleLightHeaded)
\ No newline at end of file
diff --git a/SVUI_Skins/components/addons/MasterPlan.lua b/SVUI_Skins/components/addons/MasterPlan.lua
new file mode 100644
index 0000000..3ae50e3
--- /dev/null
+++ b/SVUI_Skins/components/addons/MasterPlan.lua
@@ -0,0 +1,131 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+local ipairs  = _G.ipairs;
+local pairs   = _G.pairs;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+HELPERS
+##########################################################
+]]--
+local RING_TEXTURE = [[Interface\AddOns\SVUI_Skins\artwork\FOLLOWER-RING]]
+local LVL_TEXTURE = [[Interface\AddOns\SVUI_Skins\artwork\FOLLOWER-LEVEL]]
+local HIGHLIGHT_TEXTURE = SV.media.background.default
+local DEFAULT_COLOR = {r = 0.25, g = 0.25, b = 0.25};
+local FOCUS_RINGS = {}
+--[[
+##########################################################
+STYLE
+##########################################################
+]]--
+local StyleRewardIcon = function(self)
+  local icon = self.Icon or self.icon
+  if(icon) then
+    local texture = icon:GetTexture()
+    icon:SetTexture(texture)
+    icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+    icon:ClearAllPoints()
+    icon:InsetPoints(self, 1, 1)
+    icon:SetDesaturated(false)
+  end
+end
+
+local MasterPlan_GarrPortraits = function(self)
+  local parent = self:GetParent()
+  parent:RemoveTextures()
+  self:ClearAllPoints()
+  self:SetPoint("TOPLEFT", parent, "TOPLEFT", -3, 0)
+  self:SetPoint("BOTTOMRIGHT", parent, "BOTTOMRIGHT", 3, -6)
+  self:SetTexture(RING_TEXTURE)
+  self:SetVertexColor(1, 0.86, 0)
+  if(parent:GetWidth() == 36) then
+    tinsert(FOCUS_RINGS, parent)
+  end
+end
+
+local GarrMission_FocusRings = function(self)
+  for k,frame in pairs(FOCUS_RINGS) do
+    frame:RemoveTextures()
+  end
+end
+
+local GarrMission_Rewards = function(self)
+  local frame = self:GetParent()
+  if(frame and (not frame.Panel)) then
+    local size = frame:GetHeight() - 6
+    frame:RemoveTextures()
+    frame:SetStyle("Frame", 'Icon', true, 2)
+    hooksecurefunc(frame, "SetPoint", StyleRewardIcon)
+  end
+end
+
+local GarrMission_Buttons = function(self)
+  local frame = self:GetParent()
+  if(frame) then
+    SV.API:Set("ItemButton", frame)
+  end
+end
+
+local GarrMission_Highlights = function(self)
+  local parent = self:GetParent()
+  if(not parent.AtlasHighlight) then
+      local frame = parent:CreateTexture(nil, "HIGHLIGHT")
+    frame:InsetPoints(parent,1,1)
+    frame:SetTexture(HIGHLIGHT_TEXTURE)
+    frame:SetGradientAlpha("VERTICAL",0.1,0.82,0.95,0.1,0.1,0.82,0.95,0.68)
+    parent.AtlasHighlight = frame
+  end
+  self:SetTexture("")
+end
+
+local function StyleMasterPlan()
+	assert(MasterPlan, "AddOn Not Loaded")
+
+  SV:SetAtlasFunc("MasterPlan_GarrPortraits", MasterPlan_GarrPortraits)
+  SV:SetAtlasFunc("GarrMission_Rewards", GarrMission_Rewards)
+  SV:SetAtlasFunc("GarrMission_Buttons", GarrMission_Buttons)
+  SV:SetAtlasFunc("GarrMission_Highlights", GarrMission_Highlights)
+
+  SV:SetAtlasFilter("Garr_FollowerPortrait_Ring", "MasterPlan_GarrPortraits");
+  SV:SetAtlasFilter("_GarrMission_MissionListTopHighlight", "GarrMission_Highlights")
+  SV:SetAtlasFilter("!GarrMission_Bg-Edge", "GarrMission_Buttons")
+  SV:SetAtlasFilter("GarrMission_RewardsShadow", "GarrMission_Rewards")
+
+  SV:SetAtlasFilter("_GarrMission_TopBorder-Highlight");
+  SV:SetAtlasFilter("GarrMission_ListGlow-Highlight");
+  SV:SetAtlasFilter("GarrMission_TopBorderCorner-Highlight");
+  SV:SetAtlasFilter("Garr_InfoBox-BackgroundTile");
+  SV:SetAtlasFilter("_Garr_InfoBoxBorder-Top");
+  SV:SetAtlasFilter("!Garr_InfoBoxBorder-Left");
+  SV:SetAtlasFilter("!Garr_InfoBox-Left");
+  SV:SetAtlasFilter("_Garr_InfoBox-Top");
+  SV:SetAtlasFilter("Garr_InfoBoxBorder-Corner");
+  SV:SetAtlasFilter("Garr_InfoBox-CornerShadow");
+  SV:SetAtlasFilter("_GarrMission_Bg-BottomEdgeSmall");
+  SV:SetAtlasFilter("_GarrMission_TopBorder");
+  SV:SetAtlasFilter("GarrMission_TopBorderCorner");
+  SV:SetAtlasFilter("Garr_MissionList-IconBG");
+
+  -- SV:SetAtlasFunc("GarrMission_FocusRings", GarrMission_FocusRings)
+  -- SV:SetAtlasFilter("GarrMission_MissionParchment", "GarrMission_FocusRings");
+
+	SV.API:Set("Tab", GarrisonMissionFrameTab3)
+	SV.API:Set("Tab", GarrisonMissionFrameTab4)
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveAddonStyle("MasterPlan", StyleMasterPlan, false, true)
diff --git a/SVUI_Skins/components/addons/Mogit.lua b/SVUI_Skins/components/addons/Mogit.lua
new file mode 100644
index 0000000..4a30517
--- /dev/null
+++ b/SVUI_Skins/components/addons/Mogit.lua
@@ -0,0 +1,78 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local string 	= _G.string;
+--[[ STRING METHODS ]]--
+local format = string.format;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+MOGIT
+##########################################################
+]]--
+local function StyleMogItPreview()
+	for i = 1, 99 do
+		local MogItGearSlots = {
+			"HeadSlot",
+			"ShoulderSlot",
+			"BackSlot",
+			"ChestSlot",
+			"ShirtSlot",
+			"TabardSlot",
+			"WristSlot",
+			"HandsSlot",
+			"WaistSlot",
+			"LegsSlot",
+			"FeetSlot",
+			"MainHandSlot",
+			"SecondaryHandSlot",
+		}
+		for _, object in pairs(MogItGearSlots) do
+			if _G["MogItPreview"..i..object] then
+				SV.API:Set("ItemButton", _G["MogItPreview"..i..object])
+				_G["MogItPreview"..i..object]:SetPushedTexture(nil)
+				_G["MogItPreview"..i..object]:SetHighlightTexture(nil)
+			end
+		end
+		if _G["MogItPreview"..i] then SV.API:Set("Frame", _G["MogItPreview"..i]) end
+		if _G["MogItPreview"..i.."CloseButton"] then SV.API:Set("CloseButton", _G["MogItPreview"..i.."CloseButton"]) end
+		if _G["MogItPreview"..i.."Inset"] then _G["MogItPreview"..i.."Inset"]:RemoveTextures(true) end
+		if _G["MogItPreview"..i.."Activate"] then _G["MogItPreview"..i.."Activate"]:SetStyle("Button") end
+	end
+end
+
+local function StyleMogIt()
+	assert(MogItFrame, "AddOn Not Loaded")
+
+	SV.API:Set("Frame", MogItFrame)
+	MogItFrameInset:RemoveTextures(true)
+	SV.API:Set("Frame", MogItFilters)
+	MogItFiltersInset:RemoveTextures(true)
+
+	hooksecurefunc(MogIt, "CreatePreview", StyleMogItPreview)
+	SV.API:Set("Tooltip", MogItTooltip)
+	SV.API:Set("CloseButton", MogItFrameCloseButton)
+	SV.API:Set("CloseButton", MogItFiltersCloseButton)
+	MogItFrameFiltersDefaults:RemoveTextures(true)
+	MogItFrameFiltersDefaults:SetStyle("Button")
+	SV.API:Set("ScrollBar", MogItScroll)
+	SV.API:Set("ScrollBar", MogItFiltersScrollScrollBar)
+end
+MOD:SaveAddonStyle("MogIt", StyleMogIt)
\ No newline at end of file
diff --git a/SVUI_Skins/components/addons/Omen.lua b/SVUI_Skins/components/addons/Omen.lua
new file mode 100644
index 0000000..0f53785
--- /dev/null
+++ b/SVUI_Skins/components/addons/Omen.lua
@@ -0,0 +1,75 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+local pairs   = _G.pairs;
+local string  = _G.string;
+--[[ STRING METHODS ]]--
+local format = string.format;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+OMEN
+##########################################################
+]]--
+local function StyleOmen()
+  assert(Omen, "AddOn Not Loaded")
+
+  --[[ Background Settings ]]--
+  Omen.db.profile.Background.BarInset = 3
+  Omen.db.profile.Background.EdgeSize = 1
+  Omen.db.profile.Background.Texture = "None"
+
+  --[[ Bar Settings ]]--
+  Omen.db.profile.Bar.Font = "SVUI Default Font"
+  Omen.db.profile.Bar.FontOutline = "None"
+  Omen.db.profile.Bar.FontSize = 11
+  Omen.db.profile.Bar.Height = 14
+  Omen.db.profile.Bar.ShowHeadings = false
+  Omen.db.profile.Bar.ShowTPS = false
+  Omen.db.profile.Bar.Spacing = 1
+  Omen.db.profile.Bar.Texture = "SVUI MultiColorBar"
+
+ --[[ Titlebar Settings ]]--
+  Omen.db.profile.TitleBar.BorderColor.g = 0
+  Omen.db.profile.TitleBar.BorderColor.r = 0
+  Omen.db.profile.TitleBar.BorderTexture = "None"
+  Omen.db.profile.TitleBar.EdgeSize = 1
+  Omen.db.profile.TitleBar.Font = "Arial Narrow"
+  Omen.db.profile.TitleBar.FontSize = 12
+  Omen.db.profile.TitleBar.Height = 23
+  Omen.db.profile.TitleBar.ShowTitleBar=true
+  Omen.db.profile.TitleBar.Texture = "None"
+  Omen.db.profile.TitleBar.UseSameBG = false
+
+  hooksecurefunc(Omen, 'UpdateBackdrop', function(self)
+    if(not MOD.Docklet:IsEmbedded("Omen")) then
+      SV.API:Set("Frame", self.BarList, 'Transparent')
+      self.Title:RemoveTextures()
+      self.Title:SetStyle("Frame", "Default")
+      self.Title:SetPanelColor("class")
+    end
+    self.BarList:SetPoint('TOPLEFT', self.Title, 'BOTTOMLEFT', 0, 1)
+  end)
+
+  Omen:UpdateBackdrop()
+  Omen:ReAnchorBars()
+  Omen:ResizeBars()
+end
+
+MOD:SaveAddonStyle("Omen", StyleOmen, nil, true)
\ No newline at end of file
diff --git a/SVUI_Skins/components/addons/Outfitter.lua b/SVUI_Skins/components/addons/Outfitter.lua
new file mode 100644
index 0000000..ea2a4d1
--- /dev/null
+++ b/SVUI_Skins/components/addons/Outfitter.lua
@@ -0,0 +1,108 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local string 	= _G.string;
+--[[ STRING METHODS ]]--
+local format = string.format;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+OUTFITTER
+##########################################################
+]]--
+local function StyleOutfitter()
+	assert(OutfitterFrame, "AddOn Not Loaded")
+
+	CharacterFrame:HookScript("OnShow", function(self) PaperDollSidebarTabs:SetPoint("BOTTOMRIGHT", CharacterFrameInsetRight, "TOPRIGHT", -14, 0) end)
+	OutfitterFrame:HookScript("OnShow", function(self)
+		SV.API:Set("Frame", OutfitterFrame)
+		OutfitterFrameTab1:SetSize(60, 25)
+		OutfitterFrameTab2:SetSize(60, 25)
+		OutfitterFrameTab3:SetSize(60, 25)
+		OutfitterMainFrame:RemoveTextures(true)
+		for i = 0, 13 do
+			if _G["OutfitterItem"..i.."OutfitSelected"] then
+				_G["OutfitterItem"..i.."OutfitSelected"]:SetStyle("Button")
+				_G["OutfitterItem"..i.."OutfitSelected"]:ClearAllPoints()
+				_G["OutfitterItem"..i.."OutfitSelected"]:SetSize(16, 16)
+				_G["OutfitterItem"..i.."OutfitSelected"]:SetPoint("LEFT", _G["OutfitterItem"..i.."Outfit"], "LEFT", 8, 0)
+			end
+		end
+	end)
+	OutfitterMainFrameScrollbarTrench:RemoveTextures(true)
+	OutfitterFrameTab1:ClearAllPoints()
+	OutfitterFrameTab2:ClearAllPoints()
+	OutfitterFrameTab3:ClearAllPoints()
+	OutfitterFrameTab1:SetPoint("TOPLEFT", OutfitterFrame, "BOTTOMRIGHT", -65, -2)
+	OutfitterFrameTab2:SetPoint("LEFT", OutfitterFrameTab1, "LEFT", -65, 0)
+	OutfitterFrameTab3:SetPoint("LEFT", OutfitterFrameTab2, "LEFT", -65, 0)
+	OutfitterFrameTab1:SetStyle("Button")
+	OutfitterFrameTab2:SetStyle("Button")
+	OutfitterFrameTab3:SetStyle("Button")
+	SV.API:Set("ScrollBar", OutfitterMainFrameScrollFrameScrollBar)
+	SV.API:Set("CloseButton", OutfitterCloseButton)
+	OutfitterNewButton:SetStyle("Button")
+	OutfitterEnableNone:SetStyle("Button")
+	OutfitterEnableAll:SetStyle("Button")
+	OutfitterButton:ClearAllPoints()
+	OutfitterButton:SetPoint("RIGHT", PaperDollSidebarTabs, "RIGHT", 26, -2)
+	OutfitterButton:SetHighlightTexture(nil)
+	OutfitterSlotEnables:SetFrameStrata("HIGH")
+	OutfitterEnableHeadSlot:SetStyle("CheckButton")
+	OutfitterEnableNeckSlot:SetStyle("CheckButton")
+	OutfitterEnableShoulderSlot:SetStyle("CheckButton")
+	OutfitterEnableBackSlot:SetStyle("CheckButton")
+	OutfitterEnableChestSlot:SetStyle("CheckButton")
+	OutfitterEnableShirtSlot:SetStyle("CheckButton")
+	OutfitterEnableTabardSlot:SetStyle("CheckButton")
+	OutfitterEnableWristSlot:SetStyle("CheckButton")
+	OutfitterEnableMainHandSlot:SetStyle("CheckButton")
+	OutfitterEnableSecondaryHandSlot:SetStyle("CheckButton")
+	OutfitterEnableHandsSlot:SetStyle("CheckButton")
+	OutfitterEnableWaistSlot:SetStyle("CheckButton")
+	OutfitterEnableLegsSlot:SetStyle("CheckButton")
+	OutfitterEnableFeetSlot:SetStyle("CheckButton")
+	OutfitterEnableFinger0Slot:SetStyle("CheckButton")
+	OutfitterEnableFinger1Slot:SetStyle("CheckButton")
+	OutfitterEnableTrinket0Slot:SetStyle("CheckButton")
+	OutfitterEnableTrinket1Slot:SetStyle("CheckButton")
+	OutfitterItemComparisons:SetStyle("Button")
+	OutfitterTooltipInfo:SetStyle("Button")
+	OutfitterShowHotkeyMessages:SetStyle("Button")
+	OutfitterShowMinimapButton:SetStyle("Button")
+	OutfitterShowOutfitBar:SetStyle("Button")
+	OutfitterAutoSwitch:SetStyle("Button")
+	OutfitterItemComparisons:SetSize(20, 20)
+	OutfitterTooltipInfo:SetSize(20, 20)
+	OutfitterShowHotkeyMessages:SetSize(20, 20)
+	OutfitterShowMinimapButton:SetSize(20, 20)
+	OutfitterShowOutfitBar:SetSize(20, 20)
+	OutfitterAutoSwitch:SetSize(20, 20)
+	OutfitterShowOutfitBar:SetPoint("TOPLEFT", OutfitterAutoSwitch, "BOTTOMLEFT", 0, -5)
+	OutfitterEditScriptDialogDoneButton:SetStyle("Button")
+	OutfitterEditScriptDialogCancelButton:SetStyle("Button")
+	SV.API:Set("ScrollBar", OutfitterEditScriptDialogSourceScriptScrollBar)
+	SV.API:Set("Frame", OutfitterEditScriptDialogSourceScript,"Transparent")
+	SV.API:Set("Frame", OutfitterEditScriptDialog)
+	SV.API:Set("CloseButton", OutfitterEditScriptDialog.CloseButton)
+	SV.API:Set("Tab", OutfitterEditScriptDialogTab1)
+	SV.API:Set("Tab", OutfitterEditScriptDialogTab2)
+end
+MOD:SaveAddonStyle("Outfitter", StyleOutfitter)
\ No newline at end of file
diff --git a/SVUI_Skins/components/addons/Postal.lua b/SVUI_Skins/components/addons/Postal.lua
new file mode 100644
index 0000000..b907784
--- /dev/null
+++ b/SVUI_Skins/components/addons/Postal.lua
@@ -0,0 +1,78 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local string 	= _G.string;
+--[[ STRING METHODS ]]--
+local format = string.format;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+POSTAL
+##########################################################
+]]--
+local function StylePostal()
+	assert(PostalOpenAllButton, "AddOn Not Loaded")
+
+	InboxPrevPageButton:SetPoint("CENTER", InboxFrame, "BOTTOMLEFT", 45, 112)
+	InboxNextPageButton:SetPoint("CENTER", InboxFrame, "BOTTOMLEFT", 295, 112)
+
+	for i = 1, INBOXITEMS_TO_DISPLAY do
+		local b = _G["MailItem"..i.."ExpireTime"]
+		b:SetPoint("TOPRIGHT", "MailItem"..i, "TOPRIGHT", -5, -10)
+		if b.returnicon then
+			b.returnicon:SetPoint("TOPRIGHT", b, "TOPRIGHT", 20, 0)
+		end
+		if _G['PostalInboxCB'..i] and not _G['PostalInboxCB'..i].handled then
+			_G['PostalInboxCB'..i]:SetStyle("CheckButton")
+			_G['PostalInboxCB'..i].handled = true
+		end
+	end
+	if PostalSelectOpenButton and not PostalSelectOpenButton.handled then
+		PostalSelectOpenButton:SetStyle("Button")
+		PostalSelectOpenButton.handled = true
+		PostalSelectOpenButton:SetPoint("RIGHT", InboxFrame, "TOP", -41, -48)
+	end
+	if Postal_OpenAllMenuButton and not Postal_OpenAllMenuButton.handled then
+		SV.API:Set("PageButton", Postal_OpenAllMenuButton, true)
+		Postal_OpenAllMenuButton:SetPoint('LEFT', PostalOpenAllButton, 'RIGHT', 5, 0)
+		Postal_OpenAllMenuButton.handled = true
+	end
+	if PostalOpenAllButton and not PostalOpenAllButton.handled then
+		PostalOpenAllButton:SetStyle("Button")
+		PostalOpenAllButton.handled = true
+		PostalOpenAllButton:SetPoint("CENTER", InboxFrame, "TOP", -34, -400)
+	end
+	if PostalSelectReturnButton and not PostalSelectReturnButton.handled then
+		PostalSelectReturnButton:SetStyle("Button")
+		PostalSelectReturnButton.handled = true
+		PostalSelectReturnButton:SetPoint("LEFT", InboxFrame, "TOP", -5, -48)
+	end
+	if Postal_PackageMenuButton and not Postal_PackageMenuButton.handled then
+		SV.API:Set("PageButton", Postal_PackageMenuButton, true)
+		Postal_PackageMenuButton.handled = true
+		Postal_PackageMenuButton:SetPoint('TOPRIGHT', MailFrame, -53, -6)
+	end
+	if Postal_BlackBookButton and not Postal_BlackBookButton.handled then
+		SV.API:Set("PageButton", Postal_BlackBookButton, true)
+		Postal_BlackBookButton.handled = true
+		Postal_BlackBookButton:SetPoint('LEFT', SendMailNameEditBox, 'RIGHT', 5, 2)
+	end
+end
+MOD:SaveAddonStyle("Postal", StylePostal, nil, nil, 'MAIL_SHOW')
\ No newline at end of file
diff --git a/SVUI_Skins/components/addons/Quartz.lua b/SVUI_Skins/components/addons/Quartz.lua
new file mode 100644
index 0000000..0f742d2
--- /dev/null
+++ b/SVUI_Skins/components/addons/Quartz.lua
@@ -0,0 +1,67 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local string 	= _G.string;
+--[[ STRING METHODS ]]--
+local format = string.format;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+QUARTZ
+##########################################################
+]]--
+local function StyleQuartz()
+	local AceAddon = LibStub("AceAddon-3.0")
+	if(not AceAddon) then return end
+	local Quartz3 = AceAddon:GetAddon("Quartz3", true)
+
+	assert(Quartz3, "AddOn Not Loaded")
+
+	local GCD = Quartz3:GetModule("GCD")
+	local CastBar = Quartz3.CastBarTemplate.template
+	local function StyleQuartzBar(self)
+		if not self.isStyled then
+			self.IconBorder = CreateFrame("Frame", nil, self)
+			SV.API:Set("Frame", self.IconBorder,"Transparent")
+			self.IconBorder:SetFrameLevel(0)
+			self.IconBorder:WrapPoints(self.Icon)
+			SV.API:Set("Frame", self.Bar,"Transparent",true)
+			self.isStyled = true
+		end
+ 		if self.config.hideicon then
+ 			self.IconBorder:Hide()
+ 		else
+ 			self.IconBorder:Show()
+ 		end
+	end
+
+	hooksecurefunc(CastBar, 'ApplySettings', StyleQuartzBar)
+	hooksecurefunc(CastBar, 'UNIT_SPELLCAST_START', StyleQuartzBar)
+	hooksecurefunc(CastBar, 'UNIT_SPELLCAST_CHANNEL_START', StyleQuartzBar)
+
+	if GCD then
+		hooksecurefunc(GCD, 'CheckGCD', function()
+			if not Quartz3GCDBar.backdrop then
+				SV.API:Set("Frame", Quartz3GCDBar,"Transparent",true)
+			end
+		end)
+	end
+end
+MOD:SaveAddonStyle("Quartz", StyleQuartz)
\ No newline at end of file
diff --git a/SVUI_Skins/components/addons/Recount.lua b/SVUI_Skins/components/addons/Recount.lua
new file mode 100644
index 0000000..15f3969
--- /dev/null
+++ b/SVUI_Skins/components/addons/Recount.lua
@@ -0,0 +1,116 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local string 	= _G.string;
+--[[ STRING METHODS ]]--
+local format = string.format;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+RECOUNT
+##########################################################
+]]--
+local StripKeys = {"CloseButton", "ConfigButton", "FileButton", "LeftButton", "ResetButton", "RightButton", "ReportButton", "SummaryButton"}
+
+local Recount_ShowReset = function(self)
+	MOD:LoadAlert(L['Reset Recount?'], function(self) Recount:ResetData() self:GetParent():Hide() end)
+end
+
+local Title_OnUpdate = function(self, elapsed)
+	self.timeLapse = self.timeLapse + elapsed
+	if(self.timeLapse < 0.2) then
+		return
+	else
+		self.timeLapse = 0
+	end
+	local parent = self:GetParent()parent:GetWidth()
+	self:SetSize(parent:GetWidth(), 23)
+end
+
+local function StyleFrame(frame)
+	if((not frame) or (frame.Panel)) then return end
+
+	frame:SetBackdrop(nil)
+	frame:SetStyle("Frame", "Transparent")
+	--frame.Panel:SetAllPoints()
+	--frame.Panel:SetPoint('TOPLEFT', frame, 'TOPLEFT', 0, -6)
+	frame.CloseButton:SetPoint('TOPRIGHT', frame, 'TOPRIGHT', -1, -1)
+
+	frame.TitleBackground = CreateFrame('Frame', nil, frame)
+	frame.TitleBackground:SetStyle("!_Frame", "Transparent")
+	--frame.TitleBackground:SetPanelColor("class")
+	frame.TitleBackground:SetPoint('TOP', frame, 'TOP', 0, 0)
+	frame.TitleBackground.timeLapse = 0;
+	frame.TitleBackground:SetFrameLevel(frame:GetFrameLevel())
+	frame.TitleBackground:SetScript('OnUpdate', Title_OnUpdate)
+
+	frame.Title:ClearAllPoints()
+	frame.Title:SetPoint('TOPLEFT', frame, 'TOPLEFT', 6, -5)
+
+	for i=1, #StripKeys do
+		local subframe = frame[StripKeys[i]]
+		if(subframe) then
+			for i = 1, subframe:GetNumRegions() do
+				local region = select(i, subframe:GetRegions())
+				if(region:GetObjectType() == 'Texture') then
+					region:SetDesaturated(true)
+					if(region:GetTexture() == 'Interface\\DialogFrame\\UI-DialogBox-Corner') then
+						region:SetTexture("")
+						region:Die()
+					end
+				end
+			end
+		end
+	end
+end
+
+local function StyleRecount()
+	assert(Recount, "AddOn Not Loaded")
+
+	Recount.ShowReset = Recount_ShowReset
+
+	local RecountFrames = {
+		Recount.MainWindow,
+		Recount.ConfigWindow,
+		Recount.GraphWindow,
+		Recount.DetailWindow,
+	}
+
+	for _, frame in pairs(RecountFrames) do StyleFrame(frame) end
+
+	SV.API:Set("ScrollBar", Recount_MainWindow_ScrollBarScrollBar)
+
+	Recount.MainWindow:HookScript('OnShow', function(self) if InCombatLockdown() then return end if MOD.Docklet:IsEmbedded("Recount") then MOD.Docklet:Show() end end)
+	Recount.MainWindow.FileButton:HookScript('OnClick', function(self) if LibDropdownFrame0 then SV.API:Set("Frame", LibDropdownFrame0) end end)
+
+	hooksecurefunc(Recount, 'ShowScrollbarElements', function(self, name) Recount_MainWindow_ScrollBarScrollBar:Show() end)
+	hooksecurefunc(Recount, 'HideScrollbarElements', function(self, name) Recount_MainWindow_ScrollBarScrollBar:Hide() end)
+	hooksecurefunc(Recount, 'CreateFrame', function(self, frame) StyleFrame(_G[frame]) end)
+
+	hooksecurefunc(Recount, 'ShowReport', function(self)
+		if Recount_ReportWindow.isStyled then return end
+		Recount_ReportWindow.isStyled = true
+		SV.API:Set("Frame", Recount_ReportWindow.Whisper)
+		Recount_ReportWindow.ReportButton:SetStyle("Button")
+		SV.API:Set("ScrollBar", Recount_ReportWindow_Slider)
+		Recount_ReportWindow_Slider:GetThumbTexture():SetSize(6,6)
+	end)
+end
+MOD:SaveAddonStyle("Recount", StyleRecount)
\ No newline at end of file
diff --git a/SVUI_Skins/components/addons/SVUI_!Options.lua b/SVUI_Skins/components/addons/SVUI_!Options.lua
new file mode 100644
index 0000000..78f231b
--- /dev/null
+++ b/SVUI_Skins/components/addons/SVUI_!Options.lua
@@ -0,0 +1,261 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+--[[
+##########################################################
+HELPERS
+##########################################################
+]]--
+local RegisterAsWidget, RegisterAsContainer;
+
+local ProxyLSMType = {
+	["LSM30_Font"] = true,
+	["LSM30_Sound"] = true,
+	["LSM30_Border"] = true,
+	["LSM30_Background"] = true,
+	["LSM30_Statusbar"] = true
+}
+
+local ProxyType = {
+	["InlineGroup"] = true,
+	["TreeGroup"] = true,
+	["TabGroup"] = true,
+	["SimpleGroup"] = true,
+	["DropdownGroup"] = true
+}
+
+local function Widget_OnEnter(b)
+	b:SetBackdropBorderColor(0.1, 0.8, 0.8)
+end
+
+local function Widget_OnLeave(b)
+	b:SetBackdropBorderColor(0,0,0,1)
+end
+
+local function Widget_ScrollStyle(frame, arg)
+	return SV.API:Set("ScrollBar", frame)
+end
+
+local function Widget_ButtonStyle(frame, strip, bypass)
+	if frame.Left then frame.Left:SetAlpha(0) end
+	if frame.Middle then frame.Middle:SetAlpha(0) end
+	if frame.Right then frame.Right:SetAlpha(0) end
+	if frame.SetNormalTexture then frame:SetNormalTexture("") end
+	if frame.SetHighlightTexture then frame:SetHighlightTexture(0,0,0,0) end
+	if frame.SetPushedTexture then frame:SetPushedTexture(0,0,0,0) end
+	if frame.SetDisabledTexture then frame:SetDisabledTexture("") end
+	if strip then frame:RemoveTextures() end
+	if not bypass then
+		frame:SetStyle("Button")
+	end
+end
+
+local function Widget_PaginationStyle(...)
+	SV.API:Set("PageButton", ...)
+end
+
+local function SetAdjustedStyle(this, xTopleft, yTopleft, xBottomright, yBottomright)
+	if(not this or (this and this.Panel)) then return end
+	this:RemoveTextures()
+	this:SetStyle("Frame", "Transparent")
+	this.Panel:SetPoint("TOPLEFT", this, "TOPLEFT", xTopleft, yTopleft)
+	this.Panel:SetPoint("BOTTOMRIGHT", this, "BOTTOMRIGHT", xBottomright, yBottomright)
+end
+
+local NOOP = SV.fubar
+
+local WidgetButton_OnClick = function(self)
+	local obj = self.obj;
+	if(obj and obj.pullout and obj.pullout.frame) then
+		SV.API:Set("Frame", obj.pullout.frame, "Default", true)
+	end
+end
+
+local WidgetDropButton_OnClick = function(self)
+	local obj = self.obj;
+	local widgetFrame = obj.dropdown
+	if(widgetFrame) then
+    	widgetFrame:SetWidth(220)
+		widgetFrame:SetStyle("Frame", "Default")
+	end
+end
+--[[
+##########################################################
+AceGUI MOD
+##########################################################
+]]--
+function MOD:StyleSVUIOptions()
+	local AceGUI = LibStub("AceGUI-3.0")
+
+	assert(AceGUI and (AceGUI.RegisterAsContainer ~= RegisterAsContainer or AceGUI.RegisterAsWidget ~= RegisterAsWidget), "Addon Not Loaded")
+
+	local regWidget = AceGUI.RegisterAsWidget;
+	local regContainer = AceGUI.RegisterAsContainer;
+
+	RegisterAsWidget = function(self, widget)
+
+		local widgetType = widget.type;
+		-- print("RegisterAsWidget: " .. widgetType);
+		if(widgetType == "MultiLineEditBox") then
+			local widgetFrame = widget.frame;
+			SV.API:Set("!_Frame", widgetFrame, "Default", true)
+			SV.API:Set("Frame", widget.scrollBG, "Lite", true)
+			Widget_ButtonStyle(widget.button)
+			SV.API:Set("ScrollBar", widget.scrollBar)
+			widget.scrollBar:SetPoint("RIGHT", widgetFrame, "RIGHT", -4)
+			widget.scrollBG:SetPoint("TOPRIGHT", widget.scrollBar, "TOPLEFT", -2, 19)
+			widget.scrollBG:SetPoint("BOTTOMLEFT", widget.button, "TOPLEFT")
+			widget.scrollFrame:SetPoint("BOTTOMRIGHT", widget.scrollBG, "BOTTOMRIGHT", -4, 8)
+
+		elseif(widgetType == "CheckBox") then
+			widget.checkbg:Die()
+			widget.highlight:Die()
+			if not widget.styledCheckBG then
+				widget.styledCheckBG = CreateFrame("Frame", nil, widget.frame)
+				widget.styledCheckBG:InsetPoints(widget.check)
+				SV.API:Set("!_Frame", widget.styledCheckBG, "CheckButton")
+			end
+			widget.check:SetParent(widget.styledCheckBG)
+
+		elseif(widgetType == "Dropdown") then
+			local widgetDropdown = widget.dropdown;
+			local widgetButton = widget.button;
+
+			widgetDropdown:RemoveTextures()
+			widgetButton:ClearAllPoints()
+			widgetButton:SetPoint("RIGHT", widgetDropdown, "RIGHT", -20, 0)
+			widgetButton:SetFrameLevel(widgetButton:GetFrameLevel() + 1)
+			Widget_PaginationStyle(widgetButton, true)
+
+			SetAdjustedStyle(widgetDropdown, 20, -2, -20, 2)
+
+			widgetButton:SetParent(widgetDropdown.Panel)
+			widget.text:SetParent(widgetDropdown.Panel)
+			widgetButton:HookScript("OnClick", WidgetButton_OnClick)
+
+		elseif(widgetType == "EditBox") then
+			local widgetEditbox = widget.editbox;
+			SV.API:Set("EditBox", widgetEditbox, nil, 15, 2, -2)
+
+		elseif(widgetType == "Button") then
+			local widgetFrame = widget.frame;
+			Widget_ButtonStyle(widgetFrame, true)
+			widget.text:SetParent(widgetFrame.Panel)
+
+		elseif(widgetType == "Slider") then
+			local widgetSlider = widget.slider;
+			local widgetEditbox = widget.editbox;
+
+			SV.API:Set("!_Frame", widgetSlider, "Bar")
+
+			widgetSlider:SetHeight(20)
+			widgetSlider:SetThumbTexture("Interface\\Buttons\\UI-ScrollBar-Knob")
+			widgetSlider:GetThumbTexture():SetVertexColor(0.8, 0.8, 0.8)
+
+			widgetEditbox:SetHeight(15)
+			widgetEditbox:SetPoint("TOP", widgetSlider, "BOTTOM", 0, -1)
+
+			widget.lowtext:SetPoint("TOPLEFT", widgetSlider, "BOTTOMLEFT", 2, -2)
+			widget.hightext:SetPoint("TOPRIGHT", widgetSlider, "BOTTOMRIGHT", -2, -2)
+
+		elseif(ProxyLSMType[widgetType]) then
+			local widgetFrame = widget.frame;
+			local dropButton = widgetFrame.dropButton;
+
+			widgetFrame:RemoveTextures()
+			Widget_PaginationStyle(dropButton, true)
+			widgetFrame.text:ClearAllPoints()
+			widgetFrame.text:SetPoint("RIGHT", dropButton, "LEFT", -2, 0)
+			dropButton:ClearAllPoints()
+			dropButton:SetPoint("RIGHT", widgetFrame, "RIGHT", -10, -6)
+			if(not widgetFrame.Panel) then
+				if(widgetType == "LSM30_Sound") then
+					SetAdjustedStyle(widgetFrame, 20, -17, 2, -2)
+					widget.soundbutton:SetParent(widgetFrame.Panel)
+					widget.soundbutton:ClearAllPoints()
+					widget.soundbutton:SetPoint("LEFT", widgetFrame.Panel, "LEFT", 2, 0)
+				elseif(widgetType == "LSM30_Statusbar") then
+					SetAdjustedStyle(widgetFrame, 20, -17, 2, -2)
+					widget.bar:SetParent(widgetFrame.Panel)
+					widget.bar:InsetPoints()
+				elseif(widgetType == "LSM30_Border" or widgetType == "LSM30_Background") then
+					SetAdjustedStyle(widgetFrame, 42, -17, 2, -2)
+				else
+					SetAdjustedStyle(widgetFrame, 20, -17, 2, -2)
+				end
+				widgetFrame.Panel:SetPoint("BOTTOMRIGHT", dropButton, "BOTTOMRIGHT", 2, -2)
+			end
+			dropButton:SetParent(widgetFrame.Panel)
+			widgetFrame.text:SetParent(widgetFrame.Panel)
+		end
+		return regWidget(self, widget)
+	end
+
+	AceGUI.RegisterAsWidget = RegisterAsWidget
+
+	RegisterAsContainer = function(self, widget)
+		local widgetType = widget.type;
+		-- print("RegisterAsContainer: " .. widgetType);
+		local widgetParent = widget.content:GetParent()
+		if widgetType == "ScrollFrame" then
+			SV.API:Set("ScrollBar", widget.scrollBar)
+		elseif widgetType == "Frame" then
+			for i = 1, widgetParent:GetNumChildren()do
+				local childFrame = select(i, widgetParent:GetChildren())
+				if childFrame:GetObjectType() == "Button" and childFrame:GetText() then
+					Widget_ButtonStyle(childFrame)
+				else
+					childFrame:RemoveTextures()
+				end
+			end
+			SV.API:Set("Window", widgetParent)
+		elseif(ProxyType[widgetType]) then
+
+			if widget.treeframe then
+				SV.API:Set("Frame", widget.treeframe, "Transparent")
+				widgetParent:SetPoint("TOPLEFT", widget.treeframe, "TOPRIGHT", 1, 0)
+				local oldFunc = widget.CreateButton;
+				widget.CreateButton = function(self)
+					local newButton = oldFunc(self)
+					newButton.toggle:RemoveTextures()
+					newButton.toggle.SetNormalTexture = NOOP;
+					newButton.toggle.SetPushedTexture = NOOP;
+					newButton.toggle:SetStyle("Button")
+					newButton.toggleText = newButton.toggle:CreateFontString(nil, "OVERLAY")
+					newButton.toggleText:SetFont([[Interface\AddOns\SVUI_!Core\assets\fonts\Default.ttf]], 19)
+					newButton.toggleText:SetPoint("CENTER")
+					newButton.toggleText:SetText("*")
+					return newButton
+				end
+			elseif(not widgetParent.Panel) then
+				SV.API:Set("Frame", widgetParent, "Lite")
+			end
+
+			if(widgetType == "TabGroup") then
+				local oldFunc = widget.CreateTab;
+				widget.CreateTab = function(self, arg)
+					local newTab = oldFunc(self, arg)
+					newTab:RemoveTextures()
+					return newTab
+				end
+			end
+
+			if widget.scrollbar then
+				SV.API:Set("ScrollBar", widget.scrollBar)
+			end
+		end
+		return regContainer(self, widget)
+	end
+
+	AceGUI.RegisterAsContainer = RegisterAsContainer
+end
\ No newline at end of file
diff --git a/SVUI_Skins/components/addons/SexyCooldown.lua b/SVUI_Skins/components/addons/SexyCooldown.lua
new file mode 100644
index 0000000..67e3bcf
--- /dev/null
+++ b/SVUI_Skins/components/addons/SexyCooldown.lua
@@ -0,0 +1,96 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local string 	= _G.string;
+--[[ STRING METHODS ]]--
+local format = string.format;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+SEXYCOOLDOWN
+##########################################################
+]]--
+local function SCDStripStyleSettings(bar)
+	bar.optionsTable.args.icon.args.borderheader = nil
+	bar.optionsTable.args.icon.args.border = nil
+	bar.optionsTable.args.icon.args.borderColor = nil
+	bar.optionsTable.args.icon.args.borderSize = nil
+	bar.optionsTable.args.icon.args.borderInset = nil
+	bar.optionsTable.args.bar.args.bnbheader = nil
+	bar.optionsTable.args.bar.args.texture = nil
+	bar.optionsTable.args.bar.args.backgroundColor = nil
+	bar.optionsTable.args.bar.args.border = nil
+	bar.optionsTable.args.bar.args.borderColor = nil
+	bar.optionsTable.args.bar.args.borderSize = nil
+	bar.optionsTable.args.bar.args.borderInset = nil
+end
+
+local function StyleSexyCooldownBar(bar)
+	SCDStripStyleSettings(bar)
+	SV.API:Set("Frame", bar)
+	SV:ManageVisibility(bar)
+	if MOD:IsAddonReady("SexyCooldown_Anchored") then
+		if(SV.ActionBars and SV.ActionBars.MainAnchor) then
+			bar:ClearAllPoints()
+			bar:SetPoint('BOTTOMRIGHT', SV.ActionBars.MainAnchor, 'TOPRIGHT', 0, 4)
+			bar:SetPoint("BOTTOMLEFT", SV.ActionBars.MainAnchor, "TOPLEFT", 0, 4)
+			bar:SetHeight(SV.ActionBars.MainAnchor:GetHeight())
+		end
+	end
+end
+
+local function StyleSexyCooldownIcon(bar, icon)
+	if not icon.styled then
+		SV.API:Set("Frame", icon, false, true)
+		SV.API:Set("Frame", icon.overlay,"Transparent",true)
+		icon.styled = true
+	end
+	icon.overlay.tex:SetTexCoord(0.1,0.9,0.1,0.9)
+	icon.tex:SetTexCoord(0.1,0.9,0.1,0.9)
+end
+
+local function StyleSexyCooldownBackdrop(bar)
+	bar:SetStyle("!_Frame", "Transparent")
+end
+
+local function HookSCDBar(bar)
+	if bar.hooked then return end
+	hooksecurefunc(bar, "UpdateBarLook", StyleSexyCooldownBar)
+	hooksecurefunc(bar, "UpdateSingleIconLook", StyleSexyCooldownIcon)
+	hooksecurefunc(bar, "UpdateBarBackdrop", StyleSexyCooldownBackdrop)
+	bar.settings.icon.borderInset = 0
+	bar.hooked = true
+end
+
+local function StyleSexyCooldown()
+	assert(SexyCooldown2, "AddOn Not Loaded")
+
+	for _, bar in ipairs(SexyCooldown2.bars) do
+		HookSCDBar(bar)
+		bar:UpdateBarLook()
+	end
+	hooksecurefunc(SexyCooldown2, 'CreateBar', function(self)
+		for _, bar in ipairs(self.bars) do
+			HookSCDBar(bar)
+			bar:UpdateBarLook()
+		end
+	end)
+end
+MOD:SaveAddonStyle("SexyCooldown", StyleSexyCooldown)
\ No newline at end of file
diff --git a/SVUI_Skins/components/addons/Skada.lua b/SVUI_Skins/components/addons/Skada.lua
new file mode 100644
index 0000000..df834b5
--- /dev/null
+++ b/SVUI_Skins/components/addons/Skada.lua
@@ -0,0 +1,87 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local string 	= _G.string;
+--[[ STRING METHODS ]]--
+local format = string.format;
+local twipe = table.wipe;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+SKADA
+##########################################################
+]]--
+local function Skada_ShowPopup(self)
+	MOD:LoadAlert('Do you want to reset Skada?', function(self) Skada:Reset() self:GetParent():Hide() end)
+end
+
+local function StyleSkada()
+	assert(Skada, "AddOn Not Loaded")
+	Skada.ShowPopup = Skada_ShowPopup
+
+	local SkadaDisplayBar = Skada.displays['bar']
+
+	hooksecurefunc(SkadaDisplayBar, 'AddDisplayOptions', function(self, window, options)
+		options.baroptions.args.barspacing = nil
+		options.titleoptions.args.texture = nil
+		options.titleoptions.args.bordertexture = nil
+		options.titleoptions.args.thickness = nil
+		options.titleoptions.args.margin = nil
+		options.titleoptions.args.color = nil
+		options.windowoptions = nil
+	end)
+
+	hooksecurefunc(SkadaDisplayBar, 'ApplySettings', function(self, window)
+		local skada = window.bargroup
+		if not skada then return end
+		local panelAnchor = skada
+		skada:SetSpacing(1)
+		skada:SetFrameLevel(5)
+		skada:SetBackdrop(nil)
+
+		if(window.db.enabletitle) then
+			panelAnchor = skada.button
+			skada.button:SetHeight(23)
+			skada.button:RemoveTextures()
+			skada.button:SetStyle("Frame", "Transparent")
+			--skada.button:SetPanelColor("class")
+			local titleFont = skada.button:GetFontString()
+			titleFont:SetFont(SV.media.font.dialog, 13, "NONE")
+			titleFont:SetShadowColor(0, 0, 0, 1)
+			titleFont:SetShadowOffset(1, -1)
+		end
+
+		skada:SetStyle("Frame", "Transparent")
+	end)
+
+	hooksecurefunc(Skada, 'CreateWindow', function()
+		if MOD.Docklet:IsEmbedded("Skada") then
+			MOD:RegisterAddonDocklets()
+		end
+	end)
+
+	hooksecurefunc(Skada, 'DeleteWindow', function()
+		if MOD.Docklet:IsEmbedded("Skada") then
+			MOD:RegisterAddonDocklets()
+		end
+	end)
+end
+
+MOD:SaveAddonStyle("Skada", StyleSkada, nil, true)
diff --git a/SVUI_Skins/components/addons/Storyline.lua b/SVUI_Skins/components/addons/Storyline.lua
new file mode 100644
index 0000000..ddebc78
--- /dev/null
+++ b/SVUI_Skins/components/addons/Storyline.lua
@@ -0,0 +1,155 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+local ipairs  = _G.ipairs;
+local pairs   = _G.pairs;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+
+local bubbleBackdrop = {
+	bgFile = [[Interface\AddOns\SVUI_!Core\assets\textures\CHATBUBBLE-BG]],
+    tile = false,
+    tileSize = 0,
+    edgeFile = [[Interface\AddOns\SVUI_!Core\assets\textures\CHATBUBBLE-BACKDROP]],
+    edgeSize = 15,
+    insets =
+    {
+        left = 15,
+        right = 15,
+        top = 15,
+        bottom = 15,
+    },
+};
+--[[
+##########################################################
+STYLE (IN DEVELOPMENT)
+##########################################################
+]]--
+local function StyleStoryline()
+	assert(_G.Storyline_NPCFrame, "AddOn Not Loaded");
+
+	Storyline_NPCFrame:RemoveTextures()
+	Storyline_NPCFrame:SetStyle("Frame", "Window2")
+	Storyline_NPCFrameModels:RemoveTextures()
+
+	local leftBG = CreateFrame("Frame", nil, Storyline_NPCFrame)
+	leftBG:SetPoint("TOPLEFT",  Storyline_NPCFrame, "TOPLEFT", 20, -20)
+	leftBG:SetPoint("BOTTOMRIGHT",  Storyline_NPCFrame, "BOTTOM", -4, 20)
+	leftBG:SetStyle("Frame", 'Model', false, 3, 2, 2)
+
+	local rightBG = CreateFrame("Frame", nil, Storyline_NPCFrame)
+	rightBG:SetPoint("TOPLEFT",  Storyline_NPCFrame, "TOP", 4, -20)
+	rightBG:SetPoint("BOTTOMRIGHT",  Storyline_NPCFrame, "BOTTOMRIGHT", -20, 20)
+	rightBG:SetStyle("Frame", 'Model', false, 3, 2, 2)
+
+	Storyline_NPCFrameModels:SetParent(leftBG)
+
+	--SV.API:Set("Button", Storyline_NPCFrameConfigButton, true)
+	Storyline_NPCFrameConfigButton:RemoveTextures()
+	Storyline_NPCFrameConfigButton:SetParent(Storyline_NPCFrameModels)
+	Storyline_NPCFrameConfigButton:ClearAllPoints()
+	Storyline_NPCFrameConfigButton:SetSize(24,24)
+	Storyline_NPCFrameConfigButton:SetPoint("BOTTOMLEFT", Storyline_NPCFrame, "BOTTOMLEFT", 0, 0)
+	Storyline_NPCFrameConfigButton:SetNormalTexture([[Interface\WorldMap\Gear_64Grey]])
+	Storyline_NPCFrameConfigButton:GetNormalTexture():SetTexCoord(0,1,0,1)
+	Storyline_NPCFrameConfigButton:SetPushedTexture([[Interface\WorldMap\Gear_64Grey]])
+	Storyline_NPCFrameConfigButton:GetPushedTexture():SetTexCoord(0,1,0,1)
+	Storyline_NPCFrameConfigButton:SetHighlightTexture([[Interface\WorldMap\Gear_64Grey]])
+
+	--SV.API:Set("Button", Storyline_NPCFrameResizeButton, true)
+	Storyline_NPCFrameResizeButton:RemoveTextures()
+	Storyline_NPCFrameResizeButton:SetParent(Storyline_NPCFrameModels)
+	Storyline_NPCFrameResizeButton:ClearAllPoints()
+	Storyline_NPCFrameResizeButton:SetSize(24,24)
+	Storyline_NPCFrameResizeButton:SetPoint("BOTTOMRIGHT", Storyline_NPCFrame, "BOTTOMRIGHT", 0, 0)
+	Storyline_NPCFrameResizeButton:SetNormalTexture([[Interface\ChatFrame\UI-ChatIM-SizeGrabber-Up]])
+	Storyline_NPCFrameResizeButton:GetNormalTexture():SetTexCoord(0,1,0,1)
+	Storyline_NPCFrameResizeButton:SetPushedTexture([[Interface\ChatFrame\UI-ChatIM-SizeGrabber-Down]])
+	Storyline_NPCFrameResizeButton:GetPushedTexture():SetTexCoord(0,1,0,1)
+	Storyline_NPCFrameResizeButton:SetHighlightTexture([[Interface\ChatFrame\UI-ChatIM-SizeGrabber-Highlight]])
+
+	SV.API:Set("CloseButton", Storyline_NPCFrameClose)
+	Storyline_NPCFrameClose:SetParent(Storyline_NPCFrameModels)
+	Storyline_NPCFrameClose:ClearAllPoints()
+	Storyline_NPCFrameClose:SetPoint("TOPRIGHT", Storyline_NPCFrame, "TOPRIGHT", 0, 0)
+
+	Storyline_NPCFrameChat:RemoveTextures()
+	Storyline_NPCFrameChat:SetBackdrop(bubbleBackdrop)
+	Storyline_NPCFrameChat:SetParent(Storyline_NPCFrameModels)
+	local tail0 = Storyline_NPCFrameChat:CreateTexture(nil, 'OVERLAY')
+	tail0:SetSize(20,20)
+	tail0:SetPoint("BOTTOMRIGHT", Storyline_NPCFrameChat, "TOPRIGHT", -60, -2)
+	tail0:SetTexture([[Interface\AddOns\SVUI_!Core\assets\textures\CHATBUBBLE-TAIL-UP]])
+
+	Storyline_NPCFrameChatOption1:RemoveTextures()
+	Storyline_NPCFrameChatOption2:RemoveTextures()
+	Storyline_NPCFrameChatOption3:RemoveTextures()
+	--frame:SetStyle("!_Frame", 'Transparent')
+	local callout = CreateFrame("Frame", nil, Storyline_NPCFrameChatOption1)
+	callout:SetPoint("TOPLEFT",  Storyline_NPCFrameChatOption1, "TOPLEFT", 0, 15)
+	callout:SetPoint("BOTTOMRIGHT",  Storyline_NPCFrameChatOption3, "BOTTOMRIGHT", 0, -15)
+	callout:SetBackdrop(bubbleBackdrop)
+
+	local tail = callout:CreateTexture(nil, 'OVERLAY')
+	tail:SetSize(20,20)
+	tail:SetPoint("RIGHT", callout, "LEFT", 2, 0)
+	tail:SetTexture([[Interface\AddOns\SVUI_!Core\assets\textures\CHATBUBBLE-TAIL-LEFT]])
+
+	local level = Storyline_NPCFrameChatOption1:GetFrameLevel()
+	callout:SetFrameLevel(level)
+	Storyline_NPCFrameChatOption1:SetFrameLevel(level + 2)
+	Storyline_NPCFrameChatOption2:SetFrameLevel(level + 2)
+	Storyline_NPCFrameChatOption3:SetFrameLevel(level + 2)
+
+	Storyline_NPCFrameChatPrevious:RemoveTextures()
+	Storyline_NPCFrameChatPrevious:SetSize(18,18)
+	Storyline_NPCFrameChatPrevious:SetNormalTexture([[Interface\Buttons\UI-RefreshButton]])
+	Storyline_NPCFrameChatPrevious:GetNormalTexture():SetTexCoord(0,1,0,1)
+	Storyline_NPCFrameChatPrevious:SetPushedTexture([[Interface\Buttons\UI-RefreshButton]])
+	Storyline_NPCFrameChatPrevious:GetPushedTexture():SetTexCoord(0,1,0,1)
+	Storyline_NPCFrameChatPrevious:SetHighlightTexture([[Interface\Buttons\UI-RefreshButton]])
+
+	Storyline_NPCFrameConfig:RemoveTextures()
+	Storyline_NPCFrameConfig:SetStyle("Frame", "Paper")
+	Storyline_NPCFrameConfig:ClearAllPoints()
+	Storyline_NPCFrameConfig:SetPoint("TOPLEFT", Storyline_NPCFrame, "BOTTOMLEFT", 20, -10)
+	Storyline_NPCFrameConfig:SetPoint("TOPRIGHT", Storyline_NPCFrame, "BOTTOMRIGHT", -20, -10)
+	Storyline_NPCFrameConfig:SetHeight(150)
+
+	SV.API:Set("DropDown", Storyline_NPCFrameConfigLocale)
+	Storyline_NPCFrameConfigLocale:ClearAllPoints()
+	Storyline_NPCFrameConfigLocale:SetPoint("TOP", Storyline_NPCFrameConfigText, "BOTTOM", 0, -10);
+
+	SV.API:Set("ScrollBar", Storyline_NPCFrameConfigSpeedSlider)
+	Storyline_NPCFrameConfigSpeedSliderValText:ClearAllPoints()
+	Storyline_NPCFrameConfigSpeedSliderValText:SetPoint("BOTTOMLEFT", Storyline_NPCFrameConfigSpeedSlider, "TOPLEFT", 0, 4)
+	Storyline_NPCFrameConfigSpeedSliderValText:SetPoint("BOTTOMRIGHT", Storyline_NPCFrameConfigSpeedSlider, "TOPRIGHT", 0, 4)
+
+	Storyline_NPCFrameConfigSpeedSlider:ClearAllPoints()
+	Storyline_NPCFrameConfigSpeedSlider:SetPoint("TOPLEFT", Storyline_NPCFrameConfigText, "BOTTOMLEFT", 0, -70);
+
+	SV.API:Set("CheckButton", Storyline_NPCFrameConfigAutoEquip)
+	Storyline_NPCFrameConfigAutoEquipText:ClearAllPoints()
+	Storyline_NPCFrameConfigAutoEquipText:SetPoint("LEFT", Storyline_NPCFrameConfigAutoEquip, "RIGHT", 10, 0)
+
+	Storyline_NPCFrameObjectives:SetFrameLevel(Storyline_NPCFrameModels:GetFrameLevel() + 20)
+
+	if(SV.Tooltip) then
+		SV.Tooltip:SetCustomStyle(Storyline_MainTooltip)
+	end
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveAddonStyle("Storyline", StyleStoryline)
diff --git a/SVUI_Skins/components/addons/TinyDPS.lua b/SVUI_Skins/components/addons/TinyDPS.lua
new file mode 100644
index 0000000..bd140d9
--- /dev/null
+++ b/SVUI_Skins/components/addons/TinyDPS.lua
@@ -0,0 +1,50 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local string 	= _G.string;
+--[[ STRING METHODS ]]--
+local format = string.format;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+TINYDPS
+##########################################################
+]]--
+local function StyleTinyDPS()
+	assert(tdpsFrame, "AddOn Not Loaded")
+
+	SV.API:Set("Frame", tdpsFrame)
+
+	tdpsFrame:HookScript("OnShow", function()
+		if InCombatLockdown() then return end
+		if MOD.Docklet:IsEmbedded("TinyDPS") then
+			MOD.Docklet:Show()
+		end
+	end)
+
+	if tdpsStatusBar then
+		tdpsStatusBar:SetBackdrop({bgFile = SV.media.background.default, edgeFile = [[Interface\AddOns\SVUI_!Core\assets\textures\EMPTY]], tile = false, tileSize = 0, edgeSize = 1})
+		tdpsStatusBar:SetStatusBarTexture(SV.media.statusbar.default)
+	end
+
+	tdpsRefresh()
+end
+
+MOD:SaveAddonStyle("TinyDPS", StyleTinyDPS)
diff --git a/SVUI_Skins/components/addons/TomTom.lua b/SVUI_Skins/components/addons/TomTom.lua
new file mode 100644
index 0000000..cce5f9b
--- /dev/null
+++ b/SVUI_Skins/components/addons/TomTom.lua
@@ -0,0 +1,34 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local string 	= _G.string;
+--[[ STRING METHODS ]]--
+local format = string.format;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+TOMTOM
+##########################################################
+]]--
+local function StyleTomTom()
+  assert(TomTomBlock, "AddOn Not Loaded")
+  SV.API:Set("Frame", TomTomBlock)
+end
+MOD:SaveAddonStyle("TomTom", StyleTomTom)
\ No newline at end of file
diff --git a/SVUI_Skins/components/addons/TradeSkillDW.lua b/SVUI_Skins/components/addons/TradeSkillDW.lua
new file mode 100644
index 0000000..bc85018
--- /dev/null
+++ b/SVUI_Skins/components/addons/TradeSkillDW.lua
@@ -0,0 +1,136 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local string 	= _G.string;
+--[[ STRING METHODS ]]--
+local format = string.format;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+TSDW
+##########################################################
+]]--
+local function StyleTradeSkillDW()
+	assert(TradeSkillDW_QueueFrame, "AddOn Not Loaded")
+
+	TradeSkillFrame:SetStyle("Frame", "Window2")
+	TradeSkillListScrollFrame:RemoveTextures(true)
+	TradeSkillDetailScrollFrame:RemoveTextures(true)
+	TradeSkillFrameInset:RemoveTextures(true)
+	TradeSkillExpandButtonFrame:RemoveTextures(true)
+	TradeSkillDetailScrollChildFrame:RemoveTextures(true)
+	TradeSkillListScrollFrame:RemoveTextures(true)
+	SV.API:Set("Frame", TradeSkillGuildFrame,"Transparent")
+	SV.API:Set("Frame", TradeSkillGuildFrameContainer,"Transparent")
+	TradeSkillGuildFrame:SetPoint("BOTTOMLEFT", TradeSkillFrame, "BOTTOMRIGHT", 3, 19)
+	SV.API:Set("CloseButton", TradeSkillGuildFrameCloseButton)
+
+	TradeSkillFrame:HookScript("OnShow", function()
+		SV.API:Set("Frame", TradeSkillFrame)
+		TradeSkillListScrollFrame:RemoveTextures()
+		if not TradeSkillDWExpandButton then return end
+		if not TradeSkillDWExpandButton.styled then
+			SV.API:Set("PageButton", TradeSkillDWExpandButton)
+			TradeSkillDWExpandButton.styled = true
+		end
+	end)
+
+	TradeSkillFrame:SetHeight(TradeSkillFrame:GetHeight() + 12)
+	TradeSkillRankFrame:SetStyle("Frame", 'Transparent')
+	TradeSkillRankFrame:SetStatusBarTexture(SV.media.statusbar.default)
+	TradeSkillCreateButton:SetStyle("Button")
+	TradeSkillCancelButton:SetStyle("Button")
+	TradeSkillFilterButton:SetStyle("Button")
+	TradeSkillCreateAllButton:SetStyle("Button")
+	TradeSkillViewGuildCraftersButton:SetStyle("Button")
+	TradeSkillLinkButton:GetNormalTexture():SetTexCoord(0.25, 0.7, 0.37, 0.75)
+	TradeSkillLinkButton:GetPushedTexture():SetTexCoord(0.25, 0.7, 0.45, 0.8)
+	TradeSkillLinkButton:GetHighlightTexture():Die()
+	SV.API:Set("Frame", TradeSkillLinkButton,"Transparent")
+	TradeSkillLinkButton:SetSize(17, 14)
+	TradeSkillLinkButton:SetPoint("LEFT", TradeSkillLinkFrame, "LEFT", 5, -1)
+	TradeSkillFrameSearchBox:SetStyle("Editbox")
+	TradeSkillInputBox:SetStyle("Editbox")
+	TradeSkillIncrementButton:SetPoint("RIGHT", TradeSkillCreateButton, "LEFT", -13, 0)
+	SV.API:Set("CloseButton", TradeSkillFrameCloseButton)
+	SV.API:Set("ScrollBar", TradeSkillDetailScrollFrameScrollBar)
+
+	local once = false
+
+	hooksecurefunc("TradeSkillFrame_SetSelection", function(id)
+		TradeSkillSkillIcon:SetStyle("Button")
+
+		if TradeSkillSkillIcon:GetNormalTexture() then
+			TradeSkillSkillIcon:GetNormalTexture():SetTexCoord(0.1,0.9,0.1,0.9)
+			TradeSkillSkillIcon:GetNormalTexture():ClearAllPoints()
+			TradeSkillSkillIcon:GetNormalTexture():SetPoint("TOPLEFT", 2, -2)
+			TradeSkillSkillIcon:GetNormalTexture():SetPoint("BOTTOMRIGHT", -2, 2)
+		end
+
+		for i = 1, MAX_TRADE_SKILL_REAGENTS do
+			local button = _G["TradeSkillReagent"..i]
+			local icon = _G["TradeSkillReagent"..i.."IconTexture"]
+			local count = _G["TradeSkillReagent"..i.."Count"]
+			icon:SetTexCoord(0.1,0.9,0.1,0.9)
+			icon:SetDrawLayer("OVERLAY")
+			if not icon.backdrop then
+				icon.backdrop = CreateFrame("Frame", nil, button)
+				icon.backdrop:SetFrameLevel(button:GetFrameLevel() - 1)
+				SV.API:Set("Frame", icon.backdrop,"Transparent")
+				icon.backdrop:SetPoint("TOPLEFT", icon, "TOPLEFT", -2, 2)
+				icon.backdrop:SetPoint("BOTTOMRIGHT", icon, "BOTTOMRIGHT", 2, -2)
+			end
+			icon:SetParent(icon.backdrop)
+			count:SetParent(icon.backdrop)
+			count:SetDrawLayer("OVERLAY")
+			if i > 2 and once == false then
+				local point, anchoredto, point2, x, y = button:GetPoint()
+				button:ClearAllPoints()
+				button:SetPoint(point, anchoredto, point2, x, y - 3)
+				once = true
+			end
+			_G["TradeSkillReagent"..i.."NameFrame"]:Die()
+		end
+	end)
+
+	TradeSkillDW_QueueFrame:HookScript("OnShow", function() SV.API:Set("Frame", TradeSkillDW_QueueFrame,"Transparent") end)
+
+	SV.API:Set("CloseButton", TradeSkillDW_QueueFrameCloseButton)
+
+	TradeSkillDW_QueueFrameInset:RemoveTextures()
+	TradeSkillDW_QueueFrameClear:SetStyle("Button")
+	TradeSkillDW_QueueFrameDown:SetStyle("Button")
+	TradeSkillDW_QueueFrameUp:SetStyle("Button")
+	TradeSkillDW_QueueFrameDo:SetStyle("Button")
+	TradeSkillDW_QueueFrameDetailScrollFrame:RemoveTextures()
+	TradeSkillDW_QueueFrameDetailScrollFrameChildFrame:RemoveTextures()
+	TradeSkillDW_QueueFrameDetailScrollFrameChildFrameReagent1:RemoveTextures()
+	TradeSkillDW_QueueFrameDetailScrollFrameChildFrameReagent2:RemoveTextures()
+	TradeSkillDW_QueueFrameDetailScrollFrameChildFrameReagent3:RemoveTextures()
+	TradeSkillDW_QueueFrameDetailScrollFrameChildFrameReagent4:RemoveTextures()
+	TradeSkillDW_QueueFrameDetailScrollFrameChildFrameReagent5:RemoveTextures()
+	TradeSkillDW_QueueFrameDetailScrollFrameChildFrameReagent6:RemoveTextures()
+	TradeSkillDW_QueueFrameDetailScrollFrameChildFrameReagent7:RemoveTextures()
+	TradeSkillDW_QueueFrameDetailScrollFrameChildFrameReagent8:RemoveTextures()
+	SV.API:Set("ScrollBar", TradeSkillDW_QueueFrameDetailScrollFrameScrollBar)
+	TradeSkillListScrollFrame:RemoveTextures()
+end
+--[[#################################################]]--
+MOD:SaveAddonStyle("TradeSkillDW", StyleTradeSkillDW)
diff --git a/SVUI_Skins/components/addons/VEM.lua b/SVUI_Skins/components/addons/VEM.lua
new file mode 100644
index 0000000..9d5cb72
--- /dev/null
+++ b/SVUI_Skins/components/addons/VEM.lua
@@ -0,0 +1,239 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local string 	= _G.string;
+--[[ STRING METHODS ]]--
+local format = string.format;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+VEM
+##########################################################
+]]--
+local RaidNotice_AddMessage_ = RaidNotice_AddMessage
+local NewHook = hooksecurefunc
+
+local function StyleBars(self)
+	for bar in self:GetBarIterator() do
+		if not bar.injected then
+			bar.ApplyStyle = function()
+				local frame = bar.frame
+				local tbar = _G[frame:GetName()..'Bar']
+				local spark = _G[frame:GetName()..'BarSpark']
+				local texture = _G[frame:GetName()..'BarTexture']
+				local icon1 = _G[frame:GetName()..'BarIcon1']
+				local icon2 = _G[frame:GetName()..'BarIcon2']
+				local name = _G[frame:GetName()..'BarName']
+				local timer = _G[frame:GetName()..'BarTimer']
+
+				if not icon1.overlay then
+					icon1.overlay = CreateFrame('Frame', '$parentIcon1Overlay', tbar)
+					icon1.overlay:SetStyle("!_Frame")
+					icon1.overlay:SetFrameLevel(0)
+					icon1.overlay:SetSize(22, 22)
+					icon1.overlay:SetPoint('BOTTOMRIGHT', frame, 'BOTTOMLEFT', -2, 0)
+				end
+				if not icon2.overlay then
+					icon2.overlay = CreateFrame('Frame', '$parentIcon2Overlay', tbar)
+					icon2.overlay:SetStyle("!_Frame")
+					icon2.overlay:SetFrameLevel(0)
+					icon2.overlay:SetSize(22, 22)
+					icon2.overlay:SetPoint('BOTTOMLEFT', frame, 'BOTTOMRIGHT', 2, 0)
+				end
+
+				if bar.color then
+					tbar:SetStatusBarColor(bar.color.r, bar.color.g, bar.color.b)
+				else
+					tbar:SetStatusBarColor(bar.owner.options.StartColorR, bar.owner.options.StartColorG, bar.owner.options.StartColorB)
+				end
+
+				if bar.enlarged then
+					frame:SetWidth(bar.owner.options.HugeWidth)
+					tbar:SetWidth(bar.owner.options.HugeWidth)
+					frame:SetScale(bar.owner.options.HugeScale)
+				else
+					frame:SetWidth(bar.owner.options.Width)
+					tbar:SetWidth(bar.owner.options.Width)
+					frame:SetScale(bar.owner.options.Scale)
+				end
+
+				spark:SetAlpha(0)
+				spark:SetTexture("")
+
+				icon1:SetTexCoord(0.1,0.9,0.1,0.9)
+				icon1:ClearAllPoints()
+				icon1:InsetPoints(icon1.overlay)
+
+				icon2:SetTexCoord(0.1,0.9,0.1,0.9)
+				icon2:ClearAllPoints()
+				icon2:InsetPoints(icon2.overlay)
+
+				texture:SetTexture(SV.media.statusbar.default)
+				tbar:InsetPoints(frame)
+
+				frame:SetStyle("!_Frame")
+
+				name:ClearAllPoints()
+				name:SetWidth(165)
+				name:SetHeight(8)
+				name:SetJustifyH('LEFT')
+				name:SetShadowColor(0, 0, 0, 0)
+				timer:ClearAllPoints()
+				timer:SetJustifyH('RIGHT')
+				timer:SetShadowColor(0, 0, 0, 0)
+
+				frame:SetHeight(22)
+				name:SetPoint('LEFT', frame, 'LEFT', 4, 0)
+				timer:SetPoint('RIGHT', frame, 'RIGHT', -4, 0)
+
+				name:SetFont(SV.media.font.dialog, 12, 'OUTLINE')
+				timer:SetFont(SV.media.font.dialog, 12, 'OUTLINE')
+
+				name:SetTextColor(bar.owner.options.TextColorR, bar.owner.options.TextColorG, bar.owner.options.TextColorB)
+				timer:SetTextColor(bar.owner.options.TextColorR, bar.owner.options.TextColorG, bar.owner.options.TextColorB)
+
+				if bar.owner.options.IconLeft then icon1:Show() icon1.overlay:Show() else icon1:Hide() icon1.overlay:Hide() end
+				if bar.owner.options.IconRight then icon2:Show() icon2.overlay:Show() else icon2:Hide() icon2.overlay:Hide() end
+
+				tbar:SetAlpha(1)
+				frame:SetAlpha(1)
+				texture:SetAlpha(1)
+				frame:Show()
+				bar:Update(0)
+				bar.injected = true
+			end
+			bar:ApplyStyle()
+		end
+	end
+end
+
+local StyleBossTitle = function()
+	local anchor = VEMBossHealthDropdown:GetParent()
+	if not anchor.styled then
+		local header = {anchor:GetRegions()}
+		if header[1]:IsObjectType('FontString') then
+			header[1]:SetFont(SV.media.font.dialog, 12, 'OUTLINE')
+			header[1]:SetTextColor(1, 1, 1)
+			header[1]:SetShadowColor(0, 0, 0, 0)
+			anchor.styled = true
+		end
+		header = nil
+	end
+	anchor = nil
+end
+
+local StyleBoss = function()
+	local count = 1
+	while _G[format('VEM_BossHealth_Bar_%d', count)] do
+		local bar = _G[format('VEM_BossHealth_Bar_%d', count)]
+		local background = _G[bar:GetName()..'BarBorder']
+		local progress = _G[bar:GetName()..'Bar']
+		local name = _G[bar:GetName()..'BarName']
+		local timer = _G[bar:GetName()..'BarTimer']
+		local prev = _G[format('VEM_BossHealth_Bar_%d', count-1)]
+		local _, anch, _ ,_, _ = bar:GetPoint()
+		bar:ClearAllPoints()
+		if count == 1 then
+			if VEM_SavedOptions.HealthFrameGrowUp then
+				bar:SetPoint('BOTTOM', anch, 'TOP' , 0 , 12)
+			else
+				bar:SetPoint('TOP', anch, 'BOTTOM' , 0, -22)
+			end
+		else
+			if VEM_SavedOptions.HealthFrameGrowUp then
+				bar:SetPoint('TOPLEFT', prev, 'TOPLEFT', 0, 26)
+			else
+				bar:SetPoint('TOPLEFT', prev, 'TOPLEFT', 0, -26)
+			end
+		end
+		bar:SetStyle("!_Frame", 'Transparent')
+		background:SetNormalTexture(nil)
+		progress:SetStatusBarTexture(SV.media.statusbar.default)
+		progress:ClearAllPoints()
+		progress:InsetPoints(bar)
+		name:ClearAllPoints()
+		name:SetJustifyH('LEFT')
+		name:SetShadowColor(0, 0, 0, 0)
+		timer:ClearAllPoints()
+		timer:SetJustifyH('RIGHT')
+		timer:SetShadowColor(0, 0, 0, 0)
+
+		bar:SetHeight(22)
+		name:SetPoint('LEFT', bar, 'LEFT', 4, 0)
+		timer:SetPoint('RIGHT', bar, 'RIGHT', -4, 0)
+
+		name:SetFont(SV.media.font.dialog, 12, 'OUTLINE')
+		timer:SetFont(SV.media.font.dialog, 12, 'OUTLINE')
+		count = count + 1
+	end
+end
+
+local _hook_OnShow = function(self)
+	if(not self.Panel) then
+		self:SetStyle("!_Frame", 'Transparent')
+	end
+end
+
+local function StyleVEM(event, addon)
+	assert(VEM, "AddOn Not Loaded")
+
+	if event == 'PLAYER_ENTERING_WORLD' then
+		NewHook(DBT, 'CreateBar', StyleBars)
+		NewHook(VEM.BossHealth, 'Show', StyleBossTitle)
+		NewHook(VEM.BossHealth, 'AddBoss', StyleBoss)
+		NewHook(VEM.BossHealth, 'UpdateSettings', StyleBoss)
+
+		if not VEM_SavedOptions['DontShowRangeFrame'] then
+			VEM.RangeCheck:Show()
+			VEM.RangeCheck:Hide()
+			VEMRangeCheck:HookScript('OnShow', _hook_OnShow)
+			VEMRangeCheckRadar:SetStyle("!_Frame", 'Transparent')
+		end
+
+		if not VEM_SavedOptions['DontShowInfoFrame'] then
+			VEM.InfoFrame:Show(5, 'test')
+			VEM.InfoFrame:Hide()
+			VEMInfoFrame:HookScript('OnShow', _hook_OnShow)
+		end
+
+		RaidNotice_AddMessage = function(noticeFrame, textString, colorInfo)
+			if textString:find(' |T') then
+				textString = gsub(textString,'(:12:12)',':18:18:0:0:64:64:5:59:5:59')
+			end
+			return RaidNotice_AddMessage_(noticeFrame, textString, colorInfo)
+		end
+	end
+
+	if addon == 'VEM-GUI' then
+		VEM_GUI_OptionsFrame:HookScript('OnShow', function()
+			SV.API:Set("Frame", VEM_GUI_OptionsFrame)
+			SV.API:Set("Frame", VEM_GUI_OptionsFrameBossMods)
+			SV.API:Set("Frame", VEM_GUI_OptionsFrameVEMOptions)
+			SV.API:Set("Frame", VEM_GUI_OptionsFramePanelContainer, 'Transparent', true)
+		end)
+		SV.API:Set("Tab", VEM_GUI_OptionsFrameTab1)
+		SV.API:Set("Tab", VEM_GUI_OptionsFrameTab2)
+		VEM_GUI_OptionsFrameOkay:SetStyle("Button")
+		VEM_GUI_OptionsFrameWebsiteButton:SetStyle("Button")
+		SV.API:Set("ScrollBar", VEM_GUI_OptionsFramePanelContainerFOVScrollBar)
+		MOD:SafeEventRemoval("VEM", event)
+	end
+end
+MOD:SaveAddonStyle("VEM", StyleVEM, nil, true)
diff --git a/SVUI_Skins/components/addons/Zygor.lua b/SVUI_Skins/components/addons/Zygor.lua
new file mode 100644
index 0000000..4fc56b6
--- /dev/null
+++ b/SVUI_Skins/components/addons/Zygor.lua
@@ -0,0 +1,78 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local string 	= _G.string;
+--[[ STRING METHODS ]]--
+local format = string.format;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+ZYGOR
+##########################################################
+]]--
+local function StyleZygorTabs()
+	if(not ZGVCharacterGearFinderButton) then return end
+	ZGVCharacterGearFinderButton.Highlight:SetColorTexture(1, 1, 1, 0.3)
+	ZGVCharacterGearFinderButton.Highlight:SetPoint("TOPLEFT", 3, -4)
+	ZGVCharacterGearFinderButton.Highlight:SetPoint("BOTTOMRIGHT", -1, 0)
+	ZGVCharacterGearFinderButton.Hider:SetColorTexture(0.4, 0.4, 0.4, 0.4)
+	ZGVCharacterGearFinderButton.Hider:SetPoint("TOPLEFT", 3, -4)
+	ZGVCharacterGearFinderButton.Hider:SetPoint("BOTTOMRIGHT", -1, 0)
+	ZGVCharacterGearFinderButton.TabBg:Die()
+	if i == 1 then
+		for x = 1, ZGVCharacterGearFinderButton:GetNumRegions()do
+			local texture = select(x, ZGVCharacterGearFinderButton:GetRegions())
+			texture:SetTexCoord(0.16, 0.86, 0.16, 0.86)
+		end
+	end
+	ZGVCharacterGearFinderButton:SetStyle("Frame", "Default", true, 2)
+	ZGVCharacterGearFinderButton.Panel:SetPoint("TOPLEFT", 2, -3)
+	ZGVCharacterGearFinderButton.Panel:SetPoint("BOTTOMRIGHT", 0, -2)
+end
+
+local function StyleZygor()
+	--MOD.Debugging = true;
+	local ZygorGuidesViewer = LibStub('AceAddon-3.0'):GetAddon('ZygorGuidesViewer')
+	assert(ZygorGuidesViewer, "AddOn Not Loaded")
+
+	SV.API:Set("Window", ZygorGuidesViewerFrame)
+	ZygorGuidesViewerFrame_Border:RemoveTextures(true)
+	SV.API:Set("Frame", ZygorGuidesViewer_CreatureViewer, 'Model')
+
+	for i = 1, 6 do
+		SV.API:Set("Frame", _G['ZygorGuidesViewerFrame_Step'..i], 'Default')
+	end
+
+	CharacterFrame:HookScript("OnShow", StyleZygorTabs)
+
+	ZygorGuidesViewerFrame_Border:HookScript('OnHide', function(self) self:RemoveTextures(true) end)
+	ZygorGuidesViewerFrame_Border:HookScript('OnShow', function(self) self:RemoveTextures(true) end)
+	if(SV.Maps and SV.db.Maps) then
+		if(SV.db.Maps.customIcons) then
+			--Minimap:SetBlipTexture(SV.Maps.media.customBlips)
+			--Minimap.SetBlipTexture = function() return end
+		else
+			--Minimap:SetBlipTexture(SV.Maps.media.defaultBlips)
+			--Minimap.SetBlipTexture = function() return end
+		end
+	end
+end
+
+MOD:SaveAddonStyle("ZygorGuidesViewer", StyleZygor)
\ No newline at end of file
diff --git a/SVUI_Skins/components/addons/_load.xml b/SVUI_Skins/components/addons/_load.xml
new file mode 100644
index 0000000..231c531
--- /dev/null
+++ b/SVUI_Skins/components/addons/_load.xml
@@ -0,0 +1,32 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+	<Script file='SVUI_!Options.lua'/>
+	<Script file='ACP.lua'/>
+	<Script file='AdiBags.lua'/>
+	<Script file='Altoholic.lua'/>
+	<Script file='AtlasLoot.lua'/>
+	<Script file='AuctionLite.lua'/>
+	<Script file='alDamageMeter.lua'/>
+	<Script file='BigWigs.lua'/>
+	<Script file='Bugsack.lua'/>
+	<Script file='Clique.lua'/>
+	<Script file='Cooline.lua'/>
+	<Script file='Details.lua'/>
+	<Script file='DBM.lua'/>
+	<Script file='DXE.lua'/>
+	<Script file='LightHeaded.lua'/>
+	<Script file='MasterPlan.lua'/>
+	<Script file='Mogit.lua'/>
+	<Script file='Omen.lua'/>
+	<Script file='Outfitter.lua'/>
+	<Script file='Postal.lua'/>
+	<Script file='Quartz.lua'/>
+	<Script file='Recount.lua'/>
+	<Script file='SexyCooldown.lua'/>
+	<Script file='Skada.lua'/>
+	<Script file='Storyline.lua'/>
+	<Script file='TinyDPS.lua'/>
+	<Script file='TomTom.lua'/>
+	<Script file='TradeSkillDW.lua'/>
+	<Script file='VEM.lua'/>
+	<Script file='Zygor.lua'/>
+</Ui>
diff --git a/SVUI_Skins/components/addons/alDamageMeter.lua b/SVUI_Skins/components/addons/alDamageMeter.lua
new file mode 100644
index 0000000..092fa75
--- /dev/null
+++ b/SVUI_Skins/components/addons/alDamageMeter.lua
@@ -0,0 +1,42 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local string 	= _G.string;
+--[[ STRING METHODS ]]--
+local format = string.format;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+ALDAMAGEMETER
+##########################################################
+]]--
+local function StyleALDamageMeter()
+  assert(_G['alDamagerMeterFrame'], "AddOn Not Loaded")
+
+  alDamageMeterFrame.bg:Die()
+  SV.API:Set("Frame", alDamageMeterFrame)
+  alDamageMeterFrame:HookScript('OnShow', function()
+    if InCombatLockdown() then return end
+    if MOD.Docklet:IsEmbedded("alDamageMeter") then
+    	MOD.Docklet:Show()
+    end
+  end)
+end
+MOD:SaveAddonStyle("alDamageMeter", StyleALDamageMeter)
\ No newline at end of file
diff --git a/SVUI_Skins/components/atlas.lua b/SVUI_Skins/components/atlas.lua
new file mode 100644
index 0000000..25a17ee
--- /dev/null
+++ b/SVUI_Skins/components/atlas.lua
@@ -0,0 +1,56 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+local ipairs  = _G.ipairs;
+local pairs   = _G.pairs;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+HELPERS
+##########################################################
+]]--
+local RING_TEXTURE = [[Interface\AddOns\SVUI_Skins\artwork\FOLLOWER-RING]]
+local LVL_TEXTURE = [[Interface\AddOns\SVUI_Skins\artwork\FOLLOWER-LEVEL]]
+local DEFAULT_COLOR = {r = 0.25, g = 0.25, b = 0.25};
+--[[
+##########################################################
+STYLE
+##########################################################
+]]--
+local GarrMission_PortraitsFromLevel = function(self)
+	local parent = self:GetParent()
+	if(parent.PortraitRing) then
+  		parent.PortraitRing:SetTexture(RING_TEXTURE)
+  	end
+end
+SV:SetAtlasFunc("GarrMission_PortraitsFromLevel", GarrMission_PortraitsFromLevel)
+
+local GarrMission_MaterialFrame = function(self)
+  local frame = self:GetParent()
+  frame:RemoveTextures()
+  frame:SetStyle("Frame", "Inset", true, 1, -5, -7)
+	self:SetTexture("")
+end
+SV:SetAtlasFunc("GarrMission_MaterialFrame", GarrMission_MaterialFrame)
+
+SV:SetAtlasFilter("GarrMission_PortraitRing_LevelBorder", "GarrMission_PortraitsFromLevel")
+SV:SetAtlasFilter("GarrMission_PortraitRing_iLvlBorder", "GarrMission_PortraitsFromLevel")
+SV:SetAtlasFilter("Garr_Mission_MaterialFrame", "GarrMission_MaterialFrame")
+
+SV:SetAtlasFilter("Garr_FollowerToast-Uncommon");
+SV:SetAtlasFilter("Garr_FollowerToast-Epic");
+SV:SetAtlasFilter("Garr_FollowerToast-Rare");
+SV:SetAtlasFilter("GarrLanding-MinimapIcon-Horde-Up");
+SV:SetAtlasFilter("GarrLanding-MinimapIcon-Horde-Down");
+SV:SetAtlasFilter("GarrLanding-MinimapIcon-Alliance-Up");
+SV:SetAtlasFilter("GarrLanding-MinimapIcon-Alliance-Down");
diff --git a/SVUI_Skins/components/atlas/_load.xml b/SVUI_Skins/components/atlas/_load.xml
new file mode 100644
index 0000000..b7c6494
--- /dev/null
+++ b/SVUI_Skins/components/atlas/_load.xml
@@ -0,0 +1,3 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+	<Script file='garrison.lua'/>
+</Ui>
\ No newline at end of file
diff --git a/SVUI_Skins/components/atlas/garrison.lua b/SVUI_Skins/components/atlas/garrison.lua
new file mode 100644
index 0000000..00ead02
--- /dev/null
+++ b/SVUI_Skins/components/atlas/garrison.lua
@@ -0,0 +1,57 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+local ipairs  = _G.ipairs;
+local pairs   = _G.pairs;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+HELPERS
+##########################################################
+]]--
+local RING_TEXTURE = [[Interface\AddOns\SVUI_Skins\artwork\FOLLOWER-RING]]
+local LVL_TEXTURE = [[Interface\AddOns\SVUI_Skins\artwork\FOLLOWER-LEVEL]]
+local DEFAULT_COLOR = {r = 0.25, g = 0.25, b = 0.25};
+--[[
+##########################################################
+STYLE
+##########################################################
+]]--
+local GarrMission_PortraitsFromLevel = function(self)
+	local parent = self:GetParent()
+	if(parent.PortraitRing) then
+  		parent.PortraitRing:SetTexture(RING_TEXTURE)
+  	end
+end
+SV:SetAtlasFunc("GarrMission_PortraitsFromLevel", GarrMission_PortraitsFromLevel)
+
+local GarrMission_MaterialFrame = function(self)
+  local frame = self:GetParent()
+  frame:RemoveTextures()
+  frame:SetStyle("Frame", "Inset", true, 1, -5, -7)
+  self:SetTexture("")
+end
+SV:SetAtlasFunc("GarrMission_MaterialFrame", GarrMission_MaterialFrame)
+
+SV:SetAtlasFilter("GarrMission_PortraitRing_LevelBorder", "GarrMission_PortraitsFromLevel")
+SV:SetAtlasFilter("GarrMission_PortraitRing_iLvlBorder", "GarrMission_PortraitsFromLevel")
+SV:SetAtlasFilter("Garr_Mission_MaterialFrame", "GarrMission_MaterialFrame")
+SV:SetAtlasFilter("Garr_FollowerToast-Uncommon");
+SV:SetAtlasFilter("Garr_FollowerToast-Epic");
+SV:SetAtlasFilter("Garr_FollowerToast-Rare");
+SV:SetAtlasFilter("GarrLanding-MinimapIcon-Horde-Up");
+SV:SetAtlasFilter("GarrLanding-MinimapIcon-Horde-Down");
+SV:SetAtlasFilter("GarrLanding-MinimapIcon-Alliance-Up");
+SV:SetAtlasFilter("GarrLanding-MinimapIcon-Alliance-Down");
+
+SV:SetAtlasFilter("Garr_FollowerToast-Rare");
diff --git a/SVUI_Skins/components/blizzard/_load.xml b/SVUI_Skins/components/blizzard/_load.xml
new file mode 100644
index 0000000..5b51d0b
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/_load.xml
@@ -0,0 +1,41 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+	<Script file='achievement.lua'/>
+	<Script file='alert.lua'/>
+	<Script file='archeology.lua'/>
+	<Script file='auctionhouse.lua'/>
+	<Script file='barbershop.lua'/>
+	<Script file='battlefield.lua'/>
+	<Script file='blackmarket.lua'/>
+	<Script file='calendar.lua'/>
+	<Script file='challenges.lua'/>
+	<Script file='chat.lua'/>
+	<Script file='character.lua'/>
+	<Script file='collections.lua'/>
+	<Script file='encounterjournal.lua'/>
+	<Script file='friends.lua'/>
+	<Script file='garrison.lua'/>
+	<Script file='guild.lua'/>
+	<Script file='help.lua'/>
+	<Script file='inspect.lua'/>
+	<Script file='itemsocketing.lua'/>
+	<Script file='itemupgrade.lua'/>
+	<Script file='keybinding.lua'/>
+	<Script file='lfd.lua'/>
+	<Script file='macro.lua'/>
+	<Script file='petbattle.lua'/>
+	<Script file='pvp.lua'/>
+	<Script file='quest.lua'/>
+	<Script file='raid.lua'/>
+	<Script file='reforging.lua'/>
+	<!-- <Script file='social.lua'/> -->
+	<Script file='spellbook.lua'/>
+	<Script file='talents.lua'/>
+	<Script file='timemanager.lua'/>
+	<Script file='tradeskill.lua'/>
+	<Script file='trainer.lua'/>
+	<Script file='transmog.lua'/>
+	<Script file='voidstorage.lua'/>
+	<Script file='worldmap.lua'/>
+	<Script file='system.lua'/>
+	<Script file='misc.lua'/>
+</Ui>
\ No newline at end of file
diff --git a/SVUI_Skins/components/blizzard/achievement.lua b/SVUI_Skins/components/blizzard/achievement.lua
new file mode 100644
index 0000000..c0e7c6d
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/achievement.lua
@@ -0,0 +1,462 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pcall         = _G.pcall;
+local print         = _G.print;
+local ipairs        = _G.ipairs;
+local pairs         = _G.pairs;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+HELPERS
+##########################################################
+]]--
+local AchievementFrameList = {
+	"AchievementFrame",
+	"AchievementFrameCategories",
+	"AchievementFrameSummary",
+	"AchievementFrameHeader",
+	"AchievementFrameSummaryCategoriesHeader",
+	"AchievementFrameSummaryAchievementsHeader",
+	"AchievementFrameStatsBG",
+	"AchievementFrameAchievements",
+	"AchievementFrameComparison",
+	"AchievementFrameComparisonHeader",
+	"AchievementFrameComparisonSummaryPlayer",
+	"AchievementFrameComparisonSummaryFriend"
+}
+
+local AchievementTextureList = {
+	"AchievementFrameStats",
+	"AchievementFrameSummary",
+	"AchievementFrameAchievements",
+	"AchievementFrameComparison"
+}
+
+local AchievementItemButtons = {
+	"AchievementFrameAchievementsContainerButton1",
+	"AchievementFrameAchievementsContainerButton2",
+	"AchievementFrameAchievementsContainerButton3",
+	"AchievementFrameAchievementsContainerButton4",
+	"AchievementFrameAchievementsContainerButton5",
+	"AchievementFrameAchievementsContainerButton6",
+	"AchievementFrameAchievementsContainerButton7",
+}
+
+local _hook_DescriptionColor = function(self, r, g, b)
+	if(r ~= 0.6 or g ~= 0.6 or b ~= 0.6) then
+		self:SetTextColor(0.6, 0.6, 0.6)
+	end
+end
+
+local _hook_HiddenDescriptionColor = function(self, r, g, b)
+	if(r ~= 1 or g ~= 1 or b ~= 1) then
+		self:SetTextColor(1, 1, 1)
+	end
+end
+
+local _hook_TrackingPoint = function(self, anchor, parent, relative, x, y)
+	local actual = self.ListParent
+	if(anchor ~= "BOTTOMLEFT" or parent ~= actual or relative ~= "BOTTOMLEFT" or x ~= 5 or y ~= 5) then
+		self:ClearAllPoints()
+		self:SetPoint("BOTTOMLEFT", actual, "BOTTOMLEFT", 5, 5)
+	end
+end
+
+local _hook_AchievementsUpdate = function()
+	for i = 1, ACHIEVEMENTUI_MAX_SUMMARY_ACHIEVEMENTS do
+		local globalName = ("AchievementFrameSummaryAchievement%d"):format(i)
+		local summary = _G[globalName]
+		if(summary) then
+			summary:RemoveTextures()
+			summary:SetStyle("Button")
+
+			local highlight = _G[("%sHighlight"):format(globalName)]
+			local desc = _G[("%sDescription"):format(globalName)]
+			local icon = _G[("%sIcon"):format(globalName)]
+			local iconbling = _G[("%sIconBling"):format(globalName)]
+			local iconover = _G[("%sIconOverlay"):format(globalName)]
+			local icontex = _G[("%sIconTexture"):format(globalName)]
+
+			if(highlight) then highlight:Die() end
+			if(desc) then desc:SetTextColor(0.6, 0.6, 0.6) end
+			if(iconbling) then iconbling:Die() end
+			if(iconover) then iconover:Die() end
+			if(icontex) then
+				icontex:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+				icontex:InsetPoints()
+			end
+			if(icon and not icon.Panel) then
+				icon:SetStyle("!_Frame", "Icon")
+				icon:SetHeight(icon:GetHeight() - 14)
+				icon:SetWidth(icon:GetWidth() - 14)
+				icon:ClearAllPoints()
+				icon:SetPoint("LEFT", 6, 0)
+			end
+
+			if summary.accountWide then
+				summary:SetBackdropBorderColor(ACHIEVEMENTUI_BLUEBORDER_R, ACHIEVEMENTUI_BLUEBORDER_G, ACHIEVEMENTUI_BLUEBORDER_B)
+			else
+				summary:SetBackdropBorderColor(0,0,0,1)
+			end
+		end
+	end
+end
+
+local function BarStyleHelper(bar)
+	bar:RemoveTextures()
+	bar:SetStatusBarTexture(SV.media.statusbar.default)
+	bar:SetStatusBarColor(4/255, 179/255, 30/255)
+	bar:SetStyle("Frame", "Default")
+	if _G[bar:GetName().."Title"]then
+		_G[bar:GetName().."Title"]:SetPoint("LEFT", 4, 0)
+	end
+	if _G[bar:GetName().."Label"]then
+		_G[bar:GetName().."Label"]:SetPoint("LEFT", 4, 0)
+	end
+	if _G[bar:GetName().."Text"]then
+		_G[bar:GetName().."Text"]:SetPoint("RIGHT", -4, 0)
+	end
+end
+--[[
+##########################################################
+ACHIEVEMENTFRAME MODR
+##########################################################
+]]--
+local function AchievementStyle()
+	if SV.db.Skins.blizzard.enable  ~= true or SV.db.Skins.blizzard.achievement  ~= true then
+		return
+	end
+
+	AchievementFrameHeader:EnableMouse(false)
+
+	for _, gName in pairs(AchievementFrameList) do
+		local frame = _G[gName]
+		if(frame) then
+			frame:RemoveTextures(true)
+		end
+	end
+
+	for _, gName in pairs(AchievementTextureList) do
+		local frame = _G[gName]
+		if(frame) then
+			local count = frame:GetNumChildren()
+			for i = 1, count do
+				local childFrame = select(i, frame:GetChildren())
+				if(childFrame and not childFrame:GetName()) then
+					childFrame:SetBackdrop(nil)
+				end
+			end
+		end
+	end
+
+	SV.API:Set("Window", AchievementFrame, false, false, 1, 4, 8)
+
+	AchievementFrameSummaryAchievements:RemoveTextures(true)
+	AchievementFrameSummaryAchievements:SetStyle("Frame", 'Inset')
+	AchievementFrameHeaderTitle:ClearAllPoints()
+	AchievementFrameHeaderTitle:SetPoint("TOPLEFT", AchievementFrame.Panel, "TOPLEFT", -30, -8)
+	AchievementFrameHeaderPoints:ClearAllPoints()
+	AchievementFrameHeaderPoints:SetPoint("LEFT", AchievementFrameHeaderTitle, "RIGHT", 2, 0)
+	AchievementFrameCategoriesContainer:SetStyle("Frame", "Inset", true, 2, -2, 2)
+	AchievementFrameAchievementsContainer:SetStyle("Frame", "Default")
+	AchievementFrameAchievementsContainer.Panel:SetPoint("TOPLEFT", 0, 2)
+	AchievementFrameAchievementsContainer.Panel:SetPoint("BOTTOMRIGHT", -3, -3)
+	SV.API:Set("CloseButton", AchievementFrameCloseButton, AchievementFrame.Panel)
+	SV.API:Set("DropDown", AchievementFrameFilterDropDown)
+	AchievementFrameFilterDropDown:SetPoint("TOPRIGHT", AchievementFrame, "TOPRIGHT", -44, 5)
+
+	SV.API:Set("ScrollBar", AchievementFrameCategoriesContainerScrollBar, 5)
+	SV.API:Set("ScrollBar", AchievementFrameAchievementsContainerScrollBar, 5)
+	SV.API:Set("ScrollBar", AchievementFrameStatsContainerScrollBar, 5)
+	SV.API:Set("ScrollBar", AchievementFrameComparisonContainerScrollBar, 5)
+	SV.API:Set("ScrollBar", AchievementFrameComparisonStatsContainerScrollBar, 5)
+
+	for i = 1, 3 do
+		local tab = _G["AchievementFrameTab"..i]
+		if(tab) then
+			SV.API:Set("Tab", tab)
+			tab:SetFrameLevel(tab:GetFrameLevel() + 2)
+		end
+	end
+
+	BarStyleHelper(AchievementFrameSummaryCategoriesStatusBar)
+	BarStyleHelper(AchievementFrameComparisonSummaryPlayerStatusBar)
+	BarStyleHelper(AchievementFrameComparisonSummaryFriendStatusBar)
+
+	AchievementFrameComparisonSummaryFriendStatusBar.text:ClearAllPoints()
+	AchievementFrameComparisonSummaryFriendStatusBar.text:SetPoint("CENTER")
+	AchievementFrameComparisonHeader:SetPoint("BOTTOMRIGHT", AchievementFrameComparison, "TOPRIGHT", 45, -20)
+
+	for i = 1, 12 do
+		local categoryName = ("AchievementFrameSummaryCategoriesCategory%d"):format(i)
+		if(_G[categoryName]) then
+			if _G[categoryName.."Button"] then
+				_G[categoryName.."Button"]:RemoveTextures()
+			end
+			local hlName = categoryName.."ButtonHighlight"
+			local highlight = _G[hlName]
+			if(highlight) then
+				highlight:RemoveTextures()
+				_G[hlName.."Middle"]:SetColorTexture(1, 1, 1, 0.3)
+				_G[hlName.."Middle"]:SetAllPoints(categoryName)
+			end
+			BarStyleHelper(_G[categoryName])
+		end
+	end
+
+	AchievementFrame:HookScript("OnShow", function(self)
+		if(self.containerStyled) then return end
+		for i = 1, 20 do
+			SV.API:Set("!_ItemButton", _G["AchievementFrameCategoriesContainerButton"..i])
+		end
+		self.containerStyled = true
+	end)
+
+	hooksecurefunc("AchievementButton_DisplayAchievement", function(self)
+		if(self.accountWide and self.bg3) then
+			self.bg3:SetBackdropBorderColor(ACHIEVEMENTUI_BLUEBORDER_R, ACHIEVEMENTUI_BLUEBORDER_G, ACHIEVEMENTUI_BLUEBORDER_B)
+		elseif self.bg3 then
+			self.bg3:SetBackdropBorderColor(0,0,0)
+		end
+	end)
+
+	hooksecurefunc("AchievementFrameSummary_UpdateAchievements", _hook_AchievementsUpdate)
+
+	for i = 1, #AchievementItemButtons do
+		local gName = AchievementItemButtons[i]
+		local button = _G[gName]
+
+		if(button) then
+			local hl = _G[gName.."Highlight"]
+			local desc = _G[gName.."Description"]
+			local hdesc = _G[gName.."HiddenDescription"]
+			local icon = _G[gName.."Icon"]
+			local track = _G[gName.."Tracked"]
+
+			if(hl) then hl:Die() end
+
+			button:RemoveTextures(true)
+
+			button.bg1 = button:CreateTexture(nil, "BACKGROUND", nil, 4)
+			button.bg1:SetTexture(SV.media.background.button)
+			button.bg1:SetVertexColor(unpack(SV.media.color.default))
+			button.bg1:SetPoint("TOPLEFT", 1, -1)
+			button.bg1:SetPoint("BOTTOMRIGHT", -1, 1)
+
+			button.bg3 = CreateFrame("Frame", nil, button)
+			button.bg3:WrapPoints(3,3)
+			button.bg3:SetBackdrop(SV.media.backdrop.shadowoutline)
+
+			if(desc) then
+				desc:SetTextColor(0.6, 0.6, 0.6)
+				hooksecurefunc(desc, "SetTextColor", _hook_DescriptionColor)
+			end
+
+			if(hdesc) then
+				hdesc:SetTextColor(1, 1, 1)
+				hooksecurefunc(hdesc, "SetTextColor", _hook_HiddenDescriptionColor)
+			end
+
+			if(icon) then
+				local bling = _G[gName.."IconBling"]
+				local over = _G[gName.."IconOverlay"]
+				local tex = _G[gName.."IconTexture"]
+				if(bling) then bling:Die() end
+				if(over) then over:Die() end
+				if(tex) then
+					tex:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+					tex:InsetPoints()
+				end
+
+				icon:SetStyle("!_Frame", "Default")
+				icon:SetHeight(icon:GetHeight()-14)
+				icon:SetWidth(icon:GetWidth()-14)
+				icon:ClearAllPoints()
+				icon:SetPoint("LEFT", 6, 0)
+			end
+
+			if(track) then
+				track:ClearAllPoints()
+				track:SetPoint("BOTTOMLEFT", 1, 5)
+				track:RemoveTextures()
+				track:SetStyle("CheckButton")
+				track.ListParent = button
+			end
+		end
+	end
+
+	local u = {"Player", "Friend"}
+	for c, v in pairs(u) do
+		for f = 1, 9 do
+			local d = "AchievementFrameComparisonContainerButton"..f..v;
+			_G[d]:RemoveTextures()
+			_G[d.."Background"]:Die()
+			if _G[d.."Description"]then
+				_G[d.."Description"]:SetTextColor(0.6, 0.6, 0.6)
+				hooksecurefunc(_G[d.."Description"], "SetTextColor", _hook_DescriptionColor)
+			end
+			_G[d].bg1 = _G[d]:CreateTexture(nil, "BACKGROUND")
+			_G[d].bg1:SetDrawLayer("BACKGROUND", 4)
+			_G[d].bg1:SetTexture(SV.media.background.transparent)
+			_G[d].bg1:SetVertexColor(unpack(SV.media.color.default))
+			_G[d].bg1:SetPoint("TOPLEFT", 4, -4)
+			_G[d].bg1:SetPoint("BOTTOMRIGHT", -4, 4)
+			_G[d].bg2 = _G[d]:CreateTexture(nil, "BACKGROUND")
+			_G[d].bg2:SetDrawLayer("BACKGROUND", 3)
+			_G[d].bg2:SetColorTexture(0, 0, 0)
+			_G[d].bg2:SetPoint("TOPLEFT", 3, -3)
+			_G[d].bg2:SetPoint("BOTTOMRIGHT", -3, 3)
+			_G[d].bg3 = _G[d]:CreateTexture(nil, "BACKGROUND")
+			_G[d].bg3:SetDrawLayer("BACKGROUND", 2)
+			_G[d].bg3:SetColorTexture(0,0,0,1)
+			_G[d].bg3:SetPoint("TOPLEFT", 2, -2)
+			_G[d].bg3:SetPoint("BOTTOMRIGHT", -2, 2)
+			_G[d].bg4 = _G[d]:CreateTexture(nil, "BACKGROUND")
+			_G[d].bg4:SetDrawLayer("BACKGROUND", 1)
+			_G[d].bg4:SetColorTexture(0, 0, 0)
+			_G[d].bg4:SetPoint("TOPLEFT", 1, -1)
+			_G[d].bg4:SetPoint("BOTTOMRIGHT", -1, 1)
+
+			if v == "Friend"then
+				_G[d.."Shield"]:SetPoint("TOPRIGHT", _G["AchievementFrameComparisonContainerButton"..f.."Friend"], "TOPRIGHT", -20, -3)
+			end
+
+			_G[d.."IconBling"]:Die()
+			_G[d.."IconOverlay"]:Die()
+			_G[d.."Icon"]:SetStyle("!_Frame", "Default")
+			_G[d.."Icon"]:SetHeight(_G[d.."Icon"]:GetHeight()-14)
+			_G[d.."Icon"]:SetWidth(_G[d.."Icon"]:GetWidth()-14)
+			_G[d.."Icon"]:ClearAllPoints()
+			_G[d.."Icon"]:SetPoint("LEFT", 6, 0)
+			_G[d.."IconTexture"]:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+			_G[d.."IconTexture"]:InsetPoints()
+		end
+	end
+
+	hooksecurefunc("AchievementFrameComparison_DisplayAchievement", function(i)
+		local w = i.player;
+		local x = i.friend
+		w.titleBar:Die()
+		x.titleBar:Die()
+		if not w.bg3 or not x.bg3 then
+			return
+		end
+		if w.accountWide then
+			w.bg3:SetTexture(ACHIEVEMENTUI_BLUEBORDER_R, ACHIEVEMENTUI_BLUEBORDER_G, ACHIEVEMENTUI_BLUEBORDER_B)
+		else
+			w.bg3:SetColorTexture(0,0,0,1)
+		end
+
+		if x.accountWide then
+			x.bg3:SetTexture(ACHIEVEMENTUI_BLUEBORDER_R, ACHIEVEMENTUI_BLUEBORDER_G, ACHIEVEMENTUI_BLUEBORDER_B)
+		else
+			x.bg3:SetColorTexture(0,0,0,1)
+		end
+	end)
+
+	for f = 1, 20 do
+		local d = _G["AchievementFrameStatsContainerButton"..f]
+		_G["AchievementFrameStatsContainerButton"..f.."BG"]:SetColorTexture(1, 1, 1, 0.2)
+		_G["AchievementFrameStatsContainerButton"..f.."HeaderLeft"]:Die()
+		_G["AchievementFrameStatsContainerButton"..f.."HeaderRight"]:Die()
+		_G["AchievementFrameStatsContainerButton"..f.."HeaderMiddle"]:Die()
+		local d = "AchievementFrameComparisonStatsContainerButton"..f;
+		_G[d]:RemoveTextures()
+		_G[d]:SetStyle("Frame", "Default")
+		_G[d.."BG"]:SetColorTexture(1, 1, 1, 0.2)
+		_G[d.."HeaderLeft"]:Die()
+		_G[d.."HeaderRight"]:Die()
+		_G[d.."HeaderMiddle"]:Die()
+	end
+
+	hooksecurefunc("AchievementButton_GetProgressBar", function(y)
+		local d = _G["AchievementFrameProgressBar"..y]
+		if d then
+			if not d.styled then
+				d:RemoveTextures()
+				d:SetStatusBarTexture(SV.media.statusbar.default)
+				d:SetStatusBarColor(4/255, 179/255, 30/255)
+				d:SetFrameLevel(d:GetFrameLevel()+3)
+				d:SetHeight(d:GetHeight()-2)
+				d.bg1 = d:CreateTexture(nil, "BACKGROUND")
+				d.bg1:SetDrawLayer("BACKGROUND", 4)
+				d.bg1:SetTexture(SV.media.background.transparent)
+				d.bg1:SetVertexColor(unpack(SV.media.color.default))
+				d.bg1:SetAllPoints()
+				d.bg3 = d:CreateTexture(nil, "BACKGROUND")
+				d.bg3:SetDrawLayer("BACKGROUND", 2)
+				d.bg3:SetColorTexture(0,0,0,1)
+				d.bg3:SetPoint("TOPLEFT", -1, 1)
+				d.bg3:SetPoint("BOTTOMRIGHT", 1, -1);
+				d.text:ClearAllPoints()
+				d.text:SetPoint("CENTER", d, "CENTER", 0, -1)
+				d.text:SetJustifyH("CENTER")
+				if y>1 then
+					d:ClearAllPoints()
+					d:SetPoint("TOP", _G["AchievementFrameProgressBar"..y-1], "BOTTOM", 0, -5)
+					hooksecurefunc(d, "SetPoint", function(k, p, q, r, s, t, z)
+						if not z then
+							k:ClearAllPoints()k:SetPoint("TOP", _G["AchievementFrameProgressBar"..y-1], "BOTTOM", 0, -5, true)
+						end
+					end)
+				end
+				d.styled = true
+			end
+		end
+	end)
+
+	hooksecurefunc("AchievementObjectives_DisplayCriteria", function(A, B)
+		local C = GetAchievementNumCriteria(B)
+		local D, E = 0, 0;
+		for f = 1, C do
+			local F, G, H, I, J, K, L, M, N = GetAchievementCriteriaInfo(B, f)
+			if G == CRITERIA_TYPE_ACHIEVEMENT and M then
+				E = E+1;
+				local O = AchievementButton_GetMeta(E)
+				if A.completed and H then
+					O.label:SetShadowOffset(0, 0)
+					O.label:SetTextColor(1, 1, 1, 1)
+				elseif H then
+					O.label:SetShadowOffset(1, -1)
+					O.label:SetTextColor(0, 1, 0, 1)
+				else
+					O.label:SetShadowOffset(1, -1)
+					O.label:SetTextColor(.6, .6, .6, 1)
+				end
+			elseif G  ~= 1 then
+				D = D+1;
+				local P = AchievementButton_GetCriteria(D)
+				if A.completed and H then
+					P.name:SetTextColor(1, 1, 1, 1)
+					P.name:SetShadowOffset(0, 0)
+				elseif H then
+					P.name:SetTextColor(0, 1, 0, 1)
+					P.name:SetShadowOffset(1, -1)
+				else
+					P.name:SetTextColor(.6, .6, .6, 1)
+					P.name:SetShadowOffset(1, -1)
+				end
+			end
+		end
+	end)
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveBlizzardStyle("Blizzard_AchievementUI", AchievementStyle)
diff --git a/SVUI_Skins/components/blizzard/alert.lua b/SVUI_Skins/components/blizzard/alert.lua
new file mode 100644
index 0000000..c31f7f0
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/alert.lua
@@ -0,0 +1,513 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+OVERRIDES AND HOOKS
+##########################################################
+]]--
+local RING_TEXTURE = [[Interface\AddOns\SVUI_Skins\artwork\FOLLOWER-RING]]
+local LVL_TEXTURE = [[Interface\AddOns\SVUI_Skins\artwork\FOLLOWER-LEVEL]]
+
+local AlphaBlock = function() return end
+
+local _hook_DisableBackground = function(self)
+    self:DisableDrawLayer("BACKGROUND")
+end;
+
+local _hook_DisableBorder = function(self)
+    self:DisableDrawLayer("BORDER")
+end;
+
+local _hook_DisableBoth = function(self)
+	self:DisableDrawLayer("BACKGROUND")
+    self:DisableDrawLayer("BORDER")
+end;
+
+local _hook_DisableOverlay = function(self)
+    self:DisableDrawLayer("OVERLAY")
+end;
+
+local _hook_BackdropColor = function(self,...)
+    if(self.AlertPanel) then
+        self.AlertPanel:AlertColor(...)
+    end
+end
+--[[
+##########################################################
+HELPERS
+##########################################################
+]]--
+local function StyleAlertIcon(frame, icon)
+	if((not frame) or (not icon)) then return end
+
+	icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+	icon:SetDrawLayer("BORDER")
+
+	if(not frame.IconSlot) then
+		frame.IconSlot = CreateFrame("Frame", nil, frame)
+		frame.IconSlot:WrapPoints(icon)
+		frame.IconSlot:SetStyle("Icon")
+		icon:SetParent(frame.IconSlot)
+	end
+end
+--/script LOOT_WON_ALERT_FRAMES[1]:Show()
+local function StyleLootFrame(frame)
+	if(not frame) then return end
+
+	if(not frame.Panel) then
+		SV.API:Set("!_Alert", frame)
+    if(frame.PvPBackground) then frame.PvPBackground:Die() end
+		if(frame.Background) then frame.Background:Die() end
+		if(frame.BGAtlas) then frame.BGAtlas:Die() end
+		if(frame.IconBorder) then frame.IconBorder:Die() end
+		if(frame.SpecIcon) then frame.SpecIcon:Die() end
+		if(frame.SpecRing) then frame.SpecRing:Die() end
+	end
+
+	if(frame.Icon and (not frame.IconSlot)) then
+		StyleAlertIcon(frame, frame.Icon)
+		frame.Icon:ClearAllPoints()
+		frame.Icon:SetPoint("CENTER", frame.AlertPanel.icon, "CENTER", 0, 0)
+	end
+
+	if(frame.Label) then
+		frame.Label:ClearAllPoints()
+		frame.Label:SetPoint("TOPLEFT", frame.Icon, "TOPRIGHT", 57, 5)
+	end
+	if(frame.ItemName) then
+		frame.ItemName:ClearAllPoints()
+		frame.ItemName:SetPoint("TOPLEFT", frame.Icon, "TOPRIGHT", 60, -16)
+	end
+	if(frame.Amount) then
+		frame.Amount:ClearAllPoints()
+		frame.Amount:SetPoint("TOPLEFT", frame.Icon, "TOPRIGHT", 60, -16)
+	end
+end
+
+local function StyleUpgradeFrame(frame)
+	if(not frame) then return end
+
+	if(not frame.Panel) then
+		SV.API:Set("!_Alert", frame)
+
+		frame.Background:Die()
+		frame.BorderGlow:Die()
+		frame.BaseQualityBorder:Die()
+		frame.UpgradeQualityBorder:Die()
+
+		frame:DisableDrawLayer("OVERLAY")
+		frame:HookScript("OnShow", _hook_DisableOverlay)
+	end
+
+	if(frame.Icon and (not frame.IconSlot)) then
+		frame.Icon:ClearAllPoints()
+		frame.Icon:SetPoint("CENTER", frame.AlertPanel.icon, "CENTER", 0, 0)
+		StyleAlertIcon(frame, frame.Icon)
+	end
+end
+--[[
+local function AchievementStyle()
+	for i = 1, MAX_ACHIEVEMENT_ALERTS do
+		local frameName = "AchievementAlertFrame"..i
+		local frame = _G[frameName]
+		if(frame and (not frame.Panel)) then
+
+			SV.API:Set("!_Alert", frame)
+
+			local icon = _G[frameName.."IconTexture"];
+			icon:ClearAllPoints()
+			icon:SetPoint("CENTER", frame.AlertPanel.icon, "CENTER", 0, 0)
+
+			_G[frameName.."Unlocked"]:SetTextColor(1, 1, 1);
+			_G[frameName.."Name"]:SetTextColor(1, 1, 0);
+
+			StyleAlertIcon(frame, icon)
+
+			if(_G[frameName .. 'Glow']) then _G[frameName .. 'Glow']:Die() end
+			if(_G[frameName .. 'Shine']) then _G[frameName .. 'Shine']:Die() end
+			if(_G[frameName .. 'Background']) then _G[frameName .. 'Background']:SetTexture("") end
+			if(_G[frameName .. 'IconOverlay']) then _G[frameName .. 'IconOverlay']:Die() end
+			if(_G[frameName .. 'GuildBanner']) then _G[frameName .. 'GuildBanner']:Die() end
+			if(_G[frameName .. 'GuildBorder']) then _G[frameName .. 'GuildBorder']:Die() end
+			if(_G[frameName .. 'OldAchievement']) then _G[frameName .. 'OldAchievement']:Die() end
+		end
+	end
+end
+
+local function CriteriaStyle()
+	for i = 1, MAX_ACHIEVEMENT_ALERTS do
+		local frameName = "CriteriaAlertFrame"..i
+		local frame = _G[frameName]
+		if(frame and (not frame.Panel)) then
+
+			SV.API:Set("!_Alert", frame)
+
+			local icon = _G[frameName .. 'IconTexture'];
+			if(icon) then
+				icon:ClearAllPoints()
+				icon:SetPoint("CENTER", frame.AlertPanel.icon, "CENTER", 0, 0)
+				StyleAlertIcon(frame, icon)
+			end
+
+			if(_G[frameName .. 'Glow']) then _G[frameName .. 'Glow']:Die() end
+			if(_G[frameName .. 'Shine']) then _G[frameName .. 'Shine']:Die() end
+			if(_G[frameName .. 'Background']) then _G[frameName .. 'Background']:SetTexture("") end
+			if(_G[frameName .. 'IconOverlay']) then _G[frameName .. 'IconOverlay']:Die() end
+			if(_G[frameName .. 'IconBling']) then _G[frameName .. 'IconBling']:Die() end
+		end
+	end
+end
+]]--
+local function DungeonCompletionStyle()
+	local frameName = "DungeonCompletionAlertFrame1"
+	local frame = _G[frameName]
+	if(frame and (not frame.Panel)) then
+
+		SV.API:Set("!_Alert", frame)
+
+		local icon = frame.dungeonTexture;
+		if(icon) then
+			icon:SetDrawLayer("OVERLAY")
+			icon:ClearAllPoints()
+			icon:SetPoint("CENTER", frame.AlertPanel.icon, "CENTER", 0, 0)
+			StyleAlertIcon(frame, icon)
+		end
+
+		if(_G[frameName .. 'GlowFrame']) then
+			if(_G[frameName .. 'GlowFrame'].glow) then _G[frameName .. 'GlowFrame'].glow:Die() end
+			_G[frameName .. 'GlowFrame']:Die()
+		end
+		if(_G[frameName .. 'Shine']) then _G[frameName .. 'Shine']:Die() end
+
+		frame:DisableDrawLayer("BORDER")
+		frame:HookScript("OnShow", _hook_DisableBorder)
+	end
+end
+
+local function GuildChallengeStyle()
+    local frameName = "GuildChallengeAlertFrame"
+	local frame = _G[frameName];
+	if(frame and (not frame.Panel)) then
+
+		SV.API:Set("!_Alert", frame)
+
+		local icon = _G[frameName .. 'EmblemIcon'];
+		if(icon) then
+			icon:ClearAllPoints()
+			icon:SetPoint("CENTER", frame.AlertPanel.icon, "CENTER", 0, 0)
+			StyleAlertIcon(frame, icon)
+			SetLargeGuildTabardTextures("player", icon, nil, nil)
+		end
+
+		if(_G[frameName .. 'Glow']) then _G[frameName .. 'Glow']:Die() end
+		if(_G[frameName .. 'Shine']) then _G[frameName .. 'Shine']:Die() end
+
+		frame:DisableDrawLayer("BACKGROUND")
+		frame:DisableDrawLayer("BORDER")
+		frame:HookScript("OnShow", _hook_DisableBoth)
+	end
+end
+
+local function ChallengeModeStyle()
+	local frameName = "ChallengeModeAlertFrame1"
+	local frame = _G[frameName];
+	if(frame and (not frame.Panel)) then
+
+		SV.API:Set("!_Alert", frame)
+
+		local icon = _G[frameName .. 'DungeonTexture'];
+		if(icon) then
+			icon:ClearAllPoints()
+			icon:SetPoint("CENTER", frame.AlertPanel.icon, "CENTER", 0, 0)
+			StyleAlertIcon(frame, icon)
+		end
+
+		if(_G[frameName .. 'GlowFrame']) then
+			if(_G[frameName .. 'GlowFrame'].glow) then _G[frameName .. 'GlowFrame'].glow:Die() end
+			_G[frameName .. 'GlowFrame']:Die()
+		end
+		if(_G[frameName .. 'Shine']) then _G[frameName .. 'Shine']:Die() end
+		if(_G[frameName .. 'Border']) then _G[frameName .. 'Border']:Die() end
+
+		frame:DisableDrawLayer("BACKGROUND")
+		frame:HookScript("OnShow", _hook_DisableBackground)
+	end
+end
+
+local function ScenarioStyle()
+	local frameName = "ScenarioAlertFrame1"
+	local frame = _G[frameName];
+	if(frame and (not frame.Panel)) then
+
+		SV.API:Set("!_Alert", frame)
+
+		local icon = _G[frameName .. 'DungeonTexture'];
+		if(icon) then
+			icon:ClearAllPoints()
+			icon:SetPoint("CENTER", frame.AlertPanel.icon, "CENTER", 0, 0)
+			StyleAlertIcon(frame, icon)
+		end
+
+		if(_G[frameName .. 'GlowFrame']) then
+			if(_G[frameName .. 'GlowFrame'].glow) then _G[frameName .. 'GlowFrame'].glow:Die() end
+			_G[frameName .. 'GlowFrame']:Die()
+		end
+		if(_G[frameName .. 'Shine']) then _G[frameName .. 'Shine']:Die() end
+
+		frame:DisableDrawLayer("BORDER")
+		frame:HookScript("OnShow", _hook_DisableBorder)
+	end
+end
+
+-- [[ GarrisonMissionAlertFrame ]] --
+local function GarrisonAlertPositioning(frame, missionID)
+	if (frame.MissionType and frame.AlertPanel and frame.AlertPanel.icon) then
+		frame.MissionType:ClearAllPoints()
+		frame.MissionType:SetPoint("CENTER", frame.AlertPanel.icon, "CENTER", 0, 0)
+	end
+end
+
+-- [[ GarrisonFollowerAlertFrame ]] --
+local function GarrisonFollowerAlertStyle(followerID, name, displayID, level, quality, isUpgraded)
+	local color = BAG_ITEM_QUALITY_COLORS[quality];
+	if (color) then
+		GarrisonFollowerAlertFrame.PortraitFrame.LevelBorder:SetVertexColor(color.r, color.g, color.b);
+		GarrisonFollowerAlertFrame.PortraitFrame.PortraitRing:SetVertexColor(color.r, color.g, color.b);
+	else
+		GarrisonFollowerAlertFrame.PortraitFrame.LevelBorder:SetVertexColor(1, 1, 1);
+		GarrisonFollowerAlertFrame.PortraitFrame.PortraitRing:SetVertexColor(1, 1, 1);
+	end
+end
+--[[
+##########################################################
+ALERTFRAME STYLES
+##########################################################
+]]--
+local function AlertStyle()
+	--print('test AlertStyle')
+	if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.alertframes ~= true then return end
+
+	--[[ SVUI ]]--
+	for i = 1, 4 do
+		local frame = _G["SVUI_SystemAlert"..i];
+		if(frame) then
+			frame:RemoveTextures()
+
+			SV.API:Set("Alert", frame)
+
+			frame.buttons[1]:SetStyle("Button")
+			frame.buttons[2]:SetStyle("Button")
+			frame.buttons[3]:SetStyle("Button")
+
+			frame.gold:SetStyle("Editbox")
+			frame.silver:SetStyle("Editbox")
+			frame.copper:SetStyle("Editbox")
+
+			frame.input:SetStyle("Editbox")
+			frame.input.Panel:SetPoint("TOPLEFT", -2, -4)
+			frame.input.Panel:SetPoint("BOTTOMRIGHT", 2, 4)
+		end
+	end
+
+	--[[
+	do
+		for i = 1, #LOOT_WON_ALERT_FRAMES do
+			StyleLootFrame(LOOT_WON_ALERT_FRAMES[i])
+		end
+		StyleLootFrame(BonusRollLootWonFrame)
+		hooksecurefunc("AlertFrame_SetLootWonAnchors", function()
+			for i = 1, #LOOT_WON_ALERT_FRAMES do
+				local frame = LOOT_WON_ALERT_FRAMES[i]
+				if(frame) then StyleLootFrame(frame) end
+			end
+		end)
+		hooksecurefunc("LootWonAlertFrame_SetUp", function(self, itemLink, ...)
+		    local itemName, itemHyperLink, itemRarity, itemTexture, _;
+		    if (self.isCurrency) then
+		        itemName, _, itemTexture, _, _, _, _, itemRarity = GetCurrencyInfo(itemLink);
+		        itemHyperLink = itemLink;
+		    else
+		        itemName, itemHyperLink, itemRarity, _, _, _, _, _, _, itemTexture = GetItemInfo(itemLink);
+		    end
+	    	if(itemRarity) then
+		    	local color = ITEM_QUALITY_COLORS[itemRarity];
+		    	if(not self.IconSlot) then return end;
+				self.IconSlot:SetBackdropColor(color.r, color.g, color.b);
+				self:AlertColor(color.r, color.g, color.b)
+			end
+		end)
+	end
+
+	do
+		for i = 1, #MONEY_WON_ALERT_FRAMES do
+			StyleLootFrame(MONEY_WON_ALERT_FRAMES[i])
+		end
+		StyleLootFrame(BonusRollMoneyWonFrame)
+		hooksecurefunc("AlertFrame_SetMoneyWonAnchors", function()
+			for i = 1, #MONEY_WON_ALERT_FRAMES do
+				local frame = MONEY_WON_ALERT_FRAMES[i]
+				if(frame) then StyleLootFrame(frame) end
+			end
+		end)
+	end
+
+	do
+		for i = 1, #LOOT_UPGRADE_ALERT_FRAMES do
+			StyleUpgradeFrame(LOOT_UPGRADE_ALERT_FRAMES[i])
+		end
+		hooksecurefunc("AlertFrame_SetLootUpgradeFrameAnchors", function()
+			for i = 1, #LOOT_UPGRADE_ALERT_FRAMES do
+				local frame = LOOT_UPGRADE_ALERT_FRAMES[i]
+				if(frame) then StyleUpgradeFrame(frame) end
+			end
+		end)
+		hooksecurefunc("LootUpgradeFrame_SetUp", function(self, itemLink, ...)
+		    local itemName, itemHyperLink, itemRarity, _, _, _, _, _, _, itemTexture = GetItemInfo(itemLink);
+		    if(itemRarity) then
+		    	local color = ITEM_QUALITY_COLORS[itemRarity];
+		    	if(not self.IconSlot) then return end;
+				self.IconSlot:SetBackdropColor(color.r, color.g, color.b);
+				self:AlertColor(color.r, color.g, color.b)
+			end
+		end)
+	end
+
+	AchievementStyle()
+	hooksecurefunc("AlertFrame_SetAchievementAnchors", AchievementStyle)
+
+	CriteriaStyle()
+	hooksecurefunc("AlertFrame_SetCriteriaAnchors", CriteriaStyle)
+
+	DungeonCompletionStyle()
+	hooksecurefunc("AlertFrame_SetDungeonCompletionAnchors", DungeonCompletionStyle)
+
+	GuildChallengeStyle()
+	hooksecurefunc("AlertFrame_SetGuildChallengeAnchors", GuildChallengeStyle)
+
+	ChallengeModeStyle()
+	hooksecurefunc("AlertFrame_SetChallengeModeAnchors", ChallengeModeStyle)
+
+	ScenarioStyle()
+	hooksecurefunc("AlertFrame_SetScenarioAnchors", ScenarioStyle)
+	]]--
+
+
+	--[[ GARRISON ]]--
+	do
+		local frameName, frame;
+
+		--Garrison Mission
+	    frameName = "GarrisonMissionAlertFrame"
+	    frame = _G[frameName]
+	    if(frame and (not frame.Panel)) then
+			frame:DisableDrawLayer("BACKGROUND")
+
+			SV.API:Set("!_Alert", frame)
+			frame.IconBG:ClearAllPoints()
+			frame.IconBG:SetPoint("CENTER", frame.AlertPanel.icon, "CENTER", 0, 0)
+			frame.IconBG:SetTexture('')
+			frame.IconBG:SetDrawLayer("BORDER")
+			frame.MissionType:ClearAllPoints()
+			frame.MissionType:SetPoint("CENTER", frame.AlertPanel.icon, "CENTER", 0, 0)
+			frame.Title:SetTextColor(1, 1, 1)
+
+			if(_G[frameName .. 'Glow']) then _G[frameName .. 'Glow']:Die() end
+			if(_G[frameName .. 'Shine']) then _G[frameName .. 'Shine']:Die() end
+
+			frame:HookScript("OnShow", _hook_DisableBackground)
+
+		end
+
+		--Garrison Shipyard Mission
+	    frameName = "GarrisonShipMissionAlertFrame"
+	    frame = _G[frameName]
+	    if(frame and (not frame.Panel)) then
+			frame:DisableDrawLayer("BACKGROUND")
+
+			SV.API:Set("!_Alert", frame)
+			frame.MissionType:ClearAllPoints()
+			frame.MissionType:SetPoint("CENTER", frame.AlertPanel.icon, "CENTER", 0, 0)
+			frame.Title:SetTextColor(1, 1, 1)
+
+			if(_G[frameName .. 'Glow']) then _G[frameName .. 'Glow']:Die() end
+			if(_G[frameName .. 'Shine']) then _G[frameName .. 'Shine']:Die() end
+
+			frame:HookScript("OnShow", _hook_DisableBackground)
+		end
+
+		--Garrison Building
+		frameName = "GarrisonBuildingAlertFrame"
+	    frame = _G[frameName]
+	    if(frame and (not frame.Panel)) then
+			frame:DisableDrawLayer("BACKGROUND")
+
+			SV.API:Set("!_Alert", frame)
+			frame.Icon:ClearAllPoints()
+			frame.Icon:SetPoint("CENTER", frame.AlertPanel.icon, "CENTER", 0, 0)
+			frame.Icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+			frame.Icon:SetDrawLayer("BORDER")
+			frame.Title:SetTextColor(1, 1, 1)
+
+			if(_G[frameName .. 'Glow']) then _G[frameName .. 'Glow']:Die() end
+			if(_G[frameName .. 'Shine']) then _G[frameName .. 'Shine']:Die() end
+
+			frame:HookScript("OnShow", _hook_DisableBackground)
+		end
+
+		--Garrison Follower
+		frameName = "GarrisonFollowerAlertFrame"
+	    frame = _G[frameName]
+	    if(frame) then
+	    	if(not frame.Panel) then
+				frame:DisableDrawLayer("BACKGROUND")
+
+				SV.API:Set("!_Alert", frame)
+				frame.Title:SetTextColor(1, 1, 1)
+
+				if(_G[frameName .. 'Glow']) then _G[frameName .. 'Glow']:Die() end
+				if(_G[frameName .. 'Shine']) then _G[frameName .. 'Shine']:Die() end
+
+				frame:HookScript("OnShow", _hook_DisableBackground)
+			end
+
+			if(frame.PortraitFrame) then
+				frame.PortraitFrame.PortraitRing:SetTexture(RING_TEXTURE)
+				frame.PortraitFrame.PortraitRingQuality:SetTexture('')
+				frame.PortraitFrame.LevelBorder:SetTexture('')
+
+				if(not frame.PortraitFrame.LevelCallout) then
+					frame.PortraitFrame.LevelCallout = frame.PortraitFrame:CreateTexture(nil, 'BORDER')
+					frame.PortraitFrame.LevelCallout:SetAllPoints(frame.PortraitFrame)
+					frame.PortraitFrame.LevelCallout:SetTexture(LVL_TEXTURE)
+					frame.PortraitFrame.LevelBorder:SetDrawLayer('OVERLAY')
+				end
+
+				frame.PortraitFrame:ClearAllPoints()
+				frame.PortraitFrame:SetPoint("CENTER", frame.AlertPanel.icon, "CENTER", 0, 0)
+			end
+		end
+	end
+	hooksecurefunc("GarrisonMissionAlertFrame_SetUp", GarrisonAlertPositioning)
+	hooksecurefunc("GarrisonFollowerAlertFrame_SetUp", GarrisonFollowerAlertStyle)
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveCustomStyle(AlertStyle)
+-- /script GarrisonMissionAlertFrame:Show()
+-- /script GarrisonBuildingAlertFrame:Show()
+-- /script GarrisonFollowerAlertFrame:Show()
diff --git a/SVUI_Skins/components/blizzard/archeology.lua b/SVUI_Skins/components/blizzard/archeology.lua
new file mode 100644
index 0000000..796a929
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/archeology.lua
@@ -0,0 +1,89 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+ARCHEOLOGYFRAME MODR
+##########################################################
+]]--
+local function ArchaeologyStyle()
+	if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.archaeology ~= true then return end
+
+	ArchaeologyFrame:RemoveTextures()
+	ArchaeologyFrameInset:RemoveTextures()
+	ArchaeologyFrame:SetStyle("Frame", "Window")
+	ArchaeologyFrame.Panel:SetAllPoints()
+	ArchaeologyFrame.portrait:SetAlpha(0)
+	ArchaeologyFrameInset:SetStyle("Frame", "Inset")
+	ArchaeologyFrameInset.Panel:SetPoint("TOPLEFT")
+	ArchaeologyFrameInset.Panel:SetPoint("BOTTOMRIGHT", -3, -1)
+	ArchaeologyFrameArtifactPageSolveFrameSolveButton:SetStyle("Button")
+	ArchaeologyFrameArtifactPageBackButton:SetStyle("Button")
+	ArchaeologyFrameRaceFilter:SetFrameLevel(ArchaeologyFrameRaceFilter:GetFrameLevel()+2)
+	SV.API:Set("DropDown", ArchaeologyFrameRaceFilter, 125)
+	SV.API:Set("PageButton", ArchaeologyFrameCompletedPageNextPageButton)
+	SV.API:Set("PageButton", ArchaeologyFrameCompletedPagePrevPageButton)
+	ArchaeologyFrameRankBar:RemoveTextures()
+	ArchaeologyFrameRankBar:SetStatusBarTexture(SV.media.statusbar.default)
+	ArchaeologyFrameRankBar:SetFrameLevel(ArchaeologyFrameRankBar:GetFrameLevel()+2)
+	ArchaeologyFrameRankBar:SetStyle("Frame", "Default")
+	ArchaeologyFrameArtifactPageSolveFrameStatusBar:RemoveTextures()
+	ArchaeologyFrameArtifactPageSolveFrameStatusBar:SetStatusBarTexture(SV.media.statusbar.default)
+	ArchaeologyFrameArtifactPageSolveFrameStatusBar:SetStatusBarColor(0.7, 0.2, 0)
+	ArchaeologyFrameArtifactPageSolveFrameStatusBar:SetFrameLevel(ArchaeologyFrameArtifactPageSolveFrameStatusBar:GetFrameLevel()+2)
+	ArchaeologyFrameArtifactPageSolveFrameStatusBar:SetStyle("Frame", "Default")
+
+	for b = 1, ARCHAEOLOGY_MAX_COMPLETED_SHOWN do
+		local c = _G["ArchaeologyFrameCompletedPageArtifact"..b]
+		if c then
+			_G["ArchaeologyFrameCompletedPageArtifact"..b.."Border"]:Die()
+			_G["ArchaeologyFrameCompletedPageArtifact"..b.."Bg"]:Die()
+			_G["ArchaeologyFrameCompletedPageArtifact"..b.."Icon"]:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+			_G["ArchaeologyFrameCompletedPageArtifact"..b.."Icon"].backdrop = CreateFrame("Frame", nil, c)
+			_G["ArchaeologyFrameCompletedPageArtifact"..b.."Icon"].backdrop:SetStyle("!_Frame", "Default")
+			_G["ArchaeologyFrameCompletedPageArtifact"..b.."Icon"].backdrop:WrapPoints(_G["ArchaeologyFrameCompletedPageArtifact"..b.."Icon"])
+			_G["ArchaeologyFrameCompletedPageArtifact"..b.."Icon"].backdrop:SetFrameLevel(c:GetFrameLevel()-2)
+			_G["ArchaeologyFrameCompletedPageArtifact"..b.."Icon"]:SetDrawLayer("OVERLAY")
+		end
+	end
+
+	ArchaeologyFrameArtifactPageIcon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+	ArchaeologyFrameArtifactPageIcon.backdrop = CreateFrame("Frame", nil, ArchaeologyFrameArtifactPage)
+	ArchaeologyFrameArtifactPageIcon.backdrop:SetStyle("!_Frame", "Default")
+	ArchaeologyFrameArtifactPageIcon.backdrop:WrapPoints(ArchaeologyFrameArtifactPageIcon)
+	ArchaeologyFrameArtifactPageIcon.backdrop:SetFrameLevel(ArchaeologyFrameArtifactPage:GetFrameLevel())
+	ArchaeologyFrameArtifactPageIcon:SetParent(ArchaeologyFrameArtifactPageIcon.backdrop)
+	ArchaeologyFrameArtifactPageIcon:SetDrawLayer("OVERLAY")
+	SV.API:Set("CloseButton", ArchaeologyFrameCloseButton)
+
+	local progressBarHolder = CreateFrame("Frame", "SVUI_ArcheologyProgressBar", SV.Screen)
+	progressBarHolder:SetSize(240, 24)
+	progressBarHolder:SetPoint("TOP", SV.Screen, "CENTER", 0, -180)
+	SV:NewAnchor(progressBarHolder, "Archeology Progress Bar")
+
+	ArcheologyDigsiteProgressBar:SetAllPoints(progressBarHolder)
+	progressBarHolder:SetParent(ArcheologyDigsiteProgressBar)
+
+	ArcheologyDigsiteProgressBar.Shadow:SetTexture("Interface\\AddOns\\SVUI_Skins\\artwork\\ArcheologyToast")
+	ArcheologyDigsiteProgressBar.BarBackground:SetTexture("Interface\\AddOns\\SVUI_Skins\\artwork\\ArcheologyToast")
+	ArcheologyDigsiteProgressBar.BarBorderAndOverlay:SetTexture("Interface\\AddOns\\SVUI_Skins\\artwork\\ArcheologyToast")
+	ArcheologyDigsiteProgressBar.Flash:SetTexture("Interface\\AddOns\\SVUI_Skins\\artwork\\ArcheologyToast")
+	ArcheologyDigsiteProgressBar.FillBar:SetStatusBarTexture("Interface\\AddOns\\SVUI_Skins\\artwork\\Arch-Progress-Fill")
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveBlizzardStyle("Blizzard_ArchaeologyUI", ArchaeologyStyle)
diff --git a/SVUI_Skins/components/blizzard/auctionhouse.lua b/SVUI_Skins/components/blizzard/auctionhouse.lua
new file mode 100644
index 0000000..88b758d
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/auctionhouse.lua
@@ -0,0 +1,345 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+local pairs   = _G.pairs;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+HELPERS
+##########################################################
+]]--
+local AuctionSortLinks = {
+	"BrowseQualitySort",
+	"BrowseLevelSort",
+	"BrowseDurationSort",
+	"BrowseHighBidderSort",
+	"BrowseCurrentBidSort",
+	"BidQualitySort",
+	"BidLevelSort",
+	"BidDurationSort",
+	"BidBuyoutSort",
+	"BidStatusSort",
+	"BidBidSort",
+	"AuctionsQualitySort",
+	"AuctionsDurationSort",
+	"AuctionsHighBidderSort",
+	"AuctionsBidSort"
+}
+local AuctionBidButtons = {
+	"BrowseBidButton",
+	"BidBidButton",
+	"BrowseBuyoutButton",
+	"BidBuyoutButton",
+	"BrowseCloseButton",
+	"BidCloseButton",
+	"BrowseSearchButton",
+	"AuctionsCreateAuctionButton",
+	"AuctionsCancelAuctionButton",
+	"AuctionsCloseButton",
+	"BrowseResetButton",
+	"AuctionsStackSizeMaxButton",
+	"AuctionsNumStacksMaxButton",
+}
+
+local AuctionTextFields = {
+	"BrowseName",
+	"BrowseMinLevel",
+	"BrowseMaxLevel",
+	"BrowseBidPriceGold",
+	"BidBidPriceGold",
+	"AuctionsStackSizeEntry",
+	"AuctionsNumStacksEntry",
+	"StartPriceGold",
+	"BuyoutPriceGold",
+	"BrowseBidPriceSilver",
+	"BrowseBidPriceCopper",
+	"BidBidPriceSilver",
+	"BidBidPriceCopper",
+	"StartPriceSilver",
+	"StartPriceCopper",
+	"BuyoutPriceSilver",
+	"BuyoutPriceCopper"
+}
+--[[
+##########################################################
+AUCTIONFRAME MODR
+##########################################################
+]]--
+local _hook_FilterButton_SetType = function(button)
+	if(button) then
+		local normalTexture = _G[button:GetName().."NormalTexture"];
+		normalTexture:SetTexture("")
+		if(not button.Panel) then
+			button:RemoveTextures(true)
+			button:SetStyle("!_Button")
+			button.Panel.CanBeRemoved = true
+		end
+	end
+end
+
+local function AuctionStyle()
+	--MOD.Debugging = true
+	if(SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.auctionhouse ~= true) then return end
+
+	SV.API:Set("Window", AuctionFrame, false, true, 1, 2, -8)
+
+	BrowseFilterScrollFrame:RemoveTextures()
+	BrowseScrollFrame:RemoveTextures()
+	AuctionsScrollFrame:RemoveTextures()
+	BidScrollFrame:RemoveTextures()
+
+	SV.API:Set("CloseButton", AuctionFrameCloseButton)
+	SV.API:Set("ScrollBar", AuctionsScrollFrame)
+
+	SV.API:Set("DropDown", BrowseDropDown)
+	SV.API:Set("DropDown", PriceDropDown)
+	SV.API:Set("DropDown", DurationDropDown)
+	SV.API:Set("ScrollBar", BrowseFilterScrollFrame)
+	SV.API:Set("ScrollBar", BrowseScrollFrame)
+	IsUsableCheckButton:SetStyle("CheckButton")
+	ShowOnPlayerCheckButton:SetStyle("CheckButton")
+
+	ExactMatchCheckButton:RemoveTextures()
+	ExactMatchCheckButton:SetStyle("CheckButton")
+	ExactMatchCheckButtonText:ClearAllPoints()
+	ExactMatchCheckButtonText:SetPoint("LEFT", ExactMatchCheckButton, "RIGHT", 6, 0)
+	--SideDressUpFrame:SetPoint("LEFT", AuctionFrame, "RIGHT", 16, 0)
+
+	AuctionProgressFrame:RemoveTextures()
+	AuctionProgressFrame:SetStyle("!_Frame", "Transparent", true)
+	AuctionProgressFrameCancelButton:SetStyle("Button")
+	AuctionProgressFrameCancelButton:SetStyle("!_Frame", "Default")
+	AuctionProgressFrameCancelButton:SetHitRectInsets(0, 0, 0, 0)
+	AuctionProgressFrameCancelButton:GetNormalTexture():InsetPoints()
+	AuctionProgressFrameCancelButton:GetNormalTexture():SetTexCoord(0.67, 0.37, 0.61, 0.26)
+	AuctionProgressFrameCancelButton:SetSize(28, 28)
+	AuctionProgressFrameCancelButton:SetPoint("LEFT", AuctionProgressBar, "RIGHT", 8, 0)
+	AuctionProgressBarIcon:SetTexCoord(0.67, 0.37, 0.61, 0.26)
+
+	local AuctionProgressBarBG = CreateFrame("Frame", nil, AuctionProgressBarIcon:GetParent())
+	AuctionProgressBarBG:WrapPoints(AuctionProgressBarIcon)
+	AuctionProgressBarBG:SetStyle("!_Frame", "Default")
+	AuctionProgressBarIcon:SetParent(AuctionProgressBarBG)
+
+	AuctionProgressBarText:ClearAllPoints()
+	AuctionProgressBarText:SetPoint("CENTER")
+	AuctionProgressBar:RemoveTextures()
+	AuctionProgressBar:SetStyle("Frame", "Default")
+	AuctionProgressBar:SetStatusBarTexture(SV.media.statusbar.default)
+	AuctionProgressBar:SetStatusBarColor(1, 1, 0)
+
+	SV.API:Set("PageButton", BrowseNextPageButton)
+	SV.API:Set("PageButton", BrowsePrevPageButton)
+
+	for _,gName in pairs(AuctionBidButtons) do
+		if(_G[gName]) then
+			_G[gName]:RemoveTextures()
+			_G[gName]:SetStyle("Button")
+		end
+	end
+
+	AuctionsCloseButton:SetPoint("BOTTOMRIGHT", AuctionFrameAuctions, "BOTTOMRIGHT", 66, 10)
+	AuctionsCancelAuctionButton:SetPoint("RIGHT", AuctionsCloseButton, "LEFT", -4, 0)
+
+	BidBuyoutButton:SetPoint("RIGHT", BidCloseButton, "LEFT", -4, 0)
+	BidBidButton:SetPoint("RIGHT", BidBuyoutButton, "LEFT", -4, 0)
+
+	BrowseBuyoutButton:SetPoint("RIGHT", BrowseCloseButton, "LEFT", -4, 0)
+	BrowseBidButton:SetPoint("RIGHT", BrowseBuyoutButton, "LEFT", -4, 0)
+
+	AuctionsItemButton:RemoveTextures()
+	AuctionsItemButton:SetStyle("Button")
+	AuctionsItemButton:SetScript("OnUpdate", function()
+		if AuctionsItemButton:GetNormalTexture()then
+			AuctionsItemButton:GetNormalTexture():SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+			AuctionsItemButton:GetNormalTexture():InsetPoints()
+		end
+	end)
+
+	for _,frame in pairs(AuctionSortLinks)do
+		_G[frame.."Left"]:Die()
+		_G[frame.."Middle"]:Die()
+		_G[frame.."Right"]:Die()
+	end
+
+	SV.API:Set("Tab", _G["AuctionFrameTab1"])
+	SV.API:Set("Tab", _G["AuctionFrameTab2"])
+	SV.API:Set("Tab", _G["AuctionFrameTab3"])
+
+	AuctionFrameBrowse.bg1 = CreateFrame("Frame", nil, AuctionFrameBrowse)
+	AuctionFrameBrowse.bg1:SetPoint("TOPLEFT", 20, -103)
+	AuctionFrameBrowse.bg1:SetPoint("BOTTOMRIGHT", -575, 40)
+	AuctionFrameBrowse.bg1:SetStyle("!_Frame", "Inset")
+
+	BrowseNoResultsText:SetParent(AuctionFrameBrowse.bg1)
+	BrowseSearchCountText:SetParent(AuctionFrameBrowse.bg1)
+
+	BrowseSearchButton:SetPoint("TOPRIGHT", AuctionFrameBrowse, "TOPRIGHT", 25, -34)
+	BrowseResetButton:SetPoint("TOPRIGHT", BrowseSearchButton, "TOPLEFT", -4, 0)
+
+	AuctionFrameBrowse.bg1:SetFrameLevel(AuctionFrameBrowse.bg1:GetFrameLevel()-1)
+	BrowseFilterScrollFrame:SetHeight(300)
+	AuctionFrameBrowse.bg2 = CreateFrame("Frame", nil, AuctionFrameBrowse)
+	AuctionFrameBrowse.bg2:SetStyle("!_Frame", "Inset")
+	AuctionFrameBrowse.bg2:SetPoint("TOPLEFT", AuctionFrameBrowse.bg1, "TOPRIGHT", 4, 0)
+	AuctionFrameBrowse.bg2:SetPoint("BOTTOMRIGHT", AuctionFrame, "BOTTOMRIGHT", -8, 40)
+	AuctionFrameBrowse.bg2:SetFrameLevel(AuctionFrameBrowse.bg2:GetFrameLevel() - 1)
+
+	hooksecurefunc("FilterButton_SetType", _hook_FilterButton_SetType)
+
+	for _,field in pairs(AuctionTextFields) do
+		_G[field]:RemoveTextures()
+		_G[field]:SetStyle("Editbox", 2, 2)
+		_G[field]:SetTextInsets(-1, -1, -2, -2)
+	end
+
+	BrowseNameText:ClearAllPoints()
+	BrowseNameText:SetPoint("BOTTOMLEFT", AuctionFrame, "TOPLEFT", 30, -47)
+	BrowseLevelText:ClearAllPoints()
+	BrowseLevelText:SetPoint("BOTTOMLEFT", AuctionFrame, "TOPLEFT", 190, -47)
+	BrowseNameSearchIcon:ClearAllPoints()
+	BrowseNameSearchIcon:SetPoint("RIGHT", BrowseName, "LEFT", -2, -2)
+	BrowseMinLevel:ClearAllPoints()
+	BrowseMinLevel:SetPoint("LEFT", BrowseName, "RIGHT", 18, 0)
+	BrowseLevelHyphen:ClearAllPoints()
+	BrowseLevelHyphen:SetPoint("LEFT", BrowseMinLevel, "RIGHT", 5, 0)
+	BrowseMaxLevel:ClearAllPoints()
+	BrowseMaxLevel:SetPoint("LEFT", BrowseMinLevel, "RIGHT", 16, 0)
+	BrowseDropDownName:ClearAllPoints()
+	BrowseDropDownName:SetPoint("BOTTOMLEFT", BrowseLevelText, "BOTTOMRIGHT", 18, 0)
+	BrowseDropDown:ClearAllPoints()
+	BrowseDropDown:SetPoint("TOPLEFT", BrowseLevelText, "BOTTOMRIGHT", -2, 0)
+	AuctionsStackSizeEntry.Panel:SetAllPoints()
+	AuctionsNumStacksEntry.Panel:SetAllPoints()
+
+	for h = 1, NUM_BROWSE_TO_DISPLAY do
+		local button = _G["BrowseButton"..h];
+		local buttonItem = _G["BrowseButton"..h.."Item"];
+		local buttonTex = _G["BrowseButton"..h.."ItemIconTexture"];
+
+		if(button and (not button.Panel)) then
+			button:RemoveTextures()
+			button:SetStyle("Button")
+			button.Panel:ClearAllPoints()
+			button.Panel:SetPoint("TOPLEFT", button, "TOPLEFT", 0, 0)
+			button.Panel:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", 0, 5)
+
+			if(buttonItem) then
+				buttonItem:RemoveTextures()
+				buttonItem:SetStyle("Icon")
+				if(buttonTex) then
+					buttonTex:SetParent(buttonItem.Panel)
+					buttonTex:InsetPoints(buttonItem.Panel, 2, 2)
+					buttonTex:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+					buttonTex:SetDesaturated(false)
+				end
+
+				local highLight = button:GetHighlightTexture()
+				highLight:ClearAllPoints()
+				highLight:SetPoint("TOPLEFT", buttonItem, "TOPRIGHT", 2, -2)
+				highLight:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -2, 7)
+				button:GetPushedTexture():SetAllPoints(highLight)
+				_G["BrowseButton"..h.."Highlight"] = highLight
+			end
+		end
+	end
+
+	for h = 1, NUM_AUCTIONS_TO_DISPLAY do
+		local button = _G["AuctionsButton"..h];
+		local buttonItem = _G["AuctionsButton"..h.."Item"];
+		local buttonTex = _G["AuctionsButton"..h.."ItemIconTexture"];
+
+		if(button) then
+			if(buttonTex) then
+				buttonTex:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+				buttonTex:InsetPoints()
+				buttonTex:SetDesaturated(false)
+			end
+
+			button:RemoveTextures()
+			button:SetStyle("Button")
+
+			if(buttonItem) then
+				buttonItem:SetStyle("Button")
+				buttonItem.Panel:SetAllPoints()
+				buttonItem:HookScript("OnUpdate", function()
+					buttonItem:GetNormalTexture():Die()
+				end)
+
+				local highLight = button:GetHighlightTexture()
+				_G["AuctionsButton"..h.."Highlight"] = highLight
+				highLight:ClearAllPoints()
+				highLight:SetPoint("TOPLEFT", buttonItem, "TOPRIGHT", 2, 0)
+				highLight:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -2, 5)
+				button:GetPushedTexture():SetAllPoints(highLight)
+			end
+		end
+	end
+
+	for h = 1, NUM_BIDS_TO_DISPLAY do
+		local button = _G["BidButton"..h];
+		local buttonItem = _G["BidButton"..h.."Item"];
+		local buttonTex = _G["BidButton"..h.."ItemIconTexture"];
+
+		if(button) then
+			if(buttonTex) then
+				buttonTex:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+				buttonTex:InsetPoints()
+				buttonTex:SetDesaturated(false)
+			end
+
+			button:RemoveTextures()
+			button:SetStyle("Button")
+
+			if(buttonItem) then
+				buttonItem:SetStyle("Button")
+				buttonItem.Panel:SetAllPoints()
+				buttonItem:HookScript("OnUpdate", function()
+					buttonItem:GetNormalTexture():Die()
+				end)
+
+				local highLight = button:GetHighlightTexture()
+				_G["BidButton"..h.."Highlight"] = highLight
+				highLight:ClearAllPoints()
+				highLight:SetPoint("TOPLEFT", buttonItem, "TOPRIGHT", 2, 0)
+				highLight:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -2, 5)
+				button:GetPushedTexture():SetAllPoints(highLight)
+			end
+		end
+	end
+
+	BrowseScrollFrame:SetHeight(300)
+	AuctionFrameBid.bg = CreateFrame("Frame", nil, AuctionFrameBid)
+	AuctionFrameBid.bg:SetStyle("!_Frame", "Inset")
+	AuctionFrameBid.bg:SetPoint("TOPLEFT", 22, -72)
+	AuctionFrameBid.bg:SetPoint("BOTTOMRIGHT", 66, 39)
+	AuctionFrameBid.bg:SetFrameLevel(AuctionFrameBid.bg:GetFrameLevel()-1)
+	BidScrollFrame:SetHeight(332)
+	AuctionsScrollFrame:SetHeight(336)
+	AuctionFrameAuctions.bg1 = CreateFrame("Frame", nil, AuctionFrameAuctions)
+	AuctionFrameAuctions.bg1:SetStyle("!_Frame", "Inset")
+	AuctionFrameAuctions.bg1:SetPoint("TOPLEFT", 15, -70)
+	AuctionFrameAuctions.bg1:SetPoint("BOTTOMRIGHT", -545, 35)
+	AuctionFrameAuctions.bg1:SetFrameLevel(AuctionFrameAuctions.bg1:GetFrameLevel() - 2)
+	AuctionFrameAuctions.bg2 = CreateFrame("Frame", nil, AuctionFrameAuctions)
+	AuctionFrameAuctions.bg2:SetStyle("!_Frame", "Inset")
+	AuctionFrameAuctions.bg2:SetPoint("TOPLEFT", AuctionFrameAuctions.bg1, "TOPRIGHT", 3, 0)
+	AuctionFrameAuctions.bg2:SetPoint("BOTTOMRIGHT", AuctionFrame, -8, 35)
+	AuctionFrameAuctions.bg2:SetFrameLevel(AuctionFrameAuctions.bg2:GetFrameLevel() - 2)
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveBlizzardStyle("Blizzard_AuctionUI", AuctionStyle)
diff --git a/SVUI_Skins/components/blizzard/barbershop.lua b/SVUI_Skins/components/blizzard/barbershop.lua
new file mode 100644
index 0000000..3ef9462
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/barbershop.lua
@@ -0,0 +1,78 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+BARBERSHOP MODR
+##########################################################
+]]--
+local function BarberShopStyle()
+	if SV.db.Skins.blizzard.enable~=true or SV.db.Skins.blizzard.barber~=true then return end
+
+	local buttons = {"BarberShopFrameOkayButton", "BarberShopFrameCancelButton", "BarberShopFrameResetButton"}
+
+	BarberShopFrameOkayButton:SetPoint("RIGHT", BarberShopFrameSelector4, "BOTTOM", 2, -50)
+
+	for b = 1, #buttons do
+		_G[buttons[b]]:RemoveTextures()
+		_G[buttons[b]]:SetStyle("Button")
+	end
+
+	BarberShopFrame:RemoveTextures()
+	BarberShopFrame:SetStyle("Frame", "Window")
+	BarberShopFrame:SetSize(BarberShopFrame:GetWidth()-30, BarberShopFrame:GetHeight()-56)
+
+	local lastframe;
+	for i = 1, 5 do
+		local selector = _G["BarberShopFrameSelector"..i]
+		if selector then
+			SV.API:Set("PageButton", _G["BarberShopFrameSelector"..i.."Prev"])
+			SV.API:Set("PageButton", _G["BarberShopFrameSelector"..i.."Next"])
+			selector:ClearAllPoints()
+
+			if lastframe then
+				selector:SetPoint("TOP", lastframe, "BOTTOM", 0, -3)
+			else
+				selector:SetPoint("TOP", BarberShopFrame, "TOP", 0, -12)
+			end
+
+			selector:RemoveTextures()
+			if(selector:IsShown()) then
+				lastframe = selector
+			end
+		end
+	end
+
+	BarberShopFrameMoneyFrame:RemoveTextures()
+	BarberShopFrameMoneyFrame:SetStyle("Frame", "Inset")
+	BarberShopFrameMoneyFrame:SetPoint("TOP", lastframe, "BOTTOM", 0, -10)
+
+	BarberShopFrameBackground:Die()
+	BarberShopBannerFrameBGTexture:Die()
+	BarberShopBannerFrame:Die()
+
+	BarberShopAltFormFrameBorder:RemoveTextures()
+	BarberShopAltFormFrame:SetPoint("BOTTOM", BarberShopFrame, "TOP", 0, 5)
+	BarberShopAltFormFrame:RemoveTextures()
+	BarberShopAltFormFrame:SetStyle("Frame", "Window2")
+
+	BarberShopFrameResetButton:ClearAllPoints()
+	BarberShopFrameResetButton:SetPoint("BOTTOM", BarberShopFrame.Panel, "BOTTOM", 0, 4)
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveBlizzardStyle("Blizzard_BarbershopUI",BarberShopStyle)
\ No newline at end of file
diff --git a/SVUI_Skins/components/blizzard/battlefield.lua b/SVUI_Skins/components/blizzard/battlefield.lua
new file mode 100644
index 0000000..37894fd
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/battlefield.lua
@@ -0,0 +1,89 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+BATTLEFIELD MODR
+##########################################################
+]]--
+local function BattlefieldStyle()
+	if SV.db.Skins.blizzard.enable~=true or SV.db.Skins.blizzard.bgmap~=true then return end
+	BattlefieldMinimap:SetClampedToScreen(true)
+	BattlefieldMinimapCorner:Die()
+	BattlefieldMinimapBackground:Die()
+	BattlefieldMinimapTab:Die()
+	BattlefieldMinimapTabLeft:Die()
+	BattlefieldMinimapTabMiddle:Die()
+	BattlefieldMinimapTabRight:Die()
+	BattlefieldMinimap:SetStyle("!_Frame", "Transparent")
+	BattlefieldMinimap.Panel:SetPoint("BOTTOMRIGHT", -4, 2)
+	BattlefieldMinimap:SetFrameStrata("LOW")
+	BattlefieldMinimapCloseButton:ClearAllPoints()
+	BattlefieldMinimapCloseButton:SetPoint("TOPRIGHT", -4, 0)
+	SV.API:Set("CloseButton", BattlefieldMinimapCloseButton)
+	BattlefieldMinimapCloseButton:SetFrameStrata("MEDIUM")
+	BattlefieldMinimap:EnableMouse(true)
+	BattlefieldMinimap:SetMovable(true)
+	BattlefieldMinimap:SetScript("OnMouseUp", function(f, g)
+		if g == "LeftButton"then
+			BattlefieldMinimapTab:StopMovingOrSizing()BattlefieldMinimapTab:SetUserPlaced(true)
+			if OpacityFrame:IsShown()then
+				OpacityFrame:Hide()
+			end
+		elseif g == "RightButton"then
+			ToggleDropDownMenu(1, nil, BattlefieldMinimapTabDropDown, f:GetName(), 0, -4)
+			if OpacityFrame:IsShown()then
+				OpacityFrame:Hide()
+			end
+		end
+	end)
+	BattlefieldMinimap:SetScript("OnMouseDown", function(f, g)
+		if g == "LeftButton"then
+			if BattlefieldMinimapOptions and BattlefieldMinimapOptions.locked then
+				return
+			else
+				BattlefieldMinimapTab:StartMoving()
+			end
+		end
+	end)
+	hooksecurefunc("BattlefieldMinimap_UpdateOpacity", function(opacity)
+		local h = 1.0-BattlefieldMinimapOptions.opacity or 0;
+		BattlefieldMinimap.Panel:SetAlpha(h)
+	end)
+	local i;
+	BattlefieldMinimap:HookScript("OnEnter", function()
+		i = BattlefieldMinimapOptions.opacity or 0;
+		BattlefieldMinimap_UpdateOpacity(0)
+	end)
+	BattlefieldMinimap:HookScript("OnLeave", function()
+		if i then
+			BattlefieldMinimap_UpdateOpacity(i)i = nil
+		end
+	end)
+	BattlefieldMinimapCloseButton:HookScript("OnEnter", function()
+		i = BattlefieldMinimapOptions.opacity or 0;
+		BattlefieldMinimap_UpdateOpacity(0)
+	end)
+	BattlefieldMinimapCloseButton:HookScript("OnLeave", function()
+		if i then
+			BattlefieldMinimap_UpdateOpacity(i)i = nil
+		end
+	end)
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveBlizzardStyle("Blizzard_BattlefieldMinimap",BattlefieldStyle)
\ No newline at end of file
diff --git a/SVUI_Skins/components/blizzard/blackmarket.lua b/SVUI_Skins/components/blizzard/blackmarket.lua
new file mode 100644
index 0000000..c061daa
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/blackmarket.lua
@@ -0,0 +1,88 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+BLACKMARKET MODR
+##########################################################
+]]--
+local function ChangeTab(tab)
+	tab.Left:SetAlpha(0)
+	if tab.Middle then
+		tab.Middle:SetAlpha(0)
+	end
+	tab.Right:SetAlpha(0)
+end
+
+local _hook_ScrollFrameUpdate = function()
+	local self = BlackMarketScrollFrame;
+	local buttons = self.buttons;
+	local offset = HybridScrollFrame_GetOffset(self)
+	local itemCount = C_BlackMarket.GetNumItems()
+	for i = 1, #buttons do
+		local button = buttons[i];
+		if(button) then
+			local indexOffset = offset + i;
+			if(not button.Panel) then
+				button:RemoveTextures()
+				button:SetStyle("Button")
+				SV.API:Set("ItemButton", button.Item)
+			end
+			if indexOffset <= itemCount then
+				local name, texture = C_BlackMarket.GetItemInfoByIndex(indexOffset)
+				if(name) then
+					button.Item.IconTexture:SetTexture(texture)
+				end
+			end
+		end
+	end
+end
+
+local function BlackMarketStyle()
+	if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.bmah ~= true then
+		return
+	end
+
+	SV.API:Set("Window", BlackMarketFrame)
+
+	BlackMarketFrame.Inset:RemoveTextures()
+	BlackMarketFrame.Inset:SetStyle("!_Frame", "Inset")
+
+	SV.API:Set("CloseButton", BlackMarketFrame.CloseButton)
+	SV.API:Set("ScrollBar", BlackMarketScrollFrame, 4)
+
+	ChangeTab(BlackMarketFrame.ColumnName)
+	ChangeTab(BlackMarketFrame.ColumnLevel)
+	ChangeTab(BlackMarketFrame.ColumnType)
+	ChangeTab(BlackMarketFrame.ColumnDuration)
+	ChangeTab(BlackMarketFrame.ColumnHighBidder)
+	ChangeTab(BlackMarketFrame.ColumnCurrentBid)
+
+	BlackMarketFrame.MoneyFrameBorder:RemoveTextures()
+	BlackMarketBidPriceGold:SetStyle("Editbox")
+	BlackMarketBidPriceGold.Panel:SetPoint("TOPLEFT", -2, 0)
+	BlackMarketBidPriceGold.Panel:SetPoint("BOTTOMRIGHT", -2, 0)
+	BlackMarketFrame.BidButton:SetStyle("Button")
+
+	hooksecurefunc("BlackMarketScrollFrame_Update", _hook_ScrollFrameUpdate)
+
+	BlackMarketFrame.HotDeal:RemoveTextures()
+	SV.API:Set("ItemButton", BlackMarketFrame.HotDeal.Item)
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveBlizzardStyle("Blizzard_BlackMarketUI",BlackMarketStyle)
\ No newline at end of file
diff --git a/SVUI_Skins/components/blizzard/calendar.lua b/SVUI_Skins/components/blizzard/calendar.lua
new file mode 100644
index 0000000..331b53e
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/calendar.lua
@@ -0,0 +1,185 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+local ipairs        = _G.ipairs;
+local pairs         = _G.pairs;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+HELPERS
+##########################################################
+]]--
+local CalendarButtons = {
+	"CalendarViewEventAcceptButton",
+	"CalendarViewEventTentativeButton",
+	"CalendarViewEventRemoveButton",
+	"CalendarViewEventDeclineButton"
+};
+--[[
+##########################################################
+CALENDAR MODR
+##########################################################
+]]--
+local function CalendarStyle()
+	if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.calendar ~= true then
+		 return
+	end
+
+	SV.API:Set("Window", CalendarFrame)
+
+	SV.API:Set("CloseButton", CalendarCloseButton)
+	CalendarCloseButton:SetPoint("TOPRIGHT", CalendarFrame, "TOPRIGHT", -4, -4)
+	SV.API:Set("PageButton", CalendarPrevMonthButton)
+	SV.API:Set("PageButton", CalendarNextMonthButton)
+
+	do
+		local cfframe = _G["CalendarFilterFrame"];
+
+		if(cfframe) then
+			cfframe:RemoveTextures()
+			cfframe:SetWidth(155)
+			cfframe:SetStyle("Frame", "Default")
+
+			local cfbutton = _G["CalendarFilterButton"];
+			if(cfbutton) then
+				cfbutton:ClearAllPoints()
+				cfbutton:SetPoint("RIGHT", cfframe, "RIGHT", -10, 3)
+				SV.API:Set("PageButton", cfbutton, true)
+				cfframe.Panel:SetPoint("TOPLEFT", 20, 2)
+				cfframe.Panel:SetPoint("BOTTOMRIGHT", cfbutton, "BOTTOMRIGHT", 2, -2)
+
+				local cftext = _G["CalendarFilterFrameText"]
+				if(cftext) then
+					cftext:ClearAllPoints()
+					cftext:SetPoint("RIGHT", cfbutton, "LEFT", -2, 0)
+				end
+			end
+		end
+	end
+
+	local l = CreateFrame("Frame", "CalendarFrameBackdrop", CalendarFrame)
+	l:SetStyle("!_Frame", "Default")
+	l:SetPoint("TOPLEFT", 10, -72)
+	l:SetPoint("BOTTOMRIGHT", -8, 3)
+	CalendarContextMenu:SetStyle("!_Frame", "Default")
+	hooksecurefunc(CalendarContextMenu, "SetBackdropColor", function(f, r, g, b, a)
+		if r ~= 0 or g ~= 0 or b ~= 0 or a ~= 0.5 then
+			 f:SetBackdropColor(0, 0, 0, 0.5)
+		end
+	end)
+	hooksecurefunc(CalendarContextMenu, "SetBackdropBorderColor", function(f, r, g, b)
+		if r ~= 0 or g ~= 0 or b ~= 0 then
+			 f:SetBackdropBorderColor(0, 0, 0)
+		end
+	end)
+	for u = 1, 42 do
+		 _G["CalendarDayButton"..u]:SetFrameLevel(_G["CalendarDayButton"..u]:GetFrameLevel()+1)
+	end
+	CalendarCreateEventFrame:RemoveTextures()
+	CalendarCreateEventFrame:SetStyle("!_Frame", "Transparent", true)
+	CalendarCreateEventFrame:SetPoint("TOPLEFT", CalendarFrame, "TOPRIGHT", 3, -24)
+	CalendarCreateEventTitleFrame:RemoveTextures()
+	CalendarCreateEventCreateButton:SetStyle("Button")
+	CalendarCreateEventMassInviteButton:SetStyle("Button")
+	CalendarCreateEventInviteButton:SetStyle("Button")
+	CalendarCreateEventInviteButton:SetPoint("TOPLEFT", CalendarCreateEventInviteEdit, "TOPRIGHT", 4, 1)
+	CalendarCreateEventInviteEdit:SetWidth(CalendarCreateEventInviteEdit:GetWidth()-2)
+	CalendarCreateEventInviteList:RemoveTextures()
+	CalendarCreateEventInviteList:SetStyle("!_Frame", "Default")
+	CalendarCreateEventInviteEdit:SetStyle("Editbox")
+	CalendarCreateEventTitleEdit:SetStyle("Editbox")
+	SV.API:Set("DropDown", CalendarCreateEventTypeDropDown, 120)
+	CalendarCreateEventDescriptionContainer:RemoveTextures()
+	CalendarCreateEventDescriptionContainer:SetStyle("!_Frame", "Default")
+	SV.API:Set("CloseButton", CalendarCreateEventCloseButton)
+	CalendarCreateEventLockEventCheck:SetStyle("CheckButton")
+	SV.API:Set("DropDown", CalendarCreateEventHourDropDown, 68)
+	SV.API:Set("DropDown", CalendarCreateEventMinuteDropDown, 68)
+	SV.API:Set("DropDown", CalendarCreateEventAMPMDropDown, 68)
+	SV.API:Set("DropDown", CalendarCreateEventRepeatOptionDropDown, 120)
+	CalendarCreateEventIcon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+	hooksecurefunc(CalendarCreateEventIcon, "SetTexCoord", function(f, v, w, x, y)
+		local z, A, B, C = 0.1, 0.9, 0.1, 0.9
+		if v ~= z or w ~= A or x ~= B or y ~= C then
+			 f:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+		end
+	end)
+	CalendarCreateEventInviteListSection:RemoveTextures()
+	CalendarClassButtonContainer:HookScript("OnShow", function()
+		for u, D in ipairs(CLASS_SORT_ORDER)do
+			local e = _G["CalendarClassButton"..u]e:RemoveTextures()
+			e:SetStyle("Frame", "Default")
+			local E = CLASS_ICON_TCOORDS[D]
+			local F = e:GetNormalTexture()
+			F:SetTexture("Interface\\Glues\\CharacterCreate\\UI-CharacterCreate-Classes")
+			F:SetTexCoord(E[1]+0.015, E[2]-0.02, E[3]+0.018, E[4]-0.02)
+		end
+		CalendarClassButton1:SetPoint("TOPLEFT", CalendarClassButtonContainer, "TOPLEFT", 5, 0)
+		CalendarClassTotalsButton:RemoveTextures()
+		CalendarClassTotalsButton:SetStyle("Frame", "Default")
+	end)
+	CalendarTexturePickerFrame:RemoveTextures()
+	CalendarTexturePickerTitleFrame:RemoveTextures()
+	CalendarTexturePickerFrame:SetStyle("!_Frame", "Transparent", true)
+	SV.API:Set("ScrollBar", CalendarTexturePickerScrollBar)
+	CalendarTexturePickerAcceptButton:SetStyle("Button")
+	CalendarTexturePickerCancelButton:SetStyle("Button")
+	CalendarCreateEventInviteButton:SetStyle("Button")
+	CalendarCreateEventRaidInviteButton:SetStyle("Button")
+	CalendarMassInviteFrame:RemoveTextures()
+	CalendarMassInviteFrame:SetStyle("!_Frame", "Transparent", true)
+	CalendarMassInviteTitleFrame:RemoveTextures()
+	SV.API:Set("CloseButton", CalendarMassInviteCloseButton)
+	CalendarMassInviteGuildAcceptButton:SetStyle("Button")
+	SV.API:Set("DropDown", CalendarMassInviteGuildRankMenu, 130)
+	CalendarMassInviteGuildMinLevelEdit:SetStyle("Editbox")
+	CalendarMassInviteGuildMaxLevelEdit:SetStyle("Editbox")
+	CalendarViewRaidFrame:RemoveTextures()
+	CalendarViewRaidFrame:SetStyle("!_Frame", "Transparent", true)
+	CalendarViewRaidFrame:SetPoint("TOPLEFT", CalendarFrame, "TOPRIGHT", 3, -24)
+	CalendarViewRaidTitleFrame:RemoveTextures()
+	SV.API:Set("CloseButton", CalendarViewRaidCloseButton)
+	CalendarViewHolidayFrame:RemoveTextures(true)
+	CalendarViewHolidayFrame:SetStyle("!_Frame", "Transparent", true)
+	CalendarViewHolidayFrame:SetPoint("TOPLEFT", CalendarFrame, "TOPRIGHT", 3, -24)
+	CalendarViewHolidayTitleFrame:RemoveTextures()
+	SV.API:Set("CloseButton", CalendarViewHolidayCloseButton)
+	CalendarViewEventFrame:RemoveTextures()
+	CalendarViewEventFrame:SetStyle("!_Frame", "Transparent", true)
+	CalendarViewEventFrame:SetPoint("TOPLEFT", CalendarFrame, "TOPRIGHT", 3, -24)
+	CalendarViewEventTitleFrame:RemoveTextures()
+	CalendarViewEventDescriptionContainer:RemoveTextures()
+	CalendarViewEventDescriptionContainer:SetStyle("!_Frame", "Transparent", true)
+	CalendarViewEventInviteList:RemoveTextures()
+	CalendarViewEventInviteList:SetStyle("!_Frame", "Transparent", true)
+	CalendarViewEventInviteListSection:RemoveTextures()
+	SV.API:Set("CloseButton", CalendarViewEventCloseButton)
+	SV.API:Set("ScrollBar", CalendarViewEventInviteListScrollFrame)
+	for _,btn in pairs(CalendarButtons)do
+		 _G[btn]:SetStyle("Button")
+	end
+	CalendarEventPickerFrame:RemoveTextures()
+	CalendarEventPickerTitleFrame:RemoveTextures()
+	CalendarEventPickerFrame:SetStyle("!_Frame", "Transparent", true)
+	SV.API:Set("ScrollBar", CalendarEventPickerScrollBar)
+	CalendarEventPickerCloseButton:SetStyle("Button")
+	SV.API:Set("ScrollBar", CalendarCreateEventDescriptionScrollFrame)
+	SV.API:Set("ScrollBar", CalendarCreateEventInviteListScrollFrame)
+	SV.API:Set("ScrollBar", CalendarViewEventDescriptionScrollFrame)
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveBlizzardStyle("Blizzard_Calendar",CalendarStyle)
\ No newline at end of file
diff --git a/SVUI_Skins/components/blizzard/challenges.lua b/SVUI_Skins/components/blizzard/challenges.lua
new file mode 100644
index 0000000..daeafc8
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/challenges.lua
@@ -0,0 +1,57 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+CHALLENGES UI MODR
+##########################################################
+]]--
+local function ChallengesFrameStyle()
+  if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.lfg ~= true then return end
+  ChallengesFrameInset:RemoveTextures()
+  ChallengesFrameInsetBg:Hide()
+  ChallengesFrameDetails.bg:Hide()
+  ChallengesFrameDetails:SetStyle("Frame", "Inset")
+  ChallengesFrameLeaderboard:SetStyle("Button")
+  select(2, ChallengesFrameDetails:GetRegions()):Hide()
+  select(9, ChallengesFrameDetails:GetRegions()):Hide()
+  select(10, ChallengesFrameDetails:GetRegions()):Hide()
+  select(11, ChallengesFrameDetails:GetRegions()):Hide()
+  ChallengesFrameDungeonButton1:SetPoint("TOPLEFT", ChallengesFrame, "TOPLEFT", 8, -83)
+
+  for u = 1, 9 do
+    local v = ChallengesFrame["button"..u]
+    v:SetStyle("Button")
+    v:SetHighlightTexture("")
+    v.selectedTex:SetAlpha(.2)
+    v.selectedTex:SetPoint("TOPLEFT", 1, -1)
+    v.selectedTex:SetPoint("BOTTOMRIGHT", -1, 1)
+    v.NoMedal:Die()
+  end
+
+  for u = 1, 3 do
+    local F = ChallengesFrame["RewardRow"..u]
+    for A = 1, 2 do
+      local v = F["Reward"..A]
+      v:SetStyle("Frame")
+      v.Icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+    end
+  end
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveBlizzardStyle("Blizzard_ChallengesUI",ChallengesFrameStyle)
\ No newline at end of file
diff --git a/SVUI_Skins/components/blizzard/character.lua b/SVUI_Skins/components/blizzard/character.lua
new file mode 100644
index 0000000..368fd35
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/character.lua
@@ -0,0 +1,411 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+local ipairs  = _G.ipairs;
+local pairs   = _G.pairs;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+HELPERS
+##########################################################
+]]--
+local SlotListener = CreateFrame("Frame")
+
+local CharacterSlotNames = {
+	"HeadSlot",
+	"NeckSlot",
+	"ShoulderSlot",
+	"BackSlot",
+	"ChestSlot",
+	"ShirtSlot",
+	"TabardSlot",
+	"WristSlot",
+	"HandsSlot",
+	"WaistSlot",
+	"LegsSlot",
+	"FeetSlot",
+	"Finger0Slot",
+	"Finger1Slot",
+	"Trinket0Slot",
+	"Trinket1Slot",
+	"MainHandSlot",
+	"SecondaryHandSlot"
+};
+
+local CharFrameList = {
+	"CharacterFrame",
+	"CharacterModelFrame",
+	"CharacterFrameInset",
+	"CharacterStatsPane",
+	"CharacterFrameInsetRight",
+	"PaperDollFrame",
+	"PaperDollSidebarTabs",
+	"PaperDollEquipmentManagerPane"
+};
+
+local CharacterStatsSubFrames = {
+	"ItemLevelCategory",
+	"AttributesCategory",
+	"EnhancementsCategory"
+};
+
+local function SetItemFrame(frame, point)
+	point = point or frame
+	local noscalemult = 2 * UIParent:GetScale()
+	if point.bordertop then return end
+	point.backdrop = frame:CreateTexture(nil, "BORDER")
+	point.backdrop:SetDrawLayer("BORDER", -4)
+	point.backdrop:SetAllPoints(point)
+	point.backdrop:SetTexture(SV.media.statusbar.default)
+	point.backdrop:SetVertexColor(unpack(SV.media.color.default))
+	point.bordertop = frame:CreateTexture(nil, "BORDER")
+	point.bordertop:SetPoint("TOPLEFT", point, "TOPLEFT", -noscalemult, noscalemult)
+	point.bordertop:SetPoint("TOPRIGHT", point, "TOPRIGHT", noscalemult, noscalemult)
+	point.bordertop:SetHeight(noscalemult)
+	point.bordertop:SetColorTexture(0,0,0)
+	point.bordertop:SetDrawLayer("BORDER", 1)
+	point.borderbottom = frame:CreateTexture(nil, "BORDER")
+	point.borderbottom:SetPoint("BOTTOMLEFT", point, "BOTTOMLEFT", -noscalemult, -noscalemult)
+	point.borderbottom:SetPoint("BOTTOMRIGHT", point, "BOTTOMRIGHT", noscalemult, -noscalemult)
+	point.borderbottom:SetHeight(noscalemult)
+	point.borderbottom:SetColorTexture(0,0,0)
+	point.borderbottom:SetDrawLayer("BORDER", 1)
+	point.borderleft = frame:CreateTexture(nil, "BORDER")
+	point.borderleft:SetPoint("TOPLEFT", point, "TOPLEFT", -noscalemult, noscalemult)
+	point.borderleft:SetPoint("BOTTOMLEFT", point, "BOTTOMLEFT", noscalemult, -noscalemult)
+	point.borderleft:SetWidth(noscalemult)
+	point.borderleft:SetColorTexture(0,0,0)
+	point.borderleft:SetDrawLayer("BORDER", 1)
+	point.borderright = frame:CreateTexture(nil, "BORDER")
+	point.borderright:SetPoint("TOPRIGHT", point, "TOPRIGHT", noscalemult, noscalemult)
+	point.borderright:SetPoint("BOTTOMRIGHT", point, "BOTTOMRIGHT", -noscalemult, -noscalemult)
+	point.borderright:SetWidth(noscalemult)
+	point.borderright:SetColorTexture(0,0,0)
+	point.borderright:SetDrawLayer("BORDER", 1)
+end
+
+local function StyleCharacterSlots()
+	for _,slotName in pairs(CharacterSlotNames) do
+		local globalName = ("Character%s"):format(slotName)
+		local charSlot = _G[globalName]
+		if(charSlot) then
+			if(not charSlot.Panel) then
+				charSlot:RemoveTextures()
+				charSlot.ignoreTexture:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-LeaveItem-Transparent]])
+				charSlot:SetStyle("!_ActionSlot", 1, 0, 0)
+
+				local iconTex = _G[globalName.."IconTexture"] or charSlot.icon;
+				if(iconTex) then
+					iconTex:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+					iconTex:InsetPoints(charSlot)
+					--iconTex:SetParent(charSlot.Panel)
+				end
+				if(charSlot.IconBorder) then
+					charSlot.IconBorder:Die()
+				end
+			end
+
+			local slotID,_ = GetInventorySlotInfo(slotName)
+			local r, g, b = 0, 0, 0;
+			if(slotID) then
+				local itemLink = GetInventoryItemLink("player", slotID)
+				if(itemLink) then
+					local key, _, quality, _, _, _, _, _, equipSlot = GetItemInfo(itemLink);
+					if(quality and quality > 1) then
+						r,g,b = GetItemQualityColor(quality)
+					end
+				end
+				charSlot:SetBackdropColor(r,g,b,0.6)
+				charSlot:SetBackdropBorderColor(r,g,b,1)
+			end
+		end
+	end
+
+	for i = 1, #PAPERDOLL_SIDEBARS do
+		local tab = _G["PaperDollSidebarTab"..i]
+		if(tab) then
+			if(not tab.Panel) then
+				tab.Highlight:SetColorTexture(1, 1, 1, 0.3)
+				tab.Highlight:SetPoint("TOPLEFT", 3, -4)
+				tab.Highlight:SetPoint("BOTTOMRIGHT", -1, 0)
+				tab.Hider:SetColorTexture(0.4, 0.4, 0.4, 0.4)
+				tab.Hider:SetPoint("TOPLEFT", 3, -4)
+				tab.Hider:SetPoint("BOTTOMRIGHT", -1, 0)
+				tab.TabBg:Die()
+				if i == 1 then
+					for x = 1, tab:GetNumRegions()do
+						local texture = select(x, tab:GetRegions())
+						texture:SetTexCoord(0.16, 0.86, 0.16, 0.86)
+					end
+				end
+				tab:SetStyle("Frame", "Default", true, 2)
+				tab.Panel:SetPoint("TOPLEFT", 2, -3)
+				tab.Panel:SetPoint("BOTTOMRIGHT", 0, -2)
+			end
+			if(i == 1) then
+				tab:ClearAllPoints()
+				tab:SetPoint("BOTTOM", CharacterFrameInsetRight, "TOP", -30, 4)
+			else
+				tab:ClearAllPoints()
+				tab:SetPoint("LEFT",  _G["PaperDollSidebarTab"..i-1], "RIGHT", 4, 0)
+			end
+		end
+	end
+end
+
+local function StyleFlyoutButton(button, texture)
+	button:SetStyle("Button")
+	texture:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+	button:GetNormalTexture():SetTexture("")
+	texture:InsetPoints()
+	button:SetFrameLevel(button:GetFrameLevel() + 2)
+	if not button.Panel then
+		button:SetStyle("Frame", "Default")
+		button.Panel:SetAllPoints()
+	end
+end
+
+local function EquipmentFlyout_OnShow()
+	EquipmentFlyoutFrameButtons:RemoveTextures()
+	EquipmentFlyoutFrame.NavigationFrame:RemoveTextures()
+	SV.API:Set("!_PageButton", EquipmentFlyoutFrame.NavigationFrame.PrevButton)
+	SquareButton_SetIcon(EquipmentFlyoutFrame.NavigationFrame.PrevButton, 'LEFT')
+	SV.API:Set("!_PageButton", EquipmentFlyoutFrame.NavigationFrame.NextButton)
+	SquareButton_SetIcon(EquipmentFlyoutFrame.NavigationFrame.NextButton, 'RIGHT')
+	local counter = 1;
+	local button = _G["EquipmentFlyoutFrameButton"..counter]
+	while button do
+		local texture = _G["EquipmentFlyoutFrameButton"..counter.."IconTexture"]
+		StyleFlyoutButton(button, texture)
+		counter = counter + 1;
+		button = _G["EquipmentFlyoutFrameButton"..counter]
+	end
+end
+
+local function Reputation_OnShow()
+	for i = 1, GetNumFactions()do
+		local bar = _G["ReputationBar"..i.."ReputationBar"]
+		if bar then
+			 bar:SetStatusBarTexture(SV.media.statusbar.default)
+			if not bar.Panel then
+				 bar:SetStyle("Frame", "Inset")
+			end
+			_G["ReputationBar"..i.."Background"]:SetTexture("")
+			_G["ReputationBar"..i.."ReputationBarHighlight1"]:SetTexture("")
+			_G["ReputationBar"..i.."ReputationBarHighlight2"]:SetTexture("")
+			_G["ReputationBar"..i.."ReputationBarAtWarHighlight1"]:SetTexture("")
+			_G["ReputationBar"..i.."ReputationBarAtWarHighlight2"]:SetTexture("")
+			_G["ReputationBar"..i.."ReputationBarLeftTexture"]:SetTexture("")
+			_G["ReputationBar"..i.."ReputationBarRightTexture"]:SetTexture("")
+		end
+	end
+end
+
+local function PaperDollTitlesPane_OnShow()
+	for i,btn in pairs(PaperDollTitlesPane.buttons) do
+		if(btn) then
+			btn.BgTop:SetTexture("")
+			btn.BgBottom:SetTexture("")
+			btn.BgMiddle:SetTexture("")
+			SV:FontManager(btn.text, "default")
+		end
+	end
+	PaperDollTitlesPane_Update()
+end
+
+local function PaperDollEquipmentManagerPane_OnShow()
+	for i,btn in pairs(PaperDollEquipmentManagerPane.buttons) do
+		if(btn) then
+			btn.BgTop:SetTexture("")
+			btn.BgBottom:SetTexture("")
+			btn.BgMiddle:SetTexture("")
+			btn.icon:SetSize(36, 36)
+			btn.Check:SetTexture("")
+			btn.icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+			btn.icon:SetPoint("LEFT", btn, "LEFT", 4, 0)
+			if not btn.icon.bordertop then
+				 SetItemFrame(btn, btn.icon)
+			end
+		end
+	end
+
+	GearManagerDialogPopup:RemoveTextures()
+	GearManagerDialogPopup:SetStyle("Frame", "Inset", true)
+	GearManagerDialogPopup:SetPoint("LEFT", PaperDollFrame, "RIGHT", 4, 0)
+	GearManagerDialogPopupScrollFrame:RemoveTextures()
+	GearManagerDialogPopupEditBox:RemoveTextures()
+	GearManagerDialogPopupEditBox:SetStyle("Frame", 'Inset')
+	GearManagerDialogPopupOkay:SetStyle("Button")
+	GearManagerDialogPopupCancel:SetStyle("Button")
+
+	for i = 1, NUM_GEARSET_ICONS_SHOWN do
+		local btn = _G["GearManagerDialogPopupButton"..i]
+		if(btn and (not btn.Panel)) then
+			btn:RemoveTextures()
+			btn:SetFrameLevel(btn:GetFrameLevel() + 2)
+			btn:SetStyle("Button")
+			if(btn.icon) then
+				btn.icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+				btn.icon:SetTexture("")
+				btn.icon:InsetPoints()
+			end
+		end
+	end
+end
+--[[
+##########################################################
+CHARACTERFRAME MODR
+##########################################################
+]]--
+local function CharacterFrameStyle()
+	--print('test CharacterFrameStyle')
+	if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.character ~= true then
+		 return
+	end
+
+	SV.API:Set("Window", CharacterFrame, true, true, 1, 3, 3)
+
+	SV.API:Set("CloseButton", CharacterFrameCloseButton)
+	SV.API:Set("ScrollBar", CharacterStatsPane)
+	SV.API:Set("ScrollBar", ReputationListScrollFrame)
+	SV.API:Set("ScrollBar", TokenFrameContainer)
+	SV.API:Set("ScrollBar", GearManagerDialogPopupScrollFrame)
+
+	StyleCharacterSlots()
+
+	SlotListener:RegisterEvent("PLAYER_EQUIPMENT_CHANGED")
+	SlotListener:SetScript("OnEvent", StyleCharacterSlots)
+	CharacterFrame:HookScript("OnShow", StyleCharacterSlots)
+
+	--[[
+	CharacterFrameExpandButton:RemoveTextures(true)
+	SV.API:Set("!_PageButton", CharacterFrameExpandButton)
+
+	hooksecurefunc('CharacterFrame_Collapse', function()
+		SV.API:Set("!_PageButton", CharacterFrameExpandButton)
+		SquareButton_SetIcon(CharacterFrameExpandButton, 'RIGHT')
+	end)
+
+	hooksecurefunc('CharacterFrame_Expand', function()
+		SV.API:Set("!_PageButton", CharacterFrameExpandButton)
+		SquareButton_SetIcon(CharacterFrameExpandButton, 'LEFT')
+	end)
+	CharacterFrameExpandButton:SetFrameLevel(CharacterModelFrame:GetFrameLevel() + 5)
+	]]--
+	SV.API:Set("CloseButton", ReputationDetailCloseButton)
+	SV.API:Set("CloseButton", TokenFramePopupCloseButton)
+	ReputationDetailAtWarCheckBox:SetStyle("CheckButton")
+	ReputationDetailMainScreenCheckBox:SetStyle("CheckButton")
+	ReputationDetailInactiveCheckBox:SetStyle("CheckButton")
+	ReputationDetailLFGBonusReputationCheckBox:SetStyle("CheckButton")
+	TokenFramePopupInactiveCheckBox:SetStyle("CheckButton")
+	TokenFramePopupBackpackCheckBox:SetStyle("CheckButton")
+	EquipmentFlyoutFrameHighlight:Die()
+	EquipmentFlyoutFrame:HookScript("OnShow", EquipmentFlyout_OnShow)
+	hooksecurefunc("EquipmentFlyout_Show", EquipmentFlyout_OnShow)
+
+	CharacterFramePortrait:Die()
+	SV.API:Set("ScrollBar", _G["PaperDollTitlesPaneScrollBar"], 5)
+	SV.API:Set("ScrollBar", _G["PaperDollEquipmentManagerPaneScrollBar"], 5)
+
+	for _,gName in pairs(CharFrameList) do
+		if(_G[gName]) then _G[gName]:RemoveTextures(true) end
+	end
+
+	for _,gName in pairs(CharacterStatsSubFrames) do
+		if(CharacterStatsPane[gName]) then
+			CharacterStatsPane[gName]:RemoveTextures(true)
+			CharacterStatsPane[gName]:SetStyle("Frame", 'Inset')
+		end
+	end
+
+	CharacterFrameInsetRight:SetStyle("Frame", 'Inset')
+
+	for i=1, 6 do
+		local pane = _G["CharacterStatsPaneCategory"..i]
+		if(pane) then
+			pane:RemoveTextures()
+		end
+	end
+
+	CharacterModelFrameBackgroundTopLeft:SetTexture("")
+	CharacterModelFrameBackgroundTopRight:SetTexture("")
+	CharacterModelFrameBackgroundBotLeft:SetTexture("")
+	CharacterModelFrameBackgroundBotRight:SetTexture("")
+
+	CharacterModelFrame:SetStyle("!_Frame", "Model")
+
+	PaperDollTitlesPane:RemoveTextures()
+	PaperDollTitlesPaneScrollChild:RemoveTextures()
+	PaperDollTitlesPane:SetStyle("Frame", 'Inset')
+	PaperDollTitlesPane:HookScript("OnShow", PaperDollTitlesPane_OnShow)
+
+	PaperDollEquipmentManagerPane:SetStyle("Frame", 'Inset')
+	PaperDollEquipmentManagerPaneEquipSet:SetStyle("Button")
+	PaperDollEquipmentManagerPaneSaveSet:SetStyle("Button")
+	PaperDollEquipmentManagerPaneEquipSet:SetWidth(PaperDollEquipmentManagerPaneEquipSet:GetWidth()-8)
+	PaperDollEquipmentManagerPaneSaveSet:SetWidth(PaperDollEquipmentManagerPaneSaveSet:GetWidth()-8)
+	PaperDollEquipmentManagerPaneEquipSet:SetPoint("TOPLEFT", PaperDollEquipmentManagerPane, "TOPLEFT", 8, 0)
+	PaperDollEquipmentManagerPaneSaveSet:SetPoint("LEFT", PaperDollEquipmentManagerPaneEquipSet, "RIGHT", 4, 0)
+	PaperDollEquipmentManagerPaneEquipSet.ButtonBackground:SetTexture("")
+
+	PaperDollEquipmentManagerPane:HookScript("OnShow", PaperDollEquipmentManagerPane_OnShow)
+
+	for i = 1, 4 do
+		 SV.API:Set("Tab", _G["CharacterFrameTab"..i])
+	end
+
+	ReputationFrame:RemoveTextures(true)
+	ReputationListScrollFrame:RemoveTextures()
+	ReputationListScrollFrame:SetStyle("Frame", "Inset")
+	ReputationDetailFrame:RemoveTextures()
+	ReputationDetailFrame:SetStyle("Frame", "Inset", true)
+	ReputationDetailFrame:SetPoint("TOPLEFT", ReputationFrame, "TOPRIGHT", 4, -28)
+	ReputationFrame:HookScript("OnShow", Reputation_OnShow)
+	hooksecurefunc("ExpandFactionHeader", Reputation_OnShow)
+	hooksecurefunc("CollapseFactionHeader", Reputation_OnShow)
+	TokenFrameContainer:SetStyle("Frame", 'Inset')
+
+	TokenFrame:HookScript("OnShow", function()
+		for i = 1, GetCurrencyListSize() do
+			local currency = _G["TokenFrameContainerButton"..i]
+			if(currency) then
+				currency.highlight:Die()
+				currency.categoryMiddle:Die()
+				currency.categoryLeft:Die()
+				currency.categoryRight:Die()
+				if currency.icon then
+					 currency.icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+				end
+			end
+		end
+		TokenFramePopup:RemoveTextures()
+		TokenFramePopup:SetStyle("Frame", "Inset", true)
+		TokenFramePopup:SetPoint("TOPLEFT", TokenFrame, "TOPRIGHT", 4, -28)
+	end)
+
+	--[[
+	PetModelFrame:SetStyle("Frame", "Model", false, 1, -7, -7)
+	PetPaperDollPetInfo:GetRegions():SetTexCoord(.12, .63, .15, .55)
+	PetPaperDollPetInfo:SetFrameLevel(PetPaperDollPetInfo:GetFrameLevel() + 10)
+	PetPaperDollPetInfo:SetStyle("Frame", "Icon")
+	PetPaperDollPetInfo.Panel:SetFrameLevel(0)
+	PetPaperDollPetInfo:SetSize(24, 24)
+	]]--
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveCustomStyle(CharacterFrameStyle)
diff --git a/SVUI_Skins/components/blizzard/chat.lua b/SVUI_Skins/components/blizzard/chat.lua
new file mode 100644
index 0000000..e6ea8c9
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/chat.lua
@@ -0,0 +1,312 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+local string 	= _G.string;
+local math 		= _G.math;
+local table 	= _G.table;
+--[[ STRING METHODS ]]--
+local format, join, gsub = string.format, string.join, string.gsub;
+--[[ MATH METHODS ]]--
+local ceil = math.ceil;  -- Basic
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+FRAME LISTS
+##########################################################
+]]--
+local CHAT_CONFIG_CHANNEL_LIST = _G.CHAT_CONFIG_CHANNEL_LIST;
+local CHANNELS = _G.CHANNELS;
+
+local ChatMenuList = {
+	"ChatMenu",
+	"EmoteMenu",
+	"LanguageMenu",
+	"VoiceMacroMenu",
+};
+local ChatFrameWipeList = {
+	"ChatConfigFrame",
+	"ChatConfigBackgroundFrame",
+	"ChatConfigCategoryFrame",
+	"ChatConfigChatSettingsClassColorLegend",
+	"ChatConfigChatSettingsLeft",
+	"ChatConfigChannelSettingsLeft",
+	"ChatConfigChannelSettingsClassColorLegend",
+	"ChatConfigOtherSettingsCombat",
+	"ChatConfigOtherSettingsPVP",
+	"ChatConfigOtherSettingsSystem",
+	"ChatConfigOtherSettingsCreature",
+	"ChatConfigCombatSettingsFilters",
+	"CombatConfigMessageSourcesDoneBy",
+	"CombatConfigMessageSourcesDoneTo",
+	"CombatConfigColorsUnitColors",
+	"CombatConfigColorsHighlighting",
+	"CombatConfigColorsColorizeUnitName",
+	"CombatConfigColorsColorizeSpellNames",
+	"CombatConfigColorsColorizeDamageNumber",
+	"CombatConfigColorsColorizeDamageSchool",
+	"CombatConfigColorsColorizeEntireLine",
+	"ChatConfigFrameDefaultButton",
+	"ChatConfigFrameOkayButton",
+	"CombatLogDefaultButton",
+	"ChatConfigCombatSettingsFiltersCopyFilterButton",
+	"ChatConfigCombatSettingsFiltersAddFilterButton",
+	"ChatConfigCombatSettingsFiltersDeleteButton",
+	"CombatConfigSettingsSaveButton",
+	"ChatConfigFrameCancelButton",
+	"ChatConfigCategoryFrame",
+	"ChatConfigBackgroundFrame",
+	"ChatConfigChatSettingsClassColorLegend",
+	"ChatConfigChannelSettingsClassColorLegend",
+	"ChatConfigCombatSettingsFilters",
+	"ChatConfigCombatSettingsFiltersScrollFrame",
+	"CombatConfigColorsHighlighting",
+	"CombatConfigColorsColorizeUnitName",
+	"CombatConfigColorsColorizeSpellNames",
+	"CombatConfigColorsColorizeDamageNumber",
+	"CombatConfigColorsColorizeDamageSchool",
+	"CombatConfigColorsColorizeEntireLine",
+	"ChatConfigChatSettingsLeft",
+	"ChatConfigOtherSettingsCombat",
+	"ChatConfigOtherSettingsPVP",
+	"ChatConfigOtherSettingsSystem",
+	"ChatConfigOtherSettingsCreature",
+	"ChatConfigChannelSettingsLeft",
+	"CombatConfigMessageSourcesDoneBy",
+	"CombatConfigMessageSourcesDoneTo",
+	"CombatConfigColorsUnitColors",
+};
+local ChatFrameList4 = {
+	"CombatConfigColorsColorizeSpellNames",
+	"CombatConfigColorsColorizeDamageNumber",
+	"CombatConfigColorsColorizeDamageSchool",
+	"CombatConfigColorsColorizeEntireLine",
+};
+local ChatFrameList5 = {
+	"ChatConfigFrameOkayButton",
+	"ChatConfigFrameDefaultButton",
+	"CombatLogDefaultButton",
+	"ChatConfigCombatSettingsFiltersDeleteButton",
+	"ChatConfigCombatSettingsFiltersAddFilterButton",
+	"ChatConfigCombatSettingsFiltersCopyFilterButton",
+	"CombatConfigSettingsSaveButton",
+};
+local ChatFrameList6 = {
+	"CombatConfigColorsHighlightingLine",
+	"CombatConfigColorsHighlightingAbility",
+	"CombatConfigColorsHighlightingDamage",
+	"CombatConfigColorsHighlightingSchool",
+	"CombatConfigColorsColorizeUnitNameCheck",
+	"CombatConfigColorsColorizeSpellNamesCheck",
+	"CombatConfigColorsColorizeSpellNamesSchoolColoring",
+	"CombatConfigColorsColorizeDamageNumberCheck",
+	"CombatConfigColorsColorizeDamageNumberSchoolColoring",
+	"CombatConfigColorsColorizeDamageSchoolCheck",
+	"CombatConfigColorsColorizeEntireLineCheck",
+	"CombatConfigFormattingShowTimeStamp",
+	"CombatConfigFormattingShowBraces",
+	"CombatConfigFormattingUnitNames",
+	"CombatConfigFormattingSpellNames",
+	"CombatConfigFormattingItemNames",
+	"CombatConfigFormattingFullText",
+	"CombatConfigSettingsShowQuickButton",
+	"CombatConfigSettingsSolo",
+	"CombatConfigSettingsParty",
+	"CombatConfigSettingsRaid",
+};
+--[[
+##########################################################
+HELPERS
+##########################################################
+]]--
+local ChatGeneric_OnShow = function(self)
+	 if(not self.Panel) then
+	 	self:SetStyle("Frame", "Window")
+	end
+end
+
+local ChatMenu_OnShow = function(self)
+	if(not self.Panel) then
+		self:SetStyle("Frame", "Window")
+	end
+	self:ClearAllPoints()
+	self:SetPoint("BOTTOMLEFT", ChatFrame1, "TOPLEFT", 0, 30)
+end
+
+local _hook_ChatConfig_UpdateCheckboxes = function(frame)
+	local checkBoxTable = frame.checkBoxTable;
+	local checkBoxNameString = frame:GetName().."CheckBox";
+	local boxHeight = ChatConfigOtherSettingsCombatCheckBox1:GetHeight() or 20
+  local colorsHeight = ChatConfigChatSettingsLeftCheckBox1Check:GetHeight() or 20
+
+	local checkbox, baseName;
+
+	for index, value in ipairs(checkBoxTable) do
+		baseName = checkBoxNameString..index;
+		checkbox = _G[baseName];
+		if(checkbox) then
+			if(not checkbox.Panel) then
+				checkbox:RemoveTextures()
+				checkbox:SetStyle("Frame", 'Transparent')
+			end
+			checkbox:SetHeight(boxHeight)
+			checkbox.Panel:SetPoint("TOPLEFT",3,-1)
+			checkbox.Panel:SetPoint("BOTTOMRIGHT",-3,1)
+
+			local check = _G[baseName.."Check"]
+			if(check) then
+				check:SetStyle("CheckButton")
+			end
+
+			local colors = _G[baseName.."ColorClasses"]
+			if(colors) then
+				colors:SetStyle("CheckButton")
+				colors:SetHeight(colorsHeight)
+			end
+		end
+	end
+end
+--[[
+##########################################################
+CHAT MODR
+##########################################################
+]]--
+local function ChatStyle()
+	--print('test ChatStyle')
+	if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.chat ~= true then
+		 return
+	end
+
+	for i = 1, #ChatMenuList do
+		local name = ChatMenuList[i]
+		local this = _G[name]
+		if(this) then
+			if(name == "ChatMenu") then
+				this:HookScript("OnShow", ChatMenu_OnShow)
+			else
+				this:HookScript("OnShow", ChatGeneric_OnShow)
+			end
+		end
+	end
+
+	for i = 1, #ChatFrameWipeList do
+		local frame = _G[ChatFrameWipeList[i]]
+		if(frame) then
+			frame:RemoveTextures()
+		end
+	end
+
+	ChatConfigFrameOkayButton:SetPoint("RIGHT", ChatConfigFrameCancelButton, "RIGHT", -11, -1)
+	ChatConfigCombatSettingsFiltersDeleteButton:SetPoint("TOPRIGHT", ChatConfigCombatSettingsFilters, "BOTTOMRIGHT", 0, -1)
+	ChatConfigCombatSettingsFiltersAddFilterButton:SetPoint("RIGHT", ChatConfigCombatSettingsFiltersDeleteButton, "LEFT", -1, 0)
+	ChatConfigCombatSettingsFiltersCopyFilterButton:SetPoint("RIGHT", ChatConfigCombatSettingsFiltersAddFilterButton, "LEFT", -1, 0)
+
+	if(_G["CombatConfigTab1"]) then _G["CombatConfigTab1"]:RemoveTextures() end
+	if(_G["CombatConfigTab2"]) then _G["CombatConfigTab2"]:RemoveTextures() end
+	if(_G["CombatConfigTab3"]) then _G["CombatConfigTab3"]:RemoveTextures() end
+	if(_G["CombatConfigTab4"]) then _G["CombatConfigTab4"]:RemoveTextures() end
+	if(_G["CombatConfigTab5"]) then _G["CombatConfigTab5"]:RemoveTextures() end
+
+	CombatConfigSettingsNameEditBox:SetStyle("Editbox")
+	ChatConfigFrame:SetStyle("Frame", "Window", true)
+
+	ChatConfigCategoryFrame:SetStyle("Frame", 'Transparent')
+	ChatConfigBackgroundFrame:SetStyle("Frame", 'Transparent')
+
+	for i = 1, #ChatFrameList4 do
+		local this = _G[ChatFrameList4[i]]
+		if(this) then
+			this:ClearAllPoints()
+			if this == CombatConfigColorsColorizeSpellNames then
+				this:SetPoint("TOP",CombatConfigColorsColorizeUnitName,"BOTTOM",0,-2)
+			else
+				this:SetPoint("TOP",_G[ChatFrameList4[i-1]],"BOTTOM",0,-2)
+			end
+		end
+	end
+
+	hooksecurefunc("ChatConfig_UpdateCheckboxes", _hook_ChatConfig_UpdateCheckboxes)
+	-- do
+	-- 	local chatchannellist = GetChannelList()
+	-- 	local CreateChatChannelList = _G.CreateChatChannelList;
+	-- 	local ChatConfigChannelSettings = _G.ChatConfigChannelSettings;
+	-- 	CreateChatChannelList(ChatConfigChannelSettings, chatchannellist)
+	-- end
+
+	ChatConfig_CreateCheckboxes(ChatConfigChannelSettingsLeft, CHAT_CONFIG_CHANNEL_LIST, "ChatConfigCheckBoxWithSwatchAndClassColorTemplate", CHANNELS)
+	ChatConfig_UpdateCheckboxes(ChatConfigChannelSettingsLeft)
+
+	for i = 1, #COMBAT_CONFIG_TABS do
+		local this = _G["CombatConfigTab"..i]
+		if(this) then
+			SV.API:Set("Tab", this)
+			this:SetHeight(this:GetHeight()-2)
+			this:SetWidth(ceil(this:GetWidth()+1.6))
+			_G["CombatConfigTab"..i.."Text"]:SetPoint("BOTTOM", 0, 10)
+		end
+	end
+
+	CombatConfigTab1:ClearAllPoints()
+	CombatConfigTab1:SetPoint("BOTTOMLEFT", ChatConfigBackgroundFrame, "TOPLEFT", 6, -2)
+
+	for i = 1, #ChatFrameList5 do
+		local this = _G[ChatFrameList5[i]]
+		if(this) then
+			this:SetStyle("Button")
+		end
+	end
+
+	ChatConfigFrameOkayButton:SetPoint("TOPRIGHT", ChatConfigBackgroundFrame, "BOTTOMRIGHT", -3, -5)
+	ChatConfigFrameDefaultButton:SetPoint("TOPLEFT", ChatConfigCategoryFrame, "BOTTOMLEFT", 1, -5)
+	CombatLogDefaultButton:SetPoint("TOPLEFT", ChatConfigCategoryFrame, "BOTTOMLEFT", 1, -5)
+	ChatConfigCombatSettingsFiltersDeleteButton:SetPoint("TOPRIGHT", ChatConfigCombatSettingsFilters, "BOTTOMRIGHT", -3, -1)
+	ChatConfigCombatSettingsFiltersCopyFilterButton:SetPoint("RIGHT", ChatConfigCombatSettingsFiltersDeleteButton, "LEFT", -2, 0)
+	ChatConfigCombatSettingsFiltersAddFilterButton:SetPoint("RIGHT", ChatConfigCombatSettingsFiltersCopyFilterButton, "LEFT", -2, 0)
+
+	for i = 1, #ChatFrameList6 do
+		local this = _G[ChatFrameList6[i]]
+		if(this) then
+			this:SetStyle("CheckButton")
+		end
+	end
+
+	SV.API:Set("PageButton", ChatConfigMoveFilterUpButton,true)
+	SV.API:Set("PageButton", ChatConfigMoveFilterDownButton,true)
+	SV.API:Set("PageButton", CombatLogQuickButtonFrame_CustomAdditionalFilterButton,true)
+
+	SV.API:Set("ScrollBar", SVUI_CopyChatScrollFrameScrollBar)
+	SV.API:Set("CloseButton", SVUI_CopyChatFrameCloseButton)
+
+	ChatConfigMoveFilterUpButton:ClearAllPoints()
+	ChatConfigMoveFilterDownButton:ClearAllPoints()
+	ChatConfigMoveFilterUpButton:SetPoint("TOPLEFT",ChatConfigCombatSettingsFilters,"BOTTOMLEFT",3,0)
+	ChatConfigMoveFilterDownButton:SetPoint("LEFT",ChatConfigMoveFilterUpButton,24,0)
+
+	CombatConfigSettingsNameEditBox:SetStyle("Editbox")
+
+	ChatConfigFrame:SetSize(680,596)
+	ChatConfigFrameHeader:ClearAllPoints()
+	ChatConfigFrameHeader:SetPoint("TOP", ChatConfigFrame, "TOP", 0, -5)
+
+	-- for i=1, select("#", GetChatWindowChannels(3)) do
+	-- 	local info = select(i, GetChatWindowChannels(3))
+	-- 	print(info)
+	-- end
+	_hook_ChatConfig_UpdateCheckboxes(ChatConfigChatSettingsLeft)
+	_hook_ChatConfig_UpdateCheckboxes(ChatConfigChannelSettingsLeft)
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveCustomStyle(ChatStyle)
diff --git a/SVUI_Skins/components/blizzard/collections.lua b/SVUI_Skins/components/blizzard/collections.lua
new file mode 100644
index 0000000..0a76a8f
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/collections.lua
@@ -0,0 +1,378 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+HELPERS
+##########################################################
+]]--
+local FAV_ICON = SV.media.icon.star
+local NORMAL_COLOR = {r = 1, g = 1, b = 1}
+local SELECTED_COLOR = {r = 1, g = 1, b = 0}
+local WARDROBE_NUM_ROWS = 3;
+local WARDROBE_NUM_COLS = 6;
+local WARDROBE_SLOT_ICONS = {
+	[[Interface\ICONS\INV_Helmet_03]],
+	[[Interface\ICONS\INV_Shoulder_09]],
+	[[Interface\ICONS\INV_Misc_Cape_19]],
+	[[Interface\ICONS\INV_Chest_Chain]],
+	[[Interface\ICONS\INV_Shirt_White_01]],
+	[[Interface\ICONS\INV_MISC_TABARDSUMMER01]],
+	[[Interface\ICONS\INV_Bracer_05]],
+	[[Interface\ICONS\INV_Gauntlets_24]],
+	[[Interface\ICONS\INV_Belt_24]],
+	[[Interface\ICONS\INV_Pants_09]],
+	[[Interface\ICONS\INV_BOOTS_09]],
+	[[Interface\ICONS\INV_Sword_04]],
+	[[Interface\ICONS\INV_Shield_06]]
+};
+
+local function PetJournal_UpdateMounts()
+	for b = 1, #MountJournal.ListScrollFrame.buttons do
+		local d = _G["MountJournalListScrollFrameButton"..b]
+		local e = _G["MountJournalListScrollFrameButton"..b.."Name"]
+		if d.selectedTexture:IsShown() then
+			if(e) then e:SetTextColor(1, 1, 0) end
+			if d.Panel then
+				d:SetBackdropBorderColor(1, 1, 0)
+			end
+			if d.IconShadow then
+				d.IconShadow:SetBackdropBorderColor(1, 1, 0)
+			end
+		else
+			if(e) then e:SetTextColor(1, 1, 1) end
+			if d.Panel then
+				d:SetBackdropBorderColor(0,0,0,1)
+			end
+			if d.IconShadow then
+				d.IconShadow:SetBackdropBorderColor(0,0,0,1)
+			end
+		end
+	end
+end
+
+local function PetJournal_UpdatePets()
+	local u = PetJournal.listScroll.buttons;
+	local isWild = PetJournal.isWild;
+	for b = 1, #u do
+		local v = u[b].index;
+		if not v then
+			break
+		end
+		local d = _G["PetJournalListScrollFrameButton"..b]
+		local e = _G["PetJournalListScrollFrameButton"..b.."Name"]
+		local levelText = _G["PetJournalListScrollFrameButton"..b.."Level"]
+		local w, x, y, z, level, favorite, A, B, C, D, E, F, G, H, I = C_PetJournal.GetPetInfoByIndex(v, isWild)
+		if w ~= nil then
+			local J, K, L, M, N = C_PetJournal.GetPetStats(w)
+			local color = NORMAL_COLOR
+			if(N) then
+				color = ITEM_QUALITY_COLORS[N-1]
+			end
+			d:SetBackdropBorderColor(0,0,0,1)
+			if(d.selectedTexture:IsShown() and d.Panel) then
+				d:SetBackdropBorderColor(1,1,0,1)
+				if d.IconShadow then
+					d.IconShadow:SetBackdropBorderColor(1,1,0)
+				end
+			else
+				if d.IconShadow then
+					d.IconShadow:SetBackdropBorderColor(color.r, color.g, color.b)
+				end
+			end
+
+			e:SetTextColor(color.r, color.g, color.b)
+		end
+	end
+end
+
+local function WardrobeFrameUpdateSlots(...)
+	if (not WardrobeCollectionFrame or not WardrobeCollectionFrame.ModelsFrame or not WardrobeCollectionFrame.ModelsFrame.SlotsFrame or not WardrobeCollectionFrame.ModelsFrame.SlotsFrame.Buttons) then return end
+	local slotButtons = WardrobeCollectionFrame.ModelsFrame.SlotsFrame.Buttons;
+	for i = 1, #slotButtons do
+		local button = slotButtons[i];
+		local icon = WARDROBE_SLOT_ICONS[i];
+		if (not button.Panel and icon) then
+			SV.API:Set("IconButton", button, icon)
+		end
+	end
+end
+
+local function WardrobeFrameUpdateModels(...)
+	if (not WardrobeCollectionFrame or not WardrobeCollectionFrame.ModelsFrame) then return end
+	for r = 1, WARDROBE_NUM_ROWS do
+		for c = 1, WARDROBE_NUM_COLS do
+			model = WardrobeCollectionFrame.ModelsFrame["ModelR"..r.."C"..c];
+			model:RemoveTextures(true);
+			model:SetStyle("!_ShadowBox", 'Model');
+		end
+	end
+end
+--[[
+##########################################################
+FRAME MODR
+##########################################################
+]]--
+local function CollectionsJournalStyle()
+	if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.mounts ~= true then return end
+
+	SV.API:Set("Window", CollectionsJournal)
+
+	CollectionsJournalPortrait:Hide()
+	SV.API:Set("Tab", CollectionsJournalTab1)
+	SV.API:Set("Tab", CollectionsJournalTab2)
+	SV.API:Set("CloseButton", CollectionsJournalCloseButton)
+
+	MountJournal:RemoveTextures()
+	MountJournal.LeftInset:RemoveTextures()
+	MountJournal.RightInset:RemoveTextures()
+	MountJournal.MountDisplay:RemoveTextures()
+	MountJournal.MountDisplay.ShadowOverlay:RemoveTextures()
+	MountJournal.MountCount:RemoveTextures()
+	MountJournalListScrollFrame:RemoveTextures()
+	MountJournalMountButton:RemoveTextures()
+	MountJournalMountButton:SetStyle("Button")
+	MountJournalSearchBox:SetStyle("Editbox")
+
+	SV.API:Set("ScrollBar", MountJournalListScrollFrame)
+	MountJournal.MountDisplay:SetStyle("!_Frame", "Model")
+
+	local buttons = MountJournal.ListScrollFrame.buttons
+	for i = 1, #buttons do
+		local button = buttons[i]
+		if(button) then
+			SV.API:Set("ItemButton", button)
+			local bar = _G["SVUI_MountSelectBar"..i]
+			if(bar) then bar:SetParent(button.Panel) end
+			if(button.favorite) then
+				local fg = CreateFrame("Frame", nil, button)
+				fg:SetAllPoints(favorite)
+				fg:SetFrameLevel(button:GetFrameLevel() + 30)
+				button.favorite:SetParent(fg)
+				button.favorite:SetTexture(SV.media.icon.star)
+			end
+		end
+	end
+
+	hooksecurefunc("MountJournal_UpdateMountList", PetJournal_UpdateMounts)
+	MountJournalListScrollFrame:HookScript("OnVerticalScroll", PetJournal_UpdateMounts)
+	MountJournalListScrollFrame:HookScript("OnMouseWheel", PetJournal_UpdateMounts)
+	PetJournalSummonButton:RemoveTextures()
+	PetJournalFindBattle:RemoveTextures()
+	PetJournalSummonButton:SetStyle("Button")
+	PetJournalFindBattle:SetStyle("Button")
+	PetJournalRightInset:RemoveTextures()
+	PetJournalLeftInset:RemoveTextures()
+
+	for i = 1, 3 do
+		local button = _G["PetJournalLoadoutPet" .. i .. "HelpFrame"]
+		button:RemoveTextures()
+	end
+
+	PetJournalTutorialButton:Die()
+	PetJournal.PetCount:RemoveTextures()
+	PetJournalSearchBox:SetStyle("Editbox")
+	PetJournalFilterButton:RemoveTextures(true)
+	PetJournalFilterButton:SetStyle("Button")
+	PetJournalListScrollFrame:RemoveTextures()
+	SV.API:Set("ScrollBar", PetJournalListScrollFrame)
+
+	for i = 1, #PetJournal.listScroll.buttons do
+		local button = _G["PetJournalListScrollFrameButton" .. i]
+		local favorite = _G["PetJournalListScrollFrameButton" .. i .. "Favorite"]
+		SV.API:Set("ItemButton", button)
+		if(not button.Riser) then
+			local fg = CreateFrame("Frame", nil, button)
+			fg:SetAllPoints(button)
+			fg:SetFrameLevel(button:GetFrameLevel() + 30)
+			button.Riser = fg
+		end
+		if(favorite) then
+			favorite:SetParent(button.Riser)
+			button.dragButton.favorite:SetParent(button.Riser)
+			favorite:SetTexture(SV.media.icon.star)
+			favorite:SetTexCoord(0,1,0,1)
+		end
+
+		button.dragButton.levelBG:SetAlpha(0)
+		button.dragButton.level:SetParent(button.Riser)
+		--button.dragButton.level:SetDrawLayer("OVERLAY", 7)
+		button.petTypeIcon:SetParent(button.Panel)
+	end
+
+	hooksecurefunc('PetJournal_UpdatePetList', PetJournal_UpdatePets)
+	PetJournalListScrollFrame:HookScript("OnVerticalScroll", PetJournal_UpdatePets)
+	PetJournalListScrollFrame:HookScript("OnMouseWheel", PetJournal_UpdatePets)
+	PetJournalAchievementStatus:DisableDrawLayer('BACKGROUND')
+	SV.API:Set("!_ItemButton", PetJournalHealPetButton)
+	PetJournalHealPetButton.texture:SetTexture([[Interface\Icons\spell_magic_polymorphrabbit]])
+	PetJournalLoadoutBorder:RemoveTextures()
+
+	for b = 1, 3 do
+		local pjPet = _G['PetJournalLoadoutPet'..b]
+		pjPet:RemoveTextures()
+		pjPet.petTypeIcon:SetPoint('BOTTOMLEFT', 2, 2)
+		pjPet.dragButton:WrapPoints(_G['PetJournalLoadoutPet'..b..'Icon'])
+		pjPet.hover = true;
+		pjPet.pushed = true;
+		pjPet.checked = true;
+		SV.API:Set("ItemButton", pjPet, true)
+		pjPet.setButton:RemoveTextures()
+		_G['PetJournalLoadoutPet'..b..'HealthFrame'].healthBar:RemoveTextures()
+		_G['PetJournalLoadoutPet'..b..'HealthFrame'].healthBar:SetStyle("Frame", 'Default')
+		_G['PetJournalLoadoutPet'..b..'HealthFrame'].healthBar:SetStatusBarTexture(SV.media.statusbar.default)
+		_G['PetJournalLoadoutPet'..b..'XPBar']:RemoveTextures()
+		_G['PetJournalLoadoutPet'..b..'XPBar']:SetStyle("Frame", 'Default')
+		_G['PetJournalLoadoutPet'..b..'XPBar']:SetStatusBarTexture(SV.media.statusbar.default)
+		_G['PetJournalLoadoutPet'..b..'XPBar']:SetFrameLevel(_G['PetJournalLoadoutPet'..b..'XPBar']:GetFrameLevel()+2)
+		for v = 1, 3 do
+			local s = _G['PetJournalLoadoutPet'..b..'Spell'..v]
+			SV.API:Set("ItemButton", s)
+			s.FlyoutArrow:SetTexture([[Interface\Buttons\ActionBarFlyoutButton]])
+			_G['PetJournalLoadoutPet'..b..'Spell'..v..'Icon']:InsetPoints(s)
+			s.Panel:SetFrameLevel(s:GetFrameLevel() + 1)
+			_G['PetJournalLoadoutPet'..b..'Spell'..v..'Icon']:SetParent(s.Panel)
+		end
+	end
+
+	PetJournalSpellSelect:RemoveTextures()
+
+	for b = 1, 2 do
+		local Q = _G['PetJournalSpellSelectSpell'..b]
+		SV.API:Set("ItemButton", Q)
+		_G['PetJournalSpellSelectSpell'..b..'Icon']:InsetPoints(Q)
+		_G['PetJournalSpellSelectSpell'..b..'Icon']:SetDrawLayer('BORDER')
+	end
+
+	PetJournalPetCard:RemoveTextures()
+	SV.API:Set("ItemButton", PetJournalPetCard, true)
+	PetJournalPetCardInset:RemoveTextures()
+	PetJournalPetCardPetInfo.levelBG:SetAlpha(0)
+	PetJournalPetCardPetInfoIcon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+	SV.API:Set("ItemButton", PetJournalPetCardPetInfo, true)
+
+	local fg = CreateFrame("Frame", nil, PetJournalPetCardPetInfo)
+	fg:SetSize(40,40)
+	fg:SetPoint("TOPLEFT", PetJournalPetCardPetInfo, "TOPLEFT", -1, 1)
+	fg:SetFrameLevel(PetJournalPetCardPetInfo:GetFrameLevel() + 30)
+
+	PetJournalPetCardPetInfo.favorite:SetParent(fg)
+	PetJournalPetCardPetInfo.Panel:WrapPoints(PetJournalPetCardPetInfoIcon)
+	PetJournalPetCardPetInfoIcon:SetParent(PetJournalPetCardPetInfo.Panel)
+
+	local R = PetJournalPrimaryAbilityTooltip;
+	R.Background:SetTexture("")
+	if R.Delimiter1 then
+		R.Delimiter1:SetTexture("")
+		R.Delimiter2:SetTexture("")
+	end
+
+	R.BorderTop:SetTexture("")
+	R.BorderTopLeft:SetTexture("")
+	R.BorderTopRight:SetTexture("")
+	R.BorderLeft:SetTexture("")
+	R.BorderRight:SetTexture("")
+	R.BorderBottom:SetTexture("")
+	R.BorderBottomRight:SetTexture("")
+	R.BorderBottomLeft:SetTexture("")
+	R:SetStyle("!_Frame", "Transparent", true)
+
+	for b = 1, 6 do
+		local S = _G['PetJournalPetCardSpell'..b]
+		S:SetFrameLevel(S:GetFrameLevel() + 2)
+		S:DisableDrawLayer('BACKGROUND')
+		S:SetStyle("Frame", 'Transparent')
+		S.Panel:SetAllPoints()
+		S.icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+		S.icon:InsetPoints(S.Panel)
+	end
+
+	PetJournalPetCardHealthFrame.healthBar:RemoveTextures()
+	PetJournalPetCardHealthFrame.healthBar:SetStyle("Frame", 'Default')
+	PetJournalPetCardHealthFrame.healthBar:SetStatusBarTexture(SV.media.statusbar.default)
+	PetJournalPetCardXPBar:RemoveTextures()
+	PetJournalPetCardXPBar:SetStyle("Frame", 'Default')
+	PetJournalPetCardXPBar:SetStatusBarTexture(SV.media.statusbar.default)
+
+	SV.API:Set("Tab", CollectionsJournalTab3)
+	SV.API:Set("Tab", CollectionsJournalTab4)
+
+	ToyBox:RemoveTextures()
+	ToyBox.searchBox:SetStyle("Editbox")
+	ToyBoxFilterButton:RemoveTextures(true)
+	ToyBoxFilterButton:SetStyle("Button")
+	ToyBox.iconsFrame:RemoveTextures()
+	ToyBox.iconsFrame:SetStyle("!_Frame", 'Model')
+	ToyBox.progressBar:RemoveTextures()
+	ToyBox.progressBar:SetStatusBarTexture([[Interface\BUTTONS\WHITE8X8]])
+	ToyBox.progressBar:SetStyle("Frame", "Bar", true, 2, 2, 2)
+	SV.API:Set("PageButton", ToyBox.navigationFrame.prevPageButton, false, true)
+	SV.API:Set("PageButton", ToyBox.navigationFrame.nextPageButton)
+
+	HeirloomsJournal:RemoveTextures()
+	HeirloomsJournal.SearchBox:SetStyle("Editbox")
+	HeirloomsJournalFilterButton:RemoveTextures(true)
+	HeirloomsJournalFilterButton:SetStyle("Button")
+	HeirloomsJournal.iconsFrame:RemoveTextures()
+	HeirloomsJournal.iconsFrame:SetStyle("!_Frame", 'Model')
+
+	HeirloomsJournal.progressBar:RemoveTextures()
+	HeirloomsJournal.progressBar:SetStatusBarTexture([[Interface\BUTTONS\WHITE8X8]])
+	HeirloomsJournal.progressBar:SetStyle("Frame", "Bar", true, 2, 2, 2)
+	SV.API:Set("PageButton", HeirloomsJournal.navigationFrame.prevPageButton, false, true)
+	SV.API:Set("PageButton", HeirloomsJournal.navigationFrame.nextPageButton)
+
+	SV.API:Set("DropDown", HeirloomsJournalClassDropDown)
+
+	MountJournalFilterButton:RemoveTextures(true)
+	MountJournalFilterButton:SetStyle("Button")
+
+	MountJournal.SummonRandomFavoriteButton:RemoveTextures()
+	MountJournal.SummonRandomFavoriteButton:SetStyle("ActionSlot")
+	MountJournal.SummonRandomFavoriteButton.texture:SetTexture([[Interface\ICONS\ACHIEVEMENT_GUILDPERK_MOUNTUP]])
+	MountJournal.SummonRandomFavoriteButton.texture:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+
+	for i = 1, 18 do
+		local gName = ("ToySpellButton%d"):format(i)
+		local button = _G[gName]
+		if(button) then
+			button:SetStyle("Button")
+		end
+	end
+
+	SV.API:Set("Tab", CollectionsJournalTab5)
+	WardrobeCollectionFrame:RemoveTextures()
+	WardrobeCollectionFrameSearchBox:SetStyle("Editbox")
+	WardrobeCollectionFrame.FilterButton:RemoveTextures(true)
+	WardrobeCollectionFrame.FilterButton:SetStyle("Button")
+	WardrobeCollectionFrame.ModelsFrame:RemoveTextures()
+	WardrobeCollectionFrame.ModelsFrame:SetStyle("!_Frame", 'Premium')
+	SV.API:Set("DropDown", WardrobeCollectionFrameWeaponDropDown)
+
+	WardrobeCollectionFrame.progressBar:RemoveTextures()
+	WardrobeCollectionFrame.progressBar:SetStatusBarTexture([[Interface\BUTTONS\WHITE8X8]])
+	WardrobeCollectionFrame.progressBar:SetStyle("Frame", "Bar", true, 2, 2, 2)
+	SV.API:Set("PageButton", WardrobeCollectionFrame.NavigationFrame.PrevPageButton, false, true)
+	SV.API:Set("PageButton", WardrobeCollectionFrame.NavigationFrame.NextPageButton)
+
+	WardrobeFrameUpdateModels()
+	WardrobeFrameUpdateSlots()
+	--hooksecurefunc("WardrobeCollectionFrame_OnShow", WardrobeFrameUpdateModels)
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveBlizzardStyle("Blizzard_Collections", CollectionsJournalStyle)
\ No newline at end of file
diff --git a/SVUI_Skins/components/blizzard/encounterjournal.lua b/SVUI_Skins/components/blizzard/encounterjournal.lua
new file mode 100644
index 0000000..29ee498
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/encounterjournal.lua
@@ -0,0 +1,295 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+local ipairs  = _G.ipairs;
+local pairs   = _G.pairs;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+ENCOUNTERJOURNAL MODR
+##########################################################
+]]--
+local PVP_LOST = [[Interface\WorldMap\Skull_64Red]]
+
+local function Tab_OnEnter(this)
+  this.backdrop:SetPanelColor("highlight")
+  this.backdrop:SetBackdropBorderColor(0.1, 0.8, 0.8)
+end
+
+local function Tab_OnLeave(this)
+  this.backdrop:SetPanelColor("dark")
+  this.backdrop:SetBackdropBorderColor(0,0,0,1)
+end
+
+local function ChangeTabHelper(this, xOffset, yOffset)
+  this:SetNormalTexture(SV.NoTexture)
+  this:SetPushedTexture(SV.NoTexture)
+  this:SetDisabledTexture(SV.NoTexture)
+  this:SetHighlightTexture(SV.NoTexture)
+
+  this.backdrop = CreateFrame("Frame", nil, this)
+  this.backdrop:InsetPoints(this)
+  this.backdrop:SetFrameLevel(0)
+
+  this.backdrop:SetStyle("Frame")
+  this.backdrop:SetPanelColor("dark")
+  this:HookScript("OnEnter",Tab_OnEnter)
+  this:HookScript("OnLeave",Tab_OnLeave)
+
+  local initialAnchor, anchorParent, relativeAnchor, xPosition, yPosition = this:GetPoint()
+  this:ClearAllPoints()
+  this:SetPoint(initialAnchor, anchorParent, relativeAnchor, xOffset or 0, yOffset or 0)
+end
+
+local function Outline(frame, noHighlight)
+    if(frame.Outlined) then return; end
+    local offset = noHighlight and 30 or 5
+    local mod = noHighlight and 50 or 5
+
+    local panel = CreateFrame('Frame', nil, frame)
+    panel:SetPoint('TOPLEFT', frame, 'TOPLEFT', 1, -1)
+    panel:SetPoint('BOTTOMRIGHT', frame, 'BOTTOMRIGHT', -1, 1)
+
+    --[[ UNDERLAY BORDER ]]--
+    local borderLeft = panel:CreateTexture(nil, "BORDER")
+    borderLeft:SetColorTexture(0, 0, 0)
+    borderLeft:SetPoint("TOPLEFT")
+    borderLeft:SetPoint("BOTTOMLEFT")
+    borderLeft:SetWidth(offset)
+
+    local borderRight = panel:CreateTexture(nil, "BORDER")
+    borderRight:SetColorTexture(0, 0, 0)
+    borderRight:SetPoint("TOPRIGHT")
+    borderRight:SetPoint("BOTTOMRIGHT")
+    borderRight:SetWidth(offset)
+
+    local borderTop = panel:CreateTexture(nil, "BORDER")
+    borderTop:SetColorTexture(0, 0, 0)
+    borderTop:SetPoint("TOPLEFT")
+    borderTop:SetPoint("TOPRIGHT")
+    borderTop:SetHeight(mod)
+
+    local borderBottom = panel:CreateTexture(nil, "BORDER")
+    borderBottom:SetColorTexture(0, 0, 0)
+    borderBottom:SetPoint("BOTTOMLEFT")
+    borderBottom:SetPoint("BOTTOMRIGHT")
+    borderBottom:SetHeight(mod)
+
+    if(not noHighlight) then
+      local highlight = frame:CreateTexture(nil, "HIGHLIGHT")
+      highlight:SetColorTexture(0, 1, 1, 0.35)
+      highlight:SetAllPoints(panel)
+    end
+
+    frame.Outlined = true
+end
+
+local function _hook_EncounterJournal_SetBullets(object, ...)
+    local parent = object:GetParent();
+    if (parent.Bullets and #parent.Bullets > 0) then
+        for i = 1, #parent.Bullets do
+            local bullet = parent.Bullets[i];
+            bullet.Text:SetTextColor(1,1,1)
+        end
+    end
+end
+
+local function _hook_EncounterJournal_ListInstances()
+  local frame = EncounterJournal.instanceSelect.scroll.child
+  local index = 1
+  local instanceButton = frame["instance"..index];
+  while instanceButton do
+      Outline(instanceButton)
+      index = index + 1;
+      instanceButton = frame["instance"..index]
+  end
+end
+
+local function _hook_EncounterJournal_ToggleHeaders(self)
+  local isOverview = self.isOverview;
+
+  if (not isOverview) then
+    local usedHeaders = EncounterJournal.encounter.usedHeaders
+    for key,used in pairs(usedHeaders) do
+      if(not used.button.Panel) then
+          used:RemoveTextures(true)
+          used.button:RemoveTextures(true)
+          used.button:SetStyle("Button")
+      end
+      used.description:SetTextColor(1, 1, 1)
+      --used.button.portrait.icon:Hide()
+    end
+  else
+    local overviews = EncounterJournal.encounter.overviewFrame.overviews
+    for i = 1, #overviews do
+      local overview = overviews[i];
+      if(overview) then
+        if(not overview.Panel) then
+            overview:RemoveTextures(true)
+            overview.button:RemoveTextures(true)
+            overview:SetStyle("Button")
+        end
+        if(overview.loreDescription) then
+          overview.loreDescription:SetTextColor(1, 1, 1)
+        end
+        if(overview.description) then
+          overview.description:SetTextColor(1, 1, 1)
+        end
+      end
+    end
+  end
+end
+
+local function _hook_EncounterJournal_LootUpdate()
+  local scrollFrame = EncounterJournal.encounter.info.lootScroll;
+  local offset = HybridScrollFrame_GetOffset(scrollFrame);
+  local items = scrollFrame.buttons;
+  local item, index;
+
+  local numLoot = EJ_GetNumLoot()
+
+  for i = 1,#items do
+    item = items[i];
+    index = offset + i;
+    if index <= numLoot then
+        item.icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+        SV.API:Set("ItemButton", item)
+        item.slot:SetTextColor(0.5, 1, 0)
+        item.armorType:SetTextColor(1, 1, 0)
+        item.boss:SetTextColor(0.7, 0.08, 0)
+    end
+  end
+end
+
+local function EncounterJournalStyle()
+	if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.encounterjournal ~= true then
+		 return
+	end
+
+	EncounterJournal:RemoveTextures(true)
+  EncounterJournalInstanceSelect:RemoveTextures(true)
+  EncounterJournalInset:RemoveTextures(true)
+
+  EncounterJournalEncounterFrame:RemoveTextures(true)
+  EncounterJournalEncounterFrameInfo:RemoveTextures(true)
+  EncounterJournalEncounterFrameInfoDifficulty:RemoveTextures(true)
+  EncounterJournalEncounterFrameInfoLootScrollFrameFilterToggle:RemoveTextures(true)
+
+  ChangeTabHelper(EncounterJournalEncounterFrameInfoOverviewTab, 10)
+  ChangeTabHelper(EncounterJournalEncounterFrameInfoLootTab, 0, -10)
+  ChangeTabHelper(EncounterJournalEncounterFrameInfoBossTab, 0, -10)
+  ChangeTabHelper(EncounterJournalEncounterFrameInfoModelTab, 0, -20)
+
+  EncounterJournalEncounterFrameInfoOverviewScrollFrame:RemoveTextures()
+  EncounterJournalEncounterFrameInfoOverviewScrollFrameScrollChildTitle:SetTextColor(1,1,0)
+  EncounterJournalEncounterFrameInfoOverviewScrollFrameScrollChildLoreDescription:SetTextColor(1,1,1)
+  EncounterJournalEncounterFrameInfoOverviewScrollFrameScrollChild.overviewDescription.Text:SetTextColor(1,1,1)
+
+  EncounterJournalSearchResults:RemoveTextures(true)
+  SV.API:Set("EditBox", EncounterJournalSearchBox)
+
+  EncounterJournal:SetStyle("Frame", "Window")
+  EncounterJournalInset:SetStyle("!_Frame", "Window2")
+  EncounterJournalInset:SetPanelColor("darkest")
+
+  SV.API:Set("ScrollBar", EncounterJournalInstanceSelectScrollFrame)
+  SV.API:Set("ScrollBar", EncounterJournalEncounterFrameInfoBossesScrollFrame)
+  SV.API:Set("ScrollBar", EncounterJournalEncounterFrameInfoOverviewScrollFrame)
+  SV.API:Set("ScrollBar", EncounterJournalEncounterFrameInfoLootScrollFrame)
+  SV.API:Set("ScrollBar", EncounterJournalEncounterFrameInfoDetailsScrollFrame)
+  SV.API:Set("DropDown", EncounterJournalInstanceSelectTierDropDown)
+  SV.API:Set("CloseButton", EncounterJournalCloseButton)
+
+  EncounterJournalEncounterFrameInfoResetButton:SetStyle("Button")
+
+  EncounterJournalNavBar:RemoveTextures(true)
+  EncounterJournalNavBarOverlay:RemoveTextures(true)
+  EncounterJournalNavBarOverflowButton:RemoveTextures(true)
+  EncounterJournalNavBarHomeButton:RemoveTextures(true)
+  EncounterJournalNavBarHomeButton:SetStyle("Button")
+  EncounterJournalNavBarOverflowButton:SetStyle("Button")
+  EncounterJournalEncounterFrameInfoDifficulty:SetStyle("Button")
+  EncounterJournalEncounterFrameInfoDifficulty:SetFrameLevel(EncounterJournalEncounterFrameInfoDifficulty:GetFrameLevel() + 10)
+  EncounterJournalEncounterFrameInfoLootScrollFrameFilterToggle:SetStyle("Button")
+  EncounterJournalEncounterFrameInfoLootScrollFrameFilterToggle:SetFrameLevel(EncounterJournalEncounterFrameInfoLootScrollFrameFilterToggle:GetFrameLevel() + 10)
+
+  if(EncounterJournalSuggestFrame) then
+    if(EncounterJournalSuggestFrame.Suggestion1 and EncounterJournalSuggestFrame.Suggestion1.button) then
+      EncounterJournalSuggestFrame.Suggestion1.button:RemoveTextures(true)
+      EncounterJournalSuggestFrame.Suggestion1.button:SetStyle("Button")
+    end
+    if(EncounterJournalSuggestFrame.Suggestion2 and EncounterJournalSuggestFrame.Suggestion2.centerDisplay and EncounterJournalSuggestFrame.Suggestion2.centerDisplay.button) then
+      EncounterJournalSuggestFrame.Suggestion2.centerDisplay.button:RemoveTextures(true)
+      EncounterJournalSuggestFrame.Suggestion2.centerDisplay.button:SetStyle("Button")
+    end
+  end
+
+  local tabBaseName = "EncounterJournalInstanceSelect";
+  if(_G[tabBaseName .. "SuggestTab"]) then
+    _G[tabBaseName .. "SuggestTab"]:RemoveTextures(true)
+    _G[tabBaseName .. "SuggestTab"]:SetStyle("Button")
+  end
+  if(_G[tabBaseName .. "DungeonTab"]) then
+    _G[tabBaseName .. "DungeonTab"]:RemoveTextures(true)
+    _G[tabBaseName .. "DungeonTab"]:SetStyle("Button")
+  end
+  if(_G[tabBaseName .. "RaidTab"]) then
+    _G[tabBaseName .. "RaidTab"]:RemoveTextures(true)
+    _G[tabBaseName .. "RaidTab"]:SetStyle("Button")
+  end
+
+  local bgParent = EncounterJournal.encounter.instance
+  local loreParent = EncounterJournal.encounter.instance.loreScroll
+
+  bgParent.loreBG:SetPoint("TOPLEFT", bgParent, "TOPLEFT", 0, 0)
+  bgParent.loreBG:SetPoint("BOTTOMRIGHT", bgParent, "BOTTOMRIGHT", 0, 90)
+
+  loreParent:SetStyle("Frame", "Pattern")
+  --loreParent:SetPanelColor("dark")
+  loreParent.child.lore:SetTextColor(1, 1, 1)
+  EncounterJournal.encounter.infoFrame.description:SetTextColor(1, 1, 1)
+
+  loreParent:SetFrameLevel(loreParent:GetFrameLevel() + 10)
+
+  local frame = EncounterJournal.instanceSelect.scroll.child
+  local index = 1
+  local instanceButton = frame["instance"..index];
+  while instanceButton do
+      Outline(instanceButton)
+      index = index + 1;
+      instanceButton = frame["instance"..index]
+  end
+
+  local bulletParent = EncounterJournalEncounterFrameInfoOverviewScrollFrameScrollChild;
+  if (bulletParent.Bullets and #bulletParent.Bullets > 0) then
+      for i = 1, #bulletParent.Bullets do
+          local bullet = bulletParent.Bullets[1];
+          bullet.Text:SetTextColor(1,1,1)
+      end
+  end
+
+  EncounterJournal.instanceSelect.raidsTab:GetFontString():SetTextColor(1, 1, 1);
+
+  hooksecurefunc("EncounterJournal_SetBullets", _hook_EncounterJournal_SetBullets)
+  hooksecurefunc("EncounterJournal_ListInstances", _hook_EncounterJournal_ListInstances)
+  hooksecurefunc("EncounterJournal_ToggleHeaders", _hook_EncounterJournal_ToggleHeaders)
+  hooksecurefunc("EncounterJournal_LootUpdate", _hook_EncounterJournal_LootUpdate)
+
+  _hook_EncounterJournal_ToggleHeaders()
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveBlizzardStyle('Blizzard_EncounterJournal', EncounterJournalStyle)
diff --git a/SVUI_Skins/components/blizzard/friends.lua b/SVUI_Skins/components/blizzard/friends.lua
new file mode 100644
index 0000000..52b2181
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/friends.lua
@@ -0,0 +1,290 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+local ipairs  = _G.ipairs;
+local pairs   = _G.pairs;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+HELPERS
+##########################################################
+]]--
+local FrameSuffix = {
+	"LeftDisabled",
+	"MiddleDisabled",
+	"RightDisabled",
+	"Left",
+	"Middle",
+	"Right"
+};
+local FriendsFrameList1 = {
+	"ScrollOfResurrectionSelectionFrame",
+	"ScrollOfResurrectionSelectionFrameList",
+	"FriendsListFrame",
+	"FriendsTabHeader",
+	"FriendsFrameFriendsScrollFrame",
+	"WhoFrameColumnHeader1",
+	"WhoFrameColumnHeader2",
+	"WhoFrameColumnHeader3",
+	"WhoFrameColumnHeader4",
+	"ChannelListScrollFrame",
+	"ChannelRoster",
+	"FriendsFramePendingButton1",
+	"FriendsFramePendingButton2",
+	"FriendsFramePendingButton3",
+	"FriendsFramePendingButton4",
+	"ChannelFrameDaughterFrame",
+	"AddFriendFrame",
+	"AddFriendNoteFrame"
+};
+-- local FriendsFrameList2 = {
+-- 	"FriendsFrameBroadcastInputLeft",
+-- 	"FriendsFrameBroadcastInputRight",
+-- 	"FriendsFrameBroadcastInputMiddle",
+-- 	"ChannelFrameDaughterFrameChannelNameLeft",
+-- 	"ChannelFrameDaughterFrameChannelNameRight",
+-- 	"ChannelFrameDaughterFrameChannelNameMiddle",
+-- 	"ChannelFrameDaughterFrameChannelPasswordLeft",
+-- 	"ChannelFrameDaughterFrameChannelPasswordRight",
+-- 	"ChannelFrameDaughterFrameChannelPasswordMiddle"
+-- };
+local FriendsFrameButtons = {
+	"FriendsFrameAddFriendButton",
+	"FriendsFrameSendMessageButton",
+	"WhoFrameWhoButton",
+	"WhoFrameAddFriendButton",
+	"WhoFrameGroupInviteButton",
+	"ChannelFrameNewButton",
+	"FriendsFrameIgnorePlayerButton",
+	"FriendsFrameUnsquelchButton",
+	"FriendsFramePendingButton1AcceptButton",
+	"FriendsFramePendingButton1DeclineButton",
+	"FriendsFramePendingButton2AcceptButton",
+	"FriendsFramePendingButton2DeclineButton",
+	"FriendsFramePendingButton3AcceptButton",
+	"FriendsFramePendingButton3DeclineButton",
+	"FriendsFramePendingButton4AcceptButton",
+	"FriendsFramePendingButton4DeclineButton",
+	"ChannelFrameDaughterFrameOkayButton",
+	"ChannelFrameDaughterFrameCancelButton",
+	"AddFriendEntryFrameAcceptButton",
+	"AddFriendEntryFrameCancelButton",
+	"AddFriendInfoFrameContinueButton",
+	"ScrollOfResurrectionSelectionFrameAcceptButton",
+	"ScrollOfResurrectionSelectionFrameCancelButton"
+};
+
+local function TabCustomHelper(this)
+	if not this then return end
+	for _,prop in pairs(FrameSuffix) do
+		local frame = _G[this:GetName()..prop]
+		frame:SetTexture("")
+	end
+	this:GetHighlightTexture():SetTexture("")
+	this.backdrop = CreateFrame("Frame", nil, this)
+	this.backdrop:SetStyle("!_Frame", "Default")
+	this.backdrop:SetFrameLevel(this:GetFrameLevel()-1)
+	this.backdrop:SetPoint("TOPLEFT", 3, -8)
+	this.backdrop:SetPoint("BOTTOMRIGHT", -6, 0)
+end
+
+local function ChannelList_OnUpdate()
+	for i = 1, MAX_DISPLAY_CHANNEL_BUTTONS do
+		local btn = _G["ChannelButton"..i]
+		if btn then
+			btn:RemoveTextures()
+			btn:SetHighlightTexture("Interface\\PaperDollInfoFrame\\UI-Character-Tab-Highlight")
+			_G["ChannelButton"..i.."Text"]:SetFontObject(SVUI_Font_Default)
+		end
+	end
+end
+--[[
+##########################################################
+FRIENDSFRAME MODR
+##########################################################
+]]--FriendsFrameBattlenetFrameScrollFrame
+local function FriendsFrameStyle()
+	--print('test FriendsFrameStyle')
+	if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.friends ~= true then
+		 return
+	end
+
+	SV.API:Set("Window", FriendsFrame)
+
+	FriendsFrameInset:RemoveTextures()
+	WhoFrameListInset:RemoveTextures()
+	WhoFrameEditBoxInset:RemoveTextures()
+	SV.API:Set("EditBox", WhoFrameEditBoxInset)
+	ChannelFrameRightInset:RemoveTextures()
+	ChannelFrameLeftInset:RemoveTextures()
+	ChannelFrameRightInset:SetStyle("!_Frame", "Model")
+	ChannelFrameLeftInset:SetStyle("!_Frame", "Model")
+	LFRQueueFrameListInset:RemoveTextures()
+	LFRQueueFrameRoleInset:RemoveTextures()
+	LFRQueueFrameCommentInset:RemoveTextures()
+	LFRQueueFrameListInset:SetStyle("!_Frame", "Model")
+	FriendsFrameInset:SetStyle("!_Frame", "Model")
+	--FriendsFrameFriendsScrollFrame:SetStyle("!_Frame", "Model")
+	WhoFrameListInset:SetStyle("!_Frame", "Model")
+	--RaidFrame:SetStyle("!_Frame", "Model")
+
+	for _, frame in pairs(FriendsFrameButtons)do
+		if(_G[frame]) then
+			_G[frame]:SetStyle("Button")
+		end
+	end
+
+	-- for c, texture in pairs(FriendsFrameList2)do
+	-- 	 _G[texture]:Die()
+	-- end
+
+	for _, frame in pairs(FriendsFrameList1) do
+		if(_G[frame]) then
+			_G[frame]:RemoveTextures(true)
+		end
+	end
+
+	for i = 1, FriendsFrame:GetNumRegions()do
+		local a1 = select(i, FriendsFrame:GetRegions())
+		if a1:GetObjectType() == "Texture"then
+			a1:SetTexture("")
+			a1:SetAlpha(0)
+		end
+	end
+
+	FriendsFrameFriendsScrollFrame:DisableDrawLayer("BACKGROUND")
+
+	SV.API:Set("ScrollBar", FriendsFrameFriendsScrollFrame, 5)
+	SV.API:Set("ScrollBar", WhoListScrollFrame, 5)
+	SV.API:Set("ScrollBar", ChannelRosterScrollFrame, 5)
+
+	FriendsFrameStatusDropDown:SetPoint('TOPLEFT', FriendsTabHeader, 'TOPLEFT', 0, -27)
+	SV.API:Set("DropDown", FriendsFrameStatusDropDown, 70)
+	FriendsFrameBattlenetFrame:RemoveTextures()
+	FriendsFrameBattlenetFrame:SetHeight(22)
+	FriendsFrameBattlenetFrame:SetPoint('TOPLEFT', FriendsFrameStatusDropDown, 'TOPRIGHT', 0, -1)
+	FriendsFrameBattlenetFrame:SetStyle("!_Frame", "Inset")
+	FriendsFrameBattlenetFrame:SetBackdropColor(0,0,0,0.8)
+
+	-- FriendsFrameBattlenetFrame.BroadcastButton:GetNormalTexture():SetTexCoord(.28, .72, .28, .72)
+	-- FriendsFrameBattlenetFrame.BroadcastButton:GetPushedTexture():SetTexCoord(.28, .72, .28, .72)
+	-- FriendsFrameBattlenetFrame.BroadcastButton:GetHighlightTexture():SetTexCoord(.28, .72, .28, .72)
+	FriendsFrameBattlenetFrame.BroadcastButton:RemoveTextures()
+	FriendsFrameBattlenetFrame.BroadcastButton:SetSize(22,22)
+	FriendsFrameBattlenetFrame.BroadcastButton:SetPoint('TOPLEFT', FriendsFrameBattlenetFrame, 'TOPRIGHT', 8, 0)
+	FriendsFrameBattlenetFrame.BroadcastButton:SetStyle("Button")
+	FriendsFrameBattlenetFrame.BroadcastButton:SetBackdropColor(0.4,0.4,0.4)
+	FriendsFrameBattlenetFrame.BroadcastButton:SetNormalTexture([[Interface\FriendsFrame\UI-Toast-BroadcastIcon]])
+	FriendsFrameBattlenetFrame.BroadcastButton:SetPushedTexture([[Interface\FriendsFrame\UI-Toast-BroadcastIcon]])
+	FriendsFrameBattlenetFrame.BroadcastButton:SetScript('OnClick', function()
+		SV:StaticPopup_Show("SET_BN_BROADCAST")
+	end)
+	FriendsFrameBattlenetFrame.Tag:SetFontObject(SVUI_Font_Narrator)
+	AddFriendNameEditBox:SetStyle("Editbox")
+	AddFriendFrame:SetStyle("!_Frame", "Transparent", true)
+	ScrollOfResurrectionSelectionFrame:SetStyle("!_Frame", 'Transparent')
+	ScrollOfResurrectionSelectionFrameList:SetStyle("!_Frame", 'Default')
+	SV.API:Set("ScrollBar", ScrollOfResurrectionSelectionFrameListScrollFrame, 4)
+	ScrollOfResurrectionSelectionFrameTargetEditBox:SetStyle("Editbox")
+	FriendsFrameBroadcastInput:SetStyle("Frame", "Default")
+	ChannelFrameDaughterFrameChannelName:SetStyle("Frame", "Default")
+	ChannelFrameDaughterFrameChannelPassword:SetStyle("Frame", "Default")
+
+	ChannelFrame:HookScript("OnShow", function()
+		ChannelRosterScrollFrame:RemoveTextures()
+	end)
+
+	hooksecurefunc("FriendsFrame_OnEvent", function()
+		ChannelRosterScrollFrame:RemoveTextures()
+	end)
+
+	WhoFrame:HookScript("OnShow", function()
+		ChannelRosterScrollFrame:RemoveTextures()
+	end)
+
+	hooksecurefunc("FriendsFrame_OnEvent", function()
+		WhoListScrollFrame:RemoveTextures()
+	end)
+
+	ChannelFrameDaughterFrame:SetStyle("Frame", 'Inset')
+	SV.API:Set("CloseButton", ChannelFrameDaughterFrameDetailCloseButton, ChannelFrameDaughterFrame)
+	SV.API:Set("CloseButton", FriendsFrameCloseButton, FriendsFrame.Panel)
+	SV.API:Set("DropDown", WhoFrameDropDown, 150)
+
+	for i = 1, 4 do
+		 SV.API:Set("Tab", _G["FriendsFrameTab"..i])
+	end
+
+	for i = 1, 3 do
+		 TabCustomHelper(_G["FriendsTabHeaderTab"..i])
+	end
+
+	hooksecurefunc("ChannelList_Update", ChannelList_OnUpdate)
+	FriendsFriendsFrame:SetStyle("Frame", 'Inset')
+
+	_G["FriendsFriendsFrame"]:RemoveTextures()
+	_G["FriendsFriendsList"]:RemoveTextures()
+	--_G["FriendsFriendsNoteFrame"]:RemoveTextures()
+
+	_G["FriendsFriendsSendRequestButton"]:SetStyle("Button")
+	_G["FriendsFriendsCloseButton"]:SetStyle("Button")
+
+	FriendsFriendsList:SetStyle("Editbox")
+	--FriendsFriendsNoteFrame:SetStyle("Editbox")
+	SV.API:Set("DropDown", FriendsFriendsFrameDropDown, 150)
+
+
+	--BNConversationInviteDialog:RemoveTextures()
+	--BNConversationInviteDialog:SetStyle("Frame", 'Transparent')
+	--BNConversationInviteDialogList:RemoveTextures()
+	--BNConversationInviteDialogList:SetStyle("!_Frame", 'Default')
+	--BNConversationInviteDialogInviteButton:SetStyle("Button")
+	--BNConversationInviteDialogCancelButton:SetStyle("Button")
+	--for i = 1, BN_CONVERSATION_INVITE_NUM_DISPLAYED do
+	--	 _G["BNConversationInviteDialogListFriend"..i].checkButton:SetStyle("CheckButton")
+	--end
+	FriendsTabHeaderSoRButton:SetStyle("!_Frame", 'Default')
+	FriendsTabHeaderSoRButton:SetStyle("Button")
+	FriendsTabHeaderSoRButtonIcon:SetDrawLayer('OVERLAY')
+	FriendsTabHeaderSoRButtonIcon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+	FriendsTabHeaderSoRButtonIcon:InsetPoints()
+	FriendsTabHeaderSoRButton:SetPoint('TOPRIGHT', FriendsTabHeader, 'TOPRIGHT', -8, -56)
+	FriendsTabHeaderRecruitAFriendButton:SetStyle("!_Frame", 'Default')
+	FriendsTabHeaderRecruitAFriendButton:SetStyle("Button")
+	FriendsTabHeaderRecruitAFriendButtonIcon:SetDrawLayer('OVERLAY')
+	FriendsTabHeaderRecruitAFriendButtonIcon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+	FriendsTabHeaderRecruitAFriendButtonIcon:InsetPoints()
+
+	FriendsFrameIgnoreScrollFrame:SetStyle("!_Frame", "Model")
+	SV.API:Set("ScrollBar", FriendsFrameIgnoreScrollFrame, 4)
+	FriendsFramePendingScrollFrame:SetStyle("!_Frame", "Inset")
+	SV.API:Set("ScrollBar", FriendsFramePendingScrollFrame, 4)
+	IgnoreListFrame:RemoveTextures()
+	PendingListFrame:RemoveTextures()
+	ScrollOfResurrectionFrame:RemoveTextures()
+	ScrollOfResurrectionFrameAcceptButton:SetStyle("Button")
+	ScrollOfResurrectionFrameCancelButton:SetStyle("Button")
+	ScrollOfResurrectionFrameTargetEditBoxLeft:SetTexture("")
+	ScrollOfResurrectionFrameTargetEditBoxMiddle:SetTexture("")
+	ScrollOfResurrectionFrameTargetEditBoxRight:SetTexture("")
+	ScrollOfResurrectionFrameNoteFrame:RemoveTextures()
+	ScrollOfResurrectionFrameNoteFrame:SetStyle("!_Frame")
+	ScrollOfResurrectionFrameTargetEditBox:SetStyle("!_Frame")
+	ScrollOfResurrectionFrame:SetStyle("!_Frame", 'Transparent')
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveCustomStyle(FriendsFrameStyle)
\ No newline at end of file
diff --git a/SVUI_Skins/components/blizzard/garrison.lua b/SVUI_Skins/components/blizzard/garrison.lua
new file mode 100644
index 0000000..052ce1e
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/garrison.lua
@@ -0,0 +1,660 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+local ipairs  = _G.ipairs;
+local pairs   = _G.pairs;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+HELPERS
+##########################################################
+]]--
+local RING_TEXTURE = [[Interface\AddOns\SVUI_Skins\artwork\FOLLOWER-RING]]
+local LVL_TEXTURE = [[Interface\AddOns\SVUI_Skins\artwork\FOLLOWER-LEVEL]]
+local DEFAULT_COLOR = {r = 0.25, g = 0.25, b = 0.25};
+--[[
+##########################################################
+STYLE
+##########################################################
+]]--
+local function AddFadeBanner(frame)
+	local bg = frame:CreateTexture(nil, "OVERLAY")
+	bg:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, 0)
+	bg:SetPoint("BOTTOMRIGHT", frame, "RIGHT", 0, 0)
+	bg:SetColorTexture(1, 1, 1, 1)
+	bg:SetGradientAlpha("VERTICAL", 0, 0, 0, 0, 0, 0, 0, 0.9)
+end
+
+local function StyleTextureIcon(frame)
+	if((not frame) or (not frame.Texture)) then return end
+	frame.Texture:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+	if(not frame.IconSlot) then
+		frame.IconSlot = CreateFrame("Frame", nil, frame)
+		frame.IconSlot:WrapPoints(frame.Texture)
+		frame.IconSlot:SetStyle("Icon")
+		frame.Texture:SetParent(frame.IconSlot)
+	end
+end
+
+local function StyleIconElement(frame)
+	if(not frame) then return end
+	if(frame.Icon) then
+    	local size = frame:GetHeight() - 6
+    	if(not frame.IconSlot) then
+    		local texture = frame.Icon:GetTexture()
+			frame:RemoveTextures()
+			frame.IconSlot = CreateFrame("Frame", nil, frame)
+			frame.IconSlot:WrapPoints(frame.Icon)
+			frame.IconSlot:SetStyle("Icon")
+			frame.Icon:SetParent(frame.IconSlot)
+			frame.Icon:SetTexture(texture)
+		end
+		frame.Icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+		frame.Icon:ClearAllPoints()
+		frame.Icon:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -3, -3)
+		frame.Icon:SetSize(size, size)
+		frame.Icon:SetDesaturated(false)
+		frame.Icon:SetDrawLayer("ARTWORK", -1)
+		if(frame.Quantity) then
+	    	frame.Quantity:SetFontObject(SVUI_Font_Number)
+	        frame.Quantity:SetParent(frame.IconSlot)
+	    end
+    end
+end
+
+local function _hook_GarrisonMissionFrame_SetItemRewardDetails(item)
+	if(not item) then return; end
+    if(item.Icon) then
+    	local size = item:GetHeight() - 8
+    	local texture = item.Icon:GetTexture()
+		item:RemoveTextures()
+    	item:SetStyle("Inset")
+    	item.Icon:SetTexture(texture)
+		item.Icon:ClearAllPoints()
+		item.Icon:SetPoint("TOPLEFT", item, "TOPLEFT", 4, -4)
+		item.Icon:SetSize(size, size)
+		item.Icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+		item.Icon:SetDesaturated(false)
+		if(not item.IconSlot) then
+			item.IconSlot = CreateFrame("Frame", nil, item)
+			item.IconSlot:SetAllPoints(item.Icon)
+			item.IconSlot:SetStyle("Icon")
+			item.Icon:SetParent(item.IconSlot)
+		end
+		item.Icon:SetDrawLayer("ARTWORK", -1)
+    end
+    if(item.Quantity) then
+    	item.Quantity:SetFontObject(SVUI_Font_Number)
+        item.Quantity:SetDrawLayer("ARTWORK", 1)
+    end
+end
+
+local function StyleAbilityIcon(frame)
+	if(not frame) then return; end
+    if(frame.Icon) then
+    	local texture = frame.Icon:GetTexture()
+    	local size = frame:GetHeight() - 2
+    	frame:RemoveTextures()
+    	frame.Icon:SetTexture(texture)
+		frame.Icon:ClearAllPoints()
+		frame.Icon:SetPoint("TOPLEFT", frame, "TOPLEFT", 1, -1)
+		frame.Icon:SetSize(size, size)
+		frame.Icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+		frame.Icon:SetDesaturated(false)
+		if(not frame.IconSlot) then
+			frame.IconSlot = CreateFrame("Frame", nil, frame)
+			frame.IconSlot:WrapPoints(frame.Icon)
+			frame.IconSlot:SetStyle("Icon")
+			frame.Icon:SetParent(frame.IconSlot)
+		end
+    end
+end
+
+local function StyleFollowerPortrait(frame, color)
+	frame.PortraitRing:SetTexture('')
+	frame.PortraitRingQuality:SetTexture(RING_TEXTURE)
+end
+
+local _hook_GarrisonCapacitiveDisplayFrame_Update = function(self)
+	local reagents = GarrisonCapacitiveDisplayFrame.CapacitiveDisplay.Reagents;
+    for i = 1, #reagents do
+    	if(reagents[i] and (not reagents[i].Panel)) then
+    		reagents[i]:RemoveTextures()
+        	reagents[i]:SetStyle("Icon")
+        	if(reagents[i].Icon) then
+				reagents[i].Icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+			end
+		end
+    end
+end
+
+local _hook_GarrisonBuildingTab_Select = function()
+	local list = GarrisonBuildingFrame.BuildingList;
+	for i=1, GARRISON_NUM_BUILDING_SIZES do
+		local tab = list["Tab"..i];
+		if(tab and tab.buildings) then
+			for i=1, #tab.buildings do
+				_hook_GarrisonMissionFrame_SetItemRewardDetails(list.Buttons[i])
+			end
+		end
+	end
+end
+
+local _hook_GarrisonFollowerList_Update = function(self)
+    local buttons = self.FollowerList.listScroll.buttons;
+    local followers = self.FollowerList.followers;
+    local followersList = self.FollowerList.followersList;
+    local numFollowers = #followersList;
+    local scrollFrame = self.FollowerList.listScroll;
+    local offset = HybridScrollFrame_GetOffset(scrollFrame);
+    local numButtons = #buttons;
+
+    for i = 1, numButtons do
+        local button = buttons[i];
+        local index = offset + i;
+        if(index <= numFollowers) then
+        	local follower = followers[followersList[index]];
+	        if(not button.Panel) then
+	            button:RemoveTextures()
+	            button:SetStyle("Frame", 'Blackout', true, 1, 0, 0)
+				if(button.XPBar) then
+					button.XPBar:SetTexture(SV.media.statusbar.default)
+					button.XPBar:SetGradient('HORIZONTAL', 0.5, 0, 1, 1, 0, 1)
+				end
+	        end
+	        if(button.PortraitFrame) then
+	        	local color
+		        if(follower.isCollected) then
+	            	color = ITEM_QUALITY_COLORS[follower.quality]
+	            else
+	            	color = DEFAULT_COLOR
+				end
+				StyleFollowerPortrait(button.PortraitFrame, color)
+			end
+	    end
+    end
+end
+
+local _hook_GarrisonFollowerTooltipTemplate_SetGarrisonFollower = function(tooltip, data)
+	local color = ITEM_QUALITY_COLORS[data.quality];
+	StyleFollowerPortrait(tooltip.Portrait, color)
+end
+
+local _hook_GarrisonBuildingInfoBox_ShowFollowerPortrait = function(owned, hasFollowerSlot, infoBox, isBuilding, canActivate, ID)
+	local portraitFrame = infoBox.FollowerPortrait;
+	StyleFollowerPortrait(portraitFrame)
+end
+
+local _hook_GarrisonMissionFrame_SetFollowerPortrait = function(portraitFrame, followerInfo)
+	local color = ITEM_QUALITY_COLORS[followerInfo.quality];
+	StyleFollowerPortrait(portraitFrame, color)
+end
+
+local _hook_GarrisonRecruitSelectFrame_UpdateRecruits = function()
+	local recruitFrame = GarrisonRecruitSelectFrame.FollowerSelection;
+	local followers = C_Garrison.GetAvailableRecruits();
+	for i=1, 3 do
+		local follower = followers[i];
+		local frame = recruitFrame["Recruit"..i];
+		if(follower)then
+			local color = ITEM_QUALITY_COLORS[follower.quality];
+			StyleFollowerPortrait(frame.PortraitFrame, color);
+		end
+	end
+end
+
+local _hook_GarrisonMissionComplete_SetFollowerLevel = function(followerFrame, level, quality)
+	if(not followerFrame or (not followerFrame.PortraitFrame)) then return end
+	local color = ITEM_QUALITY_COLORS[quality];
+	followerFrame.PortraitFrame.PortraitRing:SetVertexColor(color.r, color.g, color.b)
+end
+
+local function _hook_GarrisonFollowerButton_SetCounterButton(self, index, info)
+	local counter = self.Counters[index];
+	StyleAbilityIcon(counter)
+end
+
+local function _hook_GarrisonFollowerButton_AddAbility(self, index, ability)
+	local ability = self.Abilities[index];
+	StyleAbilityIcon(ability)
+end
+
+local _hook_GarrisonFollowerPage_ShowFollower = function(self, followerID)
+	local followerInfo = C_Garrison.GetFollowerInfo(followerID);
+    if(not self.XPBar.Panel) then
+	    self.XPBar:RemoveTextures()
+		self.XPBar:SetStatusBarTexture(SV.media.statusbar.default)
+		self.XPBar:SetStyle("!_Frame", "Bar")
+	end
+
+    for i=1, #self.AbilitiesFrame.Abilities do
+        local abilityFrame = self.AbilitiesFrame.Abilities[i];
+        StyleAbilityIcon(abilityFrame.IconButton)
+    end
+
+    for i=1, #self.AbilitiesFrame.Counters do
+        local abilityFrame = self.AbilitiesFrame.Counters[i];
+        StyleAbilityIcon(abilityFrame)
+    end
+end
+
+local _hook_GarrisonFollowerPage_UpdateMissionForParty = function(self, followerID)
+	local MISSION_PAGE_FRAME = GarrisonMissionFrame.MissionTab.MissionPage;
+	local totalTimeString, totalTimeSeconds, isMissionTimeImproved, successChance, partyBuffs, isEnvMechanicCountered, xpBonus, materialMultiplier = C_Garrison.GetPartyMissionInfo(MISSION_PAGE_FRAME.missionInfo.missionID);
+	-- for i = 1, #MISSION_PAGE_FRAME.Enemies do
+	-- 	local enemyFrame = MISSION_PAGE_FRAME.Enemies[i];
+	-- 	for mechanicIndex = 1, #enemyFrame.Mechanics do
+	-- 		local mechanic = enemyFrame.Mechanics[mechanicIndex];
+	--         StyleAbilityIcon(mechanic)
+	-- 	end
+	-- end
+	-- PARTY BOOFS
+	local buffsFrame = MISSION_PAGE_FRAME.BuffsFrame;
+	local buffCount = #partyBuffs;
+	if(buffCount > 0) then
+		for i = 1, buffCount do
+			local buff = buffsFrame.Buffs[i];
+			StyleAbilityIcon(buff)
+		end
+	end
+end
+
+local function StyleRewardButtons(rewardButtons)
+    for i = 1, #rewardButtons do
+        local frame = rewardButtons[i];
+				_hook_GarrisonMissionFrame_SetItemRewardDetails(frame);
+    end
+end
+
+local function StyleListButtons(parent)
+	if(not parent) then return end
+	local listButtons = parent.Rewards
+	SV.API:Set("ItemButton", parent)
+	if(parent.LocBG) then
+		parent.LocBG:SetDrawLayer("ARTWORK", -2)
+	end
+    for i = 1, #listButtons do
+        StyleIconElement(listButtons[i])
+    end
+end
+
+local function StyleMissionComplete(parentFrame)
+	local mComplete = parentFrame.MissionComplete;
+	local mStage = mComplete.Stage;
+	local mFollowers = mStage.FollowersFrame;
+
+	mComplete:RemoveTextures()
+	mComplete:SetStyle("Frame", 'Paper', false, 4, 0, 0)
+	mStage:RemoveTextures()
+	mStage.MissionInfo:RemoveTextures()
+
+	if(mFollowers.Follower1 and mFollowers.Follower1.PortraitFrame) then
+		StyleFollowerPortrait(mFollowers.Follower1.PortraitFrame)
+	end
+	if(mFollowers.Follower2 and mFollowers.Follower2.PortraitFrame) then
+		StyleFollowerPortrait(mFollowers.Follower2.PortraitFrame)
+	end
+	if(mFollowers.Follower3 and mFollowers.Follower3.PortraitFrame) then
+		StyleFollowerPortrait(mFollowers.Follower3.PortraitFrame)
+	end
+
+	AddFadeBanner(mStage)
+	mComplete.NextMissionButton:RemoveTextures(true)
+	mComplete.NextMissionButton:SetStyle("Button")
+
+	local completedBG = CreateFrame("Frame", nil, parentFrame.MissionCompleteBackground)
+	completedBG:SetAllPoints(parentFrame.Panel)
+	local completedBGTex = completedBG:CreateTexture(nil, "BACKGROUND")
+	completedBGTex:SetAllPoints(completedBG)
+	completedBGTex:SetColorTexture(0,0,0,0.8)
+	parentFrame.MissionCompleteBackground:DisableDrawLayer("BACKGROUND")
+end
+
+local _hook_GarrisonMissionFrame_CheckRewardButtons = function(rewards)
+	StyleRewardButtons(rewards);
+end
+
+local function _hook_GarrisonMissionList_Update()
+	local self = GarrisonMissionFrame
+    local missionButtons = self.MissionTab.MissionList.listScroll.buttons;
+    for i = 1, #missionButtons do
+        StyleListButtons(missionButtons[i])
+    end
+    StyleRewardButtons(self.MissionTab.MissionPage.RewardsFrame.Rewards);
+    StyleRewardButtons(self.MissionComplete.BonusRewards.Rewards);
+end
+
+local _hook_GarrisonMissionButton_SetRewards = function(self, rewards, numRewards)
+	if (numRewards > 0) then
+		local index = 1;
+		for id, reward in pairs(rewards) do
+	        StyleIconElement(self.Rewards[index])
+		    index = index + 1;
+		end
+	end
+end
+
+local function LoadGarrisonStyle()
+	if SV.db.Skins.blizzard.enable ~= true then
+		return
+	end
+	--[[
+	##############################################################################
+	BUILDING FRAME
+	##############################################################################
+	--]]
+	SV.API:Set("Window", GarrisonBuildingFrame, true, false, 1, 0, 4)
+
+	GarrisonBuildingFrameFollowers:RemoveTextures()
+	GarrisonBuildingFrameFollowers:SetStyle("Frame", 'Inset', true, 1, -5, -5)
+	GarrisonBuildingFrameFollowers:ClearAllPoints()
+	GarrisonBuildingFrameFollowers:SetPoint("LEFT", GarrisonBuildingFrame, "LEFT", 10, 0)
+	GarrisonBuildingFrame.BuildingList:RemoveTextures()
+	GarrisonBuildingFrame.BuildingList:SetStyle("!_Frame", 'Inset')
+	GarrisonBuildingFrame.TownHallBox:RemoveTextures()
+	GarrisonBuildingFrame.TownHallBox:SetStyle("!_Frame", 'Inset')
+	GarrisonBuildingFrame.InfoBox:RemoveTextures()
+	GarrisonBuildingFrame.InfoBox:SetStyle("!_Frame", 'Inset')
+	--SV.API:Set("Tab", GarrisonBuildingFrame.BuildingList.Tab1)
+	GarrisonBuildingFrame.BuildingList.Tab1:GetNormalTexture().SetAtlas = function() return end
+	GarrisonBuildingFrame.BuildingList.Tab1:RemoveTextures(true)
+	GarrisonBuildingFrame.BuildingList.Tab1:SetStyle("Button", -4, -10)
+	--SV.API:Set("Tab", GarrisonBuildingFrame.BuildingList.Tab2)
+	GarrisonBuildingFrame.BuildingList.Tab2:GetNormalTexture().SetAtlas = function() return end
+	GarrisonBuildingFrame.BuildingList.Tab2:RemoveTextures(true)
+	GarrisonBuildingFrame.BuildingList.Tab2:SetStyle("Button", -4, -10)
+	--SV.API:Set("Tab", GarrisonBuildingFrame.BuildingList.Tab3)
+	GarrisonBuildingFrame.BuildingList.Tab3:GetNormalTexture().SetAtlas = function() return end
+	GarrisonBuildingFrame.BuildingList.Tab3:RemoveTextures(true)
+	GarrisonBuildingFrame.BuildingList.Tab3:SetStyle("Button", -4, -10)
+	GarrisonBuildingFrame.BuildingList.MaterialFrame:RemoveTextures()
+	GarrisonBuildingFrame.BuildingList.MaterialFrame:SetStyle("Frame", "Inset", true, 1, -5, -7)
+	GarrisonBuildingFrameTutorialButton:Die()
+
+	SV.API:Set("CloseButton", GarrisonBuildingFrame.CloseButton)
+
+	hooksecurefunc("GarrisonBuildingTab_Select", _hook_GarrisonBuildingTab_Select)
+  hooksecurefunc("GarrisonBuildingList_SelectTab", _hook_GarrisonBuildingTab_Select)
+  hooksecurefunc("GarrisonBuildingInfoBox_ShowFollowerPortrait", _hook_GarrisonBuildingInfoBox_ShowFollowerPortrait)
+	--[[
+	##############################################################################
+	LANDING PAGE
+	##############################################################################
+	--]]
+	SV.API:Set("Window", GarrisonLandingPage, true, false, 1, 0, 0)
+	SV.API:Set("Skin", GarrisonLandingPage.FollowerTab, 12, 0, -2, 30)
+
+	GarrisonLandingPage.FollowerTab.AbilitiesFrame:RemoveTextures()
+	GarrisonLandingPage.FollowerList:RemoveTextures()
+	GarrisonLandingPage.FollowerList:SetStyle("Frame", 'Inset', false, 4, 0, 0)
+
+	local bgFrameTop = CreateFrame("Frame", nil, GarrisonLandingPage.Report)
+	bgFrameTop:SetPoint("TOPLEFT", GarrisonLandingPage.Report, "TOPLEFT", 38, -91)
+	bgFrameTop:SetPoint("BOTTOMRIGHT", GarrisonLandingPage.Report.List, "BOTTOMLEFT", -4, 0)
+	bgFrameTop:SetStyle("Frame", "Paper")
+
+	GarrisonLandingPageReportList:RemoveTextures()
+	GarrisonLandingPageReportList:SetStyle("Frame", 'Inset', false, 4, 0, 0)
+	GarrisonLandingPageReport.Available:RemoveTextures(true)
+	GarrisonLandingPageReport.Available:SetStyle("Button")
+	GarrisonLandingPageReport.Available:GetNormalTexture().SetAtlas = function() return end
+	GarrisonLandingPageReport.InProgress:RemoveTextures(true)
+	GarrisonLandingPageReport.InProgress:SetStyle("Button")
+	GarrisonLandingPageReport.InProgress:GetNormalTexture().SetAtlas = function() return end
+
+	GarrisonLandingPageShipFollowerList:RemoveTextures()
+	GarrisonLandingPageShipFollowerList:SetStyle("Frame", 'Inset', false, 4, 0, 0)
+
+	for i = 1, GarrisonLandingPageReportListListScrollFrameScrollChild:GetNumChildren() do
+		local child = select(i, GarrisonLandingPageReportListListScrollFrameScrollChild:GetChildren())
+		for j = 1, child:GetNumChildren() do
+			local childC = select(j, child:GetChildren())
+			childC.Icon:SetTexCoord(0.1,0.9,0.1,0.9)
+			childC.Icon:SetDesaturated(false)
+		end
+	end
+
+	local a1, p, a2, x, y = GarrisonLandingPageTab1:GetPoint()
+	GarrisonLandingPageTab1:SetPoint(a1, p, a2, x, (y - 15))
+	SV.API:Set("Tab", GarrisonLandingPageTab1, nil, 10, 4)
+	SV.API:Set("Tab", GarrisonLandingPageTab2, nil, 10, 4)
+	SV.API:Set("Tab", GarrisonLandingPageTab3, nil, 10, 4)
+	SV.API:Set("ScrollBar", GarrisonLandingPageListScrollFrame)
+	SV.API:Set("ScrollBar", GarrisonLandingPageReportListListScrollFrame)
+	SV.API:Set("ScrollBar", GarrisonLandingPageShipFollowerListListScrollFrame)
+	SV.API:Set("CloseButton", GarrisonLandingPage.CloseButton)
+	GarrisonLandingPage.CloseButton:SetFrameStrata("HIGH")
+	--[[
+	##############################################################################
+	MISSION FRAME
+	##############################################################################
+	--]]
+	SV.API:Set("Window", GarrisonMissionFrame, true, false, 1, 0, 4)
+	GarrisonMissionFrame.GarrCorners:RemoveTextures()
+	GarrisonMissionFrameMissions:RemoveTextures()
+	GarrisonMissionFrameMissions:SetStyle("!_Frame", "Inset")
+
+	local readyBG = CreateFrame("Frame", nil, GarrisonMissionFrameMissions.CompleteDialog)
+	readyBG:SetAllPoints(GarrisonMissionFrame.Panel)
+	local readyBGTex = readyBG:CreateTexture(nil, "BACKGROUND")
+	readyBGTex:SetAllPoints(readyBG)
+	readyBGTex:SetColorTexture(0,0,0,0.8)
+
+	GarrisonMissionFrameMissions.CompleteDialog:DisableDrawLayer("BACKGROUND")
+	GarrisonMissionFrameMissions.CompleteDialog.BorderFrame:RemoveTextures()
+	GarrisonMissionFrameMissions.CompleteDialog.BorderFrame:SetStyle("Frame", 'Window', false, 4, 0, 0)
+	GarrisonMissionFrameMissions.CompleteDialog.BorderFrame.Stage:RemoveTextures()
+	GarrisonMissionFrameMissions.CompleteDialog.BorderFrame.Stage:SetStyle("!_Frame", "Model")
+	GarrisonMissionFrameMissions.CompleteDialog.BorderFrame.ViewButton:RemoveTextures(true)
+	GarrisonMissionFrameMissions.CompleteDialog.BorderFrame.ViewButton:SetStyle("Button")
+
+	GarrisonMissionFrameMissions.MaterialFrame:RemoveTextures()
+	GarrisonMissionFrameMissions.MaterialFrame:SetStyle("Frame", "Inset", true, 1, -3, -3)
+
+	GarrisonMissionFrame.FollowerTab.ItemWeapon:RemoveTextures()
+	_hook_GarrisonMissionFrame_SetItemRewardDetails(GarrisonMissionFrame.FollowerTab.ItemWeapon)
+	GarrisonMissionFrame.FollowerTab.ItemArmor:RemoveTextures()
+	_hook_GarrisonMissionFrame_SetItemRewardDetails(GarrisonMissionFrame.FollowerTab.ItemArmor)
+
+	GarrisonMissionFrame.MissionTab:RemoveTextures()
+	GarrisonMissionFrame.MissionTab.MissionPage:RemoveTextures()
+	GarrisonMissionFrame.MissionTab.MissionPage:SetStyle("Frame", 'Paper', false, 4, 0, 0)
+
+	local missionChance = GarrisonMissionFrame.MissionTab.MissionPage.RewardsFrame.Chance;
+	missionChance:SetFontObject(SVUI_Font_Number_Huge)
+	local chanceLabel = GarrisonMissionFrame.MissionTab.MissionPage.RewardsFrame.ChanceLabel
+	chanceLabel:SetFontObject(SVUI_Font_Header)
+	chanceLabel:ClearAllPoints()
+	chanceLabel:SetPoint("TOP", missionChance, "BOTTOM", 0, -8)
+
+	GarrisonMissionFrame.MissionTab.MissionPage.Panel:ClearAllPoints()
+	GarrisonMissionFrame.MissionTab.MissionPage.Panel:SetPoint("TOPLEFT", GarrisonMissionFrame.MissionTab.MissionPage, "TOPLEFT", 0, 4)
+	GarrisonMissionFrame.MissionTab.MissionPage.Panel:SetPoint("BOTTOMRIGHT", GarrisonMissionFrame.MissionTab.MissionPage, "BOTTOMRIGHT", 0, -20)
+
+	GarrisonMissionFrame.MissionTab.MissionPage.Stage:RemoveTextures()
+	StyleTextureIcon(GarrisonMissionFrame.MissionTab.MissionPage.Stage.MissionEnvIcon);
+	AddFadeBanner(GarrisonMissionFrame.MissionTab.MissionPage.Stage)
+	GarrisonMissionFrame.MissionTab.MissionPage.StartMissionButton:RemoveTextures(true)
+	GarrisonMissionFrame.MissionTab.MissionPage.StartMissionButton:SetStyle("Button")
+
+	GarrisonMissionFrameFollowers:RemoveTextures()
+	GarrisonMissionFrameFollowers:SetStyle("Frame", 'Inset', false, 4, 0, 0)
+	GarrisonMissionFrameFollowers.MaterialFrame:RemoveTextures()
+	GarrisonMissionFrameFollowers.MaterialFrame:SetStyle("Frame", "Inset", true, 1, -5, -7)
+
+	StyleMissionComplete(GarrisonMissionFrame)
+
+	local a1, p, a2, x, y = GarrisonMissionFrameMissionsTab1:GetPoint()
+	GarrisonMissionFrameMissionsTab1:SetPoint(a1, p, a2, x, (y + 8))
+	SV.API:Set("Tab", GarrisonMissionFrameTab1)
+	SV.API:Set("Tab", GarrisonMissionFrameTab2)
+	SV.API:Set("Tab", GarrisonMissionFrameMissionsTab1, nil, 10, 4)
+	SV.API:Set("Tab", GarrisonMissionFrameMissionsTab2, nil, 10, 4)
+	SV.API:Set("ScrollBar", GarrisonMissionFrameMissionsListScrollFrame)
+	SV.API:Set("ScrollBar", GarrisonMissionFrameFollowersListScrollFrame)
+	SV.API:Set("Skin", GarrisonMissionFrame.FollowerTab)
+	SV.API:Set("EditBox", GarrisonMissionFrameFollowers.SearchBox)
+	SV.API:Set("CloseButton", GarrisonMissionFrame.CloseButton)
+	SV.API:Set("CloseButton", GarrisonMissionFrame.MissionTab.MissionPage.CloseButton)
+	--SV.API:Set("Button", GarrisonMissionFrame.MissionTab.MissionPage.MinimizeButton)
+
+	_hook_GarrisonMissionList_Update()
+	--hooksecurefunc("GarrisonMissionList_Update", _hook_GarrisonMissionList_Update)
+	hooksecurefunc("GarrisonMissionFrame_SetItemRewardDetails", _hook_GarrisonMissionFrame_SetItemRewardDetails)
+ 	--hooksecurefunc("GarrisonMissionFrame_SetFollowerPortrait", _hook_GarrisonMissionFrame_SetFollowerPortrait)
+  	hooksecurefunc(GarrisonFollowerMissionComplete, "SetFollowerLevel", _hook_GarrisonMissionComplete_SetFollowerLevel)
+  	--hooksecurefunc(GarrisonMission, "UpdateMissionParty", _hook_GarrisonFollowerPage_UpdateMissionForParty)
+	hooksecurefunc("GarrisonMissionButton_SetRewards", _hook_GarrisonMissionButton_SetRewards)
+  	--hooksecurefunc("GarrisonMissionFrame_CheckRewardButtons", _hook_GarrisonMissionFrame_CheckRewardButtons)
+	--[[
+	##############################################################################
+	CAPACITIVE DISPLAY
+	##############################################################################
+	--]]
+	SV.API:Set("Window", GarrisonCapacitiveDisplayFrame, true, false, 1, 0, 4)
+
+	--GarrisonCapacitiveDisplayFrame:RemoveTextures(true)
+	--GarrisonCapacitiveDisplayFrame:SetStyle("Frame", "Window2")
+	GarrisonCapacitiveDisplayFrameInset:RemoveTextures(true)
+	GarrisonCapacitiveDisplayFrame.CapacitiveDisplay:RemoveTextures(true)
+	GarrisonCapacitiveDisplayFrame.CapacitiveDisplay:SetStyle("Frame", 'Transparent')
+	GarrisonCapacitiveDisplayFrame.CapacitiveDisplay.ShipmentIconFrame:SetStyle("Icon")
+	GarrisonCapacitiveDisplayFrame.CapacitiveDisplay.ShipmentIconFrame.Icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+
+	local reagents = GarrisonCapacitiveDisplayFrame.CapacitiveDisplay.Reagents;
+  for i = 1, #reagents do
+  	if(reagents[i]) then
+  		reagents[i]:RemoveTextures()
+      reagents[i]:SetStyle("Icon")
+      if(reagents[i].Icon) then
+				reagents[i].Icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+			end
+		end
+  end
+
+	if(GarrisonCapacitiveDisplayFrame.StartWorkOrderButton) then
+		GarrisonCapacitiveDisplayFrame.StartWorkOrderButton:RemoveTextures(true)
+		GarrisonCapacitiveDisplayFrame.StartWorkOrderButton:SetStyle("Button")
+	end
+
+	if(GarrisonCapacitiveDisplayFrame.CreateAllWorkOrdersButton) then
+		GarrisonCapacitiveDisplayFrame.CreateAllWorkOrdersButton:RemoveTextures(true)
+		GarrisonCapacitiveDisplayFrame.CreateAllWorkOrdersButton:SetStyle("Button")
+		SV.API:Set("PageButton", GarrisonCapacitiveDisplayFrame.DecrementButton, false, true)
+		SV.API:Set("EditBox", GarrisonCapacitiveDisplayFrame.Count)
+		SV.API:Set("PageButton", GarrisonCapacitiveDisplayFrame.IncrementButton)
+	end
+	GarrisonCapacitiveDisplayFrame.CapacitiveDisplay.FollowerActive:ClearAllPoints()
+	GarrisonCapacitiveDisplayFrame.CapacitiveDisplay.FollowerActive:SetPoint("TOP", GarrisonCapacitiveDisplayFrame, "TOP", 0, -32)
+	hooksecurefunc("GarrisonCapacitiveDisplayFrame_Update", _hook_GarrisonCapacitiveDisplayFrame_Update)
+	SV.NPC:Register(GarrisonCapacitiveDisplayFrame, GarrisonCapacitiveDisplayFrameTitleText)
+	GarrisonCapacitiveDisplayFrame.StartWorkOrderButton:HookScript('OnClick', function() SV.NPC:PlayerTalksFirst() end)
+	--[[
+	##############################################################################
+	RECRUITER FRAME
+	##############################################################################
+	--]]
+	SV.API:Set("Window", GarrisonRecruiterFrame, true)
+	SV.API:Set("Window", GarrisonRecruitSelectFrame, true)
+
+	GarrisonRecruiterFrameInset:RemoveTextures()
+	GarrisonRecruiterFrameInset:SetStyle("!_Frame", "Inset")
+	GarrisonRecruiterFrame.Pick.Radio1:SetStyle("!_CheckButton", false, -3, -3, true)
+	GarrisonRecruiterFrame.Pick.Radio2:SetStyle("!_CheckButton", false, -3, -3, true)
+	GarrisonRecruiterFrame.PortraitTexture:Die()
+
+	GarrisonRecruitSelectFrame.FollowerSelection:RemoveTextures()
+	GarrisonRecruitSelectFrame.FollowerList:RemoveTextures()
+	GarrisonRecruitSelectFrame.FollowerList:SetStyle("Frame", 'Inset', false, 4, 0, 0)
+	GarrisonRecruitSelectFrame.FollowerSelection.Recruit1:RemoveTextures()
+	GarrisonRecruitSelectFrame.FollowerSelection.Recruit2:RemoveTextures()
+	GarrisonRecruitSelectFrame.FollowerSelection.Recruit3:RemoveTextures()
+	GarrisonRecruitSelectFrame.FollowerSelection.Recruit1:SetStyle("Frame", 'Inset')
+	GarrisonRecruitSelectFrame.FollowerSelection.Recruit2:SetStyle("Frame", 'Inset')
+	GarrisonRecruitSelectFrame.FollowerSelection.Recruit3:SetStyle("Frame", 'Inset')
+
+	StyleFollowerPortrait(GarrisonRecruitSelectFrame.FollowerSelection.Recruit1.PortraitFrame)
+	StyleFollowerPortrait(GarrisonRecruitSelectFrame.FollowerSelection.Recruit2.PortraitFrame)
+	StyleFollowerPortrait(GarrisonRecruitSelectFrame.FollowerSelection.Recruit3.PortraitFrame)
+
+	GarrisonRecruitSelectFrame.FollowerSelection.Recruit1.HireRecruits:SetStyle("Button")
+	GarrisonRecruitSelectFrame.FollowerSelection.Recruit2.HireRecruits:SetStyle("Button")
+	GarrisonRecruitSelectFrame.FollowerSelection.Recruit3.HireRecruits:SetStyle("Button")
+
+	SV.API:Set("DropDown", GarrisonRecruiterFramePickThreatDropDown)
+	SV.API:Set("CloseButton", GarrisonRecruiterFrame.CloseButton)
+	SV.API:Set("CloseButton", GarrisonRecruitSelectFrame.CloseButton)
+	SV.API:Set("Button", GarrisonRecruiterFrame.Pick.ChooseRecruits)
+	SV.API:Set("Button", GarrisonRecruiterFrame.Random.ChooseRecruits)
+
+	hooksecurefunc("GarrisonRecruitSelectFrame_UpdateRecruits", _hook_GarrisonRecruitSelectFrame_UpdateRecruits)
+	--[[
+	##############################################################################
+	SHIPYARD FRAME
+	##############################################################################
+	--]]
+	SV.API:Set("Window", GarrisonShipyardFrame, true)
+	GarrisonShipyardFrame.BorderFrame:RemoveTextures()
+	GarrisonShipyardFrame.BorderFrame.GarrCorners:RemoveTextures()
+	SV.API:Set("CloseButton", GarrisonShipyardFrame.BorderFrame.CloseButton2)
+	GarrisonShipyardFrame.FollowerList:RemoveTextures()
+	GarrisonShipyardFrame.FollowerList:SetStyle("Frame", 'Inset', false, 4, 0, 0)
+	GarrisonShipyardFrame.FollowerList.MaterialFrame:RemoveTextures()
+	GarrisonShipyardFrame.FollowerList.MaterialFrame:SetStyle("Frame", "Inset", true, 1, -5, -7)
+	GarrisonShipyardFrame.MissionTab:RemoveTextures()
+	GarrisonShipyardFrame.MissionTab.MissionPage:RemoveTextures()
+	GarrisonShipyardFrame.MissionTab.MissionPage:SetStyle("Frame", 'Paper', false, 4, 0, 0)
+	GarrisonShipyardFrame.MissionTab.MissionPage.Panel:ClearAllPoints()
+	GarrisonShipyardFrame.MissionTab.MissionPage.Panel:SetPoint("TOPLEFT", GarrisonShipyardFrame.MissionTab.MissionPage, "TOPLEFT", 0, 4)
+	GarrisonShipyardFrame.MissionTab.MissionPage.Panel:SetPoint("BOTTOMRIGHT", GarrisonShipyardFrame.MissionTab.MissionPage, "BOTTOMRIGHT", 0, -20)
+
+	GarrisonShipyardFrame.MissionTab.MissionList.CompleteDialog:DisableDrawLayer("BACKGROUND")
+	GarrisonShipyardFrame.MissionTab.MissionList.CompleteDialog.BorderFrame:RemoveTextures()
+	GarrisonShipyardFrame.MissionTab.MissionList.CompleteDialog.BorderFrame:SetStyle("Frame", 'Window', false, 4, 0, 0)
+	GarrisonShipyardFrame.MissionTab.MissionList.CompleteDialog.BorderFrame.Stage:RemoveTextures()
+	GarrisonShipyardFrame.MissionTab.MissionList.CompleteDialog.BorderFrame.Stage:SetStyle("!_Frame", "Model")
+	GarrisonShipyardFrame.MissionTab.MissionList.CompleteDialog.BorderFrame.ViewButton:RemoveTextures(true)
+	GarrisonShipyardFrame.MissionTab.MissionList.CompleteDialog.BorderFrame.ViewButton:SetStyle("Button")
+
+	SV.API:Set("CloseButton", GarrisonShipyardFrame.MissionTab.MissionPage.CloseButton)
+	GarrisonShipyardFrame.MissionTab.MissionPage.StartMissionButton:RemoveTextures(true)
+	GarrisonShipyardFrame.MissionTab.MissionPage.StartMissionButton:SetStyle("Button")
+
+	GarrisonShipyardFrame.MissionTab.MissionList:SetStyle("Frame", 'Paper', false, 4, 0, 0)
+	GarrisonShipyardFrame.FollowerTab:RemoveTextures()
+
+	SV.API:Set("ScrollBar", GarrisonShipyardFrameFollowersListScrollFrame)
+	SV.API:Set("Skin", GarrisonShipyardFrame.FollowerTab, 12, 0, -2, 30)
+	SV.API:Set("EditBox", GarrisonShipyardFrameFollowers.SearchBox)
+
+	StyleMissionComplete(GarrisonShipyardFrame)
+	SV.API:Set("Tab",GarrisonShipyardFrameTab1)
+	SV.API:Set("Tab",GarrisonShipyardFrameTab2)
+	--[[
+	##############################################################################
+	FOLLOWER HOOKS
+	##############################################################################
+	--]]
+	--hooksecurefunc("GarrisonFollowerList_Update", _hook_GarrisonFollowerList_Update)
+	--hooksecurefunc("GarrisonFollowerPage_ShowFollower", _hook_GarrisonFollowerPage_ShowFollower)
+	--hooksecurefunc("GarrisonFollowerButton_AddAbility", _hook_GarrisonFollowerButton_AddAbility)
+  	--hooksecurefunc("GarrisonFollowerButton_SetCounterButton", _hook_GarrisonFollowerButton_SetCounterButton)
+	--hooksecurefunc("GarrisonFollowerTooltipTemplate_SetGarrisonFollower", _hook_GarrisonFollowerTooltipTemplate_SetGarrisonFollower)
+	--print('GARRISON DONE')
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveBlizzardStyle("Blizzard_GarrisonUI", LoadGarrisonStyle)
diff --git a/SVUI_Skins/components/blizzard/guild.lua b/SVUI_Skins/components/blizzard/guild.lua
new file mode 100644
index 0000000..52b9064
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/guild.lua
@@ -0,0 +1,772 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  	= _G.unpack;
+local select  	= _G.select;
+local ipairs  	= _G.ipairs;
+local pairs   	= _G.pairs;
+local next    	= _G.next;
+local time 		= _G.time;
+local date 		= _G.date;
+local ceil, modf = math.ceil, math.modf;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+HELPERS
+##########################################################
+]]--
+local format = string.format;
+local internalTest = false;
+
+local GuildFrameList = {
+	"GuildNewPerksFrame",
+	"GuildFrameInset",
+	"GuildFrameBottomInset",
+	"GuildAllPerksFrame",
+	"GuildMemberDetailFrame",
+	"GuildMemberNoteBackground",
+	"GuildInfoFrameInfo",
+	"GuildLogContainer",
+	"GuildLogFrame",
+	"GuildRewardsFrame",
+	"GuildMemberOfficerNoteBackground",
+	"GuildTextEditContainer",
+	"GuildTextEditFrame",
+	"GuildRecruitmentRolesFrame",
+	"GuildRecruitmentAvailabilityFrame",
+	"GuildRecruitmentInterestFrame",
+	"GuildRecruitmentLevelFrame",
+	"GuildRecruitmentCommentFrame",
+	"GuildRecruitmentCommentInputFrame",
+	"GuildInfoFrameApplicantsContainer",
+	"GuildInfoFrameApplicants",
+	"GuildNewsBossModel",
+	"GuildNewsBossModelTextFrame"
+};
+
+local GuildButtonList = {
+	"GuildPerksToggleButton",
+	"GuildMemberRemoveButton",
+	"GuildMemberGroupInviteButton",
+	"GuildAddMemberButton",
+	"GuildViewLogButton",
+	"GuildControlButton",
+	"GuildRecruitmentListGuildButton",
+	"GuildTextEditFrameAcceptButton",
+	"GuildRecruitmentInviteButton",
+	"GuildRecruitmentMessageButton",
+	"GuildRecruitmentDeclineButton"
+};
+
+local GuildCheckBoxList = {
+	"GuildRecruitmentQuestButton",
+	"GuildRecruitmentDungeonButton",
+	"GuildRecruitmentRaidButton",
+	"GuildRecruitmentPvPButton",
+	"GuildRecruitmentRPButton",
+	"GuildRecruitmentWeekdaysButton",
+	"GuildRecruitmentWeekendsButton",
+	"GuildRecruitmentLevelAnyButton",
+	"GuildRecruitmentLevelMaxButton"
+};
+
+local CalendarIconList = {
+	[CALENDAR_EVENTTYPE_PVP] = "Interface\\Calendar\\UI-Calendar-Event-PVP",
+	[CALENDAR_EVENTTYPE_MEETING] = "Interface\\Calendar\\MeetingIcon",
+	[CALENDAR_EVENTTYPE_OTHER] = "Interface\\Calendar\\UI-Calendar-Event-Other"
+};
+
+local LFGFrameList = {
+  "LookingForGuildPvPButton",
+  "LookingForGuildWeekendsButton",
+  "LookingForGuildWeekdaysButton",
+  "LookingForGuildRPButton",
+  "LookingForGuildRaidButton",
+  "LookingForGuildQuestButton",
+  "LookingForGuildDungeonButton"
+};
+
+local function GCTabHelper(tab)
+	tab.Panel:Hide()
+	tab.bg1 = tab:CreateTexture(nil,"BACKGROUND")
+	tab.bg1:SetDrawLayer("BACKGROUND",4)
+	tab.bg1:SetTexture(SV.media.background.transparent)
+	tab.bg1:SetVertexColor(unpack(SV.media.color.default))
+	tab.bg1:InsetPoints(tab.Panel,1)
+	tab.bg3 = tab:CreateTexture(nil,"BACKGROUND")
+	tab.bg3:SetDrawLayer("BACKGROUND",2)
+	tab.bg3:SetColorTexture(0,0,0,1)
+	tab.bg3:SetAllPoints(tab.Panel)
+end
+
+local function Tab_OnEnter(this)
+	this.backdrop:SetBackdropColor(0.1, 0.8, 0.8)
+	this.backdrop:SetBackdropBorderColor(0.1, 0.8, 0.8)
+end
+
+local function Tab_OnLeave(this)
+	this.backdrop:SetBackdropColor(0,0,0,1)
+	this.backdrop:SetBackdropBorderColor(0,0,0,1)
+end
+
+local function ChangeTabHelper(this)
+	this:RemoveTextures()
+	local nTex = this:GetNormalTexture()
+	if(nTex) then
+		nTex:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+		nTex:InsetPoints()
+	end
+
+	this.pushed = true;
+
+	this.backdrop = CreateFrame("Frame", nil, this)
+	this.backdrop:WrapPoints(this,1,1)
+	this.backdrop:SetFrameLevel(0)
+	this.backdrop:SetBackdrop(SV.media.backdrop.glow);
+    this.backdrop:SetBackdropColor(0,0,0,1)
+	this.backdrop:SetBackdropBorderColor(0,0,0,1)
+	this:SetScript("OnEnter", Tab_OnEnter)
+	this:SetScript("OnLeave", Tab_OnLeave)
+
+	local a,b,c,d,e = this:GetPoint()
+	this:SetPoint(a,b,c,1,e)
+end
+
+local function StyleSortingButton(button)
+	if button.styled then return end
+
+	local outer = button:CreateTexture(nil, "OVERLAY")
+	outer:WrapPoints(button, 6, 6)
+	outer:SetTexture(SV.media.button.round)
+	outer:SetGradient("VERTICAL", 0.4, 0.47, 0.5, 0.3, 0.33, 0.35)
+
+	local icon = button:CreateTexture(nil, "OVERLAY")
+	icon:WrapPoints(button, 6, 6)
+
+	if button.SetNormalTexture then
+		local iconTex = button:GetNormalTexture()
+		iconTex:SetGradient("VERTICAL", 0.5, 0.53, 0.55, 0.8, 0.8, 1)
+		SetPortraitToTexture(icon, iconTex)
+		hooksecurefunc(icon, "SetTexture", SetPortraitToTexture)
+	end
+
+	local hover = button:CreateTexture(nil, "HIGHLIGHT")
+	hover:WrapPoints(button, 6, 6)
+	hover:SetTexture(SV.media.button.round)
+	hover:SetGradient(unpack(SV.media.gradient.yellow))
+
+	if button.SetPushedTexture then
+		local pushed = button:CreateTexture(nil, "BORDER")
+		pushed:WrapPoints(button, 6, 6)
+		pushed:SetTexture(SV.media.button.round)
+		pushed:SetGradient(unpack(SV.media.gradient.highlight))
+		button:SetPushedTexture(pushed)
+	end
+
+	if button.SetCheckedTexture then
+		local checked = button:CreateTexture(nil, "BORDER")
+		checked:WrapPoints(button, 6, 6)
+		checked:SetTexture(SV.media.button.round)
+		checked:SetGradient(unpack(SV.media.gradient.green))
+		button:SetCheckedTexture(checked)
+	end
+
+	if button.SetDisabledTexture then
+		local disabled = button:CreateTexture(nil, "BORDER")
+		disabled:WrapPoints(button, 6, 6)
+		disabled:SetTexture(SV.media.button.round)
+		disabled:SetGradient(unpack(SV.media.gradient.default))
+		button:SetDisabledTexture(disabled)
+	end
+
+	local cd = button:GetName() and _G[button:GetName().."Cooldown"]
+	if cd then
+		cd:ClearAllPoints()
+		cd:InsetPoints()
+	end
+	button.styled = true
+end
+
+local _hook_RankOrder_OnUpdate = function()
+	for i = 1, GuildControlGetNumRanks()do
+		local frame = _G["GuildControlUIRankOrderFrameRank"..i]
+		if frame then
+			frame.downButton:SetStyle("Button")
+			frame.upButton:SetStyle("Button")
+			frame.deleteButton:SetStyle("Button")
+			if not frame.nameBox.Panel then
+				frame.nameBox:SetStyle("Editbox")
+			end
+			frame.nameBox.Panel:SetPoint("TOPLEFT",-2,-4)
+			frame.nameBox.Panel:SetPoint("BOTTOMRIGHT",-4,4)
+		end
+	end
+end
+
+local function GuildInfoEvents_SetButton(button, eventIndex)
+	local dateData = date("*t")
+	local month, day, weekday, hour, minute, eventType, title, calendarType, textureName = CalendarGetGuildEventInfo(eventIndex)
+	local formattedTime = GameTime_GetFormattedTime(hour, minute, true)
+	local unformattedText;
+	if dateData["day"] == day and dateData["month"] == month then
+		unformattedText = NORMAL_FONT_COLOR_CODE..GUILD_EVENT_TODAY..FONT_COLOR_CODE_CLOSE
+	else
+		local year = dateData["year"]
+		if month < dateData["month"] then
+			year = year + 1
+		end
+		local newTime = time{year = year, month = month, day = day}
+		if(((newTime - time()) < 518400) and CALENDAR_WEEKDAY_NAMES[weekday]) then
+			unformattedText = CALENDAR_WEEKDAY_NAMES[weekday]
+		elseif CALENDAR_WEEKDAY_NAMES[weekday]and day and month then
+			unformattedText = format(GUILD_NEWS_DATE, CALENDAR_WEEKDAY_NAMES[weekday], day, month)
+		end
+	end
+	if button.text and unformattedText then
+		button.text:SetFormattedText(GUILD_EVENT_FORMAT, unformattedText, formattedTime, title)
+	end
+	button.index = eventIndex;
+	if button.icon.type ~= "event" then
+		button.icon.type = "event"
+		button.icon:SetTexCoord(0, 1, 0, 1)
+		button.icon:SetWidth(14)
+		button.icon:SetHeight(14)
+	end
+	if CalendarIconList[eventType] then
+		button.icon:SetTexture(CalendarIconList[eventType])
+	else
+		button.icon:SetTexture("Interface\\LFGFrame\\LFGIcon-"..textureName)
+	end
+end
+
+local _hook_UIRankOrder = function(self)
+	SV.Timers:ExecuteTimer(1, _hook_RankOrder_OnUpdate)
+end
+
+local _hook_GuildBankFrame_Update = function(self)
+	if GuildBankFrame.mode ~= "bank" then return end
+	local curTab = GetCurrentGuildBankTab()
+	local numSlots = NUM_SLOTS_PER_GUILDBANK_GROUP
+	local maxSlots = MAX_GUILDBANK_SLOTS_PER_TAB
+	local button, btnName, btnID, slotID, itemLink;
+	for i = 1, maxSlots do
+		btnID = i % numSlots
+		if btnID == 0 then
+			btnID = numSlots
+		end
+		slotID = ceil((i - 0.5) / numSlots)
+		btnName = ("GuildBankColumn%dButton%d"):format(slotID, btnID)
+		button = _G[btnName]
+		if(button) then
+			itemLink = GetGuildBankItemLink(curTab, i)
+			local r, g, b, a = 0,0,0,1
+			if(itemLink) then
+				local quality = select(3, GetItemInfo(itemLink))
+				if(quality and quality > 1) then
+					r, g, b = GetItemQualityColor(quality)
+				end
+			end
+			button:SetBackdropBorderColor(r, g, b, a)
+		end
+	end
+end
+
+local _hook_BankTabPermissions = function(self)
+	local tab, tabs, baseName, ownedName, purchase, view, stack, deposit, update
+
+	tabs = GetNumGuildBankTabs()
+
+	if tabs < MAX_BUY_GUILDBANK_TABS then
+		tabs = tabs + 1
+	end
+
+	for i = 1, tabs do
+		baseName = ("GuildControlBankTab%d"):format(i)
+		ownedName = ("%sOwned"):format(baseName)
+		tab = _G[ownedName]
+
+		if(tab) then
+			if(tab.tabIcon) then tab.tabIcon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS)) end
+			if(tab.editBox) then tab.editBox:SetStyle("Editbox") end
+
+			if internalTest == false then
+				purchase =  _G[baseName.."BuyPurchaseButton"]
+				if(purchase) then
+					purchase:SetStyle("Button")
+				end
+				view =  _G[ownedName.."ViewCheck"]
+				if(view) then
+					view:SetStyle("CheckButton")
+					GCTabHelper(view)
+				end
+				stack =  _G[ownedName.."StackBox"]
+				if(stack) then
+					stack:SetStyle("Editbox")
+					GCTabHelper(stack)
+				end
+				deposit =  _G[ownedName.."DepositCheck"]
+				if(deposit) then
+					deposit:SetStyle("CheckButton")
+					GCTabHelper(deposit)
+				end
+				update =  _G[ownedName.."UpdateInfoCheck"]
+				if(update) then
+					update:SetStyle("CheckButton")
+					GCTabHelper(update)
+				end
+			end
+		end
+	end
+	internalTest = true
+end
+--[[
+##########################################################
+GUILDFRAME MODRS
+##########################################################
+]]--
+local function GuildBankStyle()
+	if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.gbank ~= true then
+		return
+	end
+
+	SV.API:Set("Window", GuildBankFrame)
+
+	GuildBankFrameBlackBG:Die()
+	GuildBankEmblemFrame:RemoveTextures(true)
+	GuildBankMoneyFrameBackground:Die()
+	SV.API:Set("ScrollBar", GuildBankPopupScrollFrame)
+
+	for i = 1, GuildBankFrame:GetNumChildren() do
+		local child = select(i, GuildBankFrame:GetChildren())
+		if(child and child.GetPushedTexture and child:GetPushedTexture() and not child:GetName()) then
+			SV.API:Set("CloseButton", child)
+		end
+	end
+
+	GuildBankFrameDepositButton:SetStyle("Button")
+	GuildBankFrameWithdrawButton:SetStyle("Button")
+	GuildBankInfoSaveButton:SetStyle("Button")
+	GuildBankFramePurchaseButton:SetStyle("Button")
+
+	-- local BAGS = SV.Inventory
+	-- if(BAGS) then
+		-- local sortButton = CreateFrame("Button", nil, GuildBankFrame)
+		-- sortButton:SetPoint("BOTTOMLEFT", GuildBankFrame, "BOTTOMRIGHT", 2, 0)
+		-- sortButton:SetSize(36, 36)
+		-- sortButton:SetStyle("DockButton")
+		-- sortButton:SetNormalTexture(BAGS.media.cleanupIcon)
+		-- StyleSortingButton(sortButton)
+		-- local Sort_OnClick = BAGS:RunSortingProcess(BAGS.Sort, "guild")
+		-- sortButton:SetScript("OnClick", Sort_OnClick)
+	-- end
+
+	GuildBankFrameWithdrawButton:SetPoint("RIGHT", GuildBankFrameDepositButton, "LEFT", -2, 0)
+	GuildBankInfoScrollFrame:SetPoint('TOPLEFT', GuildBankInfo, 'TOPLEFT', -10, 12)
+	GuildBankInfoScrollFrame:RemoveTextures()
+	GuildBankInfoScrollFrame:SetWidth(GuildBankInfoScrollFrame:GetWidth()-8)
+	GuildBankTransactionsScrollFrame:RemoveTextures()
+
+	for i = 1, NUM_GUILDBANK_COLUMNS do
+		local frame = _G["GuildBankColumn"..i]
+		if(frame) then
+			frame:RemoveTextures()
+			local baseName = ("GuildBankColumn%dButton"):format(i)
+			for slotID = 1, NUM_SLOTS_PER_GUILDBANK_GROUP do
+				local btnName = ("%s%d"):format(baseName, slotID)
+				local button = _G[btnName]
+				if(button) then
+					button:RemoveTextures()
+					local texture = _G[btnName.."NormalTexture"]
+					if texture then
+						texture:SetTexture("")
+					end
+					button:SetStyle("ActionSlot")
+
+					local icon = _G[btnName.."IconTexture"] or button.icon;
+					if(icon) then
+						icon:InsetPoints()
+						icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+					end
+					if(button.IconBorder) then
+						button.IconBorder:Die()
+					end
+				end
+			end
+		end
+	end
+
+	for i = 1, 8 do
+		local baseName = ("GuildBankTab%d"):format(i)
+		local tab = _G[baseName]
+		if(tab) then
+			tab:RemoveTextures(true)
+			local btnName = ("%sButton"):format(baseName)
+			local button = _G[btnName]
+			if(button) then
+				button:RemoveTextures()
+				button:SetStyle("Button")
+				local texture = _G[btnName.."IconTexture"]
+				if(texture) then
+					texture:InsetPoints()
+					texture:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+				end
+				if(button.IconBorder) then
+					button.IconBorder:Die()
+				end
+			end
+		end
+	end
+
+	for i = 1, 4 do
+		local baseName = ("GuildBankFrameTab%d"):format(i)
+		local frame = _G[baseName]
+		if(frame) then
+			SV.API:Set("Tab", _G[baseName])
+		end
+	end
+
+	hooksecurefunc('GuildBankFrame_Update', _hook_GuildBankFrame_Update)
+
+	GuildBankPopupFrame:RemoveTextures()
+	GuildBankPopupScrollFrame:RemoveTextures()
+	GuildBankPopupFrame:SetStyle("!_Frame", "Transparent", true)
+	GuildBankPopupFrame:SetPoint("TOPLEFT", GuildBankFrame, "TOPRIGHT", 1, -30)
+	GuildBankPopupOkayButton:SetStyle("Button")
+	GuildBankPopupCancelButton:SetStyle("Button")
+	GuildBankPopupEditBox:SetStyle("Editbox")
+	GuildBankPopupNameLeft:Die()
+	GuildBankPopupNameRight:Die()
+	GuildBankPopupNameMiddle:Die()
+	SV.API:Set("EditBox", GuildItemSearchBox)
+
+	for i = 1, 16 do
+		local btnName = ("GuildBankPopupButton%d"):format(i)
+		local button = _G[btnName]
+		if(button) then
+			button:RemoveTextures()
+			button:SetStyle("!_Frame", "Default")
+			button:SetStyle("Button")
+
+			local icon = _G[btnName.."Icon"]
+			if(icon) then
+				icon:InsetPoints()
+				icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+			end
+		end
+	end
+
+	SV.API:Set("ScrollBar", GuildBankTransactionsScrollFrame)
+	SV.API:Set("ScrollBar", GuildBankInfoScrollFrame)
+end
+
+local function GuildFrameStyle()
+	if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.guild ~= true then
+		return
+	end
+
+	SV.API:Set("Window", GuildFrame)
+
+	SV.API:Set("CloseButton", GuildMemberDetailCloseButton)
+	SV.API:Set("CloseButton", GuildFrameCloseButton)
+	GuildRewardsFrameVisitText:ClearAllPoints()
+	GuildRewardsFrameVisitText:SetPoint("TOP", GuildRewardsFrame, "TOP", 0, 30)
+
+	for i = 1, #GuildFrameList do
+		local frame = _G[GuildFrameList[i]]
+		if(frame) then
+			frame:RemoveTextures()
+		end
+	end
+
+	for i = 1, #GuildButtonList do
+		local button = _G[GuildButtonList[i]]
+		if(button) then
+			button:RemoveTextures(true)
+			button:SetStyle("Button")
+		end
+	end
+
+	for i = 1, #GuildCheckBoxList do
+		local check = _G[GuildCheckBoxList[i]]
+		if(check) then check:SetStyle("CheckButton") end
+	end
+
+	for i = 1, 5 do
+		local tab = _G["GuildFrameTab"..i]
+		if(tab) then
+			SV.API:Set("Tab", tab)
+			if i == 1 then
+				tab:SetPoint("TOPLEFT", GuildFrame, "BOTTOMLEFT", -10, 3)
+			end
+		end
+	end
+
+	GuildNewsBossModel:SetStyle("Frame", 'Transparent')
+	GuildNewsBossModelTextFrame:SetStyle("Frame", "Default")
+	GuildNewsBossModelTextFrame.Panel:SetPoint("TOPLEFT", GuildNewsBossModel.Panel, "BOTTOMLEFT", 0, -1)
+	GuildNewsBossModel:SetPoint("TOPLEFT", GuildFrame, "TOPRIGHT", 4, -43)
+
+	GuildRecruitmentTankButton.checkButton:SetStyle("CheckButton")
+	GuildRecruitmentHealerButton.checkButton:SetStyle("CheckButton")
+	GuildRecruitmentDamagerButton.checkButton:SetStyle("CheckButton")
+
+	GuildFactionBar:RemoveTextures()
+	GuildFactionBar.progress:SetTexture(SV.media.statusbar.default)
+	GuildFactionBar:SetStyle("Frame", "Inset")
+	GuildFactionBar.Panel:SetPoint("TOPLEFT", GuildFactionBar.progress, "TOPLEFT", -1, 1)
+	GuildFactionBar.Panel:SetPoint("BOTTOMRIGHT", GuildFactionBar, "BOTTOMRIGHT", 1, 1)
+
+	GuildRosterContainer:SetStyle("Frame", "Inset")
+	SV.API:Set("ScrollBar", GuildRosterContainerScrollBar, 4, -4)
+	GuildRosterShowOfflineButton:SetStyle("CheckButton")
+
+	for i = 1, 4 do
+		local btn = _G["GuildRosterColumnButton"..i]
+		if(btn) then
+			btn:RemoveTextures(true)
+		end
+	end
+
+	SV.API:Set("DropDown", GuildRosterViewDropdown, 200)
+
+	for i = 1, 14 do
+		local btn = _G["GuildRosterContainerButton"..i.."HeaderButton"]
+		if(btn) then
+			btn:RemoveTextures()
+			btn:SetStyle("Button")
+		end
+	end
+
+	GuildMemberDetailFrame:SetStyle("Frame", "Default", true)
+	GuildMemberNoteBackground:SetStyle("Frame", 'Transparent')
+	GuildMemberOfficerNoteBackground:SetStyle("Frame", 'Transparent')
+
+	SV.API:Set("DropDown", GuildMemberRankDropdown, 182)
+	GuildMemberRankDropdown:HookScript("OnShow", function() GuildMemberDetailRankText:Hide() end)
+	GuildMemberRankDropdown:HookScript("OnHide", function() GuildMemberDetailRankText:Show() end)
+	GuildNewsFrame:RemoveTextures()
+	GuildNewsContainer:SetStyle("Frame", "Inset")
+
+	for i = 1, 17 do
+		local btn = _G["GuildNewsContainerButton"..i]
+		if(btn) then
+			if(btn.header) then btn.header:Die() end
+			btn:RemoveTextures()
+			btn:SetStyle("Button")
+		end
+	end
+
+	GuildNewsFiltersFrame:RemoveTextures()
+	GuildNewsFiltersFrame:SetStyle("!_Frame", "Transparent", true)
+	SV.API:Set("CloseButton", GuildNewsFiltersFrameCloseButton)
+
+	for i = 1, 7 do
+		local btn = _G["GuildNewsFilterButton"..i]
+		if(btn) then
+			btn:SetStyle("CheckButton")
+		end
+	end
+
+	GuildNewsFiltersFrame:SetPoint("TOPLEFT", GuildFrame, "TOPRIGHT", 4, -20)
+	SV.API:Set("ScrollBar", GuildNewsContainerScrollBar, 4, 4)
+	SV.API:Set("ScrollBar", GuildInfoDetailsFrameScrollBar, 4, 4)
+
+	for i = 1, 3 do
+		local tab = _G["GuildInfoFrameTab"..i]
+		if(tab) then
+			tab:RemoveTextures()
+		end
+	end
+
+	local panel1 = CreateFrame("Frame", nil, GuildInfoFrameInfo)
+	panel1:SetPoint("TOPLEFT", GuildInfoFrameInfo, "TOPLEFT", 2, -22)
+	panel1:SetPoint("BOTTOMRIGHT", GuildInfoFrameInfo, "BOTTOMRIGHT", 0, 200)
+	panel1:SetStyle("Frame", 'Transparent')
+
+	local panel2 = CreateFrame("Frame", nil, GuildInfoFrameInfo)
+	panel2:SetPoint("TOPLEFT", GuildInfoFrameInfo, "TOPLEFT", 2, -158)
+	panel2:SetPoint("BOTTOMRIGHT", GuildInfoFrameInfo, "BOTTOMRIGHT", 0, 118)
+	panel2:SetStyle("Frame", 'Transparent')
+
+	local panel3 = CreateFrame("Frame", nil, GuildInfoFrameInfo)
+	panel3:SetPoint("TOPLEFT", GuildInfoFrameInfo, "TOPLEFT", 2, -233)
+	panel3:SetPoint("BOTTOMRIGHT", GuildInfoFrameInfo, "BOTTOMRIGHT", 0, 3)
+	panel3:SetStyle("Frame", 'Transparent')
+
+	GuildRecruitmentCommentInputFrame:SetStyle("!_Frame", "Default")
+	GuildTextEditFrame:SetStyle("!_Frame", "Transparent", true)
+	SV.API:Set("ScrollBar", GuildTextEditScrollFrame, 4, 4)
+	GuildTextEditContainer:SetStyle("!_Frame", "Default")
+
+	local editChildren = GuildTextEditFrame:GetNumChildren()
+
+	for i = 1, editChildren do
+		local child = select(i, GuildTextEditFrame:GetChildren())
+		if(child:GetName() == "GuildTextEditFrameCloseButton") then
+			if(child:GetWidth() < 33) then
+				SV.API:Set("CloseButton", child)
+			else
+				child:SetStyle("Button")
+			end
+		end
+	end
+
+	SV.API:Set("ScrollBar", GuildLogScrollFrame, 4, 4)
+	GuildLogFrame:SetStyle("Frame", 'Transparent')
+
+	local logChildren = GuildLogFrame:GetNumChildren()
+
+	for i = 1, logChildren do
+		local child = select(i, GuildLogFrame:GetChildren())
+		if child:GetName() == "GuildLogFrameCloseButton" then
+			if(child:GetWidth() < 33) then
+				SV.API:Set("CloseButton", child)
+			else
+				child:SetStyle("Button")
+			end
+		end
+	end
+
+	GuildRewardsFrame:SetStyle("Frame", "Inset")
+	SV.API:Set("ScrollBar", GuildRewardsContainerScrollBar, 4, -4)
+	SV.API:Set("ScrollBar", GuildPerksContainerScrollBar, 4, 2)
+
+	for i = 1, 8 do
+		local button = _G["GuildPerksContainerButton"..i]
+		if button then
+			button:RemoveTextures()
+			SV.API:Set("ItemButton", button, nil, true)
+			local icon = button.icon or button.Icon
+			if icon then
+				icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+				icon:ClearAllPoints()
+				icon:SetPoint("TOPLEFT", button, "TOPLEFT", 2, -2)
+				icon:SetParent(button.Panel)
+			end
+		end
+	end
+
+	for i = 1, 8 do
+		local button = _G["GuildRewardsContainerButton"..i]
+		if button then
+			button:RemoveTextures()
+			SV.API:Set("ItemButton", button)
+		end
+	end
+
+	local maxCalendarEvents = CalendarGetNumGuildEvents();
+	local scrollFrame = GuildInfoFrameApplicantsContainer;
+  	local offset = HybridScrollFrame_GetOffset(scrollFrame);
+  	local buttonIndex,counter = 0,0;
+
+	for _,button in next, GuildInfoFrameApplicantsContainer.buttons do
+		counter = counter + 1;
+		buttonIndex = offset + counter;
+		button.selectedTex:Die()
+		button:GetHighlightTexture():Die()
+		button:SetBackdrop(nil)
+	end
+end
+
+local function GuildControlStyle()
+	if SV.db.Skins.blizzard.enable~=true or SV.db.Skins.blizzard.guildcontrol~=true then return end
+
+	GuildControlUI:RemoveTextures()
+	GuildControlUIHbar:RemoveTextures()
+	GuildControlUIRankBankFrameInset:RemoveTextures()
+	GuildControlUIRankBankFrameInsetScrollFrame:RemoveTextures()
+
+	SV.API:Set("Window", GuildControlUI)
+
+	SV.API:Set("ScrollBar", GuildControlUIRankBankFrameInsetScrollFrame)
+
+	hooksecurefunc("GuildControlUI_RankOrder_Update", _hook_RankOrder_OnUpdate)
+	GuildControlUIRankOrderFrameNewButton:HookScript("OnClick", _hook_UIRankOrder)
+
+	SV.API:Set("DropDown", GuildControlUINavigationDropDown)
+	SV.API:Set("DropDown", GuildControlUIRankSettingsFrameRankDropDown,180)
+	GuildControlUINavigationDropDownButton:SetWidth(20)
+	GuildControlUIRankSettingsFrameRankDropDownButton:SetWidth(20)
+
+	for i=1, NUM_RANK_FLAGS do
+		local check = _G["GuildControlUIRankSettingsFrameCheckbox"..i]
+		if(check) then check:SetStyle("CheckButton") end
+	end
+
+	GuildControlUIRankOrderFrameNewButton:SetStyle("Button")
+	GuildControlUIRankSettingsFrameGoldBox:SetStyle("Editbox")
+	GuildControlUIRankSettingsFrameGoldBox.Panel:SetPoint("TOPLEFT",-2,-4)
+	GuildControlUIRankSettingsFrameGoldBox.Panel:SetPoint("BOTTOMRIGHT",2,4)
+	GuildControlUIRankSettingsFrameGoldBox:RemoveTextures()
+	GuildControlUIRankBankFrame:RemoveTextures()
+
+	hooksecurefunc("GuildControlUI_BankTabPermissions_Update", _hook_BankTabPermissions)
+
+	SV.API:Set("DropDown", GuildControlUIRankBankFrameRankDropDown, 180)
+
+	GuildControlUIRankBankFrameRankDropDownButton:SetWidth(20)
+end
+
+local function LFGuildFrameStyle()
+	if(SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.lfguild ~= true) then return end
+
+	SV.API:Set("Window", LookingForGuildFrame, true)
+
+	for i = 1, #LFGFrameList do
+		local check = _G[LFGFrameList[i]]
+		if(check) then check:SetStyle("CheckButton") end
+	end
+
+	LookingForGuildTankButton.checkButton:SetStyle("CheckButton")
+	LookingForGuildHealerButton.checkButton:SetStyle("CheckButton")
+	LookingForGuildDamagerButton.checkButton:SetStyle("CheckButton")
+	LookingForGuildFrameInset:RemoveTextures(false)
+	LookingForGuildBrowseButton_LeftSeparator:Die()
+	LookingForGuildRequestButton_RightSeparator:Die()
+
+	SV.API:Set("ScrollBar", LookingForGuildBrowseFrameContainerScrollBar)
+	LookingForGuildBrowseButton:SetStyle("Button")
+	LookingForGuildRequestButton:SetStyle("Button")
+
+	SV.API:Set("CloseButton", LookingForGuildFrameCloseButton)
+	LookingForGuildCommentInputFrame:SetStyle("Frame", "Default")
+	LookingForGuildCommentInputFrame:RemoveTextures(false)
+
+	for u = 1, 5 do
+		local J = _G["LookingForGuildBrowseFrameContainerButton"..u]
+		local K = _G["LookingForGuildAppsFrameContainerButton"..u]
+		J:SetBackdrop(nil)
+		K:SetBackdrop(nil)
+	end
+
+	for u = 1, 3 do
+		local tab = _G["LookingForGuildFrameTab"..u]
+		SV.API:Set("Tab", tab)
+		tab:SetFrameStrata("HIGH")
+		tab:SetFrameLevel(99)
+	end
+
+	GuildFinderRequestMembershipFrame:RemoveTextures(true)
+	GuildFinderRequestMembershipFrame:SetStyle("!_Frame", "Transparent", true)
+	GuildFinderRequestMembershipFrameAcceptButton:SetStyle("Button")
+	GuildFinderRequestMembershipFrameCancelButton:SetStyle("Button")
+	GuildFinderRequestMembershipFrameInputFrame:RemoveTextures()
+	GuildFinderRequestMembershipFrameInputFrame:SetStyle("!_Frame", "Default")
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveBlizzardStyle("Blizzard_GuildBankUI",GuildBankStyle)
+MOD:SaveBlizzardStyle("Blizzard_GuildUI",GuildFrameStyle)
+MOD:SaveBlizzardStyle("Blizzard_GuildControlUI",GuildControlStyle)
+MOD:SaveBlizzardStyle("Blizzard_LookingForGuildUI",LFGuildFrameStyle)
diff --git a/SVUI_Skins/components/blizzard/help.lua b/SVUI_Skins/components/blizzard/help.lua
new file mode 100644
index 0000000..97ab56e
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/help.lua
@@ -0,0 +1,181 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+local tinsert = _G.tinsert;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+HELPERS
+##########################################################
+]]--
+local HelpFrameList = {
+	"HelpFrameLeftInset",
+	"HelpFrameMainInset",
+	"HelpFrameKnowledgebase",
+	"HelpFrameHeader",
+	"HelpFrameKnowledgebaseErrorFrame"
+}
+
+local HelpFrameButtonList = {
+	"HelpFrameOpenTicketHelpItemRestoration",
+	"HelpFrameAccountSecurityOpenTicket",
+	"HelpFrameOpenTicketHelpTopIssues",
+	"HelpFrameOpenTicketHelpOpenTicket",
+	"HelpFrameKnowledgebaseSearchButton",
+	"HelpFrameKnowledgebaseNavBarHomeButton",
+	"HelpFrameCharacterStuckStuck",
+	"GMChatOpenLog",
+	"HelpFrameTicketSubmit",
+	"HelpFrameTicketCancel"
+}
+
+local function NavBarHelper(button)
+	for i = 1, #button.navList do
+		local this = button.navList[i]
+		local last = button.navList[i - 1]
+		if this and last then
+			local level = last:GetFrameLevel()
+			if(level >= 2) then
+				level = level - 2
+			else
+				level = 0
+			end
+			this:SetFrameLevel(level)
+		end
+	end
+end
+--[[
+##########################################################
+HELPFRAME MODR
+##########################################################
+]]--
+local function HelpFrameStyle()
+	--print('test HelpFrameStyle')
+	if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.help ~= true then
+		return
+	end
+	tinsert(HelpFrameButtonList, "HelpFrameButton16")
+	tinsert(HelpFrameButtonList, "HelpFrameSubmitSuggestionSubmit")
+	tinsert(HelpFrameButtonList, "HelpFrameReportBugSubmit")
+	for d = 1, #HelpFrameList do
+		_G[HelpFrameList[d]]:RemoveTextures(true)
+		_G[HelpFrameList[d]]:SetStyle("Frame", "Default")
+	end
+	HelpFrameHeader:SetFrameLevel(HelpFrameHeader:GetFrameLevel()+2)
+	HelpFrameKnowledgebaseErrorFrame:SetFrameLevel(HelpFrameKnowledgebaseErrorFrame:GetFrameLevel()+2)
+	HelpFrameReportBugScrollFrame:RemoveTextures()
+	HelpFrameReportBugScrollFrame:SetStyle("Frame", "Default")
+	HelpFrameReportBugScrollFrame.Panel:SetPoint("TOPLEFT", -4, 4)
+	HelpFrameReportBugScrollFrame.Panel:SetPoint("BOTTOMRIGHT", 6, -4)
+	for d = 1, HelpFrameReportBug:GetNumChildren()do
+		local e = select(d, HelpFrameReportBug:GetChildren())
+		if not e:GetName() then
+			e:RemoveTextures()
+		end
+	end
+	SV.API:Set("ScrollBar", HelpFrameReportBugScrollFrame)
+	HelpFrameSubmitSuggestionScrollFrame:RemoveTextures()
+	HelpFrameSubmitSuggestionScrollFrame:SetStyle("Frame", "Default")
+	HelpFrameSubmitSuggestionScrollFrame.Panel:SetPoint("TOPLEFT", -4, 4)
+	HelpFrameSubmitSuggestionScrollFrame.Panel:SetPoint("BOTTOMRIGHT", 6, -4)
+	for d = 1, HelpFrameSubmitSuggestion:GetNumChildren()do
+		local e = select(d, HelpFrameSubmitSuggestion:GetChildren())
+		if not e:GetName() then
+			e:RemoveTextures()
+		end
+	end
+	SV.API:Set("ScrollBar", HelpFrameSubmitSuggestionScrollFrame)
+	SV.API:Set("ScrollBar", HelpFrameKnowledgebaseScrollFrame2ScrollBar)
+	for d = 1, #HelpFrameButtonList do
+		local bname = HelpFrameButtonList[d]
+		if(bname and _G[bname]) then
+			_G[bname]:RemoveTextures(true)
+			_G[bname]:SetStyle("Button")
+			if _G[bname].text then
+				_G[bname].text:ClearAllPoints()
+				_G[bname].text:SetPoint("CENTER")
+				_G[bname].text:SetJustifyH("CENTER")
+			end
+		end
+	end
+	for d = 1, 6 do
+		local f = _G["HelpFrameButton"..d]
+		f:SetStyle("Button")
+		f.text:ClearAllPoints()
+		f.text:SetPoint("CENTER")
+		f.text:SetJustifyH("CENTER")
+	end
+	for d = 1, HelpFrameKnowledgebaseScrollFrameScrollChild:GetNumChildren()do
+		local f = _G["HelpFrameKnowledgebaseScrollFrameButton"..d]
+		f:RemoveTextures(true)
+		f:SetStyle("Button")
+	end
+	HelpFrameKnowledgebaseSearchBox:ClearAllPoints()
+	HelpFrameKnowledgebaseSearchBox:SetPoint("TOPLEFT", HelpFrameMainInset, "TOPLEFT", 13, -10)
+	HelpFrameKnowledgebaseNavBarOverlay:Die()
+	HelpFrameKnowledgebaseNavBar:RemoveTextures()
+	HelpFrame:RemoveTextures(true)
+	HelpFrame:SetStyle("Frame", "Window")
+	HelpFrameKnowledgebaseSearchBox:SetStyle("Editbox")
+	SV.API:Set("ScrollBar", HelpFrameKnowledgebaseScrollFrame, 5)
+
+	SV.API:Set("CloseButton", HelpFrameCloseButton, HelpFrame.Panel)
+	SV.API:Set("CloseButton", HelpFrameKnowledgebaseErrorFrameCloseButton, HelpFrameKnowledgebaseErrorFrame.Panel)
+	HelpFrameCharacterStuckHearthstone:SetStyle("Button")
+	HelpFrameCharacterStuckHearthstone:SetStyle("!_Frame", "Default")
+	HelpFrameCharacterStuckHearthstone.IconTexture:InsetPoints()
+	HelpFrameCharacterStuckHearthstone.IconTexture:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+	hooksecurefunc("NavBar_AddButton", function(h, k)
+		local i = h.navList[#h.navList]
+		if not i.styled then
+			i:SetStyle("Button")
+			i.styled = true;
+			i:HookScript("OnClick", function()
+				NavBarHelper(h)
+			end)
+		end
+		NavBarHelper(h)
+	end)
+	HelpFrameGM_ResponseNeedMoreHelp:SetStyle("Button")
+	HelpFrameGM_ResponseCancel:SetStyle("Button")
+	for d = 1, HelpFrameGM_Response:GetNumChildren()do
+		local e = select(d, HelpFrameGM_Response:GetChildren())
+		if e and e:GetObjectType()
+		 == "Frame"and not e:GetName()
+		then
+			e:SetStyle("!_Frame", "Default")
+		end
+	end
+
+	if(_G['HelpFrameTicket']) then
+		if(_G['HelpFrameTicketScrollFrame']) then
+			HelpFrameTicketScrollFrame:RemoveTextures()
+			HelpFrameTicketScrollFrame:SetStyle("Frame", "Default")
+			HelpFrameTicketScrollFrame.Panel:SetPoint("TOPLEFT", -4, 4)
+			HelpFrameTicketScrollFrame.Panel:SetPoint("BOTTOMRIGHT", 6, -4)
+		end
+		for d = 1, HelpFrameTicket:GetNumChildren()do
+			local e = select(d, HelpFrameTicket:GetChildren())
+			if not e:GetName() then
+				e:RemoveTextures()
+			end
+		end
+		SV.API:Set("ScrollBar", HelpFrameTicketScrollFrame, 4)
+	end
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveCustomStyle(HelpFrameStyle)
\ No newline at end of file
diff --git a/SVUI_Skins/components/blizzard/inspect.lua b/SVUI_Skins/components/blizzard/inspect.lua
new file mode 100644
index 0000000..8e2e44e
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/inspect.lua
@@ -0,0 +1,97 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+local ipairs  = _G.ipairs;
+local pairs   = _G.pairs;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+HELPERS
+##########################################################
+]]--
+local InspectSlotList = {
+	"HeadSlot",
+	"NeckSlot",
+	"ShoulderSlot",
+	"BackSlot",
+	"ChestSlot",
+	"ShirtSlot",
+	"TabardSlot",
+	"WristSlot",
+	"HandsSlot",
+	"WaistSlot",
+	"LegsSlot",
+	"FeetSlot",
+	"Finger0Slot",
+	"Finger1Slot",
+	"Trinket0Slot",
+	"Trinket1Slot",
+	"MainHandSlot",
+	"SecondaryHandSlot"
+};
+--[[
+##########################################################
+INSPECT UI MODR
+##########################################################
+]]--
+local function InspectStyle()
+	if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.inspect ~= true then
+		return
+	end
+	InspectFrame:RemoveTextures(true)
+	InspectFrameInset:RemoveTextures(true)
+	InspectFrame:SetStyle("Frame", "Window2")
+	SV.API:Set("CloseButton", InspectFrameCloseButton)
+	for d = 1, 4 do
+		SV.API:Set("Tab", _G["InspectFrameTab"..d])
+	end
+	InspectModelFrameBorderTopLeft:Die()
+	InspectModelFrameBorderTopRight:Die()
+	InspectModelFrameBorderTop:Die()
+	InspectModelFrameBorderLeft:Die()
+	InspectModelFrameBorderRight:Die()
+	InspectModelFrameBorderBottomLeft:Die()
+	InspectModelFrameBorderBottomRight:Die()
+	InspectModelFrameBorderBottom:Die()
+	InspectModelFrameBorderBottom2:Die()
+	InspectModelFrameBackgroundOverlay:Die()
+	InspectModelFrame:SetStyle("Frame", "Default")
+	for _, slot in pairs(InspectSlotList)do
+		local texture = _G["Inspect"..slot.."IconTexture"]
+		local frame = _G["Inspect"..slot]
+		frame:RemoveTextures()
+		frame:SetStyle("Button")
+		texture:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+		texture:InsetPoints()
+		frame:SetFrameLevel(frame:GetFrameLevel() + 1)
+		frame:SetStyle("!_Frame")
+	end
+	hooksecurefunc('InspectPaperDollItemSlotButton_Update', function(q)
+		local unit = InspectFrame.unit;
+		local r = GetInventoryItemQuality(unit, q:GetID())
+		if r and q.Panel then
+			local s, t, f = GetItemQualityColor(r)
+			q:SetBackdropBorderColor(s, t, f)
+		elseif q.Panel then
+			q:SetBackdropBorderColor(0,0,0,1)
+		end
+	end)
+	InspectGuildFrameBG:Die()
+	InspectTalentFrame:RemoveTextures()
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveBlizzardStyle("Blizzard_InspectUI",InspectStyle)
\ No newline at end of file
diff --git a/SVUI_Skins/components/blizzard/itemsocketing.lua b/SVUI_Skins/components/blizzard/itemsocketing.lua
new file mode 100644
index 0000000..3175302
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/itemsocketing.lua
@@ -0,0 +1,62 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+ITEMSOCKETING MODR
+##########################################################
+]]--
+local function ItemSocketStyle()
+	if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.socket ~= true then return end
+	ItemSocketingFrame:RemoveTextures()
+	ItemSocketingFrame:SetStyle("Frame", "Window2")
+	ItemSocketingFrameInset:Die()
+	ItemSocketingScrollFrame:RemoveTextures()
+	ItemSocketingScrollFrame:SetStyle("Frame", "Inset", true)
+	SV.API:Set("ScrollBar", ItemSocketingScrollFrame, 2)
+	for j = 1, MAX_NUM_SOCKETS do
+		local i = _G[("ItemSocketingSocket%d"):format(j)];
+		local C = _G[("ItemSocketingSocket%dBracketFrame"):format(j)];
+		local D = _G[("ItemSocketingSocket%dBackground"):format(j)];
+		local E = _G[("ItemSocketingSocket%dIconTexture"):format(j)];
+		i:RemoveTextures()
+		i:SetStyle("Button")
+		i:SetStyle("!_Frame", "Button", true)
+		C:Die()
+		D:Die()
+		E:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+		E:InsetPoints()
+	end
+	hooksecurefunc("ItemSocketingFrame_Update", function()
+		local max = GetNumSockets()
+		for j=1, max do
+			local i = _G[("ItemSocketingSocket%d"):format(j)];
+			local G = GetSocketTypes(j);
+			local color = GEM_TYPE_INFO[G]
+			i:SetBackdropColor(color.r, color.g, color.b, 0.15);
+			i:SetBackdropBorderColor(color.r, color.g, color.b)
+		end
+	end)
+	ItemSocketingFramePortrait:Die()
+	ItemSocketingSocketButton:ClearAllPoints()
+	ItemSocketingSocketButton:SetPoint("BOTTOMRIGHT", ItemSocketingFrame, "BOTTOMRIGHT", -5, 5)
+	ItemSocketingSocketButton:SetStyle("Button")
+	SV.API:Set("CloseButton", ItemSocketingFrameCloseButton)
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveBlizzardStyle("Blizzard_ItemSocketingUI",ItemSocketStyle)
\ No newline at end of file
diff --git a/SVUI_Skins/components/blizzard/itemupgrade.lua b/SVUI_Skins/components/blizzard/itemupgrade.lua
new file mode 100644
index 0000000..ab2c4f3
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/itemupgrade.lua
@@ -0,0 +1,50 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+ITEMUPGRADE UI MODR
+##########################################################
+]]--
+local function ItemUpgradeStyle()
+	if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.itemUpgrade ~= true then
+		 return
+	end
+
+	SV.API:Set("Window", ItemUpgradeFrame, true)
+
+	SV.API:Set("CloseButton", ItemUpgradeFrameCloseButton)
+	ItemUpgradeFrameUpgradeButton:RemoveTextures()
+	ItemUpgradeFrameUpgradeButton:SetStyle("Button")
+	ItemUpgradeFrame.ItemButton:RemoveTextures()
+	ItemUpgradeFrame.ItemButton:SetStyle("ActionSlot")
+	ItemUpgradeFrame.ItemButton.IconTexture:InsetPoints()
+	hooksecurefunc('ItemUpgradeFrame_Update', function()
+		if GetItemUpgradeItemInfo() then
+			ItemUpgradeFrame.ItemButton.IconTexture:SetAlpha(1)
+			ItemUpgradeFrame.ItemButton.IconTexture:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+		else
+			ItemUpgradeFrame.ItemButton.IconTexture:SetAlpha(0)
+		end
+	end)
+	ItemUpgradeFrameMoneyFrame:RemoveTextures()
+	ItemUpgradeFrame.FinishedGlow:Die()
+	ItemUpgradeFrame.ButtonFrame:DisableDrawLayer('BORDER')
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveBlizzardStyle("Blizzard_ItemUpgradeUI",ItemUpgradeStyle)
\ No newline at end of file
diff --git a/SVUI_Skins/components/blizzard/keybinding.lua b/SVUI_Skins/components/blizzard/keybinding.lua
new file mode 100644
index 0000000..8a0be74
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/keybinding.lua
@@ -0,0 +1,63 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+local ipairs  = _G.ipairs;
+local pairs   = _G.pairs;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+KEYBINDING MODR
+##########################################################
+]]--
+local BindButtons = {
+	"KeyBindingFrameDefaultButton",
+	"KeyBindingFrameUnbindButton",
+	"KeyBindingFrameOkayButton",
+	"KeyBindingFrameCancelButton"
+}
+
+local function BindingStyle()
+	if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.binding ~= true then return end
+
+	for _, gName in pairs(BindButtons)do
+		local btn = _G[gName]
+		if(btn) then
+			btn:RemoveTextures()
+			btn:SetStyle("Button")
+		end
+	end
+
+	for i = 1, KEY_BINDINGS_DISPLAYED do
+		local button1 = _G["KeyBindingFrameBinding"..i.."Key1Button"]
+		if(button1) then
+			button1:RemoveTextures(true)
+			button1:SetStyle("Editbox")
+		end
+
+		local button2 = _G["KeyBindingFrameBinding"..i.."Key2Button"]
+		if(button2) then
+			button2:RemoveTextures(true)
+			button2:SetStyle("Editbox")
+		end
+	end
+
+	SV.API:Set("ScrollBar", KeyBindingFrameScrollFrame)
+	KeyBindingFrame:RemoveTextures()
+	KeyBindingFrame:SetStyle("Frame", "Window")
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveBlizzardStyle("Blizzard_BindingUI", BindingStyle)
\ No newline at end of file
diff --git a/SVUI_Skins/components/blizzard/lfd.lua b/SVUI_Skins/components/blizzard/lfd.lua
new file mode 100644
index 0000000..2806caf
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/lfd.lua
@@ -0,0 +1,529 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+local ipairs  = _G.ipairs;
+local pairs   = _G.pairs;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+HELPERS
+##########################################################
+]]--
+local LFDFrameList = {
+  "LFDQueueFrameRoleButtonHealer",
+  "LFDQueueFrameRoleButtonDPS",
+  "LFDQueueFrameRoleButtonLeader",
+  "LFDQueueFrameRoleButtonTank",
+  "RaidFinderQueueFrameRoleButtonHealer",
+  "RaidFinderQueueFrameRoleButtonDPS",
+  "RaidFinderQueueFrameRoleButtonLeader",
+  "RaidFinderQueueFrameRoleButtonTank",
+  "LFGInvitePopupRoleButtonTank",
+  "LFGInvitePopupRoleButtonHealer",
+  "LFGInvitePopupRoleButtonDPS",
+};
+
+local LFGStatusList = {
+  "LFGDungeonReadyStatusIndividualPlayer1",
+  "LFGDungeonReadyStatusIndividualPlayer2",
+  "LFGDungeonReadyStatusIndividualPlayer3",
+  "LFGDungeonReadyStatusIndividualPlayer4",
+  "LFGDungeonReadyStatusIndividualPlayer5"
+};
+
+local function StyleMoneyRewards(frameName)
+  local frame = _G[frameName]
+  local icon = _G[frameName .. "IconTexture"]
+  if(not frame.Panel and icon) then
+      local size = frame:GetHeight() - 6
+      local texture = icon:GetTexture()
+      frame:RemoveTextures()
+      frame:SetStyle("!_Frame", "Inset")
+      icon:SetTexture(texture)
+      icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+      icon:ClearAllPoints()
+      icon:SetPoint("TOPLEFT", frame, "TOPLEFT", 3, -3)
+      icon:SetSize(size, size)
+      if(not frame.IconSlot) then
+        frame.IconSlot = CreateFrame("Frame", nil, frame)
+        frame.IconSlot:WrapPoints(icon)
+        frame.IconSlot:SetStyle("Icon")
+        icon:SetParent(frame.IconSlot)
+      end
+  end
+end
+
+local Incentive_OnShow = function(button)
+  local parent = button:GetParent()
+  local check = parent.checkButton or parent.CheckButton
+  ActionButton_ShowOverlayGlow(check)
+end
+
+local Incentive_OnHide = function(button)
+  local parent = button:GetParent()
+  local check = parent.checkButton or parent.CheckButton
+  ActionButton_HideOverlayGlow(check)
+end
+
+local _hook_QueueStatusFrame_Update = function(self)
+  for i=1, #self.StatusEntries do
+    local node = self.StatusEntries[i];
+    if(node.RoleIcon1) then
+      node.RoleIcon1:SetTexture("Interface\\AddOns\\SVUI_Skins\\artwork\\UI-LFG-ICON-ROLES")
+    end
+    if(node.RoleIcon2) then
+      node.RoleIcon2:SetTexture("Interface\\AddOns\\SVUI_Skins\\artwork\\UI-LFG-ICON-ROLES")
+    end
+    if(node.RoleIcon3) then
+      node.RoleIcon3:SetTexture("Interface\\AddOns\\SVUI_Skins\\artwork\\UI-LFG-ICON-ROLES")
+    end
+    if(node.HealersFound) then
+      node.HealersFound.Cover:SetTexture("Interface\\AddOns\\SVUI_Skins\\artwork\\UI-LFG-ICON-ROLES")
+      node.HealersFound.Texture:SetTexture("Interface\\AddOns\\SVUI_Skins\\artwork\\UI-LFG-ICON-ROLES")
+    end
+    if(node.TanksFound) then
+      node.TanksFound.Cover:SetTexture("Interface\\AddOns\\SVUI_Skins\\artwork\\UI-LFG-ICON-ROLES")
+      node.TanksFound.Texture:SetTexture("Interface\\AddOns\\SVUI_Skins\\artwork\\UI-LFG-ICON-ROLES")
+    end
+    if(node.DamagersFound) then
+      node.DamagersFound.Cover:SetTexture("Interface\\AddOns\\SVUI_Skins\\artwork\\UI-LFG-ICON-ROLES")
+      node.DamagersFound.Texture:SetTexture("Interface\\AddOns\\SVUI_Skins\\artwork\\UI-LFG-ICON-ROLES")
+    end
+  end
+end
+
+local LFDQueueRandom_OnUpdate = function()
+  LFDQueueFrame:RemoveTextures()
+  for u = 1, LFD_MAX_REWARDS do
+    local t = _G["LFDQueueFrameRandomScrollFrameChildFrameItem"..u]
+    local icon = _G["LFDQueueFrameRandomScrollFrameChildFrameItem"..u.."IconTexture"]
+    if t then
+      if not t.restyled then
+        local x = _G["LFDQueueFrameRandomScrollFrameChildFrameItem"..u.."ShortageBorder"]
+        local y = _G["LFDQueueFrameRandomScrollFrameChildFrameItem"..u.."Count"]
+        local z = _G["LFDQueueFrameRandomScrollFrameChildFrameItem"..u.."NameFrame"]
+        icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+        icon:SetDrawLayer("OVERLAY")
+        y:SetDrawLayer("OVERLAY")
+        z:SetTexture()
+        z:SetSize(118, 39)
+        x:SetAlpha(0)
+        t.border = CreateFrame("Frame", nil, t)
+        t.border:SetStyle("!_Frame")
+        t.border:WrapPoints(icon)
+        icon:SetParent(t.border)
+        y:SetParent(t.border)
+        t.restyled = true;
+        for A = 1, 3 do
+          local B = _G["LFDQueueFrameRandomScrollFrameChildFrameItem"..u.."RoleIcon"..A]
+          if B then
+             B:SetParent(t.border)
+          end
+        end
+      end
+    end
+  end
+end
+
+local ScenarioQueueRandom_OnUpdate = function()
+  LFDQueueFrame:RemoveTextures()
+  for u = 1, LFD_MAX_REWARDS do
+    local t = _G["ScenarioQueueFrameRandomScrollFrameChildFrameItem"..u]
+    local icon = _G["ScenarioQueueFrameRandomScrollFrameChildFrameItem"..u.."IconTexture"]
+    if t then
+      if not t.restyled then
+        local x = _G["ScenarioQueueFrameRandomScrollFrameChildFrameItem"..u.."ShortageBorder"]
+        local y = _G["ScenarioQueueFrameRandomScrollFrameChildFrameItem"..u.."Count"]
+        local z = _G["ScenarioQueueFrameRandomScrollFrameChildFrameItem"..u.."NameFrame"]icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+        icon:SetDrawLayer("OVERLAY")
+        y:SetDrawLayer("OVERLAY")
+        z:SetTexture()
+        z:SetSize(118, 39)
+        x:SetAlpha(0)
+        t.border = CreateFrame("Frame", nil, t)
+        t.border:SetStyle("!_Frame")
+        t.border:WrapPoints(icon)
+        icon:SetParent(t.border)
+        y:SetParent(t.border)
+        t.restyled = true
+      end
+    end
+  end
+  StyleMoneyRewards("LFDQueueFrameRandomScrollFrameChildFrameMoneyReward")
+  StyleMoneyRewards("RaidFinderQueueFrameScrollFrameChildFrameMoneyReward")
+  StyleMoneyRewards("ScenarioQueueFrameRandomScrollFrameChildFrameMoneyReward")
+end
+--[[
+##########################################################
+LFD MODR
+##########################################################
+]]--
+local function LFDFrameStyle()
+  if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.lfg ~= true then return end
+
+  SV.API:Set("Window", PVEFrame)
+
+  LFGDungeonReadyDialog:RemoveTextures()
+  LFGDungeonReadyDialog:SetStyle("Frame", "Pattern", true, 2, 4, 4)
+
+  PVEFrameLeftInset:RemoveTextures()
+  RaidFinderQueueFrame:RemoveTextures(true)
+  PVEFrameBg:Hide()
+  PVEFrameTitleBg:Hide()
+  PVEFramePortrait:Hide()
+  PVEFramePortraitFrame:Hide()
+  PVEFrameTopRightCorner:Hide()
+  PVEFrameTopBorder:Hide()
+  PVEFrameLeftInsetBg:Hide()
+  PVEFrame.shadows:Hide()
+  PVEFrame:EnableMouse(false)
+
+  LFDQueueFramePartyBackfillBackfillButton:SetStyle("Button")
+  LFDQueueFramePartyBackfillNoBackfillButton:SetStyle("Button")
+  LFDQueueFrameRandomScrollFrameChildFrameBonusRepFrame.ChooseButton:SetStyle("Button")
+  ScenarioQueueFrameRandomScrollFrameChildFrameBonusRepFrame.ChooseButton:SetStyle("Button")
+
+  SV.API:Set("ScrollBar", ScenarioQueueFrameRandomScrollFrame)
+
+  GroupFinderFrameGroupButton1.icon:SetTexture("Interface\\Icons\\INV_Helmet_08")
+  GroupFinderFrameGroupButton2.icon:SetTexture("Interface\\Icons\\Icon_Scenarios")
+  GroupFinderFrameGroupButton3.icon:SetTexture("Interface\\LFGFrame\\UI-LFR-PORTRAIT")
+  GroupFinderFrameGroupButton4.icon:SetTexture("Interface\\Icons\\Achievement_General_StayClassy")
+
+  LFGDungeonReadyDialogBackground:Die()
+  LFGDungeonReadyDialogEnterDungeonButton:SetStyle("Button")
+  LFGDungeonReadyDialogLeaveQueueButton:SetStyle("Button")
+  SV.API:Set("CloseButton", LFGDungeonReadyDialogCloseButton)
+
+  LFGDungeonReadyStatus:RemoveTextures()
+  LFGDungeonReadyStatus:SetStyle("Frame", "Pattern", true, 2, 4, 4)
+  --/script StaticPopupSpecial_Show(LFGDungeonReadyStatus);
+  LFGDungeonReadyPopup:RemoveTextures()
+  LFGDungeonReadyPopup:SetStyle("Frame", "Pattern", true, 2, 4, 4)
+  --LFGDungeonReadyPopup:SetScript('OnShow', nil)
+  --/script StaticPopupSpecial_Show(LFGDungeonReadyPopup);
+
+  for _,name in pairs(LFDFrameList) do
+    local frame = _G[name];
+    if(frame) then
+      frame:DisableDrawLayer("BACKGROUND")
+      frame:DisableDrawLayer("OVERLAY")
+      if(frame.incentiveIcon) then
+        frame.incentiveIcon:SetAlpha(0);
+        frame.incentiveIcon:HookScript("OnShow", Incentive_OnShow);
+        frame.incentiveIcon:HookScript("OnHide", Incentive_OnHide);
+      end
+      if(frame.checkButton) then
+        frame.checkButton:SetStyle("CheckButton");
+      end
+      if(frame.shortageBorder) then
+        frame.shortageBorder:Die();
+      end
+      if(frame.cover) then
+        frame.cover:SetTexture("Interface\\AddOns\\SVUI_Skins\\artwork\\UI-LFG-ICON-ROLES")
+      end
+      frame:SetNormalTexture("Interface\\AddOns\\SVUI_Skins\\artwork\\UI-LFG-ICON-ROLES")
+    end
+  end
+
+  for _,name in pairs(LFGStatusList) do
+    local frame = _G[name];
+    if(frame) then
+      local tex = _G[name..'Texture'];
+      if(tex) then
+        tex:SetTexture("Interface\\AddOns\\SVUI_Skins\\artwork\\UI-LFG-ICON-ROLES")
+      end
+    end
+  end
+
+  LFGDungeonReadyDialog.filigree:SetAlpha(0)
+  LFGDungeonReadyDialog.bottomArt:SetAlpha(0)
+  SV.API:Set("CloseButton", LFGDungeonReadyStatusCloseButton)
+
+  LFDQueueFrameRoleButtonLeader.leadIcon = LFDQueueFrameRoleButtonLeader:CreateTexture(nil, 'BACKGROUND')
+  LFDQueueFrameRoleButtonLeader.leadIcon:SetTexture([[Interface\GroupFrame\UI-Group-LeaderIcon]])
+  LFDQueueFrameRoleButtonLeader.leadIcon:SetPoint(LFDQueueFrameRoleButtonLeader:GetNormalTexture():GetPoint())
+  LFDQueueFrameRoleButtonLeader.leadIcon:SetSize(50, 50)
+  LFDQueueFrameRoleButtonLeader.leadIcon:SetAlpha(0.4)
+  RaidFinderQueueFrameRoleButtonLeader.leadIcon = RaidFinderQueueFrameRoleButtonLeader:CreateTexture(nil, 'BACKGROUND')
+  RaidFinderQueueFrameRoleButtonLeader.leadIcon:SetTexture([[Interface\GroupFrame\UI-Group-LeaderIcon]])
+  RaidFinderQueueFrameRoleButtonLeader.leadIcon:SetPoint(RaidFinderQueueFrameRoleButtonLeader:GetNormalTexture():GetPoint())
+  RaidFinderQueueFrameRoleButtonLeader.leadIcon:SetSize(50, 50)
+  RaidFinderQueueFrameRoleButtonLeader.leadIcon:SetAlpha(0.4)
+
+  if(QueueStatusFrame and QueueStatusFrame.StatusEntries) then
+    for i=1, #QueueStatusFrame.StatusEntries do
+      local node = QueueStatusFrame.StatusEntries[i];
+      if(node.RoleIcon1) then
+        node.RoleIcon1:SetTexture("Interface\\AddOns\\SVUI_Skins\\artwork\\UI-LFG-ICON-ROLES")
+      end
+      if(node.RoleIcon2) then
+        node.RoleIcon2:SetTexture("Interface\\AddOns\\SVUI_Skins\\artwork\\UI-LFG-ICON-ROLES")
+      end
+      if(node.RoleIcon3) then
+        node.RoleIcon3:SetTexture("Interface\\AddOns\\SVUI_Skins\\artwork\\UI-LFG-ICON-ROLES")
+      end
+      if(node.HealersFound) then
+        node.HealersFound.Cover:SetTexture("Interface\\AddOns\\SVUI_Skins\\artwork\\UI-LFG-ICON-ROLES")
+        node.HealersFound.Texture:SetTexture("Interface\\AddOns\\SVUI_Skins\\artwork\\UI-LFG-ICON-ROLES")
+      end
+      if(node.TanksFound) then
+        node.TanksFound.Cover:SetTexture("Interface\\AddOns\\SVUI_Skins\\artwork\\UI-LFG-ICON-ROLES")
+        node.TanksFound.Texture:SetTexture("Interface\\AddOns\\SVUI_Skins\\artwork\\UI-LFG-ICON-ROLES")
+      end
+      if(node.DamagersFound) then
+        node.DamagersFound.Cover:SetTexture("Interface\\AddOns\\SVUI_Skins\\artwork\\UI-LFG-ICON-ROLES")
+        node.DamagersFound.Texture:SetTexture("Interface\\AddOns\\SVUI_Skins\\artwork\\UI-LFG-ICON-ROLES")
+      end
+    end
+  end
+
+  hooksecurefunc('QueueStatusFrame_Update', _hook_QueueStatusFrame_Update)
+
+  hooksecurefunc('LFG_DisableRoleButton', function(self)
+    local check = self.checkButton or self.CheckButton
+    if(check) then
+      if(check:GetChecked()) then
+         check:SetAlpha(1)
+      else
+         check:SetAlpha(0)
+      end
+    end
+    if self.background then
+       self.background:Show()
+    end
+  end)
+
+  hooksecurefunc('LFG_EnableRoleButton', function(self)
+    local check = self.checkButton or self.CheckButton
+    if(check) then
+      check:SetAlpha(1)
+    end
+  end)
+
+  hooksecurefunc("LFG_PermanentlyDisableRoleButton", function(self)
+    if self.background then
+       self.background:Show()
+       self.background:SetDesaturated(true)
+    end
+  end)
+
+  for i = 1, 4 do
+    local button = GroupFinderFrame["groupButton"..i]
+    if(button) then
+      button.ring:Hide()
+      button.bg:SetTexture("")
+      button.bg:SetAllPoints()
+      button:SetStyle("Frame", 'Button')
+      button:SetStyle("Button")
+      button.icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+      button.icon:SetDrawLayer("OVERLAY")
+      button.icon:SetSize(40, 40)
+      button.icon:ClearAllPoints()
+      button.icon:SetPoint("LEFT", button, "LEFT", 10, 0)
+      button.border = CreateFrame("Frame", nil, button)
+      button.border:SetStyle("!_Frame", 'Default')
+      button.border:WrapPoints(button.icon)
+      button.icon:SetParent(button.border)
+    end
+  end
+
+  for u = 1, 3 do
+     SV.API:Set("Tab", _G['PVEFrameTab'..u])
+  end
+
+  PVEFrameTab1:SetPoint('BOTTOMLEFT', PVEFrame, 'BOTTOMLEFT', 19, -31)
+  SV.API:Set("CloseButton", PVEFrameCloseButton)
+  LFDParentFrame:RemoveTextures()
+  LFDQueueFrameFindGroupButton:RemoveTextures()
+  LFDParentFrameInset:RemoveTextures()
+  LFDQueueFrameSpecificListScrollFrame:RemoveTextures()
+  LFDQueueFrameFindGroupButton:SetStyle("Button")
+  hooksecurefunc("LFDQueueFrameRandom_UpdateFrame", LFDQueueRandom_OnUpdate)
+
+  SV.API:Set("DropDown", LFDQueueFrameTypeDropDown)
+
+  RaidFinderFrame:RemoveTextures()
+  RaidFinderFrameBottomInset:RemoveTextures()
+  RaidFinderFrameRoleInset:RemoveTextures()
+  LFDQueueFrameRandomScrollFrame:RemoveTextures()
+  ScenarioQueueFrameSpecificScrollFrame:RemoveTextures()
+  RaidFinderFrameBottomInsetBg:Hide()
+  RaidFinderFrameBtnCornerRight:Hide()
+  RaidFinderFrameButtonBottomBorder:Hide()
+  SV.API:Set("DropDown", RaidFinderQueueFrameSelectionDropDown)
+  RaidFinderFrameFindRaidButton:RemoveTextures()
+  RaidFinderFrameFindRaidButton:SetStyle("Button")
+  RaidFinderQueueFrame:RemoveTextures()
+
+  for u = 1, LFD_MAX_REWARDS do
+    local t = _G["RaidFinderQueueFrameScrollFrameChildFrameItem"..u]
+    local icon = _G["RaidFinderQueueFrameScrollFrameChildFrameItem"..u.."IconTexture"]
+    if t then
+      if not t.restyled then
+        local x = _G["RaidFinderQueueFrameScrollFrameChildFrameItem"..u.."ShortageBorder"]
+        local y = _G["RaidFinderQueueFrameScrollFrameChildFrameItem"..u.."Count"]
+        local z = _G["RaidFinderQueueFrameScrollFrameChildFrameItem"..u.."NameFrame"]
+        t:RemoveTextures()
+        icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+        icon:SetDrawLayer("OVERLAY")
+        y:SetDrawLayer("OVERLAY")
+        z:SetTexture()
+        z:SetSize(118, 39)
+        x:SetAlpha(0)
+        t.border = CreateFrame("Frame", nil, t)
+        t.border:SetStyle("!_Frame")
+        t.border:WrapPoints(icon)
+        icon:SetParent(t.border)
+        y:SetParent(t.border)
+        t.restyled = true
+      end
+    end
+  end
+
+  StyleMoneyRewards("LFDQueueFrameRandomScrollFrameChildFrameMoneyReward")
+  StyleMoneyRewards("RaidFinderQueueFrameScrollFrameChildFrameMoneyReward")
+  StyleMoneyRewards("ScenarioQueueFrameRandomScrollFrameChildFrameMoneyReward")
+
+
+  ScenarioFinderFrameInset:DisableDrawLayer("BORDER")
+  ScenarioFinderFrame.TopTileStreaks:Hide()
+  ScenarioFinderFrameBtnCornerRight:Hide()
+  ScenarioFinderFrameButtonBottomBorder:Hide()
+  ScenarioQueueFrame.Bg:Hide()
+  ScenarioFinderFrameInset:GetRegions():Hide()
+  hooksecurefunc("ScenarioQueueFrameRandom_UpdateFrame", ScenarioQueueRandom_OnUpdate)
+  ScenarioQueueFrameFindGroupButton:RemoveTextures()
+  ScenarioQueueFrameFindGroupButton:SetStyle("Button")
+  SV.API:Set("DropDown", ScenarioQueueFrameTypeDropDown)
+  LFRBrowseFrameRoleInset:DisableDrawLayer("BORDER")
+  RaidBrowserFrameBg:Hide()
+  LFRQueueFrameSpecificListScrollFrameScrollBackgroundTopLeft:Hide()
+  LFRQueueFrameSpecificListScrollFrameScrollBackgroundBottomRight:Hide()
+  LFRBrowseFrameRoleInsetBg:Hide()
+
+  for u = 1, 14 do
+    if u ~= 6 and u ~= 8 then
+       select(u, RaidBrowserFrame:GetRegions()):Hide()
+    end
+  end
+
+  RaidBrowserFrame:SetStyle("Frame", 'Pattern')
+  SV.API:Set("CloseButton", RaidBrowserFrameCloseButton)
+  LFRQueueFrameFindGroupButton:SetStyle("Button")
+  LFRQueueFrameAcceptCommentButton:SetStyle("Button")
+  SV.API:Set("ScrollBar", LFRQueueFrameCommentScrollFrame)
+  SV.API:Set("ScrollBar", LFDQueueFrameSpecificListScrollFrame)
+
+  RaidBrowserFrame:HookScript('OnShow', function()
+    if not LFRQueueFrameSpecificListScrollFrame.styled then
+      SV.API:Set("ScrollBar", LFRQueueFrameSpecificListScrollFrame)
+      LFRBrowseFrame:RemoveTextures()
+      for u = 1, 2 do
+        local C = _G['LFRParentFrameSideTab'..u]
+        C:DisableDrawLayer('BACKGROUND')
+        C:GetNormalTexture():SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+        C:GetNormalTexture():InsetPoints()
+        C.pushed = true;
+        C:SetStyle("Frame", "Default")
+        C.Panel:SetAllPoints()
+        C:SetStyle("Frame")
+        hooksecurefunc(C:GetHighlightTexture(), "SetTexture", function(o, D)
+          if D ~= nil then
+             o:SetTexture("")
+          end
+        end)
+      end
+      for u = 1, 7 do
+        local C = _G['LFRBrowseFrameColumnHeader'..u]
+        C:DisableDrawLayer('BACKGROUND')
+      end
+      SV.API:Set("DropDown", LFRBrowseFrameRaidDropDown)
+      LFRBrowseFrameRefreshButton:SetStyle("Button")
+      LFRBrowseFrameInviteButton:SetStyle("Button")
+      LFRBrowseFrameSendMessageButton:SetStyle("Button")
+      LFRQueueFrameSpecificListScrollFrame.styled = true
+    end
+  end)
+
+  LFGInvitePopup:RemoveTextures()
+  LFGInvitePopup:SetStyle("Frame", "Pattern", true, 2, 4, 4)
+  LFGInvitePopup.timeOut = 60;
+  --/script StaticPopupSpecial_Show(LFGInvitePopup);
+  LFGInvitePopupAcceptButton:SetStyle("Button")
+  LFGInvitePopupDeclineButton:SetStyle("Button")
+
+  _G[LFDQueueFrame.PartyBackfill:GetName().."BackfillButton"]:SetStyle("Button")
+  _G[LFDQueueFrame.PartyBackfill:GetName().."NoBackfillButton"]:SetStyle("Button")
+  _G[RaidFinderQueueFrame.PartyBackfill:GetName().."BackfillButton"]:SetStyle("Button")
+  _G[RaidFinderQueueFrame.PartyBackfill:GetName().."NoBackfillButton"]:SetStyle("Button")
+  _G[ScenarioQueueFrame.PartyBackfill:GetName().."BackfillButton"]:SetStyle("Button")
+  _G[ScenarioQueueFrame.PartyBackfill:GetName().."NoBackfillButton"]:SetStyle("Button")
+
+  SV.API:Set("ScrollBar", LFDQueueFrameRandomScrollFrame)
+  SV.API:Set("ScrollBar", ScenarioQueueFrameSpecificScrollFrame)
+  LFDQueueFrameRandomScrollFrame:SetStyle("Frame", 'Transparent')
+  ScenarioQueueFrameRandomScrollFrame:SetStyle("Frame", 'Transparent')
+  RaidFinderQueueFrameScrollFrame:SetStyle("Frame", 'Transparent')
+
+  -- for u = 1, NUM_LFD_CHOICE_BUTTONS do
+  --   local box = _G["LFDQueueFrameSpecificListButton"..u.."EnableButton"]
+  --   if(box and (not box.Panel)) then
+  --     box:RemoveTextures()
+  --     box:SetStyle("CheckButton")
+  --     box:SetFrameLevel(box:GetFrameLevel() + 50)
+  --   end
+  -- end
+
+  -- for u = 1, NUM_LFR_CHOICE_BUTTONS do
+  --   local box = _G["LFRQueueFrameSpecificListButton"..u.."EnableButton"]
+  --   if(box and (not box.Panel)) then
+  --     box:RemoveTextures()
+  --     box:SetStyle("CheckButton")
+  --     box:SetFrameLevel(box:GetFrameLevel() + 50)
+  --   end
+  -- end
+
+  LFGListFrame.CategorySelection:RemoveTextures()
+  LFGListFrame.CategorySelection.Inset:RemoveTextures()
+  LFGListFrame.CategorySelection.StartGroupButton:RemoveTextures()
+  LFGListFrame.CategorySelection.StartGroupButton:SetStyle("Button")
+  LFGListFrame.CategorySelection.FindGroupButton:RemoveTextures()
+  LFGListFrame.CategorySelection.FindGroupButton:SetStyle("Button")
+
+  LFGListFrame.NothingAvailable:RemoveTextures()
+  LFGListFrame.NothingAvailable.Inset:RemoveTextures()
+
+  LFGListFrame.SearchPanel:RemoveTextures()
+  LFGListFrame.SearchPanel.ResultsInset:RemoveTextures()
+
+  --LFGListFrame.SearchPanel.RefreshButton:RemoveTextures()
+  LFGListFrame.SearchPanel.RefreshButton:SetStyle("Button")
+
+  LFGListFrame.SearchPanel.FilterButton:RemoveTextures()
+  LFGListFrame.SearchPanel.FilterButton:SetStyle("Button")
+
+  LFGListFrame.SearchPanel.BackButton:RemoveTextures()
+  LFGListFrame.SearchPanel.BackButton:SetStyle("Button")
+  LFGListFrame.SearchPanel.SignUpButton:RemoveTextures()
+  LFGListFrame.SearchPanel.SignUpButton:SetStyle("Button")
+
+  SV.API:Set("!_EditBox", LFGListFrame.SearchPanel.SearchBox, false, false, -2, -1)
+  SV.API:Set("ScrollBar", LFGListSearchPanelScrollFrame)
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveCustomStyle(LFDFrameStyle)
diff --git a/SVUI_Skins/components/blizzard/macro.lua b/SVUI_Skins/components/blizzard/macro.lua
new file mode 100644
index 0000000..b8f357b
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/macro.lua
@@ -0,0 +1,152 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+HELPERS
+##########################################################
+]]--
+local MacroButtonList = {
+	"MacroSaveButton", "MacroCancelButton", "MacroDeleteButton", "MacroNewButton", "MacroExitButton", "MacroEditButton", "MacroFrameTab1", "MacroFrameTab2", "MacroPopupOkayButton", "MacroPopupCancelButton"
+}
+local MacroButtonList2 = {
+	"MacroDeleteButton", "MacroNewButton", "MacroExitButton"
+}
+--[[
+##########################################################
+MACRO UI MODR
+##########################################################
+]]--
+local function MacroUIStyle()
+	if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.macro ~= true then return end
+
+	SV.API:Set("Window", MacroFrame, true)
+
+	SV.API:Set("CloseButton", MacroFrameCloseButton)
+	SV.API:Set("ScrollBar", MacroButtonScrollFrame)
+	SV.API:Set("ScrollBar", MacroFrameScrollFrame)
+	SV.API:Set("ScrollBar", MacroPopupScrollFrame)
+
+	MacroFrame:SetWidth(360)
+
+	local parentStrata = MacroFrame:GetFrameStrata()
+	local parentLevel = MacroFrame:GetFrameLevel()
+
+	for i = 1, #MacroButtonList do
+		local button = _G[MacroButtonList[i]]
+		if(button) then
+			button:SetFrameStrata(parentStrata)
+			button:SetFrameLevel(parentLevel + 1)
+			button:RemoveTextures()
+			button:SetStyle("Button")
+		end
+	end
+
+	for i = 1, #MacroButtonList2 do
+		local button = _G[MacroButtonList2[i]]
+		if(button) then
+			local a1,p,a2,x,y = button:GetPoint()
+			button:SetPoint(a1,p,a2,x,-25)
+		end
+	end
+
+	local firstTab
+	for i = 1, 2 do
+		local tab = _G[("MacroFrameTab%d"):format(i)]
+		if(tab) then
+			tab:SetHeight(22)
+			if(i == 1) then
+				tab:SetPoint("TOPLEFT", MacroFrame, "TOPLEFT", 85, -39)
+				firstTab = tab
+			elseif(firstTab) then
+				tab:SetPoint("LEFT", firstTab, "RIGHT", 4, 0)
+			end
+		end
+	end
+
+	MacroFrameText:SetFont(SV.media.font.default, 12, "NONE")
+	MacroFrameTextBackground:RemoveTextures()
+	MacroFrameTextBackground:SetStyle("Frame", 'Transparent')
+
+	MacroPopupFrame:RemoveTextures()
+	MacroPopupFrame:SetStyle("Frame", 'Transparent')
+
+	MacroPopupScrollFrame:RemoveTextures()
+	MacroPopupScrollFrame:SetStyle("Frame", "Pattern")
+	MacroPopupScrollFrame.Panel:SetPoint("TOPLEFT", 51, 2)
+	MacroPopupScrollFrame.Panel:SetPoint("BOTTOMRIGHT", -4, 4)
+	MacroPopupEditBox:SetStyle("Editbox")
+	MacroPopupNameLeft:SetTexture("")
+	MacroPopupNameMiddle:SetTexture("")
+	MacroPopupNameRight:SetTexture("")
+
+	MacroFrameInset:Die()
+
+	MacroButtonContainer:RemoveTextures()
+	SV.API:Set("ScrollBar", MacroButtonScrollFrame)
+	MacroButtonScrollFrame:SetStyle("!_Frame", "Inset")
+
+	MacroPopupFrame:HookScript("OnShow", function(c)
+		c:ClearAllPoints()
+		c:SetPoint("TOPLEFT", MacroFrame, "TOPRIGHT", 5, -2)
+	end)
+
+	MacroFrameSelectedMacroButton:SetFrameStrata(parentStrata)
+	MacroFrameSelectedMacroButton:SetFrameLevel(parentLevel + 1)
+	MacroFrameSelectedMacroButton:RemoveTextures()
+	MacroFrameSelectedMacroButton:SetStyle("ActionSlot")
+	MacroFrameSelectedMacroButtonIcon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+	MacroFrameSelectedMacroButtonIcon:InsetPoints()
+
+	MacroEditButton:ClearAllPoints()
+	MacroEditButton:SetPoint("BOTTOMLEFT", MacroFrameSelectedMacroButton.Panel, "BOTTOMRIGHT", 10, 0)
+
+	MacroFrameCharLimitText:ClearAllPoints()
+	MacroFrameCharLimitText:SetPoint("BOTTOM", MacroFrameTextBackground, -25, -35)
+
+	for i = 1, MAX_ACCOUNT_MACROS do
+		local button = _G["MacroButton"..i]
+		if(button) then
+			button:RemoveTextures()
+			button:SetStyle("ActionSlot")
+
+			local icon = _G["MacroButton"..i.."Icon"]
+			if(icon) then
+				icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+				icon:InsetPoints()
+				icon:SetDrawLayer("OVERLAY")
+			end
+
+			local popup = _G["MacroPopupButton"..i]
+			if(popup) then
+				popup:RemoveTextures()
+				popup:SetStyle("Button")
+				popup:SetBackdropColor(0, 0, 0, 0)
+
+				local popupIcon = _G["MacroPopupButton"..i.."Icon"]
+				if(popupIcon) then
+					popupIcon:InsetPoints()
+					popupIcon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+				end
+			end
+		end
+	end
+end
+
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveBlizzardStyle("Blizzard_MacroUI", MacroUIStyle)
\ No newline at end of file
diff --git a/SVUI_Skins/components/blizzard/misc.lua b/SVUI_Skins/components/blizzard/misc.lua
new file mode 100644
index 0000000..725bb5c
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/misc.lua
@@ -0,0 +1,754 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+##########################################################
+]]--
+local _hook_NavBar_AddButton = function(self, buttonData)
+	local navButton = self.navList[#self.navList];
+	if(not navButton or navButton.Panel) then return end
+	navButton:RemoveTextures()
+	navButton:SetStyle("Button")
+	if(navButton.MenuArrowButton) then
+		navButton.MenuArrowButton:SetNormalTexture('')
+		navButton.MenuArrowButton:SetPushedTexture('')
+	end
+end
+
+hooksecurefunc("NavBar_AddButton", _hook_NavBar_AddButton)
+--[[
+local MissingLootFrame_OnShow = function(self)
+	local numMissing = GetNumMissingLootItems()
+	for i = 1, numMissing do
+		local slot = _G["MissingLootFrameItem"..i]
+		local icon = slot.icon;
+		SV.API:Set("!_ItemButton", slot)
+		local texture, name, count, quality = GetMissingLootItemInfo(i);
+		local r,g,b,hex = GetItemQualityColor(quality)
+		if(not r) then
+			r,g,b = 0,0,0
+		end
+		icon:SetTexture(texture)
+		_G.MissingLootFrame:SetBackdropBorderColor(r,g,b)
+	end
+	local calc = (ceil(numMissing * 0.5) * 43) + 38
+	_G.MissingLootFrame:SetHeight(calc + _G.MissingLootFrameLabel:GetHeight())
+end
+]]--
+local LootHistoryFrame_OnUpdate = function(self)
+	local numItems = _G.C_LootHistory.GetNumItems()
+	for i = 1, numItems do
+		local frame = _G.LootHistoryFrame.itemFrames[i]
+		if not frame.isStyled then
+			local Icon = frame.Icon:GetTexture()
+			frame:RemoveTextures()
+			frame.Icon:SetTexture(Icon)
+			frame.Icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+
+			frame:SetStyle("!_Frame", "Button")
+			frame.Panel:WrapPoints(frame.Icon)
+			frame.Icon:SetParent(frame.Panel)
+
+			frame.isStyled = true
+		end
+	end
+end
+
+local _hook_MasterLootFrame_OnShow = function()
+	local MasterLooterFrame = _G.MasterLooterFrame;
+	local item = MasterLooterFrame.Item;
+	local LootFrame = _G.LootFrame;
+	if item then
+		local icon = item.Icon;
+		local tex = icon:GetTexture()
+		local colors = ITEM_QUALITY_COLORS[LootFrame.selectedQuality]
+		item:RemoveTextures()
+		icon:SetTexture(tex)
+		icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+		item:SetStyle("Frame", "Pattern")
+		item.Panel:WrapPoints(icon)
+		item:SetBackdropBorderColor(colors.r, colors.g, colors.b)
+	end
+	for i = 1, MasterLooterFrame:GetNumChildren()do
+		local child = select(i, MasterLooterFrame:GetChildren())
+		if child and not child.isStyled and not child:GetName() then
+			if child:GetObjectType() == "Button" then
+				if child:GetPushedTexture() then
+					SV.API:Set("CloseButton", child)
+				else
+					child:SetStyle("!_Frame")
+					child:SetStyle("Button")
+				end
+				child.isStyled = true
+			end
+		end
+	end
+end
+
+local _hook_LossOfControl = function(self, ...)
+	self.Icon:ClearAllPoints()
+	self.Icon:SetPoint("CENTER", self, "CENTER", 0, 0)
+	self.AbilityName:ClearAllPoints()
+	self.AbilityName:SetPoint("BOTTOM", self, 0, -28)
+	self.AbilityName.scrollTime = nil;
+	self.AbilityName:SetFont(SV.media.font.dialog, 20, 'OUTLINE')
+	self.TimeLeft.NumberText:ClearAllPoints()
+	self.TimeLeft.NumberText:SetPoint("BOTTOM", self, 4, -58)
+	self.TimeLeft.NumberText.scrollTime = nil;
+	self.TimeLeft.NumberText:SetFont(SV.media.font.number, 20, 'OUTLINE')
+	self.TimeLeft.SecondsText:ClearAllPoints()
+	self.TimeLeft.SecondsText:SetPoint("BOTTOM", self, 0, -80)
+	self.TimeLeft.SecondsText.scrollTime = nil;
+	self.TimeLeft.SecondsText:SetFont(SV.media.font.default, 20, 'OUTLINE')
+	if self.Anim:IsPlaying() then
+		self.Anim:Stop()
+	end
+end
+
+local function MailFrame_OnUpdate()
+	for i = 1, ATTACHMENTS_MAX_SEND do
+		local slot = _G["SendMailAttachment"..i]
+		if(not slot.Panel) then
+			slot:RemoveTextures()
+			slot:SetStyle("!_ActionSlot")
+		end
+		if(slot.GetNormalTexture) then
+			local icon = slot:GetNormalTexture()
+			if(icon) then
+				icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+				icon:InsetPoints()
+			end
+		end
+	end
+end
+
+local _hook_GreetingPanelShow = function(self)
+	self:RemoveTextures()
+	_G.QuestFrameGreetingGoodbyeButton:SetStyle("Button")
+	_G.QuestGreetingFrameHorizontalBreak:Die()
+end
+
+local function StyleTradeSlots(name)
+	local slot = _G[name]
+	if(not slot) then return end
+
+	local button = _G[name.."ItemButton"]
+	if(button and (not button.Panel)) then
+		slot:RemoveTextures()
+
+		button:RemoveTextures()
+		button:SetStyle("!_ActionSlot")
+
+		local icon = _G[name.."ItemButtonIconTexture"]
+		if(icon) then
+			icon:InsetPoints(button)
+			icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+		end
+
+		local anchor = _G[name.."NameFrame"]
+		if(anchor) then
+			local bg = CreateFrame("Frame", nil, button)
+			bg:SetStyle("Frame", "Inset")
+			bg:SetPoint("TOPLEFT", button, "TOPRIGHT", 4, 0)
+			bg:SetPoint("BOTTOMRIGHT", anchor, "BOTTOMRIGHT", -10, 14)
+
+			local level = button:GetFrameLevel()
+			if(level < 3) then
+				bg:SetFrameLevel(0)
+			else
+				bg:SetFrameLevel(level - 3)
+			end
+		end
+	end
+end
+
+local TABARD_REGIONS = {
+	["TabardFrameEmblemTopRight"] = true,
+	["TabardFrameEmblemTopLeft"] = true,
+	["TabardFrameEmblemBottomRight"] = true,
+	["TabardFrameEmblemBottomLeft"] = true,
+}
+--[[
+##########################################################
+##########################################################
+]]--
+local function MiscStyles()
+	--print('test MiscStyles')
+	if SV.db.Skins.blizzard.enable ~= true then
+		 return
+	end
+
+	if(SV.db.Skins.blizzard.dressingroom) then
+		DressUpFrame:SetSize(500, 600)
+		SV.API:Set("Window", DressUpFrame, true, true)
+
+		DressUpModel:ClearAllPoints()
+		DressUpModel:SetPoint("TOPLEFT", DressUpFrame, "TOPLEFT", 12, -76)
+		DressUpModel:SetPoint("BOTTOMRIGHT", DressUpFrame, "BOTTOMRIGHT", -12, 36)
+
+		DressUpModel:SetStyle("!_Frame", "Model")
+
+		DressUpFrameCancelButton:SetPoint("BOTTOMRIGHT", DressUpFrame, "BOTTOMRIGHT", -12, 12)
+		DressUpFrameCancelButton:SetStyle("Button")
+
+		DressUpFrameResetButton:SetPoint("RIGHT", DressUpFrameCancelButton, "LEFT", -12, 0)
+		DressUpFrameResetButton:SetStyle("Button")
+
+		SV.API:Set("CloseButton", DressUpFrameCloseButton, DressUpFrame.Panel)
+	end
+
+	if(SV.db.Skins.blizzard.gossip) then
+		SV.API:Set("Window", GossipFrame, true, true)
+
+		ItemTextFrame:RemoveTextures(true)
+		ItemTextScrollFrame:RemoveTextures()
+		SV.API:Set("CloseButton", GossipFrameCloseButton)
+		SV.API:Set("PageButton", ItemTextPrevPageButton, false, true)
+		SV.API:Set("PageButton", ItemTextNextPageButton)
+		ItemTextPageText:SetTextColor(1, 1, 1)
+		hooksecurefunc(ItemTextPageText, "SetTextColor", function(q, k, l, m)
+			if k ~= 1 or l ~= 1 or m ~= 1 then
+				ItemTextPageText:SetTextColor(1, 1, 1)
+			end
+		end)
+		ItemTextFrame:SetStyle("Frame", "Pattern")
+		ItemTextFrameInset:Die()
+		SV.API:Set("ScrollBar", ItemTextScrollFrame)
+		SV.API:Set("CloseButton", ItemTextFrameCloseButton)
+		local r = {"GossipFrameGreetingPanel", "GossipFrameInset", "GossipGreetingScrollFrame"}
+		SV.API:Set("ScrollBar", GossipGreetingScrollFrame)
+		for s, t in pairs(r)do
+			_G[t]:RemoveTextures()
+		end
+		GossipFrame:SetStyle("Frame", "Window")
+		GossipGreetingScrollFrame:SetStyle("!_Frame", "Inset", true)
+		GossipGreetingScrollFrame.spellTex = GossipGreetingScrollFrame:CreateTexture(nil, "ARTWORK")
+		GossipGreetingScrollFrame.spellTex:SetTexture([[Interface\QuestFrame\QuestBG]])
+		GossipGreetingScrollFrame.spellTex:SetPoint("TOPLEFT", 2, -2)
+		GossipGreetingScrollFrame.spellTex:SetSize(506, 615)
+		GossipGreetingScrollFrame.spellTex:SetTexCoord(0, 1, 0.02, 1)
+		_G["GossipFramePortrait"]:Die()
+		_G["GossipFrameGreetingGoodbyeButton"]:RemoveTextures()
+		_G["GossipFrameGreetingGoodbyeButton"]:SetStyle("Button")
+		SV.API:Set("CloseButton", GossipFrameCloseButton, GossipFrame.Panel)
+
+		NPCFriendshipStatusBar:RemoveTextures()
+		NPCFriendshipStatusBar:SetFrameStrata('HIGH')
+		NPCFriendshipStatusBar:SetWidth(205)
+		NPCFriendshipStatusBar:SetStatusBarTexture(SV.media.statusbar.default)
+		NPCFriendshipStatusBar:SetStyle("Frame", "Bar")
+
+		NPCFriendshipStatusBar:ClearAllPoints()
+		NPCFriendshipStatusBar:SetPoint("TOPLEFT", GossipFrame, "TOPLEFT", 98, -38)
+
+		NPCFriendshipStatusBar.icon:SetSize(32,32)
+		NPCFriendshipStatusBar.icon:ClearAllPoints()
+		NPCFriendshipStatusBar.icon:SetPoint("LEFT", NPCFriendshipStatusBar, "RIGHT", 0, -2)
+
+		SV.NPC:Register(GossipFrame, GossipFrameNpcNameText)
+		hooksecurefunc("GossipTitleButton_OnClick", function() SV.NPC:PlayerTalksFirst() end)
+	end
+
+	if (SV.db.Skins.blizzard.greeting) then
+		_G.QuestFrameGreetingPanel:HookScript("OnShow", _hook_GreetingPanelShow)
+	end
+
+	if(SV.db.Skins.blizzard.guildregistrar) then
+		SV.API:Set("Window", GuildRegistrarFrame, true, true)
+
+		GuildRegistrarFrameInset:Die()
+		GuildRegistrarFrameEditBox:RemoveTextures()
+		GuildRegistrarGreetingFrame:RemoveTextures()
+
+		GuildRegistrarFrameGoodbyeButton:SetStyle("Button")
+		GuildRegistrarFrameCancelButton:SetStyle("Button")
+		GuildRegistrarFramePurchaseButton:SetStyle("Button")
+		SV.API:Set("CloseButton", GuildRegistrarFrameCloseButton)
+		GuildRegistrarFrameEditBox:SetStyle("Editbox")
+
+		for i = 1, GuildRegistrarFrameEditBox:GetNumRegions() do
+			local region = select(i, GuildRegistrarFrameEditBox:GetRegions())
+			if region and region:GetObjectType() == "Texture"then
+				if region:GetTexture() == "Interface\\ChatFrame\\UI-ChatInputBorder-Left" or region:GetTexture() == "Interface\\ChatFrame\\UI-ChatInputBorder-Right" then
+					region:Die()
+				end
+			end
+		end
+
+		GuildRegistrarFrameEditBox:SetHeight(20)
+
+		if(_G["GuildRegistrarButton1"]) then
+			_G["GuildRegistrarButton1"]:GetFontString():SetTextColor(1, 1, 1)
+		end
+		if(_G["GuildRegistrarButton2"]) then
+			_G["GuildRegistrarButton2"]:GetFontString():SetTextColor(1, 1, 1)
+		end
+
+		GuildRegistrarPurchaseText:SetTextColor(1, 1, 1)
+		AvailableServicesText:SetTextColor(1, 1, 0)
+	end
+
+	if(SV.db.Skins.blizzard.loot) then
+		local MasterLooterFrame = _G.MasterLooterFrame;
+		--local MissingLootFrame = _G.MissingLootFrame;
+		local LootHistoryFrame = _G.LootHistoryFrame;
+		local BonusRollFrame = _G.BonusRollFrame;
+		--local MissingLootFramePassButton = _G.MissingLootFramePassButton;
+
+		LootHistoryFrame:SetFrameStrata('HIGH')
+
+		--MissingLootFrame:RemoveTextures()
+		--MissingLootFrame:SetStyle("Frame", "Pattern")
+
+		--SV.API:Set("CloseButton", MissingLootFramePassButton)
+		--hooksecurefunc("MissingLootFrame_Show", MissingLootFrame_OnShow)
+		LootHistoryFrame:RemoveTextures()
+		SV.API:Set("CloseButton", LootHistoryFrame.CloseButton)
+		LootHistoryFrame:RemoveTextures()
+		LootHistoryFrame:SetStyle("!_Frame", 'Transparent')
+		SV.API:Set("CloseButton", LootHistoryFrame.ResizeButton)
+		LootHistoryFrame.ResizeButton:SetStyle("!_Frame")
+		LootHistoryFrame.ResizeButton:SetWidth(LootHistoryFrame:GetWidth())
+		LootHistoryFrame.ResizeButton:SetHeight(19)
+		LootHistoryFrame.ResizeButton:ClearAllPoints()
+		LootHistoryFrame.ResizeButton:SetPoint("TOP", LootHistoryFrame, "BOTTOM", 0, -2)
+		LootHistoryFrame.ResizeButton:SetNormalTexture("")
+
+		local txt = LootHistoryFrame.ResizeButton:CreateFontString(nil,"OVERLAY")
+		txt:SetFont(SV.media.font.default, 14, "NONE")
+		txt:SetAllPoints(LootHistoryFrame.ResizeButton)
+		txt:SetJustifyH("CENTER")
+		txt:SetText("RESIZE")
+
+		LootHistoryFrameScrollFrame:RemoveTextures()
+		SV.API:Set("ScrollBar", LootHistoryFrameScrollFrame)
+		hooksecurefunc("LootHistoryFrame_FullUpdate", LootHistoryFrame_OnUpdate)
+
+		MasterLooterFrame:RemoveTextures()
+		MasterLooterFrame:SetStyle("!_Frame")
+		MasterLooterFrame:SetFrameStrata('FULLSCREEN_DIALOG')
+
+		hooksecurefunc("MasterLooterFrame_Show", _hook_MasterLootFrame_OnShow)
+
+		BonusRollFrame:RemoveTextures()
+		SV.API:Set("Alert", BonusRollFrame)
+		BonusRollFrame.PromptFrame.Icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+		BonusRollFrame.PromptFrame.Timer.Bar:SetTexture(SV.media.statusbar.default)
+		BonusRollFrame.PromptFrame.Timer.Bar:SetVertexColor(0.1, 1, 0.1)
+	end
+
+	if(SV.db.Skins.blizzard.losscontrol) then
+		local IconBackdrop = CreateFrame("Frame", nil, LossOfControlFrame)
+		IconBackdrop:WrapPoints(LossOfControlFrame.Icon)
+		IconBackdrop:SetFrameLevel(LossOfControlFrame:GetFrameLevel()-1)
+		IconBackdrop:SetStyle("Frame", "Icon")
+		LossOfControlFrame.Icon:SetTexCoord(.1, .9, .1, .9)
+		LossOfControlFrame:RemoveTextures()
+		LossOfControlFrame.AbilityName:ClearAllPoints()
+		hooksecurefunc("LossOfControlFrame_SetUpDisplay", _hook_LossOfControl)
+	end
+
+	if(SV.db.Skins.blizzard.mail) then
+		InboxFrame:RemoveTextures()
+		MailFrameInset:Die()
+		SendMailMoneyBg:Die()
+		SendMailMoneyInset:RemoveTextures()
+		SendMailFrame:RemoveTextures()
+		MailFrameTab1:RemoveTextures()
+		MailFrameTab2:RemoveTextures()
+
+		SV.API:Set("Window", MailFrame)
+		SV.API:Set("CloseButton", MailFrameCloseButton)
+		SV.API:Set("PageButton", InboxPrevPageButton, false, true)
+		SV.API:Set("PageButton", InboxNextPageButton)
+
+		SV.API:Set("Tab", MailFrameTab1)
+		SV.API:Set("Tab", MailFrameTab2)
+
+		SendMailScrollFrame:RemoveTextures(true)
+		SendMailScrollFrame:SetStyle("!_Frame", "Inset")
+		SV.API:Set("ScrollBar", SendMailScrollFrame)
+
+		SendMailNameEditBox:SetStyle("Editbox")
+		SendMailNameEditBox.Panel:SetPoint("BOTTOMRIGHT", 2, 4)
+
+		SendMailSubjectEditBox:SetStyle("Editbox")
+		SendMailSubjectEditBox.Panel:SetPoint("BOTTOMRIGHT", 2, 0)
+
+		SendMailMoneyGold:SetStyle("Editbox")
+
+		SendMailMoneySilver:SetStyle("Editbox")
+		SendMailMoneySilver.Panel:SetPoint("TOPLEFT", -2, 1)
+		SendMailMoneySilver.Panel:SetPoint("BOTTOMRIGHT", -12, -1)
+		SendMailMoneySilver:SetTextInsets(-1, -1, -2, -2)
+
+		SendMailMoneyCopper:SetStyle("Editbox")
+		SendMailMoneyCopper.Panel:SetPoint("TOPLEFT", -2, 1)
+		SendMailMoneyCopper.Panel:SetPoint("BOTTOMRIGHT", -12, -1)
+		SendMailMoneyCopper:SetTextInsets(-1, -1, -2, -2)
+
+		hooksecurefunc("SendMailFrame_Update", MailFrame_OnUpdate)
+		SendMailCancelButton:SetStyle("Button")
+		SendMailMailButton:SetStyle("Button")
+		SendMailMailButton:SetPoint("RIGHT", SendMailCancelButton, "LEFT", -2, 0)
+
+		OpenMailFrame:RemoveTextures(true)
+		OpenMailFrame:SetStyle("!_Frame", "Transparent", true)
+		OpenMailFrameInset:Die()
+
+		OpenMailReportSpamButton:SetStyle("Button")
+		OpenMailCancelButton:SetStyle("Button")
+		OpenMailDeleteButton:SetStyle("Button")
+		OpenMailDeleteButton:SetPoint("RIGHT", OpenMailCancelButton, "LEFT", -2, 0)
+		OpenMailReplyButton:SetStyle("Button")
+		OpenMailReplyButton:SetPoint("RIGHT", OpenMailDeleteButton, "LEFT", -2, 0)
+
+		SV.API:Set("CloseButton", OpenMailFrameCloseButton)
+
+		OpenMailScrollFrame:RemoveTextures(true)
+		OpenMailScrollFrame:SetStyle("!_Frame", "Default")
+
+		SV.API:Set("ScrollBar", OpenMailScrollFrame)
+		SendMailBodyEditBox:SetTextColor(1, 1, 1)
+		OpenMailBodyText:SetTextColor(1, 1, 1)
+		InvoiceTextFontNormal:SetTextColor(1, 1, 1)
+
+		OpenMailArithmeticLine:Die()
+
+		OpenMailLetterButton:RemoveTextures()
+		OpenMailLetterButton:SetStyle("Button")
+		OpenMailLetterButtonIconTexture:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+		OpenMailLetterButtonIconTexture:InsetPoints()
+
+		OpenMailMoneyButton:RemoveTextures()
+		OpenMailMoneyButton:SetStyle("Button")
+		OpenMailMoneyButtonIconTexture:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+		OpenMailMoneyButtonIconTexture:InsetPoints()
+
+		for i = 1, INBOXITEMS_TO_DISPLAY do
+			local slot = _G["MailItem"..i]
+			if(slot) then
+				slot:RemoveTextures()
+				slot:SetStyle("Frame", "Inset")
+				slot.Panel:SetPoint("TOPLEFT", 2, 1)
+				slot.Panel:SetPoint("BOTTOMRIGHT", -2, 2)
+
+				local button = _G["MailItem"..i.."Button"]
+				if(button) then
+					button:RemoveTextures()
+					button:SetStyle("!_ActionSlot")
+				end
+
+				local icon = _G["MailItem"..i.."ButtonIcon"]
+				if(icon) then
+					icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+					icon:InsetPoints()
+				end
+			end
+		end
+
+		for i = 1, ATTACHMENTS_MAX_SEND do
+			local slot = _G["OpenMailAttachmentButton"..i]
+			if(slot) then
+				slot:RemoveTextures()
+				slot:SetStyle("!_ActionSlot")
+				local icon = _G["OpenMailAttachmentButton"..i.."IconTexture"]
+				if(icon) then
+					icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+					icon:InsetPoints()
+				end
+			end
+		end
+	end
+
+	if(SV.db.Skins.blizzard.merchant) then
+
+		SV.API:Set("Window", MerchantFrame, false, true)
+		MerchantFrame:SetWidth(360)
+
+		local level = MerchantFrame:GetFrameLevel()
+		if(level > 0) then
+			MerchantFrame:SetFrameLevel(level - 1)
+		else
+			MerchantFrame:SetFrameLevel(0)
+		end
+
+		MerchantExtraCurrencyInset:RemoveTextures()
+		MerchantExtraCurrencyBg:RemoveTextures()
+		MerchantFrameInset:RemoveTextures()
+		MerchantMoneyBg:RemoveTextures()
+		MerchantMoneyInset:RemoveTextures()
+
+		MerchantBuyBackItem:RemoveTextures(true)
+		MerchantBuyBackItem:SetStyle("Frame", "Inset", true, 2, 2, 3)
+		MerchantBuyBackItem.Panel:SetFrameLevel(MerchantBuyBackItem.Panel:GetFrameLevel() + 1)
+		MerchantBuyBackItemItemButton:RemoveTextures()
+		MerchantBuyBackItemItemButton:SetStyle("Button")
+		MerchantFrameInset:SetStyle("Frame", "Inset")
+		MerchantFrameInset.Panel:SetFrameLevel(MerchantFrameInset.Panel:GetFrameLevel() + 1)
+
+		SV.API:Set("DropDown", MerchantFrameLootFilter)
+		SV.API:Set("Tab", _G["MerchantFrameTab1"])
+		SV.API:Set("Tab", _G["MerchantFrameTab2"])
+
+		for i = 1, 12 do
+			local slot = _G["MerchantItem"..i]
+
+			if(slot) then
+				slot:RemoveTextures(true)
+				slot:SetStyle("Frame", "Inset")
+
+				local button = _G["MerchantItem"..i.."ItemButton"]
+				if(button) then
+					button:RemoveTextures()
+					button:SetStyle("!_ActionSlot")
+					button:SetPoint("TOPLEFT", slot, "TOPLEFT", 4, -4)
+					local icon = _G["MerchantItem"..i.."ItemButtonIconTexture"]
+					if(icon) then
+						icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+						icon:InsetPoints()
+					end
+					local money = _G["MerchantItem"..i.."MoneyFrame"]
+					if(money) then
+						money:ClearAllPoints()
+						money:SetPoint("BOTTOMLEFT", button, "BOTTOMRIGHT", 3, 0)
+					end
+				end
+			end
+		end
+
+		MerchantBuyBackItemItemButton:RemoveTextures()
+		MerchantBuyBackItemItemButton:SetStyle("Button")
+		MerchantBuyBackItemItemButtonIconTexture:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+		MerchantBuyBackItemItemButtonIconTexture:InsetPoints()
+		MerchantRepairItemButton:SetStyle("Button")
+
+		for i = 1, MerchantRepairItemButton:GetNumRegions()do
+			local region = select(i, MerchantRepairItemButton:GetRegions())
+			if region:GetObjectType() == "Texture" then
+				region:SetTexCoord(0.04, 0.24, 0.06, 0.5)
+				region:InsetPoints()
+			end
+		end
+
+		MerchantGuildBankRepairButton:SetStyle("Button")
+		MerchantGuildBankRepairButtonIcon:SetTexCoord(0.61, 0.82, 0.1, 0.52)
+		MerchantGuildBankRepairButtonIcon:InsetPoints()
+
+		MerchantRepairAllButton:SetStyle("Button")
+		MerchantRepairAllIcon:SetTexCoord(0.34, 0.1, 0.34, 0.535, 0.535, 0.1, 0.535, 0.535)
+		MerchantRepairAllIcon:InsetPoints()
+
+		SV.API:Set("CloseButton", MerchantFrameCloseButton, MerchantFrame.Panel)
+		SV.API:Set("!_PageButton", MerchantNextPageButton)
+		SV.API:Set("!_PageButton", MerchantPrevPageButton, false, true)
+
+		SV.NPC:Register(MerchantFrame, MerchantNameText)
+	end
+
+	if(SV.db.Skins.blizzard.petition) then
+		SV.API:Set("Window", PetitionFrame, nil, true)
+		PetitionFrameInset:Die()
+
+		PetitionFrameSignButton:SetStyle("Button")
+		PetitionFrameRequestButton:SetStyle("Button")
+		PetitionFrameRenameButton:SetStyle("Button")
+		PetitionFrameCancelButton:SetStyle("Button")
+
+		SV.API:Set("CloseButton", PetitionFrameCloseButton)
+
+		PetitionFrameCharterTitle:SetTextColor(1, 1, 0)
+		PetitionFrameCharterName:SetTextColor(1, 1, 1)
+		PetitionFrameMasterTitle:SetTextColor(1, 1, 0)
+		PetitionFrameMasterName:SetTextColor(1, 1, 1)
+		PetitionFrameMemberTitle:SetTextColor(1, 1, 0)
+
+		for i=1, 9 do
+			local frameName = ("PetitionFrameMemberName%d"):format(i)
+			local frame = _G[frameName];
+			if(frame) then
+				frame:SetTextColor(1, 1, 1)
+			end
+		end
+
+		PetitionFrameInstructions:SetTextColor(1, 1, 1)
+
+		PetitionFrameRenameButton:SetPoint("LEFT", PetitionFrameRequestButton, "RIGHT", 3, 0)
+		PetitionFrameRenameButton:SetPoint("RIGHT", PetitionFrameCancelButton, "LEFT", -3, 0)
+	end
+
+	if(SV.db.Skins.blizzard.stable) then
+		PetStableFrame:RemoveTextures()
+		PetStableFrameInset:RemoveTextures()
+		PetStableLeftInset:RemoveTextures()
+		PetStableBottomInset:RemoveTextures()
+		PetStableFrame:SetStyle("Frame", "Window")
+		PetStableFrameInset:SetStyle("!_Frame", 'Inset')
+		SV.API:Set("CloseButton", PetStableFrameCloseButton)
+		PetStablePrevPageButton:SetStyle("Button")
+		PetStableNextPageButton:SetStyle("Button")
+		SV.API:Set("PageButton", PetStablePrevPageButton)
+		SV.API:Set("PageButton", PetStableNextPageButton)
+		for i = 1, NUM_PET_ACTIVE_SLOTS do
+			 SV.API:Set("!_ItemButton", _G['PetStableActivePet'..i])
+		end
+		for i = 1, NUM_PET_STABLE_SLOTS do
+			 SV.API:Set("!_ItemButton", _G['PetStableStabledPet'..i])
+		end
+		PetStableSelectedPetIcon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+	end
+
+	if(SV.db.Skins.blizzard.tabard) then
+		for i=1, TabardFrame:GetNumRegions() do
+			local region = select(i, TabardFrame:GetRegions())
+			if(region and region.GetObjectType and region:GetObjectType() == "Texture") then
+				local regionName = region:GetName();
+				if(not TABARD_REGIONS[regionName]) then
+					region:Die()
+				end
+			end
+		end
+
+		TabardFrame:SetStyle("Frame", "Window2", false)
+		TabardModel:SetStyle("!_Frame", "Transparent")
+		TabardFrameCancelButton:SetStyle("Button")
+		TabardFrameAcceptButton:SetStyle("Button")
+		SV.API:Set("CloseButton", TabardFrameCloseButton)
+		TabardFrameCostFrame:RemoveTextures()
+		TabardFrameCustomizationFrame:RemoveTextures()
+		TabardFrameInset:Die()
+		TabardFrameMoneyInset:Die()
+		TabardFrameMoneyBg:RemoveTextures()
+
+		for i = 1, 5 do
+			local name = "TabardFrameCustomization"..i;
+			local frame = _G[name];
+			if(frame) then
+				frame:RemoveTextures()
+				SV.API:Set("PageButton", _G[name.."LeftButton"])
+				SV.API:Set("PageButton", _G[name.."RightButton"])
+
+				if(i == 1) then
+					local p1, a, p2, x, y = frame:GetPoint()
+					frame:SetPoint(p1, a, p2, x, y + 4)
+				else
+					local last = _G["TabardFrameCustomization"..i-1];
+					if(last) then
+						frame:ClearAllPoints()
+						frame:SetPoint("TOP", last, "BOTTOM", 0, -6)
+					end
+				end
+			end
+		end
+
+		TabardCharacterModelRotateLeftButton:SetPoint("BOTTOMLEFT", 4, 4)
+		TabardCharacterModelRotateRightButton:SetPoint("TOPLEFT", TabardCharacterModelRotateLeftButton, "TOPRIGHT", 4, 0)
+
+		hooksecurefunc(TabardCharacterModelRotateLeftButton, "SetPoint", function(self, p1, a, p2, x, y)
+			if((p1 ~= "BOTTOMLEFT") or (x ~= 4) or (y ~= 4)) then
+				 self:SetPoint("BOTTOMLEFT", 4, 4)
+			end
+		end)
+
+		hooksecurefunc(TabardCharacterModelRotateRightButton, "SetPoint", function(self, p1, a, p2, x, y)
+		    local anchor = _G.TabardCharacterModelRotateLeftButton
+			if((anchor) and ((p1 ~= "TOPLEFT") or (x ~= 4) or (y ~= 0))) then
+				 self:SetPoint("TOPLEFT", anchor, "TOPRIGHT", 4, 0)
+			end
+		end)
+	end
+
+	if(SV.db.Skins.blizzard.taxi) then
+		SV.API:Set("Window", TaxiFrame)
+		SV.API:Set("CloseButton", TaxiFrame.CloseButton)
+	end
+
+	if (SV.db.Skins.blizzard.trade) then
+		TradeFrameInset:Die()
+		TradeRecipientItemsInset:Die()
+		TradePlayerItemsInset:Die()
+		TradePlayerInputMoneyInset:Die()
+		TradePlayerEnchantInset:Die()
+		TradeRecipientEnchantInset:Die()
+		TradeRecipientMoneyInset:Die()
+		TradeRecipientMoneyBg:Die()
+		TradeFramePlayerPortrait:Die()
+		TradeFrameRecipientPortrait:Die()
+
+		SV.API:Set("Window", TradeFrame, true)
+
+		TradeFrameTradeButton:SetStyle("Button")
+		TradeFrameCancelButton:SetStyle("Button")
+		SV.API:Set("CloseButton", TradeFrameCloseButton, TradeFrame.Panel)
+
+		TradePlayerInputMoneyFrameGold:SetStyle("Editbox")
+
+		TradePlayerInputMoneyFrameSilver:SetStyle("Editbox")
+		TradePlayerInputMoneyFrameSilver.Panel:SetPoint("TOPLEFT", -2, 1)
+		TradePlayerInputMoneyFrameSilver.Panel:SetPoint("BOTTOMRIGHT", -12, -1)
+		TradePlayerInputMoneyFrameSilver:SetTextInsets(-1, -1, -2, -2)
+
+		TradePlayerInputMoneyFrameCopper:SetStyle("Editbox")
+		TradePlayerInputMoneyFrameCopper.Panel:SetPoint("TOPLEFT", -2, 1)
+		TradePlayerInputMoneyFrameCopper.Panel:SetPoint("BOTTOMRIGHT", -12, -1)
+		TradePlayerInputMoneyFrameCopper:SetTextInsets(-1, -1, -2, -2)
+
+		for i = 1, 7 do
+			StyleTradeSlots("TradePlayerItem"..i)
+			StyleTradeSlots("TradeRecipientItem"..i)
+		end
+
+		TradeHighlightPlayerTop:SetColorTexture(0.28, 0.75, 1, 0.2)
+		TradeHighlightPlayerBottom:SetColorTexture(0.28, 0.75, 1, 0.2)
+		TradeHighlightPlayerMiddle:SetColorTexture(0.28, 0.75, 1, 0.2)
+		TradeHighlightPlayer:SetFrameStrata("HIGH")
+		TradeHighlightPlayerEnchantTop:SetColorTexture(0.28, 0.75, 1, 0.2)
+		TradeHighlightPlayerEnchantBottom:SetColorTexture(0.28, 0.75, 1, 0.2)
+		TradeHighlightPlayerEnchantMiddle:SetColorTexture(0.28, 0.75, 1, 0.2)
+		TradeHighlightPlayerEnchant:SetFrameStrata("HIGH")
+		TradeHighlightRecipientTop:SetColorTexture(0.28, 0.75, 1, 0.2)
+		TradeHighlightRecipientBottom:SetColorTexture(0.28, 0.75, 1, 0.2)
+		TradeHighlightRecipientMiddle:SetColorTexture(0.28, 0.75, 1, 0.2)
+		TradeHighlightRecipient:SetFrameStrata("HIGH")
+		TradeHighlightRecipientEnchantTop:SetColorTexture(0.28, 0.75, 1, 0.2)
+		TradeHighlightRecipientEnchantBottom:SetColorTexture(0.28, 0.75, 1, 0.2)
+		TradeHighlightRecipientEnchantMiddle:SetColorTexture(0.28, 0.75, 1, 0.2)
+		TradeHighlightRecipientEnchant:SetFrameStrata("HIGH")
+	end
+
+	if(SV.db.Skins.blizzard.bgscore) then
+		WorldStateScoreScrollFrame:RemoveTextures()
+		WorldStateScoreFrame:RemoveTextures()
+		WorldStateScoreFrame:SetStyle("Frame", "Window")
+		SV.API:Set("CloseButton", WorldStateScoreFrameCloseButton)
+		SV.API:Set("ScrollBar", WorldStateScoreScrollFrame)
+		WorldStateScoreFrameInset:SetAlpha(0)
+		WorldStateScoreFrameLeaveButton:SetStyle("Button")
+		SV.API:Set("Tab", _G["WorldStateScoreFrameTab1"])
+		SV.API:Set("Tab", _G["WorldStateScoreFrameTab2"])
+		SV.API:Set("Tab", _G["WorldStateScoreFrameTab3"])
+	end
+
+	if(SV.db.Skins.blizzard.talkingHead) then
+		--TalkingHeadFrame:RemoveTextures()
+		--TalkingHeadFrame:SetStyle("Frame", "Window")
+	end
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveCustomStyle(MiscStyles)
diff --git a/SVUI_Skins/components/blizzard/petbattle.lua b/SVUI_Skins/components/blizzard/petbattle.lua
new file mode 100644
index 0000000..100eef3
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/petbattle.lua
@@ -0,0 +1,405 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+local ipairs  = _G.ipairs;
+local pairs   = _G.pairs;
+local hooksecurefunc = _G.hooksecurefunc;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+HELPERS
+##########################################################
+]]--
+local PBAB_WIDTH = 382;
+local PBAB_HEIGHT = 72;
+local PetBattleActionBar = CreateFrame("Frame", "SVUI_PetBattleActionBar", UIParent)
+local ITEM_QUALITY_COLORS = _G.ITEM_QUALITY_COLORS;
+
+local function PetBattleButtonHelper(frame)
+	frame:SetStyle("Frame", "Icon", 2, 2, 2)
+	frame:SetNormalTexture("")
+	frame:SetPushedTexture("")
+	frame.Icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+	frame.Icon:SetDrawLayer('BACKGROUND')
+	frame.Icon:SetParent(frame.Panel)
+	if(frame.SelectedHighlight) then frame.SelectedHighlight:SetAlpha(0) end
+	if(frame.checked) then frame.checked = true end
+	if(frame.pushed) then frame.pushed:InsetPoints(frame.Panel) end
+	if(frame.hover) then frame.hover:InsetPoints(frame.Panel) end
+	frame:SetFrameStrata('LOW')
+end
+
+local _hook_UpdateSpeedIndicators = function()
+	local frame = _G.PetBattleFrame;
+
+	if not frame.ActiveAlly.SpeedIcon:IsShown() and not frame.ActiveEnemy.SpeedIcon:IsShown() then
+		frame.ActiveAlly.FirstAttack:Hide()
+		frame.ActiveEnemy.FirstAttack:Hide()
+		return
+	end
+
+	frame.ActiveAlly.FirstAttack:Show()
+
+	if frame.ActiveAlly.SpeedIcon:IsShown() then
+		frame.ActiveAlly.FirstAttack:SetVertexColor(0, 1, 0, 1)
+	else
+		frame.ActiveAlly.FirstAttack:SetVertexColor(.8, 0, .3, 1)
+	end
+
+	frame.ActiveEnemy.FirstAttack:Show()
+
+	if frame.ActiveEnemy.SpeedIcon:IsShown() then
+		frame.ActiveEnemy.FirstAttack:SetVertexColor(0, 1, 0, 1)
+	else
+		frame.ActiveEnemy.FirstAttack:SetVertexColor(.8, 0, .3, 1)
+	end
+end
+
+local _hook_UpdatePetType = function(self)
+	if self.PetType then
+		local C_PetBattles = _G.C_PetBattles;
+		local pettype = C_PetBattles.GetPetType(self.petOwner, self.petIndex)
+		if self.PetTypeFrame then
+			local text = _G.PET_TYPE_SUFFIX[pettype]
+			self.PetTypeFrame.text:SetText(text)
+		end
+	end
+end
+
+local _hook_AuraHolderUpdate = function(self)
+    if ( not self.petOwner or not self.petIndex ) then
+        self:Hide();
+        return;
+    end
+
+    local nextFrame = 1;
+    local C_PetBattles = _G.C_PetBattles;
+    for i=1, C_PetBattles.GetNumAuras(self.petOwner, self.petIndex) do
+        local auraID, instanceID, turnsRemaining, isBuff = C_PetBattles.GetAuraInfo(self.petOwner, self.petIndex, i);
+        if ( (isBuff and self.displayBuffs) or (not isBuff and self.displayDebuffs) ) then
+			local frame = self.frames[nextFrame]
+			frame.DebuffBorder:Hide()
+			if not frame.isStyled then
+				frame:SetStyle("Icon", 2, -8,-2)
+				frame.Icon:InsetPoints(frame.Panel, 2, 2)
+				frame.Icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+				frame.isStyled = true
+			end
+			if isBuff then
+				frame:SetBackdropBorderColor(0, 1, 0)
+			else
+				frame:SetBackdropBorderColor(1, 0, 0)
+			end
+			frame.Duration:SetFont(SV.media.font.number, 16, "OUTLINE")
+			frame.Duration:ClearAllPoints()
+			frame.Duration:SetPoint("BOTTOMLEFT", frame.Icon, "BOTTOMLEFT", 4, 4)
+			if turnsRemaining > 0 then
+				frame.Duration:SetText(turnsRemaining)
+			end
+			nextFrame = nextFrame + 1
+		end
+	end
+end
+
+local _hook_WeatherFrameUpdate = function(self)
+	local LE_BATTLE_PET_WEATHER = _G.LE_BATTLE_PET_WEATHER;
+	local PET_BATTLE_PAD_INDEX = _G.PET_BATTLE_PAD_INDEX;
+	local C_PetBattles = _G.C_PetBattles;
+	local auraID = C_PetBattles.GetAuraInfo(LE_BATTLE_PET_WEATHER, PET_BATTLE_PAD_INDEX, 1)
+	if auraID then
+		self.Icon:Hide()
+		self.Name:Hide()
+		self.DurationShadow:Hide()
+		self.Label:Hide()
+		self.Duration:SetPoint("CENTER", self, 0, 8)
+		self:ClearAllPoints()
+		self:SetPoint("TOP", SV.Screen, 0, -15)
+	end
+end
+
+local _hook_UpdateDisplay = function(self)
+	self.Icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+	--Update the pet rarity border
+    if (self.IconBackdrop) then
+    	local petOwner = self.petOwner;
+		local petIndex = self.petIndex;
+        local rarity = _G.C_PetBattles.GetBreedQuality(petOwner, petIndex);
+        if (_G.ENABLE_COLORBLIND_MODE ~= "1") then
+        	self.IconBackdrop:SetBackdropColor(ITEM_QUALITY_COLORS[rarity-1].r, ITEM_QUALITY_COLORS[rarity-1].g, ITEM_QUALITY_COLORS[rarity-1].b);
+            self.IconBackdrop:SetBackdropBorderColor(ITEM_QUALITY_COLORS[rarity-1].r, ITEM_QUALITY_COLORS[rarity-1].g, ITEM_QUALITY_COLORS[rarity-1].b);
+        end
+    end
+end
+
+local _hook_AbilityTooltipShow = function()
+	SV:AnchorToCursor(PetBattlePrimaryAbilityTooltip)
+end
+
+local _hook_SkipButtonSetPoint = function(self, arg1, _, arg2, arg3, arg4)
+	if (arg1 ~= "BOTTOMLEFT" or arg2 ~= "TOPLEFT" or arg3 ~= 2 or arg4 ~= 2) then
+		self:ClearAllPoints()
+		self:SetPoint("BOTTOMLEFT", PetBattleActionBar.Panel, "TOPLEFT", 2, 2)
+	end
+end
+
+local _hook_PetSelectionFrameShow = function()
+	local frame = _G.PetBattleFrame;
+	if(frame and frame.BottomFrame) then
+		frame.BottomFrame.PetSelectionFrame:ClearAllPoints()
+		frame.BottomFrame.PetSelectionFrame:SetPoint("BOTTOM", frame.BottomFrame.xpBar, "TOP", 0, 8)
+	end
+end
+
+local _hook_UpdateActionBarLayout = function(self)
+	local list = _G.NUM_BATTLE_PET_ABILITIES;
+	for i = 1, list do
+		local actionButton = self.BottomFrame.abilityButtons[i]
+		PetBattleButtonHelper(actionButton)
+		actionButton:SetParent(PetBattleActionBar)
+		actionButton:ClearAllPoints()
+		if i == 1 then
+			actionButton:SetPoint("BOTTOMLEFT", 10, 10)
+		else
+			local lastActionButton = self.BottomFrame.abilityButtons[i - 1]
+			actionButton:SetPoint("LEFT", lastActionButton, "RIGHT", 10, 0)
+		end
+	end
+	self.BottomFrame.SwitchPetButton:SetParent(PetBattleActionBar)
+	self.BottomFrame.SwitchPetButton:ClearAllPoints()
+	self.BottomFrame.SwitchPetButton:SetPoint("LEFT", self.BottomFrame.abilityButtons[3], "RIGHT", 10, 0)
+	PetBattleButtonHelper(self.BottomFrame.SwitchPetButton)
+	self.BottomFrame.CatchButton:SetParent(PetBattleActionBar)
+	self.BottomFrame.CatchButton:ClearAllPoints()
+	self.BottomFrame.CatchButton:SetPoint("LEFT", self.BottomFrame.SwitchPetButton, "RIGHT", 10, 0)
+	PetBattleButtonHelper(self.BottomFrame.CatchButton)
+	self.BottomFrame.ForfeitButton:SetParent(PetBattleActionBar)
+	self.BottomFrame.ForfeitButton:ClearAllPoints()
+	self.BottomFrame.ForfeitButton:SetPoint("LEFT", self.BottomFrame.CatchButton, "RIGHT", 10, 0)
+	PetBattleButtonHelper(self.BottomFrame.ForfeitButton)
+end
+--[[
+##########################################################
+PETBATTLE MODR
+##########################################################
+]]--
+local function PetBattleStyle()
+	if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.petbattleui ~= true then
+		return
+	end
+
+	local PetBattleFrame = _G.PetBattleFrame;
+	local BottomFrame = PetBattleFrame.BottomFrame;
+	local ActiveFramesList = { PetBattleFrame.ActiveAlly, PetBattleFrame.ActiveEnemy }
+	local StandardFramesList = { PetBattleFrame.Ally2, PetBattleFrame.Ally3, PetBattleFrame.Enemy2, PetBattleFrame.Enemy3 }
+
+	SV.API:Set("CloseButton", FloatingBattlePetTooltip.CloseButton)
+	PetBattleFrame:RemoveTextures()
+
+	for i, frame in pairs(ActiveFramesList) do
+		if(not frame.isStyled) then
+			frame.Border:SetAlpha(0)
+			frame.Border2:SetAlpha(0)
+			frame.healthBarWidth = 300;
+
+			frame.IconBackdrop = CreateFrame("Frame", nil, frame)
+			frame.IconBackdrop:SetFrameLevel(0)
+			frame.IconBackdrop:SetAllPoints(frame.Icon)
+			frame.IconBackdrop:SetStyle("Icon", 2, 2, 2);
+
+			frame.BorderFlash:Die()
+			frame.HealthBarBG:Die()
+			frame.HealthBarFrame:Die()
+			frame.HealthBarBackdrop = CreateFrame("Frame", nil, frame)
+			frame.HealthBarBackdrop:SetFrameLevel(frame:GetFrameLevel()-1)
+			frame.HealthBarBackdrop:SetStyle("Frame", "Bar")
+			frame.HealthBarBackdrop:SetWidth(frame.healthBarWidth + 4)
+			frame.ActualHealthBar:SetTexture(SV.media.statusbar.default)
+			frame.PetTypeFrame = CreateFrame("Frame", nil, frame)
+			frame.PetTypeFrame:SetSize(100, 23)
+			frame.PetTypeFrame.text = frame.PetTypeFrame:CreateFontString(nil, 'OVERLAY')
+			frame.PetTypeFrame.text:SetFont(SV.media.font.default, 12, "OUTLINE")
+			frame.PetTypeFrame.text:SetText("")
+			frame.ActualHealthBar:ClearAllPoints()
+			frame.Name:SetFontObject(SystemFont_Shadow_Outline_Huge2)
+			frame.Name:ClearAllPoints()
+			frame.FirstAttack = frame:CreateTexture(nil, "ARTWORK")
+			frame.FirstAttack:SetSize(30, 30)
+			frame.FirstAttack:SetTexture("Interface\\PetBattles\\PetBattle-StatIcons")
+			if i == 1 then
+				frame.HealthBarBackdrop:SetPoint('TOPLEFT', frame.ActualHealthBar, 'TOPLEFT', -1, 1)
+				frame.HealthBarBackdrop:SetPoint('BOTTOMLEFT', frame.ActualHealthBar, 'BOTTOMLEFT', -1, -1)
+				frame.ActualHealthBar:SetVertexColor(171/255, 214/255, 116/255)
+				PetBattleFrame.Ally2.iconPoint = frame.IconBackdrop;
+				PetBattleFrame.Ally3.iconPoint = frame.IconBackdrop;
+				frame.ActualHealthBar:SetPoint('BOTTOMLEFT', frame.Icon, 'BOTTOMRIGHT', 10, 0)
+				frame.Name:SetPoint('BOTTOMLEFT', frame.ActualHealthBar, 'TOPLEFT', 0, 8)
+				frame.PetTypeFrame:SetPoint("BOTTOMRIGHT", frame.HealthBarBackdrop, "TOPRIGHT", 0, 4)
+				frame.PetTypeFrame.text:SetPoint("RIGHT")
+				frame.FirstAttack:SetPoint("LEFT", frame.HealthBarBackdrop, "RIGHT", 5, 0)
+				frame.FirstAttack:SetTexCoord(frame.SpeedIcon:GetTexCoord())
+				frame.FirstAttack:SetVertexColor(.1, .1, .1, 1)
+			else
+				frame.HealthBarBackdrop:SetPoint('TOPRIGHT', frame.ActualHealthBar, 'TOPRIGHT', 1, 1)
+				frame.HealthBarBackdrop:SetPoint('BOTTOMRIGHT', frame.ActualHealthBar, 'BOTTOMRIGHT', 1, -1)
+				frame.ActualHealthBar:SetVertexColor(196/255, 30/255, 60/255)
+				PetBattleFrame.Enemy2.iconPoint = frame.IconBackdrop;
+				PetBattleFrame.Enemy3.iconPoint = frame.IconBackdrop;
+				frame.ActualHealthBar:SetPoint('BOTTOMRIGHT', frame.Icon, 'BOTTOMLEFT', -10, 0)
+				frame.Name:SetPoint('BOTTOMRIGHT', frame.ActualHealthBar, 'TOPRIGHT', 0, 8)
+				frame.PetTypeFrame:SetPoint("BOTTOMLEFT", frame.HealthBarBackdrop, "TOPLEFT", 2, 4)
+				frame.PetTypeFrame.text:SetPoint("LEFT")
+				frame.FirstAttack:SetPoint("RIGHT", frame.HealthBarBackdrop, "LEFT", -5, 0)
+				frame.FirstAttack:SetTexCoord(.5, 0, .5, 1)
+				frame.FirstAttack:SetVertexColor(.1, .1, .1, 1)
+			end
+			frame.HealthText:ClearAllPoints()
+			frame.HealthText:SetPoint('CENTER', frame.HealthBarBackdrop, 'CENTER')
+			frame.PetType:SetFrameLevel(frame.PetTypeFrame:GetFrameLevel()+2)
+			frame.PetType:ClearAllPoints()
+			frame.PetType:SetAllPoints(frame.PetTypeFrame)
+			frame.PetType:SetAlpha(0)
+			frame.LevelUnderlay:SetAlpha(0)
+			frame.Level:SetFontObject(NumberFont_Outline_Huge)
+			frame.Level:ClearAllPoints()
+			frame.Level:SetPoint('BOTTOMLEFT', frame.Icon, 'BOTTOMLEFT', -2, -2)
+			if frame.SpeedIcon then
+				frame.SpeedIcon:ClearAllPoints()
+				frame.SpeedIcon:SetPoint("CENTER")
+				frame.SpeedIcon:SetAlpha(0)
+				frame.SpeedUnderlay:SetAlpha(0)
+			end
+			frame.isStyled = true
+		end
+	end
+
+	for _, frame in pairs(StandardFramesList) do
+		if(not frame.hasTempBG) then
+			frame.BorderAlive:SetAlpha(0)
+			frame.HealthBarBG:SetAlpha(0)
+			frame.HealthDivider:SetAlpha(0)
+			frame:SetSize(40, 40)
+
+			frame.IconBackdrop = CreateFrame("Frame", nil, frame)
+			frame.IconBackdrop:SetFrameLevel(0)
+			frame.IconBackdrop:SetAllPoints(frame)
+			frame.IconBackdrop:SetStyle("Icon", 2, 2, 2);
+
+			frame:ClearAllPoints()
+			frame.healthBarWidth = 40;
+			frame.ActualHealthBar:ClearAllPoints()
+			frame.ActualHealthBar:SetPoint("TOPLEFT", frame.IconBackdrop, 'BOTTOMLEFT', 0, -6)
+			frame.ActualHealthBar:SetTexture(SV.media.statusbar.default)
+			frame.HealthBarBackdrop = CreateFrame("Frame", nil, frame)
+			frame.HealthBarBackdrop:SetFrameLevel(frame:GetFrameLevel()-1)
+			frame.HealthBarBackdrop:SetStyle("Frame", "Bar")
+			frame.HealthBarBackdrop:SetWidth(frame.healthBarWidth + 4)
+			frame.HealthBarBackdrop:SetPoint('TOPLEFT', frame.ActualHealthBar, 'TOPLEFT', -1, 1)
+			frame.HealthBarBackdrop:SetPoint('BOTTOMLEFT', frame.ActualHealthBar, 'BOTTOMLEFT', -1, -1)
+			frame.hasTempBG = true
+		end
+	end
+
+	PetBattleActionBar:SetParent(PetBattleFrame)
+	PetBattleActionBar:SetSize(PBAB_WIDTH, PBAB_HEIGHT)
+	PetBattleActionBar:EnableMouse(true)
+	PetBattleActionBar:SetFrameLevel(0)
+	PetBattleActionBar:SetFrameStrata('BACKGROUND')
+	PetBattleActionBar:SetStyle("Frame", "Bar")
+
+	local SVUI_DockBottomCenter = _G.SVUI_DockBottomCenter;
+	if(SVUI_DockBottomCenter) then
+		PetBattleActionBar:SetPoint("BOTTOM", SVUI_DockBottomCenter, "TOP", 0, 4)
+	else
+		PetBattleActionBar:SetPoint("BOTTOM", SV.Screen, "BOTTOM", 0, 4)
+	end
+
+	PetBattleFrame.TopVersusText:ClearAllPoints()
+	PetBattleFrame.TopVersusText:SetPoint("TOP", PetBattleFrame, "TOP", 0, -42)
+
+	PetBattleFrame.Ally2:SetPoint("TOPRIGHT", PetBattleFrame.Ally2.iconPoint, "TOPLEFT", -6, -2)
+	PetBattleFrame.Ally3:SetPoint('TOPRIGHT', PetBattleFrame.Ally2, 'TOPLEFT', -8, 0)
+	PetBattleFrame.Enemy2:SetPoint("TOPLEFT", PetBattleFrame.Enemy2.iconPoint, "TOPRIGHT", 6, -2)
+	PetBattleFrame.Enemy3:SetPoint('TOPLEFT', PetBattleFrame.Enemy2, 'TOPRIGHT', 8, 0)
+
+	BottomFrame:RemoveTextures()
+	BottomFrame.TurnTimer:RemoveTextures()
+
+	BottomFrame.TurnTimer.SkipButton:ClearAllPoints()
+	BottomFrame.TurnTimer.SkipButton:SetParent(PetBattleActionBar)
+	BottomFrame.TurnTimer.SkipButton:SetSize((PBAB_WIDTH * 0.2) - 4, 18)
+	BottomFrame.TurnTimer.SkipButton:SetPoint("BOTTOMLEFT", PetBattleActionBar.Panel, "TOPLEFT", 2, 2)
+	BottomFrame.TurnTimer.SkipButton:SetStyle("Button")
+
+	BottomFrame.TurnTimer:SetSize(BottomFrame.TurnTimer.SkipButton:GetWidth(), BottomFrame.TurnTimer.SkipButton:GetHeight())
+	BottomFrame.TurnTimer:ClearAllPoints()
+	BottomFrame.TurnTimer:SetPoint("TOP", SV.Screen, "TOP", 0, -140)
+	BottomFrame.TurnTimer.TimerText:SetPoint("CENTER")
+
+	BottomFrame.FlowFrame:RemoveTextures()
+	BottomFrame.MicroButtonFrame:Die()
+	BottomFrame.Delimiter:RemoveTextures()
+
+	BottomFrame.xpBar:ClearAllPoints()
+	BottomFrame.xpBar:RemoveTextures()
+	BottomFrame.xpBar:SetParent(PetBattleActionBar)
+	BottomFrame.xpBar:SetSize((PBAB_WIDTH * 0.8) - 4, 16)
+	BottomFrame.xpBar:SetStatusBarTexture(SV.media.statusbar.default)
+	BottomFrame.xpBar:SetStyle("Frame", "Bar")
+	BottomFrame.xpBar:SetPoint("BOTTOMRIGHT", PetBattleActionBar.Panel, "TOPRIGHT", -3, 3)
+	BottomFrame.xpBar:SetScript("OnShow", function(self)
+		self:RemoveTextures()
+		self:SetStatusBarTexture(SV.media.statusbar.default)
+	end)
+
+	for i = 1, 3 do
+		local pet = BottomFrame.PetSelectionFrame["Pet"..i]
+		pet.HealthBarBG:SetAlpha(0)
+		pet.HealthDivider:SetAlpha(0)
+		pet.ActualHealthBar:SetAlpha(0)
+		pet.SelectedTexture:SetAlpha(0)
+		pet.MouseoverHighlight:SetAlpha(0)
+		pet.Framing:SetAlpha(0)
+		pet.Icon:SetAlpha(0)
+		pet.Name:SetAlpha(0)
+		pet.DeadOverlay:SetAlpha(0)
+		pet.Level:SetAlpha(0)
+		pet.HealthText:SetAlpha(0)
+	end
+
+	local PetBattleQueueReadyFrame = _G.PetBattleQueueReadyFrame;
+
+	PetBattleQueueReadyFrame:RemoveTextures()
+	PetBattleQueueReadyFrame:SetStyle("Frame", 'Transparent')
+	PetBattleQueueReadyFrame.AcceptButton:SetStyle("Button")
+	PetBattleQueueReadyFrame.DeclineButton:SetStyle("Button")
+	PetBattleQueueReadyFrame.Art:SetTexture([[Interface\PetBattles\PetBattlesQueue]])
+
+	--[[ TOO MANY GOD DAMN HOOKS ]]--
+	hooksecurefunc("PetBattleFrame_UpdateSpeedIndicators", _hook_UpdateSpeedIndicators)
+	hooksecurefunc("PetBattleUnitFrame_UpdatePetType", _hook_UpdatePetType)
+	hooksecurefunc("PetBattleAuraHolder_Update", _hook_AuraHolderUpdate)
+	hooksecurefunc("PetBattleWeatherFrame_Update", _hook_WeatherFrameUpdate)
+	hooksecurefunc("PetBattleUnitFrame_UpdateDisplay", _hook_UpdateDisplay)
+	hooksecurefunc("PetBattleAbilityTooltip_Show", _hook_AbilityTooltipShow)
+	hooksecurefunc(BottomFrame.TurnTimer.SkipButton, "SetPoint", _hook_SkipButtonSetPoint)
+	hooksecurefunc("PetBattlePetSelectionFrame_Show", _hook_PetSelectionFrameShow)
+	hooksecurefunc("PetBattleFrame_UpdateActionBarLayout", _hook_UpdateActionBarLayout)
+
+	SV.Tooltip:ReLoad()
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveBlizzardStyle('Blizzard_PetBattleUI', PetBattleStyle)
\ No newline at end of file
diff --git a/SVUI_Skins/components/blizzard/petjournal.lua b/SVUI_Skins/components/blizzard/petjournal.lua
new file mode 100644
index 0000000..d6f0146
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/petjournal.lua
@@ -0,0 +1,333 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+HELPERS
+##########################################################
+]]--
+local FAV_ICON = SV.media.icon.star
+local NORMAL_COLOR = {r = 1, g = 1, b = 1}
+local SELECTED_COLOR = {r = 1, g = 1, b = 0}
+
+local function PetJournal_UpdateMounts()
+	for b = 1, #MountJournal.ListScrollFrame.buttons do
+		local d = _G["MountJournalListScrollFrameButton"..b]
+		local e = _G["MountJournalListScrollFrameButton"..b.."Name"]
+		if d.selectedTexture:IsShown() then
+			if(e) then e:SetTextColor(1, 1, 0) end
+			if d.Panel then
+				d:SetBackdropBorderColor(1, 1, 0)
+			end
+			if d.IconShadow then
+				d.IconShadow:SetBackdropBorderColor(1, 1, 0)
+			end
+		else
+			if(e) then e:SetTextColor(1, 1, 1) end
+			if d.Panel then
+				d:SetBackdropBorderColor(0,0,0,1)
+			end
+			if d.IconShadow then
+				d.IconShadow:SetBackdropBorderColor(0,0,0,1)
+			end
+		end
+	end
+end
+
+local function PetJournal_UpdatePets()
+	local u = PetJournal.listScroll.buttons;
+	local isWild = PetJournal.isWild;
+	for b = 1, #u do
+		local v = u[b].index;
+		if not v then
+			break
+		end
+		local d = _G["PetJournalListScrollFrameButton"..b]
+		local e = _G["PetJournalListScrollFrameButton"..b.."Name"]
+		local levelText = _G["PetJournalListScrollFrameButton"..b.."Level"]
+		local w, x, y, z, level, favorite, A, B, C, D, E, F, G, H, I = C_PetJournal.GetPetInfoByIndex(v, isWild)
+		if w ~= nil then
+			local J, K, L, M, N = C_PetJournal.GetPetStats(w)
+			local color = NORMAL_COLOR
+			if(N) then
+				color = ITEM_QUALITY_COLORS[N-1]
+			end
+			d:SetBackdropBorderColor(0,0,0,1)
+			if(d.selectedTexture:IsShown() and d.Panel) then
+				d:SetBackdropBorderColor(1,1,0,1)
+				if d.IconShadow then
+					d.IconShadow:SetBackdropBorderColor(1,1,0)
+				end
+			else
+				if d.IconShadow then
+					d.IconShadow:SetBackdropBorderColor(color.r, color.g, color.b)
+				end
+			end
+
+			e:SetTextColor(color.r, color.g, color.b)
+		end
+	end
+end
+--[[
+##########################################################
+FRAME MODR
+##########################################################
+]]--
+local function CollectionsJournalStyle()
+	if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.mounts ~= true then return end
+
+	SV.API:Set("Window", CollectionsJournal)
+
+	CollectionsJournalPortrait:Hide()
+	SV.API:Set("Tab", CollectionsJournalTab1)
+	SV.API:Set("Tab", CollectionsJournalTab2)
+	SV.API:Set("CloseButton", CollectionsJournalCloseButton)
+
+	MountJournal:RemoveTextures()
+	MountJournal.LeftInset:RemoveTextures()
+	MountJournal.RightInset:RemoveTextures()
+	MountJournal.MountDisplay:RemoveTextures()
+	MountJournal.MountDisplay.ShadowOverlay:RemoveTextures()
+	MountJournal.MountCount:RemoveTextures()
+	MountJournalListScrollFrame:RemoveTextures()
+	MountJournalMountButton:RemoveTextures()
+	MountJournalMountButton:SetStyle("Button")
+	MountJournalSearchBox:SetStyle("Editbox")
+
+	SV.API:Set("ScrollBar", MountJournalListScrollFrame)
+	MountJournal.MountDisplay:SetStyle("!_Frame", "Model")
+
+	local buttons = MountJournal.ListScrollFrame.buttons
+	for i = 1, #buttons do
+		local button = buttons[i]
+		if(button) then
+			SV.API:Set("ItemButton", button)
+			local bar = _G["SVUI_MountSelectBar"..i]
+			if(bar) then bar:SetParent(button.Panel) end
+			if(button.favorite) then
+				local fg = CreateFrame("Frame", nil, button)
+				fg:SetAllPoints(favorite)
+				fg:SetFrameLevel(button:GetFrameLevel() + 30)
+				button.favorite:SetParent(fg)
+				button.favorite:SetTexture(SV.media.icon.star)
+			end
+		end
+	end
+
+	hooksecurefunc("MountJournal_UpdateMountList", PetJournal_UpdateMounts)
+	MountJournalListScrollFrame:HookScript("OnVerticalScroll", PetJournal_UpdateMounts)
+	MountJournalListScrollFrame:HookScript("OnMouseWheel", PetJournal_UpdateMounts)
+	PetJournalSummonButton:RemoveTextures()
+	PetJournalFindBattle:RemoveTextures()
+	PetJournalSummonButton:SetStyle("Button")
+	PetJournalFindBattle:SetStyle("Button")
+	PetJournalRightInset:RemoveTextures()
+	PetJournalLeftInset:RemoveTextures()
+
+	for i = 1, 3 do
+		local button = _G["PetJournalLoadoutPet" .. i .. "HelpFrame"]
+		button:RemoveTextures()
+	end
+
+	PetJournalTutorialButton:Die()
+	PetJournal.PetCount:RemoveTextures()
+	PetJournalSearchBox:SetStyle("Editbox")
+	PetJournalFilterButton:RemoveTextures(true)
+	PetJournalFilterButton:SetStyle("Button")
+	PetJournalListScrollFrame:RemoveTextures()
+	SV.API:Set("ScrollBar", PetJournalListScrollFrame)
+
+	for i = 1, #PetJournal.listScroll.buttons do
+		local button = _G["PetJournalListScrollFrameButton" .. i]
+		local favorite = _G["PetJournalListScrollFrameButton" .. i .. "Favorite"]
+		SV.API:Set("ItemButton", button)
+		if(not button.Riser) then
+			local fg = CreateFrame("Frame", nil, button)
+			fg:SetAllPoints(button)
+			fg:SetFrameLevel(button:GetFrameLevel() + 30)
+			button.Riser = fg
+		end
+		if(favorite) then
+			favorite:SetParent(button.Riser)
+			button.dragButton.favorite:SetParent(button.Riser)
+			favorite:SetTexture(SV.media.icon.star)
+			favorite:SetTexCoord(0,1,0,1)
+		end
+
+		button.dragButton.levelBG:SetAlpha(0)
+		button.dragButton.level:SetParent(button.Riser)
+		--button.dragButton.level:SetDrawLayer("OVERLAY", 7)
+		button.petTypeIcon:SetParent(button.Panel)
+	end
+
+	hooksecurefunc('PetJournal_UpdatePetList', PetJournal_UpdatePets)
+	PetJournalListScrollFrame:HookScript("OnVerticalScroll", PetJournal_UpdatePets)
+	PetJournalListScrollFrame:HookScript("OnMouseWheel", PetJournal_UpdatePets)
+	PetJournalAchievementStatus:DisableDrawLayer('BACKGROUND')
+	SV.API:Set("!_ItemButton", PetJournalHealPetButton)
+	PetJournalHealPetButton.texture:SetTexture([[Interface\Icons\spell_magic_polymorphrabbit]])
+	PetJournalLoadoutBorder:RemoveTextures()
+
+	for b = 1, 3 do
+		local pjPet = _G['PetJournalLoadoutPet'..b]
+		pjPet:RemoveTextures()
+		pjPet.petTypeIcon:SetPoint('BOTTOMLEFT', 2, 2)
+		pjPet.dragButton:WrapPoints(_G['PetJournalLoadoutPet'..b..'Icon'])
+		pjPet.hover = true;
+		pjPet.pushed = true;
+		pjPet.checked = true;
+		SV.API:Set("ItemButton", pjPet, true)
+		pjPet.setButton:RemoveTextures()
+		_G['PetJournalLoadoutPet'..b..'HealthFrame'].healthBar:RemoveTextures()
+		_G['PetJournalLoadoutPet'..b..'HealthFrame'].healthBar:SetStyle("Frame", 'Default')
+		_G['PetJournalLoadoutPet'..b..'HealthFrame'].healthBar:SetStatusBarTexture(SV.media.statusbar.default)
+		_G['PetJournalLoadoutPet'..b..'XPBar']:RemoveTextures()
+		_G['PetJournalLoadoutPet'..b..'XPBar']:SetStyle("Frame", 'Default')
+		_G['PetJournalLoadoutPet'..b..'XPBar']:SetStatusBarTexture(SV.media.statusbar.default)
+		_G['PetJournalLoadoutPet'..b..'XPBar']:SetFrameLevel(_G['PetJournalLoadoutPet'..b..'XPBar']:GetFrameLevel()+2)
+		for v = 1, 3 do
+			local s = _G['PetJournalLoadoutPet'..b..'Spell'..v]
+			SV.API:Set("ItemButton", s)
+			s.FlyoutArrow:SetTexture([[Interface\Buttons\ActionBarFlyoutButton]])
+			_G['PetJournalLoadoutPet'..b..'Spell'..v..'Icon']:InsetPoints(s)
+			s.Panel:SetFrameLevel(s:GetFrameLevel() + 1)
+			_G['PetJournalLoadoutPet'..b..'Spell'..v..'Icon']:SetParent(s.Panel)
+		end
+	end
+
+	PetJournalSpellSelect:RemoveTextures()
+
+	for b = 1, 2 do
+		local Q = _G['PetJournalSpellSelectSpell'..b]
+		SV.API:Set("ItemButton", Q)
+		_G['PetJournalSpellSelectSpell'..b..'Icon']:InsetPoints(Q)
+		_G['PetJournalSpellSelectSpell'..b..'Icon']:SetDrawLayer('BORDER')
+	end
+
+	PetJournalPetCard:RemoveTextures()
+	SV.API:Set("ItemButton", PetJournalPetCard, true)
+	PetJournalPetCardInset:RemoveTextures()
+	PetJournalPetCardPetInfo.levelBG:SetAlpha(0)
+	PetJournalPetCardPetInfoIcon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+	SV.API:Set("ItemButton", PetJournalPetCardPetInfo, true)
+
+	local fg = CreateFrame("Frame", nil, PetJournalPetCardPetInfo)
+	fg:SetSize(40,40)
+	fg:SetPoint("TOPLEFT", PetJournalPetCardPetInfo, "TOPLEFT", -1, 1)
+	fg:SetFrameLevel(PetJournalPetCardPetInfo:GetFrameLevel() + 30)
+
+	PetJournalPetCardPetInfo.favorite:SetParent(fg)
+	PetJournalPetCardPetInfo.Panel:WrapPoints(PetJournalPetCardPetInfoIcon)
+	PetJournalPetCardPetInfoIcon:SetParent(PetJournalPetCardPetInfo.Panel)
+
+	local R = PetJournalPrimaryAbilityTooltip;
+	R.Background:SetTexture("")
+	if R.Delimiter1 then
+		R.Delimiter1:SetTexture("")
+		R.Delimiter2:SetTexture("")
+	end
+
+	R.BorderTop:SetTexture("")
+	R.BorderTopLeft:SetTexture("")
+	R.BorderTopRight:SetTexture("")
+	R.BorderLeft:SetTexture("")
+	R.BorderRight:SetTexture("")
+	R.BorderBottom:SetTexture("")
+	R.BorderBottomRight:SetTexture("")
+	R.BorderBottomLeft:SetTexture("")
+	R:SetStyle("!_Frame", "Transparent", true)
+
+	for b = 1, 6 do
+		local S = _G['PetJournalPetCardSpell'..b]
+		S:SetFrameLevel(S:GetFrameLevel() + 2)
+		S:DisableDrawLayer('BACKGROUND')
+		S:SetStyle("Frame", 'Transparent')
+		S.Panel:SetAllPoints()
+		S.icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+		S.icon:InsetPoints(S.Panel)
+	end
+
+	PetJournalPetCardHealthFrame.healthBar:RemoveTextures()
+	PetJournalPetCardHealthFrame.healthBar:SetStyle("Frame", 'Default')
+	PetJournalPetCardHealthFrame.healthBar:SetStatusBarTexture(SV.media.statusbar.default)
+	PetJournalPetCardXPBar:RemoveTextures()
+	PetJournalPetCardXPBar:SetStyle("Frame", 'Default')
+	PetJournalPetCardXPBar:SetStatusBarTexture(SV.media.statusbar.default)
+
+	SV.API:Set("Tab", CollectionsJournalTab3)
+	SV.API:Set("Tab", CollectionsJournalTab4)
+
+	ToyBox:RemoveTextures()
+	ToyBox.searchBox:SetStyle("Editbox")
+	ToyBoxFilterButton:RemoveTextures(true)
+	ToyBoxFilterButton:SetStyle("Button")
+	ToyBox.iconsFrame:RemoveTextures()
+	ToyBox.iconsFrame:SetStyle("!_Frame", 'Model')
+	ToyBox.progressBar:RemoveTextures()
+	ToyBox.progressBar:SetStatusBarTexture([[Interface\BUTTONS\WHITE8X8]])
+	ToyBox.progressBar:SetStyle("Frame", "Bar", true, 2, 2, 2)
+	SV.API:Set("PageButton", ToyBox.navigationFrame.prevPageButton, false, true)
+	SV.API:Set("PageButton", ToyBox.navigationFrame.nextPageButton)
+
+	HeirloomsJournal:RemoveTextures()
+	HeirloomsJournal.SearchBox:SetStyle("Editbox")
+	HeirloomsJournalFilterButton:RemoveTextures(true)
+	HeirloomsJournalFilterButton:SetStyle("Button")
+	HeirloomsJournal.iconsFrame:RemoveTextures()
+	HeirloomsJournal.iconsFrame:SetStyle("!_Frame", 'Model')
+
+	HeirloomsJournal.progressBar:RemoveTextures()
+	HeirloomsJournal.progressBar:SetStatusBarTexture([[Interface\BUTTONS\WHITE8X8]])
+	HeirloomsJournal.progressBar:SetStyle("Frame", "Bar", true, 2, 2, 2)
+	SV.API:Set("PageButton", HeirloomsJournal.navigationFrame.prevPageButton, false, true)
+	SV.API:Set("PageButton", HeirloomsJournal.navigationFrame.nextPageButton)
+
+	SV.API:Set("DropDown", HeirloomsJournalClassDropDown)
+
+	MountJournalFilterButton:RemoveTextures(true)
+	MountJournalFilterButton:SetStyle("Button")
+
+	MountJournal.SummonRandomFavoriteButton:RemoveTextures()
+	MountJournal.SummonRandomFavoriteButton:SetStyle("ActionSlot")
+	MountJournal.SummonRandomFavoriteButton.texture:SetTexture([[Interface\ICONS\ACHIEVEMENT_GUILDPERK_MOUNTUP]])
+	MountJournal.SummonRandomFavoriteButton.texture:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+
+	for i = 1, 18 do
+		local gName = ("ToySpellButton%d"):format(i)
+		local button = _G[gName]
+		if(button) then
+			button:SetStyle("Button")
+		end
+	end
+
+	SV.API:Set("Tab", CollectionsJournalTab5)
+	WardrobeCollectionFrame:RemoveTextures()
+	WardrobeCollectionFrameSearchBox:SetStyle("Editbox")
+	WardrobeCollectionFrame.FilterButton:RemoveTextures(true)
+	WardrobeCollectionFrame.FilterButton:SetStyle("Button")
+	WardrobeCollectionFrame.ModelsFrame:RemoveTextures()
+	WardrobeCollectionFrame.ModelsFrame:SetStyle("!_Frame", 'Model')
+
+	WardrobeCollectionFrame.progressBar:RemoveTextures()
+	WardrobeCollectionFrame.progressBar:SetStatusBarTexture([[Interface\BUTTONS\WHITE8X8]])
+	WardrobeCollectionFrame.progressBar:SetStyle("Frame", "Bar", true, 2, 2, 2)
+	SV.API:Set("PageButton", WardrobeCollectionFrame.NavigationFrame.PrevPageButton, false, true)
+	SV.API:Set("PageButton", WardrobeCollectionFrame.NavigationFrame.NextPageButton)
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveBlizzardStyle("Blizzard_Collections", CollectionsJournalStyle)
\ No newline at end of file
diff --git a/SVUI_Skins/components/blizzard/pvp.lua b/SVUI_Skins/components/blizzard/pvp.lua
new file mode 100644
index 0000000..0cc9a7e
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/pvp.lua
@@ -0,0 +1,145 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+PVP MODR
+##########################################################
+]]--
+local _hook_PVPReadyDialogDisplay = function(self, _, _, _, queueType, _, queueRole)
+	PVPReadyDialogRoleIconTexture:SetTexture("Interface\\AddOns\\SVUI_Skins\\artwork\\UI-LFG-ICON-ROLES")
+	if(queueType == "ARENA") then
+		self:SetHeight(100)
+	end
+end
+
+local function PVPFrameStyle()
+	if (SV.db.Skins and (SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.pvp ~= true)) then
+		return
+	end
+
+	local HonorFrame = _G.HonorFrame;
+	local ConquestFrame = _G.ConquestFrame;
+	local PVPUIFrame = _G.PVPUIFrame;
+	local WarGamesFrame = _G.WarGamesFrame;
+	local PVPReadyDialog = _G.PVPReadyDialog;
+
+
+	for i = 1, 4 do
+		local btn = _G["PVPQueueFrameCategoryButton"..i]
+		if(btn) then
+			btn.Background:Die()
+			btn.Ring:Die()
+			btn:SetStyle("Button")
+			btn.Icon:SetSize(45, 45)
+			btn.Icon:SetTexCoord(.15, .85, .15, .85)
+			btn.Icon:SetDrawLayer("OVERLAY", nil, 7)
+			btn.Panel:WrapPoints(btn.Icon)
+		end
+	end
+
+	SV.API:Set("DropDown", HonorFrameTypeDropDown)
+	HonorFrame.Inset:RemoveTextures()
+	HonorFrame.Inset:SetStyle("!_Frame", "Inset")
+	SV.API:Set("ScrollBar", HonorFrameSpecificFrameScrollBar)
+	HonorFrame.QueueButton:RemoveTextures()
+	HonorFrame.QueueButton:SetStyle("Button")
+	HonorFrame.BonusFrame:RemoveTextures()
+	HonorFrame.BonusFrame.ShadowOverlay:RemoveTextures()
+	HonorFrame.BonusFrame.RandomBGButton:RemoveTextures()
+	HonorFrame.BonusFrame.RandomBGButton:SetStyle("!_Frame", "Button")
+	HonorFrame.BonusFrame.RandomBGButton:SetStyle("Button")
+	HonorFrame.BonusFrame.RandomBGButton.SelectedTexture:InsetPoints()
+	HonorFrame.BonusFrame.RandomBGButton.SelectedTexture:SetColorTexture(1, 1, 0, 0.1)
+	HonorFrame.BonusFrame.DiceButton:DisableDrawLayer("ARTWORK")
+	HonorFrame.BonusFrame.DiceButton:SetHighlightTexture("")
+
+	HonorFrame.RoleInset:RemoveTextures()
+	HonorFrame.RoleInset.DPSIcon.checkButton:SetStyle("CheckButton")
+	HonorFrame.RoleInset.TankIcon.checkButton:SetStyle("CheckButton")
+	HonorFrame.RoleInset.HealerIcon.checkButton:SetStyle("CheckButton")
+	HonorFrame.RoleInset.TankIcon:DisableDrawLayer("OVERLAY")
+	HonorFrame.RoleInset.TankIcon:DisableDrawLayer("BACKGROUND")
+	HonorFrame.RoleInset.TankIcon:SetNormalTexture("Interface\\AddOns\\SVUI_Skins\\artwork\\UI-LFG-ICON-ROLES")
+	HonorFrame.RoleInset.HealerIcon:DisableDrawLayer("OVERLAY")
+	HonorFrame.RoleInset.HealerIcon:DisableDrawLayer("BACKGROUND")
+	HonorFrame.RoleInset.HealerIcon:SetNormalTexture("Interface\\AddOns\\SVUI_Skins\\artwork\\UI-LFG-ICON-ROLES")
+	HonorFrame.RoleInset.DPSIcon:DisableDrawLayer("OVERLAY")
+	HonorFrame.RoleInset.DPSIcon:DisableDrawLayer("BACKGROUND")
+	HonorFrame.RoleInset.DPSIcon:SetNormalTexture("Interface\\AddOns\\SVUI_Skins\\artwork\\UI-LFG-ICON-ROLES")
+	hooksecurefunc("LFG_PermanentlyDisableRoleButton", function(n)
+		if n.bg then
+			n.bg:SetDesaturated(true)
+		end
+	end)
+
+	LFGListPVEStub:RemoveTextures(true)
+	LFGListPVPStub:RemoveTextures(true)
+
+	local ConquestPointsBar = _G.ConquestPointsBar;
+
+	ConquestFrame.Inset:RemoveTextures()
+	ConquestPoints.XPBar:RemoveTextures()
+	ConquestPoints.XPBar:SetStyle("!_Frame", 'Inset')
+	ConquestPoints.XPBar.Panel:WrapPoints(ConquestPointsBar, nil, -2)
+	--[[
+	ConquestPointsBarLeft:Die()
+	ConquestPointsBarRight:Die()
+	ConquestPointsBarMiddle:Die()
+	ConquestPointsBarBG:Die()
+	ConquestPointsBarShadow:Die()
+	ConquestPointsBar.progress:SetTexture(SV.media.statusbar.default)
+	ConquestPointsBar:SetStyle("!_Frame", 'Inset')
+	ConquestPointsBar.Panel:WrapPoints(ConquestPointsBar, nil, -2)
+	]]--
+	ConquestFrame:RemoveTextures()
+	ConquestFrame.ShadowOverlay:RemoveTextures()
+	ConquestJoinButton:RemoveTextures()
+	ConquestJoinButton:SetStyle("Button")
+	ConquestFrame.RatedBG:RemoveTextures()
+	ConquestFrame.RatedBG:SetStyle("!_Frame", "Inset")
+	ConquestFrame.RatedBG:SetStyle("Button")
+	ConquestFrame.RatedBG.SelectedTexture:InsetPoints()
+	ConquestFrame.RatedBG.SelectedTexture:SetColorTexture(1, 1, 0, 0.1)
+	WarGamesFrame:RemoveTextures()
+	WarGamesFrame.RightInset:RemoveTextures()
+	WarGamesFrameInfoScrollFrame:RemoveTextures()
+	WarGamesFrameInfoScrollFrameScrollBar:RemoveTextures()
+	WarGameStartButton:RemoveTextures()
+	WarGameStartButton:SetStyle("Button")
+	SV.API:Set("ScrollBar", WarGamesFrameScrollFrame)
+	SV.API:Set("ScrollBar", WarGamesFrameInfoScrollFrame)
+	WarGamesFrame.HorizontalBar:RemoveTextures()
+
+	PVPReadyDialog:RemoveTextures()
+	PVPReadyDialog:SetStyle("Frame", "Pattern")
+	PVPReadyDialogEnterBattleButton:SetStyle("Button")
+	PVPReadyDialogLeaveQueueButton:SetStyle("Button")
+	SV.API:Set("CloseButton", PVPReadyDialogCloseButton)
+	PVPReadyDialogRoleIconTexture:SetTexture("Interface\\AddOns\\SVUI_Skins\\artwork\\UI-LFG-ICON-ROLES")
+	PVPReadyDialogRoleIconTexture:SetAlpha(0.5)
+
+	ConquestFrame.Inset:SetStyle("!_Frame", "Inset")
+	WarGamesFrameScrollFrame:SetStyle("Frame", "Inset",false,2,2,6)
+
+	hooksecurefunc("PVPReadyDialog_Display", _hook_PVPReadyDialogDisplay)
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveBlizzardStyle('Blizzard_PVPUI', PVPFrameStyle)
+
+-- /script StaticPopupSpecial_Show(PVPReadyDialog)
diff --git a/SVUI_Skins/components/blizzard/quest.lua b/SVUI_Skins/components/blizzard/quest.lua
new file mode 100644
index 0000000..38a1df1
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/quest.lua
@@ -0,0 +1,264 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+local ipairs  = _G.ipairs;
+local pairs   = _G.pairs;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+
+local MAX_NUM_ITEMS = _G.MAX_NUM_ITEMS
+--[[
+##########################################################
+HELPERS
+##########################################################
+]]--
+local QuestFrameList = {
+	"QuestLogPopupDetailFrame",
+	"QuestLogPopupDetailFrameAbandonButton",
+	"QuestLogPopupDetailFrameShareButton",
+	"QuestLogPopupDetailFrameTrackButton",
+	"QuestLogPopupDetailFrameCancelButton",
+	"QuestLogPopupDetailFrameCompleteButton"
+};
+
+local function QuestScrollHelper(b, c, d, e)
+	b:SetStyle("Frame", "Inset")
+	b.spellTex = b:CreateTexture(nil, 'ARTWORK')
+	b.spellTex:SetTexture([[Interface\QuestFrame\QuestBG]])
+	if e then
+		 b.spellTex:SetPoint("TOPLEFT", 2, -2)
+	else
+		 b.spellTex:SetPoint("TOPLEFT")
+	end
+	b.spellTex:SetSize(c or 506, d or 615)
+	b.spellTex:SetTexCoord(0, 1, 0.02, 1)
+end
+
+local QuestRewardScrollFrame_OnShow = function(self)
+	if(not self.Panel) then
+		self:SetStyle("Frame", "Default")
+		QuestScrollHelper(self, 509, 630, false)
+		self:SetHeight(self:GetHeight() - 2)
+	end
+	if(self.spellTex) then
+		self.spellTex:SetHeight(self:GetHeight() + 217)
+	end
+end
+
+local function StyleQuestRewards()
+	local rewardsFrame = QuestInfoFrame.rewardsFrame
+	if(not rewardsFrame) then return end
+	local parentName = rewardsFrame:GetName()
+	for i = 1, 10 do
+		local name = ("%sQuestInfoItem%d"):format(parentName,i)
+		SV.API:Set("!_QuestItem", _G[name])
+	end
+	if(rewardsFrame:GetName() == 'MapQuestInfoRewardsFrame') then
+		SV.API:Set("!_QuestItem", rewardsFrame.XPFrame)
+		SV.API:Set("!_QuestItem", rewardsFrame.SpellFrame)
+		SV.API:Set("!_QuestItem", rewardsFrame.MoneyFrame)
+		SV.API:Set("!_QuestItem", rewardsFrame.SkillPointFrame)
+		SV.API:Set("!_QuestItem", rewardsFrame.PlayerTitleFrame)
+	end
+end
+
+local Hook_QuestFrame_SetTitleTextColor = function(fontString)
+	fontString:SetTextColor(1,1,0,1)
+end
+
+local Hook_QuestInfoItem_OnClick = function(self)
+	_G.QuestInfoItemHighlight:ClearAllPoints()
+	_G.QuestInfoItemHighlight:SetAllPoints(self)
+	_G.QuestInfoItemHighlight:Show()
+end
+
+local Hook_QuestNPCModel = function(self, _, _, _, x, y)
+	_G.QuestNPCModel:ClearAllPoints()
+	_G.QuestNPCModel:SetPoint("TOPLEFT", self, "TOPRIGHT", x + 18, y)
+end
+
+local _hook_DetailScrollShow = function(self)
+	if not self.Panel then
+		self:SetStyle("Frame", "Default")
+		QuestScrollHelper(self, 509, 630, false)
+	end
+	self.spellTex:SetHeight(self:GetHeight() + 217)
+end
+
+local _hook_QuestLogPopupDetailFrameShow = function(self)
+	local QuestLogPopupDetailFrameScrollFrame = _G.QuestLogPopupDetailFrameScrollFrame;
+	if not QuestLogPopupDetailFrameScrollFrame.spellTex then
+		QuestLogPopupDetailFrameScrollFrame:SetStyle("!_Frame", "Default")
+		QuestLogPopupDetailFrameScrollFrame.spellTex = QuestLogPopupDetailFrameScrollFrame:CreateTexture(nil, 'ARTWORK')
+		QuestLogPopupDetailFrameScrollFrame.spellTex:SetTexture([[Interface\QuestFrame\QuestBookBG]])
+		QuestLogPopupDetailFrameScrollFrame.spellTex:SetPoint("TOPLEFT", 2, -2)
+		QuestLogPopupDetailFrameScrollFrame.spellTex:SetSize(514, 616)
+		QuestLogPopupDetailFrameScrollFrame.spellTex:SetTexCoord(0, 1, 0.02, 1)
+		QuestLogPopupDetailFrameScrollFrame.spellTex2 = QuestLogPopupDetailFrameScrollFrame:CreateTexture(nil, 'BORDER')
+		QuestLogPopupDetailFrameScrollFrame.spellTex2:SetTexture([[Interface\FrameGeneral\UI-Background-Rock]])
+		QuestLogPopupDetailFrameScrollFrame.spellTex2:InsetPoints()
+	end
+end
+--[[
+##########################################################
+QUEST MODRS
+##########################################################
+]]--
+local function QuestFrameStyle()
+	--print('test QuestFrameStyle')
+	if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.quest ~= true then return end
+
+	SV.API:Set("Window", QuestLogPopupDetailFrame, true, true)
+	SV.API:Set("Window", QuestFrame, true, true)
+
+	QuestLogPopupDetailFrameScrollFrame:RemoveTextures()
+	QuestProgressScrollFrame:RemoveTextures()
+
+	QuestInfoItemHighlight:RemoveTextures()
+	QuestInfoItemHighlight:SetStyle("Frame", "Icon")
+	QuestInfoItemHighlight:SetSize(148, 40)
+
+	local choiceBG = QuestInfoItemHighlight:CreateTexture(nil, "BACKGROUND")
+	choiceBG:SetAllPoints(QuestInfoItemHighlight)
+	choiceBG:SetColorTexture(0.35, 1, 0, 0.35)
+
+	local width = QuestLogPopupDetailFrameScrollFrame:GetWidth()
+	QuestLogPopupDetailFrame.ShowMapButton:SetWidth(width)
+	QuestLogPopupDetailFrame.ShowMapButton:SetStyle("Button")
+
+	SV.API:Set("Window", QuestLogPopupDetailFrame)
+
+	QuestLogPopupDetailFrameInset:Die()
+
+	for _,i in pairs(QuestFrameList)do
+		if(_G[i]) then
+			_G[i]:SetStyle("Button")
+			_G[i]:SetFrameLevel(_G[i]:GetFrameLevel() + 2)
+		end
+	end
+	QuestLogPopupDetailFrameScrollFrame:HookScript('OnShow', _hook_DetailScrollShow)
+	QuestLogPopupDetailFrame:HookScript("OnShow", _hook_QuestLogPopupDetailFrameShow)
+
+	SV.API:Set("CloseButton", QuestLogPopupDetailFrameCloseButton)
+	SV.API:Set("ScrollBar", QuestLogPopupDetailFrameScrollFrame, 5)
+	SV.API:Set("ScrollBar", QuestRewardScrollFrame)
+
+	QuestGreetingScrollFrame:RemoveTextures()
+	SV.API:Set("ScrollBar", QuestGreetingScrollFrame)
+
+	for i = 1, 10 do
+		local name = ("QuestInfoRewardsFrameQuestInfoItem%d"):format(i)
+		SV.API:Set("!_QuestItem", _G[name])
+	end
+
+	for i = 1, 10 do
+		local name = ("MapQuestInfoRewardsFrameQuestInfoItem%d"):format(i)
+		SV.API:Set("!_QuestItem", _G[name])
+	end
+
+	QuestInfoSkillPointFrame:RemoveTextures()
+	QuestInfoSkillPointFrame:SetWidth(QuestInfoSkillPointFrame:GetWidth() - 4)
+
+	local curLvl = QuestInfoSkillPointFrame:GetFrameLevel() + 1
+	QuestInfoSkillPointFrame:SetFrameLevel(curLvl)
+	QuestInfoSkillPointFrame:SetStyle("!_Frame", "Icon")
+	QuestInfoSkillPointFrame:SetBackdropColor(1, 1, 0, 0.5)
+	QuestInfoSkillPointFrameIconTexture:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+	QuestInfoSkillPointFrameIconTexture:SetDrawLayer("OVERLAY")
+	QuestInfoSkillPointFrameIconTexture:SetPoint("TOPLEFT", 2, -2)
+	QuestInfoSkillPointFrameIconTexture:SetSize(QuestInfoSkillPointFrameIconTexture:GetWidth()-2, QuestInfoSkillPointFrameIconTexture:GetHeight()-2)
+	QuestInfoSkillPointFrameCount:SetDrawLayer("OVERLAY")
+
+	hooksecurefunc("QuestInfoItem_OnClick", Hook_QuestInfoItem_OnClick)
+	hooksecurefunc("QuestInfo_Display", StyleQuestRewards)
+
+	QuestRewardScrollFrame:HookScript("OnShow", QuestRewardScrollFrame_OnShow)
+
+	QuestFrameInset:Die()
+	QuestFrameDetailPanel:RemoveTextures(true)
+	QuestDetailScrollFrame:RemoveTextures(true)
+	QuestScrollHelper(QuestDetailScrollFrame, 506, 615, true)
+	QuestProgressScrollFrame:SetStyle("!_Frame")
+	QuestScrollHelper(QuestProgressScrollFrame, 506, 615, true)
+	QuestGreetingScrollFrame:SetStyle("!_Frame")
+	QuestScrollHelper(QuestGreetingScrollFrame, 506, 615, true)
+	QuestDetailScrollChildFrame:RemoveTextures(true)
+	QuestRewardScrollFrame:RemoveTextures(true)
+	QuestRewardScrollChildFrame:RemoveTextures(true)
+	QuestFrameProgressPanel:RemoveTextures(true)
+	QuestFrameRewardPanel:RemoveTextures(true)
+
+	QuestFrameAcceptButton:SetStyle("Button")
+	QuestFrameDeclineButton:SetStyle("Button")
+	QuestFrameCompleteButton:SetStyle("Button")
+	QuestFrameGoodbyeButton:SetStyle("Button")
+	QuestFrameCompleteQuestButton:SetStyle("Button")
+
+	SV.API:Set("CloseButton", QuestFrameCloseButton, QuestFrame.Panel)
+
+	for j = 1, 6 do
+		local i = _G["QuestProgressItem"..j]
+		local texture = _G["QuestProgressItem"..j.."IconTexture"]
+		i:RemoveTextures()
+		i:SetStyle("!_Frame", "Inset")
+		i:SetWidth(_G["QuestProgressItem"..j]:GetWidth() - 4)
+		texture:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+		texture:SetDrawLayer("OVERLAY")
+		texture:SetPoint("TOPLEFT", 2, -2)
+		texture:SetSize(texture:GetWidth() - 2, texture:GetHeight() - 2)
+		_G["QuestProgressItem"..j.."Count"]:SetDrawLayer("OVERLAY")
+	end
+
+	QuestNPCModel:RemoveTextures()
+	QuestNPCModel:SetStyle("Frame", "Model")
+
+	QuestNPCModelTextFrame:RemoveTextures()
+	QuestNPCModelTextFrame:SetStyle("Frame", "Default")
+	QuestNPCModelTextFrame.Panel:SetPoint("TOPLEFT", QuestNPCModel.Panel, "BOTTOMLEFT", 0, -2)
+
+	hooksecurefunc("QuestFrame_ShowQuestPortrait", Hook_QuestNPCModel)
+	hooksecurefunc("QuestFrame_SetTitleTextColor", Hook_QuestFrame_SetTitleTextColor)
+
+	SV.NPC:Register(QuestFrame, QuestFrameNpcNameText)
+end
+
+local function QuestChoiceFrameStyle()
+	if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.quest ~= true then return end
+
+	SV.API:Set("Window", QuestChoiceFrame, true, true)
+
+	local bgFrameTop = CreateFrame("Frame", nil, QuestChoiceFrame)
+	bgFrameTop:SetPoint("TOPLEFT", QuestChoiceFrame, "TOPLEFT", 42, -44)
+	bgFrameTop:SetPoint("TOPRIGHT", QuestChoiceFrame, "TOPRIGHT", -42, -44)
+	bgFrameTop:SetHeight(85)
+	bgFrameTop:SetStyle("Frame", "Paper")
+	bgFrameTop:SetPanelColor("dark")
+
+	local bgFrameBottom = CreateFrame("Frame", nil, QuestChoiceFrame)
+	bgFrameBottom:SetPoint("TOPLEFT", QuestChoiceFrame, "TOPLEFT", 42, -140)
+	bgFrameBottom:SetPoint("BOTTOMRIGHT", QuestChoiceFrame, "BOTTOMRIGHT", -42, 44)
+	bgFrameBottom:SetStyle("Frame", "Paper")
+
+
+	SV.API:Set("CloseButton", QuestChoiceFrame.CloseButton)
+	--QuestChoiceFrame.Option1:SetStyle("Frame", "Inset")
+	QuestChoiceFrame.Option1.OptionButton:SetStyle("Button")
+	--QuestChoiceFrame.Option2:SetStyle("Frame", "Inset")
+	QuestChoiceFrame.Option2.OptionButton:SetStyle("Button")
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveCustomStyle(QuestFrameStyle)
+MOD:SaveBlizzardStyle('Blizzard_QuestChoice', QuestChoiceFrameStyle)
diff --git a/SVUI_Skins/components/blizzard/raid.lua b/SVUI_Skins/components/blizzard/raid.lua
new file mode 100644
index 0000000..b63d624
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/raid.lua
@@ -0,0 +1,100 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+local ipairs  = _G.ipairs;
+local pairs   = _G.pairs;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+HELPERS
+##########################################################
+]]--
+local RaidGroupList = {
+	"RaidGroup1",
+	"RaidGroup2",
+	"RaidGroup3",
+	"RaidGroup4",
+	"RaidGroup5",
+	"RaidGroup6",
+	"RaidGroup7",
+	"RaidGroup8"
+};
+
+local RaidInfoFrameList = {
+	"RaidFrameConvertToRaidButton",
+	"RaidFrameRaidInfoButton",
+	"RaidFrameNotInRaidRaidBrowserButton",
+	"RaidInfoExtendButton",
+	"RaidInfoCancelButton"
+};
+--[[
+##########################################################
+RAID MODRS
+##########################################################
+]]--
+local function RaidUIStyle()
+	if InCombatLockdown() then return end
+	if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.raid ~= true then return end
+	for _,group in pairs(RaidGroupList)do
+		if _G[group] then
+			_G[group]:RemoveTextures()
+			for i = 1, 5 do
+				local name = ("%sSlot%d"):format(group, i)
+				local slot = _G[name]
+				if(slot) then
+					slot:RemoveTextures()
+					slot:SetStyle("Frame", "Inset", true)
+				end
+			end
+		end
+	end
+end
+
+local function RaidInfoStyle()
+	--print('test RaidInfoStyle')
+	if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.nonraid ~= true then
+		return
+	end
+
+	_G["RaidInfoFrame"]:RemoveTextures()
+	_G["RaidInfoInstanceLabel"]:RemoveTextures()
+	_G["RaidInfoIDLabel"]:RemoveTextures()
+	_G["RaidInfoScrollFrameScrollBarBG"]:Die()
+	_G["RaidInfoScrollFrameScrollBarTop"]:Die()
+	_G["RaidInfoScrollFrameScrollBarBottom"]:Die()
+	_G["RaidInfoScrollFrameScrollBarMiddle"]:Die()
+
+	for g = 1, #RaidInfoFrameList do
+		if _G[RaidInfoFrameList[g]] then
+			_G[RaidInfoFrameList[g]]:SetStyle("Button")
+		end
+	end
+
+	RaidInfoScrollFrame:RemoveTextures()
+	RaidInfoFrame:SetStyle("Frame", 'Transparent')
+	RaidInfoFrame.Panel:SetPoint("TOPLEFT", RaidInfoFrame, "TOPLEFT")
+	RaidInfoFrame.Panel:SetPoint("BOTTOMRIGHT", RaidInfoFrame, "BOTTOMRIGHT")
+
+	SV.API:Set("CloseButton", RaidInfoCloseButton, RaidInfoFrame)
+	SV.API:Set("ScrollBar", RaidInfoScrollFrame)
+
+	if RaidFrameRaidBrowserButton then RaidFrameRaidBrowserButton:SetStyle("Button") end
+	RaidFrameAllAssistCheckButton:SetStyle("CheckButton")
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveBlizzardStyle("Blizzard_RaidUI", RaidUIStyle)
+MOD:SaveCustomStyle(RaidInfoStyle)
\ No newline at end of file
diff --git a/SVUI_Skins/components/blizzard/reforging.lua b/SVUI_Skins/components/blizzard/reforging.lua
new file mode 100644
index 0000000..1a1b305
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/reforging.lua
@@ -0,0 +1,54 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+REFORGING MODR
+##########################################################
+]]--
+local function ReforgingStyle()
+	if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.reforge ~= true then return end
+
+	SV.API:Set("Window", ReforgingFrame, true)
+
+	ReforgingFrame.ButtonFrame:RemoveTextures()
+	ReforgingFrameReforgeButton:ClearAllPoints()
+	ReforgingFrameReforgeButton:SetPoint("LEFT", ReforgingFrameRestoreButton, "RIGHT", 2, 0)
+	ReforgingFrameReforgeButton:SetPoint("BOTTOMRIGHT", -3, 3)
+	ReforgingFrame.RestoreMessage:SetTextColor(1, 1, 1)
+
+	ReforgingFrameRestoreButton:RemoveTextures()
+	ReforgingFrameReforgeButton:RemoveTextures()
+	ReforgingFrameRestoreButton:SetStyle("Button")
+	ReforgingFrameReforgeButton:SetStyle("Button")
+
+	ReforgingFrame.ItemButton:RemoveTextures()
+	ReforgingFrame.ItemButton:SetStyle("ActionSlot")
+	ReforgingFrame.ItemButton.IconTexture:InsetPoints()
+	hooksecurefunc("ReforgingFrame_Update", function(k)
+		local w, x, u, y, z, A = GetReforgeItemInfo()
+		if x then
+			 ReforgingFrame.ItemButton.IconTexture:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+		else
+			 ReforgingFrame.ItemButton.IconTexture:SetTexture("")
+		end
+	end)
+	SV.API:Set("CloseButton", ReforgingFrameCloseButton)
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveBlizzardStyle("Blizzard_ReforgingUI",ReforgingStyle)
\ No newline at end of file
diff --git a/SVUI_Skins/components/blizzard/social.lua b/SVUI_Skins/components/blizzard/social.lua
new file mode 100644
index 0000000..81d9bac
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/social.lua
@@ -0,0 +1,35 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+TAXIFRAME MODR
+##########################################################
+]]--
+local function SocialStyle()
+	MOD.Debugging = true;
+	if SV.db.Skins.blizzard.enable ~= true then
+		 return
+	end
+	--print("Skinning Social")
+	SV.API:Set("Window", SocialPostFrame)
+	--SV.API:Set("Tooltip", _G.StoreTooltip)
+	--print("Skinning Completed")
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveBlizzardStyle("Blizzard_SocialUI", SocialStyle)
\ No newline at end of file
diff --git a/SVUI_Skins/components/blizzard/spellbook.lua b/SVUI_Skins/components/blizzard/spellbook.lua
new file mode 100644
index 0000000..3d937c9
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/spellbook.lua
@@ -0,0 +1,325 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+local ipairs  = _G.ipairs;
+local pairs   = _G.pairs;
+
+local SV = _G["SVUI"];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+FRAME LISTS
+##########################################################
+]]--
+local proButtons = {
+	"PrimaryProfession1SpellButtonTop",
+	"PrimaryProfession1SpellButtonBottom",
+	"PrimaryProfession2SpellButtonTop",
+	"PrimaryProfession2SpellButtonBottom",
+	"SecondaryProfession1SpellButtonLeft",
+	"SecondaryProfession1SpellButtonRight",
+	"SecondaryProfession2SpellButtonLeft",
+	"SecondaryProfession2SpellButtonRight",
+	"SecondaryProfession3SpellButtonLeft",
+	"SecondaryProfession3SpellButtonRight",
+	"SecondaryProfession4SpellButtonLeft",
+	"SecondaryProfession4SpellButtonRight"
+}
+
+local proFrames = {
+	"PrimaryProfession1",
+	"PrimaryProfession2",
+	"SecondaryProfession1",
+	"SecondaryProfession2",
+	"SecondaryProfession3",
+	"SecondaryProfession4"
+}
+local proBars = {
+	"PrimaryProfession1StatusBar",
+	"PrimaryProfession2StatusBar",
+	"SecondaryProfession1StatusBar",
+	"SecondaryProfession2StatusBar",
+	"SecondaryProfession3StatusBar",
+	"SecondaryProfession4StatusBar"
+}
+--[[
+##########################################################
+HELPERS
+##########################################################
+]]--
+local Tab_OnEnter = function(self)
+	self.backdrop:SetBackdropColor(0.1, 0.8, 0.8)
+	self.backdrop:SetBackdropBorderColor(0.1, 0.8, 0.8)
+end
+
+local Tab_OnLeave = function(self)
+	self.backdrop:SetBackdropColor(0,0,0,1)
+	self.backdrop:SetBackdropBorderColor(0,0,0,1)
+end
+
+local function ChangeTabHelper(tab)
+	if(tab.backdrop) then return end
+
+	local nTex = tab:GetNormalTexture()
+	tab:RemoveTextures()
+	if(nTex) then
+		nTex:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+		nTex:InsetPoints()
+	end
+
+	tab.pushed = true;
+
+	tab.backdrop = CreateFrame("Frame", nil, tab)
+	tab.backdrop:WrapPoints(tab,1,1)
+	tab.backdrop:SetFrameLevel(0)
+	tab.backdrop:SetBackdrop(SV.media.backdrop.glow);
+    tab.backdrop:SetBackdropColor(0,0,0,1)
+	tab.backdrop:SetBackdropBorderColor(0,0,0,1)
+	tab:SetScript("OnEnter", Tab_OnEnter)
+	tab:SetScript("OnLeave", Tab_OnLeave)
+
+	local a1, p, a2, x, y = tab:GetPoint()
+	tab:SetPoint(a1, p, a2, 1, y)
+end
+
+local function GetSpecTabHelper(index)
+	local tab = SpellBookCoreAbilitiesFrame.SpecTabs[index]
+	if(not tab) then return end
+	ChangeTabHelper(tab)
+	if(index > 1) then
+		local a1, p, a2, x, y = tab:GetPoint()
+		tab:ClearAllPoints()
+		tab:SetPoint(a1, p, a2, 0, y)
+	end
+end
+
+local function AbilityButtonHelper(index)
+	local button = SpellBookCoreAbilitiesFrame.Abilities[index]
+
+	if(button and (not button.Panel)) then
+		local icon = button.iconTexture;
+
+		if(not InCombatLockdown()) then
+			if not button.properFrameLevel then
+			 	button.properFrameLevel = button:GetFrameLevel() + 1
+			end
+			button:SetFrameLevel(button.properFrameLevel)
+		end
+
+		button:RemoveTextures()
+		button:SetStyle("Frame", "Icon", true, 2, 0, 0)
+
+		if(button.iconTexture) then
+			button.iconTexture:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+			button.iconTexture:ClearAllPoints()
+			button.iconTexture:InsetPoints(button, 1, 1)
+		end
+
+		if(button.Name) then
+			button.Name:SetFontObject(NumberFont_Outline_Large)
+			button.Name:SetTextColor(1,1,0)
+		end
+
+		if(button.InfoText) then
+			button.InfoText:SetFontObject(SubSpellFont)
+			button.InfoText:SetTextColor(0.8,0.8,0.8)
+		end
+	end
+end
+
+local ButtonUpdateHelper = function(self)
+	local name = self:GetName();
+	local icon = _G[name.."IconTexture"];
+
+	if(not self.Panel) then
+    	local iconTex;
+
+		if(not InCombatLockdown()) then
+			self:SetFrameLevel(SpellBookFrame:GetFrameLevel() + 5)
+		end
+
+		if(icon) then
+			iconTex = icon:GetTexture()
+		end
+
+		self:RemoveTextures()
+		self:SetStyle("Frame", "Icon", true, 2, 0, 0)
+
+		if(icon) then
+			icon:SetTexture(iconTex)
+			icon:ClearAllPoints()
+			icon:InsetPoints(self, 1, 1)
+		end
+
+		self.SpellName:SetFontObject(NumberFontNormal)
+
+		if(self.FlyoutArrow) then
+			self.FlyoutArrow:SetTexture([[Interface\Buttons\ActionBarFlyoutButton]])
+		end
+	end
+
+	if(icon) then
+		icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+	end
+
+	if(self.SpellName) then
+		self.SpellName:SetFontObject(NumberFont_Outline_Large)
+		self.SpellName:SetTextColor(1,1,0)
+	end
+
+	if(self.SpellSubName) then
+		self.SpellSubName:SetFontObject(SubSpellFont)
+		self.SpellSubName:SetTextColor(0.8,0.8,0.8)
+	end
+end
+--[[
+##########################################################
+SPELLBOOK MODR
+##########################################################
+]]--
+local function SpellBookStyle()
+	--print('test SpellBookStyle')
+	if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.spellbook ~= true then return end
+
+	SV:FontManager(_G["SubSpellFont"], "caps", "SYSTEM", 1, "OUTLINE", 0.8, 0.8, 0.8);
+	SV:FontManager(_G["CoreAbilityFont"], "zone", "SYSTEM", 10, "OUTLINE", 0, 0, 0);
+
+	SV.API:Set("Window", SpellBookFrame, false, false, 1, 3, 3)
+	SV.API:Set("CloseButton", SpellBookFrameCloseButton)
+
+	if(SpellBookFrameInset) then
+		SpellBookFrameInset:RemoveTextures()
+		SpellBookFrameInset:SetStyle("!_Frame", "Inset", true, 6)
+	end
+	if(SpellBookSpellIconsFrame) then SpellBookSpellIconsFrame:RemoveTextures() end
+	if(SpellBookSideTabsFrame) then SpellBookSideTabsFrame:RemoveTextures() end
+	if(SpellBookPageNavigationFrame) then SpellBookPageNavigationFrame:RemoveTextures() end
+
+	for i = 1, 3 do
+		local page = _G["SpellBookPage" .. i]
+		if(page) then
+			page:SetDrawLayer('BACKGROUND')
+		end
+	end
+
+	SpellBookFrameTutorialButton:Die()
+
+	SV.API:Set("PageButton", SpellBookPrevPageButton)
+	SV.API:Set("PageButton", SpellBookNextPageButton)
+
+	hooksecurefunc("SpellButton_UpdateButton", ButtonUpdateHelper)
+	--hooksecurefunc("SpellBook_GetCoreAbilityButton", AbilityButtonHelper)
+
+	for i = 1, MAX_SKILLLINE_TABS do
+		local tabName = "SpellBookSkillLineTab" .. i
+		local tab = _G[tabName]
+		if(tab) then
+			if(_G[tabName .. "Flash"]) then _G[tabName .. "Flash"]:Die() end
+			ChangeTabHelper(tab)
+		end
+	end
+
+	--hooksecurefunc('SpellBook_GetCoreAbilitySpecTab', GetSpecTabHelper)
+
+	for _, gName in pairs(proFrames)do
+		local frame = _G[gName]
+		if(frame) then
+			if(_G[gName .. "Missing"]) then
+				_G[gName .. "Missing"]:SetTextColor(1, 1, 0)
+			end
+			if(frame.missingText) then
+				frame.missingText:SetTextColor(1, 0, 0)
+			end
+	    	if(frame.missingHeader) then
+	    		frame.missingHeader:SetFontObject(NumberFont_Outline_Large)
+	    		frame.missingHeader:SetTextColor(1,1,0)
+	    	end
+	    	if(frame.missingText) then
+	    		frame.missingText:SetFontObject(NumberFont_Shadow_Small)
+	    		frame.missingText:SetTextColor(0.9,0.9,0.9)
+	    	end
+	    	if(frame.rank) then
+	    		frame.rank:SetFontObject(NumberFontNormal)
+	    		frame.rank:SetTextColor(0.9,0.9,0.9)
+	    	end
+	    	if(frame.professionName) then
+	    		frame.professionName:SetFontObject(NumberFont_Outline_Large)
+	    		frame.professionName:SetTextColor(1,1,0)
+	    	end
+	    end
+	end
+
+	for _, gName in pairs(proButtons)do
+		local button = _G[gName]
+		local buttonTex = _G[("%sIconTexture"):format(gName)]
+		if(button) then
+			button:RemoveTextures()
+			if(buttonTex) then
+				buttonTex:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+				buttonTex:InsetPoints()
+				button:SetFrameLevel(button:GetFrameLevel() + 2)
+				if not button.Panel then
+					button:SetStyle("Frame", "Inset", false, 3, 3, 3)
+					button.Panel:SetAllPoints()
+				end
+			end
+			if(button.spellString) then
+				button.spellString:SetFontObject(NumberFontNormal)
+				button.spellString:SetTextColor(1,1,0)
+			end
+			if(button.subSpellString) then
+				button.subSpellString:SetFontObject(SubSpellFont)
+			end
+		end
+	end
+
+	for _, gName in pairs(proBars) do
+		local bar = _G[gName]
+		if(bar) then
+			bar:RemoveTextures()
+			bar:SetHeight(12)
+			bar:SetStatusBarTexture(SV.media.statusbar.default)
+			bar:SetStatusBarColor(0, 220/255, 0)
+			bar:SetStyle("Frame", "Default")
+			bar.rankText:ClearAllPoints()
+			bar.rankText:SetPoint("CENTER")
+		end
+	end
+
+--[[
+	if(SpellBookCoreAbilitiesFrame.SpecName) then
+		SpellBookCoreAbilitiesFrame.SpecName:SetTextColor(1,1,0)
+	end
+]]--
+	if(SpellBookFrameTabButton1) then
+		SV.API:Set("Tab", SpellBookFrameTabButton1)
+		SpellBookFrameTabButton1:ClearAllPoints()
+		SpellBookFrameTabButton1:SetPoint('TOPLEFT', SpellBookFrame, 'BOTTOMLEFT', 0, 2)
+	end
+	if(SpellBookFrameTabButton2) then
+		SV.API:Set("Tab", SpellBookFrameTabButton2)
+	end
+	if(SpellBookFrameTabButton3) then
+		SV.API:Set("Tab", SpellBookFrameTabButton3)
+	end
+	if(SpellBookFrameTabButton4) then
+		SV.API:Set("Tab", SpellBookFrameTabButton4)
+	end
+	if(SpellBookFrameTabButton5) then
+		SV.API:Set("Tab", SpellBookFrameTabButton5)
+	end
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveCustomStyle(SpellBookStyle)
diff --git a/SVUI_Skins/components/blizzard/store.lua b/SVUI_Skins/components/blizzard/store.lua
new file mode 100644
index 0000000..04d6d27
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/store.lua
@@ -0,0 +1,33 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+TAXIFRAME MODR
+##########################################################
+]]--
+local function StoreStyle()
+	-- if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.store ~= true then
+	-- 	 return
+	-- end
+
+	--SV.API:Set("Window", StoreFrame)
+	SV.API:Set("Tooltip", _G.StoreTooltip)
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveBlizzardStyle("Blizzard_StoreUI", StoreStyle)
\ No newline at end of file
diff --git a/SVUI_Skins/components/blizzard/system.lua b/SVUI_Skins/components/blizzard/system.lua
new file mode 100644
index 0000000..636a71a
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/system.lua
@@ -0,0 +1,785 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+local ceil = math.ceil
+--[[
+##########################################################
+MASSIVE LIST OF LISTS
+##########################################################
+]]--
+local SystemPopList = {
+	"StaticPopup1",
+	"StaticPopup2",
+	"StaticPopup3"
+};
+local SystemDropDownList = {
+	"DropDownList1MenuBackdrop",
+	"DropDownList2MenuBackdrop",
+	"DropDownList1Backdrop",
+	"DropDownList2Backdrop",
+};
+local SystemFrameList1 = {
+	"GameMenuFrame",
+	"TicketStatusFrameButton",
+	"AutoCompleteBox",
+	"ConsolidatedBuffsTooltip",
+	"ReadyCheckFrame",
+	"StackSplitFrame",
+	"QueueStatusFrame",
+	"InterfaceOptionsFrame",
+	"VideoOptionsFrame",
+	"AudioOptionsFrame"
+};
+local SystemFrameList4 = {
+	"Options",
+	"Store",
+	"SoundOptions",
+	"UIOptions",
+	"Keybindings",
+	"Macros",
+	"Ratings",
+	"AddOns",
+	"Logout",
+	"Quit",
+	"Continue",
+	"MacOptions",
+	"Help",
+	"WhatsNew",
+	"Addons",
+	"SVUI"
+};
+local SystemFrameList5 = {
+	"GameMenuFrame",
+	"InterfaceOptionsFrame",
+	"AudioOptionsFrame",
+	"VideoOptionsFrame",
+};
+local SystemFrameList6 = {
+	"VideoOptionsFrameOkay",
+	"VideoOptionsFrameCancel",
+	"VideoOptionsFrameDefaults",
+	"VideoOptionsFrameApply",
+	"AudioOptionsFrameOkay",
+	"AudioOptionsFrameCancel",
+	"AudioOptionsFrameDefaults",
+	"InterfaceOptionsFrameDefaults",
+	"InterfaceOptionsFrameOkay",
+	"InterfaceOptionsFrameCancel",
+	"ReadyCheckFrameYesButton",
+	"ReadyCheckFrameNoButton",
+	"StackSplitOkayButton",
+	"StackSplitCancelButton",
+	"RolePollPopupAcceptButton"
+};
+
+local SystemFrameList13 = {
+	"VideoOptionsFrameCategoryFrame",
+	"VideoOptionsFramePanelContainer",
+	"InterfaceOptionsFrameCategories",
+	"InterfaceOptionsFramePanelContainer",
+	"InterfaceOptionsFrameAddOns",
+	"AudioOptionsSoundPanelPlayback",
+	"AudioOptionsSoundPanelVolume",
+	"AudioOptionsSoundPanelHardware",
+	"AudioOptionsVoicePanelTalking",
+	"AudioOptionsVoicePanelBinding",
+	"AudioOptionsVoicePanelListening",
+};
+local SystemFrameList14 = {
+	"InterfaceOptionsFrameTab1",
+	"InterfaceOptionsFrameTab2",
+};
+local SystemFrameList15 = {
+	"ControlsPanelBlockChatChannelInvites",
+	"ControlsPanelStickyTargeting",
+	"ControlsPanelAutoDismount",
+	"ControlsPanelAutoClearAFK",
+	"ControlsPanelBlockTrades",
+	"ControlsPanelBlockGuildInvites",
+	"ControlsPanelLootAtMouse",
+	"ControlsPanelAutoLootCorpse",
+	"ControlsPanelInteractOnLeftClick",
+	"ControlsPanelAutoOpenLootHistory",
+	"ControlsPanelReverseCleanUpBags",
+	"ControlsPanelReverseNewLoot",
+	"CombatPanelEnemyCastBarsOnOnlyTargetNameplates",
+	"CombatPanelEnemyCastBarsNameplateSpellNames",
+	"CombatPanelAttackOnAssist",
+	"CombatPanelStopAutoAttack",
+	"CombatPanelNameplateClassColors",
+	"CombatPanelTargetOfTarget",
+	"CombatPanelShowSpellAlerts",
+	"CombatPanelReducedLagTolerance",
+	"CombatPanelActionButtonUseKeyDown",
+	"CombatPanelEnemyCastBarsOnPortrait",
+	"CombatPanelEnemyCastBarsOnNameplates",
+	"CombatPanelAutoSelfCast",
+	"CombatPanelLossOfControl",
+	"DisplayPanelShowCloak",
+	"DisplayPanelShowHelm",
+	"DisplayPanelShowAggroPercentage",
+	"DisplayPanelPlayAggroSounds",
+	"DisplayPanelDetailedLootInfo",
+	"DisplayPanelShowSpellPointsAvg",
+	"DisplayPanelemphasizeMySpellEffects",
+	"DisplayPanelShowFreeBagSpace",
+	"DisplayPanelCinematicSubtitles",
+	"DisplayPanelRotateMinimap",
+	"DisplayPanelScreenEdgeFlash",
+	"DisplayPanelShowAccountAchievments",
+	"ObjectivesPanelAutoQuestTracking",
+	"ObjectivesPanelAutoQuestProgress",
+	"ObjectivesPanelMapQuestDifficulty",
+	"ObjectivesPanelAdvancedWorldMap",
+	"ObjectivesPanelWatchFrameWidth",
+	"ObjectivesPanelMapFade",
+	"SocialPanelProfanityFilter",
+	"SocialPanelSpamFilter",
+	"SocialPanelChatBubbles",
+	"SocialPanelPartyChat",
+	"SocialPanelChatHoverDelay",
+	"SocialPanelGuildMemberAlert",
+	"SocialPanelChatMouseScroll",
+	"SocialPanelEnableTwitter",
+	"ActionBarsPanelLockActionBars",
+	"ActionBarsPanelSecureAbilityToggle",
+	"ActionBarsPanelAlwaysShowActionBars",
+	"ActionBarsPanelBottomLeft",
+	"ActionBarsPanelBottomRight",
+	"ActionBarsPanelRight",
+	"ActionBarsPanelRightTwo",
+	"ActionBarsPanelCountdownCooldowns",
+	"NamesPanelMyName",
+	"NamesPanelFriendlyPlayerNames",
+	"NamesPanelFriendlyPets",
+	"NamesPanelFriendlyGuardians",
+	"NamesPanelFriendlyTotems",
+	"NamesPanelUnitFriendlyMinions",
+	"NamesPanelUnitEnemyMinions",
+	"NamesPanelUnitNameplatesPersonalResource",
+	"NamesPanelUnitNameplatesPersonalResourceOnEnemy",
+	"NamesPanelUnitNameplatesMakeLarger",
+	"NamesPanelUnitNameplatesShowAll",
+	"NamesPanelUnitNameplatesAggroFlash",
+	--"NamesPanelUnitNameplatesFriends",
+	"NamesPanelUnitNameplatesFriendlyGuardians",
+	"NamesPanelUnitNameplatesFriendlyPets",
+	"NamesPanelUnitNameplatesFriendlyTotems",
+	"NamesPanelUnitNameplatesFriendlyMinions",
+	"NamesPanelGuilds",
+	"NamesPanelGuildTitles",
+	"NamesPanelTitles",
+	"NamesPanelMinus",
+	"NamesPanelNonCombatCreature",
+	"NamesPanelEnemyPlayerNames",
+	"NamesPanelEnemyPets",
+	"NamesPanelEnemyGuardians",
+	"NamesPanelEnemyTotems",
+	"NamesPanelUnitNameplatesEnemyPets",
+	--"NamesPanelUnitNameplatesEnemies",
+	"NamesPanelUnitNameplatesEnemyGuardians",
+	"NamesPanelUnitNameplatesEnemyTotems",
+	"NamesPanelUnitNameplatesEnemyMinus",
+	"NamesPanelUnitNameplatesEnemyMinions",
+	"CombatTextPanelTargetDamage",
+	"CombatTextPanelPeriodicDamage",
+	"CombatTextPanelPetDamage",
+	"CombatTextPanelHealing",
+	"CombatTextPanelHealingAbsorbTarget",
+	"CombatTextPanelHealingAbsorbSelf",
+	"CombatTextPanelTargetEffects",
+	"CombatTextPanelOtherTargetEffects",
+	"CombatTextPanelEnableFCT",
+	"CombatTextPanelDodgeParryMiss",
+	"CombatTextPanelDamageReduction",
+	"CombatTextPanelRepChanges",
+	"CombatTextPanelReactiveAbilities",
+	"CombatTextPanelFriendlyHealerNames",
+	"CombatTextPanelCombatState",
+	"CombatTextPanelComboPoints",
+	"CombatTextPanelLowManaHealth",
+	"CombatTextPanelEnergyGains",
+	"CombatTextPanelPeriodicEnergyGains",
+	"CombatTextPanelHonorGains",
+	"CombatTextPanelAuras",
+	"CombatTextPanelPetBattle",
+	"BuffsPanelBuffDurations",
+	"BuffsPanelDispellableDebuffs",
+	"BuffsPanelCastableBuffs",
+	"BuffsPanelConsolidateBuffs",
+	"BuffsPanelShowAllEnemyDebuffs",
+	"CameraPanelFollowTerrain",
+	"CameraPanelHeadBob",
+	"CameraPanelWaterCollision",
+	"CameraPanelSmartPivot",
+	"MousePanelInvertMouse",
+	"MousePanelClickToMove",
+	"MousePanelWoWMouse",
+	"MousePanelEnableMouseSpeed",
+	"HelpPanelShowTutorials",
+	"HelpPanelLoadingScreenTips",
+	"HelpPanelEnhancedTooltips",
+	"HelpPanelBeginnerTooltips",
+	"HelpPanelShowLuaErrors",
+	"HelpPanelColorblindMode",
+	"HelpPanelMovePad",
+	"BattlenetPanelOnlineFriends",
+	"BattlenetPanelOfflineFriends",
+	"BattlenetPanelBroadcasts",
+	"BattlenetPanelFriendRequests",
+	"BattlenetPanelConversations",
+	"BattlenetPanelShowToastWindow",
+	"StatusTextPanelPlayer",
+	"StatusTextPanelPet",
+	"StatusTextPanelParty",
+	"StatusTextPanelTarget",
+	"StatusTextPanelAlternateResource",
+	"StatusTextPanelPercentages",
+	"StatusTextPanelXP",
+	"UnitFramePanelPartyBackground",
+	"UnitFramePanelPartyPets",
+	"UnitFramePanelArenaEnemyFrames",
+	"UnitFramePanelArenaEnemyCastBar",
+	"UnitFramePanelArenaEnemyPets",
+	"UnitFramePanelFullSizeFocusFrame",
+	"NamesPanelUnitNameplatesNameplateClassColors",
+	"AccessibilityPanelMovePad",
+	"AccessibilityPanelColorblindMode"
+};
+local SystemFrameList16 ={
+	"ControlsPanelAutoLootKeyDropDown",
+	"CombatPanelTOTDropDown",
+	"CombatPanelFocusCastKeyDropDown",
+	"CombatPanelSelfCastKeyDropDown",
+	"CombatPanelLossOfControlFullDropDown",
+	"CombatPanelLossOfControlSilenceDropDown",
+	"CombatPanelLossOfControlInterruptDropDown",
+	"CombatPanelLossOfControlDisarmDropDown",
+	"CombatPanelLossOfControlRootDropDown",
+	"CombatTextPanelTargetModeDropDown",
+	"DisplayPanelAggroWarningDisplay",
+	"DisplayPanelWorldPVPObjectiveDisplay",
+	"DisplayPanelOutlineDropDown",
+	"ObjectivesPanelQuestSorting",
+	"SocialPanelChatStyle",
+	"SocialPanelWhisperMode",
+	"SocialPanelTimestamps",
+	"SocialPanelBnWhisperMode",
+	"SocialPanelConversationMode",
+	"ActionBarsPanelPickupActionKeyDropDown",
+	"NamesPanelNPCNamesDropDown",
+	"NamesPanelUnitNameplatesMotionDropDown",
+	"CombatTextPanelFCTDropDown",
+	"CameraPanelStyleDropDown",
+	"MousePanelClickMoveStyleDropDown",
+	"LanguagesPanelLocaleDropDown",
+	"LanguagesPanelAudioLocaleDropDown",
+	"StatusTextPanelDisplayDropDown",
+	"AccessibilityPanelColorFilterDropDown"
+};
+local SystemFrameList17 = {
+	"Advanced_MaxFPSCheckBox",
+	"Advanced_MaxFPSBKCheckBox",
+	"Advanced_DesktopGamma",
+	"Advanced_UseUIScale",
+	"AudioOptionsSoundPanelEnableSound",
+	"AudioOptionsSoundPanelSoundEffects",
+	"AudioOptionsSoundPanelErrorSpeech",
+	"AudioOptionsSoundPanelEmoteSounds",
+	"AudioOptionsSoundPanelPetSounds",
+	"AudioOptionsSoundPanelMusic",
+	"AudioOptionsSoundPanelLoopMusic",
+	"AudioOptionsSoundPanelAmbientSounds",
+	"AudioOptionsSoundPanelSoundInBG",
+	"AudioOptionsSoundPanelReverb",
+	"AudioOptionsSoundPanelHRTF",
+	"AudioOptionsSoundPanelEnableDSPs",
+	"AudioOptionsSoundPanelUseHardware",
+	"AudioOptionsVoicePanelEnableVoice",
+	"AudioOptionsVoicePanelEnableMicrophone",
+	"AudioOptionsVoicePanelPushToTalkSound",
+	"AudioOptionsVoicePanelDialogVolume",
+	"AudioOptionsSoundPanelPetBattleMusic",
+	"NetworkOptionsPanelOptimizeSpeed",
+	"NetworkOptionsPanelUseIPv6",
+	"NetworkOptionsPanelAdvancedCombatLogging"
+};
+local SystemFrameList18 = {
+	"Display_AntiAliasingDropDown",
+	"Display_DisplayModeDropDown",
+	"Display_ResolutionDropDown",
+	"Display_RefreshDropDown",
+	"Display_PrimaryMonitorDropDown",
+	"Display_MultiSampleDropDown",
+	"Display_VerticalSyncDropDown",
+	"Graphics_TextureResolutionDropDown",
+	"Graphics_FilteringDropDown",
+	"Graphics_ProjectedTexturesDropDown",
+	"Graphics_ViewDistanceDropDown",
+	"Graphics_EnvironmentalDetailDropDown",
+	"Graphics_GroundClutterDropDown",
+	"Graphics_ShadowsDropDown",
+	"Graphics_LiquidDetailDropDown",
+	"Graphics_SunshaftsDropDown",
+	"Graphics_ParticleDensityDropDown",
+	"Graphics_SSAODropDown",
+	"Graphics_RefractionDropDown",
+	"Advanced_BufferingDropDown",
+	"Advanced_LagDropDown",
+	"Advanced_HardwareCursorDropDown",
+	"Advanced_GraphicsAPIDropDown",
+	"AudioOptionsSoundPanelHardwareDropDown",
+	"AudioOptionsSoundPanelSoundChannelsDropDown",
+	"AudioOptionsVoicePanelInputDeviceDropDown",
+	"AudioOptionsVoicePanelChatModeDropDown",
+	"AudioOptionsVoicePanelOutputDeviceDropDown",
+	"CompactUnitFrameProfilesProfileSelector",
+	"CompactUnitFrameProfilesGeneralOptionsFrameHealthTextDropdown",
+	"CompactUnitFrameProfilesGeneralOptionsFrameSortByDropdown",
+};
+local SystemFrameList19 = {
+	"RecordLoopbackSoundButton",
+	"PlayLoopbackSoundButton",
+	"AudioOptionsVoicePanelChatMode1KeyBindingButton",
+	"InterfaceOptionsSocialPanelTwitterLoginButton",
+	"CompactUnitFrameProfilesSaveButton",
+	"CompactUnitFrameProfilesDeleteButton",
+};
+local SystemFrameList20 = {
+	"KeepGroupsTogether",
+	"DisplayIncomingHeals",
+	"DisplayPowerBar",
+	"DisplayAggroHighlight",
+	"UseClassColors",
+	"DisplayPets",
+	"DisplayMainTankAndAssist",
+	"DisplayBorder",
+	"ShowDebuffs",
+	"DisplayOnlyDispellableDebuffs",
+	"AutoActivate2Players",
+	"AutoActivate3Players",
+	"AutoActivate5Players",
+	"AutoActivate10Players",
+	"AutoActivate15Players",
+	"AutoActivate25Players",
+	"AutoActivate40Players",
+	"AutoActivateSpec1",
+	"AutoActivateSpec2",
+	"AutoActivatePvP",
+	"AutoActivatePvE",
+};
+local SystemFrameList21 = {
+	"Graphics_Quality",
+	"Advanced_UIScaleSlider",
+	"Advanced_MaxFPSSlider",
+	"Advanced_MaxFPSBKSlider",
+	"AudioOptionsSoundPanelSoundQuality",
+	"AudioOptionsSoundPanelMasterVolume",
+	"AudioOptionsSoundPanelSoundVolume",
+	"AudioOptionsSoundPanelMusicVolume",
+	"AudioOptionsSoundPanelAmbienceVolume",
+	"AudioOptionsVoicePanelMicrophoneVolume",
+	"AudioOptionsVoicePanelSpeakerVolume",
+	"AudioOptionsVoicePanelSoundFade",
+	"AudioOptionsVoicePanelMusicFade",
+	"AudioOptionsVoicePanelAmbienceFade",
+	"InterfaceOptionsCombatPanelSpellAlertOpacitySlider",
+	"InterfaceOptionsCombatPanelMaxSpellStartRecoveryOffset",
+	"InterfaceOptionsBattlenetPanelToastDurationSlider",
+	"InterfaceOptionsCameraPanelMaxDistanceSlider",
+	"InterfaceOptionsCameraPanelFollowSpeedSlider",
+	"InterfaceOptionsMousePanelMouseSensitivitySlider",
+	"InterfaceOptionsMousePanelMouseLookSpeedSlider",
+	"AddonListScrollFrameScrollBar",
+	"OpacityFrameSlider",
+};
+--[[
+##########################################################
+HELPER FUNCTIONS
+##########################################################
+]]--
+local _hook_GhostFrameBackdropColor = function(self, r, g, b, a)
+	if r ~= 0 or g ~= 0 or b ~= 0 or a ~= 0 then
+		self:SetBackdropColor(0,0,0,0)
+		self:SetBackdropBorderColor(0,0,0,0)
+	end
+end
+
+local _hook_AddonsList_Update = function()
+	for i = 1, MAX_ADDONS_DISPLAYED do
+		SV.API:Set("CheckButton", _G["AddonListEntry"..i.."Enabled"])
+		SV.API:Set("Button", _G["AddonListEntry"..i.."Load"])
+	end
+end
+--[[
+##########################################################
+SYSTEM WIDGET MODRS
+##########################################################
+]]--
+local function SystemPanelQue()
+	--print('test SystemPanelQue')
+	if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.misc ~= true then return end
+
+	local GhostFrame = _G.GhostFrame;
+	local ReadyCheckFrame = _G.ReadyCheckFrame;
+	local InterfaceOptionsFrame = _G.InterfaceOptionsFrame;
+	local MacOptionsFrame = _G.MacOptionsFrame;
+	local GuildInviteFrame = _G.GuildInviteFrame;
+	local BattleTagInviteFrame = _G.BattleTagInviteFrame;
+
+	QueueStatusFrame:RemoveTextures()
+
+	for i = 1, #SystemPopList do
+		local this = _G[SystemPopList[i]]
+		if(this) then
+			this:RemoveTextures()
+			SV.API:Set("Alert", this)
+		end
+	end
+	for i = 1, #SystemDropDownList do
+		local this = _G[SystemDropDownList[i]]
+		if(this) then
+			this:RemoveTextures()
+			this:SetStyle("Frame")
+		end
+	end
+	for i = 1, #SystemFrameList1 do
+		local this = _G[SystemFrameList1[i]]
+		if(this) then
+			SV.API:Set("Window", this)
+		end
+	end
+
+	LFDRoleCheckPopup:RemoveTextures()
+	LFDRoleCheckPopup:SetStyle("!_Frame")
+	LFDRoleCheckPopupAcceptButton:SetStyle("Button")
+	LFDRoleCheckPopupDeclineButton:SetStyle("Button")
+	LFDRoleCheckPopupRoleButtonTank.checkButton:SetStyle("CheckButton")
+	LFDRoleCheckPopupRoleButtonDPS.checkButton:SetStyle("CheckButton")
+	LFDRoleCheckPopupRoleButtonHealer.checkButton:SetStyle("CheckButton")
+	LFDRoleCheckPopupRoleButtonTank.checkButton:SetFrameLevel(LFDRoleCheckPopupRoleButtonTank.checkButton:GetFrameLevel() + 1)
+	LFDRoleCheckPopupRoleButtonDPS.checkButton:SetFrameLevel(LFDRoleCheckPopupRoleButtonDPS.checkButton:GetFrameLevel() + 1)
+	LFDRoleCheckPopupRoleButtonHealer.checkButton:SetFrameLevel(LFDRoleCheckPopupRoleButtonHealer.checkButton:GetFrameLevel() + 1)
+	for i = 1, 3 do
+		for j = 1, 3 do
+			_G["StaticPopup"..i.."Button"..j]:SetStyle("Button")
+			_G["StaticPopup"..i.."EditBox"]:SetStyle("Editbox")
+			_G["StaticPopup"..i.."MoneyInputFrameGold"]:SetStyle("Editbox")
+			_G["StaticPopup"..i.."MoneyInputFrameSilver"]:SetStyle("Editbox")
+			_G["StaticPopup"..i.."MoneyInputFrameCopper"]:SetStyle("Editbox")
+			_G["StaticPopup"..i.."EditBox"].Panel:SetPoint("TOPLEFT", -2, -4)
+			_G["StaticPopup"..i.."EditBox"].Panel:SetPoint("BOTTOMRIGHT", 2, 4)
+			_G["StaticPopup"..i.."ItemFrameNameFrame"]:Die()
+			_G["StaticPopup"..i.."ItemFrame"]:GetNormalTexture():Die()
+			_G["StaticPopup"..i.."ItemFrame"]:SetStyle("!_Frame", "Default")
+			_G["StaticPopup"..i.."ItemFrame"]:SetStyle("Button")
+			_G["StaticPopup"..i.."ItemFrameIconTexture"]:SetTexCoord(0.1,0.9,0.1,0.9 )
+			_G["StaticPopup"..i.."ItemFrameIconTexture"]:InsetPoints()
+		end
+	end
+	local CAPS_TEXT_FONT = LibStub("LibSharedMedia-3.0"):Fetch("font", SV.media.font.caps.file);
+  	local caps_fontsize = SV.media.font.caps.size;
+	for i = 1, #SystemFrameList4 do
+		local this = _G["GameMenuButton"..SystemFrameList4[i]]
+		if(this) then
+			this:SetStyle("Button")
+		end
+	end
+	if IsAddOnLoaded("OptionHouse") then
+		GameMenuButtonOptionHouse:SetStyle("Button")
+	end
+
+	do
+		GhostFrame:SetStyle("Button")
+		GhostFrame:SetBackdropColor(0,0,0,0)
+		GhostFrame:SetBackdropBorderColor(0,0,0,0)
+		hooksecurefunc(GhostFrame, "SetBackdropColor", _hook_GhostFrameBackdropColor)
+		hooksecurefunc(GhostFrame, "SetBackdropBorderColor", _hook_GhostFrameBackdropColor)
+		GhostFrame:ClearAllPoints()
+		GhostFrame:SetPoint("CENTER", SVUI_SpecialAbility, "CENTER", 0, 0)
+		GhostFrameContentsFrame:SetStyle("Button")
+		GhostFrameContentsFrameIcon:SetTexture("")
+		local x = CreateFrame("Frame", nil, GhostFrame)
+		x:SetFrameStrata("MEDIUM")
+		x:SetStyle("!_Frame", "Default")
+		x:WrapPoints(GhostFrameContentsFrameIcon)
+		local tex = x:CreateTexture(nil, "OVERLAY")
+		tex:SetTexture("Interface\\Icons\\spell_holy_guardianspirit")
+		tex:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+		tex:InsetPoints()
+	end
+
+	if(AddonList) then
+		--AddonList:RemoveTextures(true)
+		SV.API:Set("Window", AddonList, true, true)
+		SV.API:Set("Button", AddonListEnableAllButton)
+		SV.API:Set("Button", AddonListDisableAllButton)
+		SV.API:Set("Button", AddonListDisableAllButton)
+		SV.API:Set("Button", AddonListCancelButton)
+		SV.API:Set("Button", AddonListOkayButton)
+		SV.API:Set("CheckButton", AddonListForceLoad)
+		SV.API:Set("DropDown", AddonCharacterDropDown)
+		SV.API:Set("ScrollBar", AddonListScrollFrame)
+		for i = 1, MAX_ADDONS_DISPLAYED do
+			SV.API:Set("CheckButton", _G["AddonListEntry"..i.."Enabled"])
+			SV.API:Set("Button", _G["AddonListEntry"..i.."Load"])
+		end
+	end
+
+	for i = 1, #SystemFrameList5 do
+		local this = _G[SystemFrameList5[i].."Header"]
+		if(this) then
+			this:SetTexture("")
+			this:ClearAllPoints()
+			if this == _G["GameMenuFrameHeader"] then
+				this:SetPoint("TOP", GameMenuFrame, 0, 7)
+			else
+				this:SetPoint("TOP", SystemFrameList5[i], 0, 0)
+			end
+		end
+	end
+	for i = 1, #SystemFrameList6 do
+		local this = _G[SystemFrameList6[i]]
+		if(this) then
+			this:SetStyle("Button")
+		end
+	end
+	VideoOptionsFrameCancel:ClearAllPoints()
+	VideoOptionsFrameCancel:SetPoint("RIGHT",VideoOptionsFrameApply,"LEFT",-4,0)
+	VideoOptionsFrameOkay:ClearAllPoints()
+	VideoOptionsFrameOkay:SetPoint("RIGHT",VideoOptionsFrameCancel,"LEFT",-4,0)
+	AudioOptionsFrameOkay:ClearAllPoints()
+	AudioOptionsFrameOkay:SetPoint("RIGHT",AudioOptionsFrameCancel,"LEFT",-4,0)
+	InterfaceOptionsFrameOkay:ClearAllPoints()
+	InterfaceOptionsFrameOkay:SetPoint("RIGHT",InterfaceOptionsFrameCancel,"LEFT", -4,0)
+	ReadyCheckFrameYesButton:SetParent(ReadyCheckFrame)
+	ReadyCheckFrameNoButton:SetParent(ReadyCheckFrame)
+	ReadyCheckFrameYesButton:SetPoint("RIGHT", ReadyCheckFrame, "CENTER", -1, 0)
+	ReadyCheckFrameNoButton:SetPoint("LEFT", ReadyCheckFrameYesButton, "RIGHT", 3, 0)
+	ReadyCheckFrameText:SetParent(ReadyCheckFrame)
+	ReadyCheckFrameText:ClearAllPoints()
+	ReadyCheckFrameText:SetPoint("TOP", 0, -12)
+	ReadyCheckListenerFrame:SetAlpha(0)
+	ReadyCheckFrame:HookScript("OnShow", function(self) if UnitIsUnit("player", self.initiator) then self:Hide() end end)
+	StackSplitFrame:GetRegions():Hide()
+	RolePollPopup:SetStyle("!_Frame", "Transparent", true)
+	InterfaceOptionsFrame:SetClampedToScreen(true)
+	InterfaceOptionsFrame:SetMovable(true)
+	InterfaceOptionsFrame:EnableMouse(true)
+	InterfaceOptionsFrame:RegisterForDrag("LeftButton", "RightButton")
+	InterfaceOptionsFrame:SetScript("OnDragStart", function(self)
+		if InCombatLockdown() then return end
+		if IsShiftKeyDown() then
+			self:StartMoving()
+		end
+	end)
+	InterfaceOptionsFrame:SetScript("OnDragStop", function(self)
+		self:StopMovingOrSizing()
+	end)
+	if IsMacClient() then
+		MacOptionsFrame:SetStyle("!_Frame", "Default")
+		MacOptionsFrameHeader:SetTexture("")
+		MacOptionsFrameHeader:ClearAllPoints()
+		MacOptionsFrameHeader:SetPoint("TOP", MacOptionsFrame, 0, 0)
+		MacOptionsFrameMovieRecording:SetStyle("!_Frame", "Default")
+		MacOptionsITunesRemote:SetStyle("!_Frame", "Default")
+		MacOptionsFrameCancel:SetStyle("Button")
+		MacOptionsFrameOkay:SetStyle("Button")
+		MacOptionsButtonKeybindings:SetStyle("Button")
+		MacOptionsFrameDefaults:SetStyle("Button")
+		MacOptionsButtonCompress:SetStyle("Button")
+		local tPoint, tRTo, tRP, tX, tY = MacOptionsButtonCompress:GetPoint()
+		MacOptionsButtonCompress:SetWidth(136)
+		MacOptionsButtonCompress:ClearAllPoints()
+		MacOptionsButtonCompress:SetPoint(tPoint, tRTo, tRP, 4, tY)
+		MacOptionsFrameCancel:SetWidth(96)
+		MacOptionsFrameCancel:SetHeight(22)
+		tPoint, tRTo, tRP, tX, tY = MacOptionsFrameCancel:GetPoint()
+		MacOptionsFrameCancel:ClearAllPoints()
+		MacOptionsFrameCancel:SetPoint(tPoint, tRTo, tRP, -14, tY)
+		MacOptionsFrameOkay:ClearAllPoints()
+		MacOptionsFrameOkay:SetWidth(96)
+		MacOptionsFrameOkay:SetHeight(22)
+		MacOptionsFrameOkay:SetPoint("LEFT",MacOptionsFrameCancel, -99,0)
+		MacOptionsButtonKeybindings:ClearAllPoints()
+		MacOptionsButtonKeybindings:SetWidth(96)
+		MacOptionsButtonKeybindings:SetHeight(22)
+		MacOptionsButtonKeybindings:SetPoint("LEFT",MacOptionsFrameOkay, -99,0)
+		MacOptionsFrameDefaults:SetWidth(96)
+		MacOptionsFrameDefaults:SetHeight(22)
+	end
+	OpacityFrame:RemoveTextures()
+	OpacityFrame:SetStyle("!_Frame", "Transparent", true)
+
+	hooksecurefunc("UIDropDownMenu_InitializeHelper", function(self)
+		for i = 1, UIDROPDOWNMENU_MAXLEVELS do
+			local name = ("DropDownList%d"):format(i)
+			local bg = _G[("%sBackdrop"):format(name)]
+			bg:SetStyle("Frame", 'Transparent')
+			local menu = _G[("%sMenuBackdrop"):format(name)]
+			menu:SetStyle("Frame", 'Transparent')
+		end
+	end)
+
+	for i=1, BattleTagInviteFrame:GetNumChildren() do
+		local child = select(i, BattleTagInviteFrame:GetChildren())
+		if child:GetObjectType() == 'Button' then
+			child:SetStyle("Button")
+		end
+	end
+
+	for i = 1, #SystemFrameList13 do
+		local frame = _G[SystemFrameList13[i]]
+		if(frame) then
+			frame:RemoveTextures()
+			frame:SetStyle("Frame", 'Transparent')
+		end
+	end
+
+	for i = 1, #SystemFrameList14 do
+		local this = _G[SystemFrameList14[i]]
+		if(this) then
+			this:RemoveTextures()
+			SV.API:Set("Tab", this)
+		end
+	end
+
+	InterfaceOptionsFrameTab1:ClearAllPoints()
+	InterfaceOptionsFrameTab1:SetPoint("BOTTOMLEFT",InterfaceOptionsFrameCategories,"TOPLEFT",-11,-2)
+	VideoOptionsFrameDefaults:ClearAllPoints()
+	InterfaceOptionsFrameDefaults:ClearAllPoints()
+	InterfaceOptionsFrameCancel:ClearAllPoints()
+	VideoOptionsFrameDefaults:SetPoint("TOPLEFT",VideoOptionsFrameCategoryFrame,"BOTTOMLEFT",-1,-5)
+	InterfaceOptionsFrameDefaults:SetPoint("TOPLEFT",InterfaceOptionsFrameCategories,"BOTTOMLEFT",-1,-5)
+	InterfaceOptionsFrameCancel:SetPoint("TOPRIGHT",InterfaceOptionsFramePanelContainer,"BOTTOMRIGHT",0,-6)
+
+	for i = 1, #SystemFrameList15 do
+		local this = _G["InterfaceOptions"..SystemFrameList15[i]]
+		if(this) then
+			this:SetStyle("CheckButton")
+		end
+	end
+
+	for i = 1, #SystemFrameList16 do
+		local this = _G["InterfaceOptions"..SystemFrameList16[i]]
+		if(this) then
+			SV.API:Set("DropDown", this)
+		end
+	end
+
+	for i = 1, #SystemFrameList17 do
+		local this = _G[SystemFrameList17[i]]
+		if(this) then
+			this:SetStyle("CheckButton")
+		end
+	end
+
+	for i = 1, #SystemFrameList18 do
+		local this = _G[SystemFrameList18[i]]
+		if(this) then
+			SV.API:Set("DropDown", this, 165)
+		end
+	end
+
+	for i = 1, #SystemFrameList19 do
+		local this = _G[SystemFrameList19[i]]
+		if(this) then
+			this:SetStyle("Button")
+		end
+	end
+
+	AudioOptionsVoicePanelChatMode1KeyBindingButton:ClearAllPoints()
+	AudioOptionsVoicePanelChatMode1KeyBindingButton:SetPoint("CENTER", AudioOptionsVoicePanelBinding, "CENTER", 0, -10)
+	if(CompactUnitFrameProfilesRaidStylePartyFrames) then CompactUnitFrameProfilesRaidStylePartyFrames:SetStyle("CheckButton") end
+	if(CompactUnitFrameProfilesGeneralOptionsFrameResetPositionButton) then CompactUnitFrameProfilesGeneralOptionsFrameResetPositionButton:SetStyle("Button") end
+
+	for i = 1, #SystemFrameList20 do
+		local this = _G["CompactUnitFrameProfilesGeneralOptionsFrame"..SystemFrameList20[i]]
+		if(this) then
+			this:SetStyle("CheckButton")
+			this:SetFrameLevel(40)
+		end
+	end
+
+	for i = 1, #SystemFrameList21 do
+		local this = _G[SystemFrameList21[i]]
+		if(this) then
+			SV.API:Set("ScrollBar", this)
+		end
+	end
+
+	--print('test SystemPanelQue 2')
+	if(MacOptionsFrame) then
+		MacOptionsFrame:RemoveTextures()
+		MacOptionsFrame:SetStyle("!_Frame")
+		MacOptionsButtonCompress:SetStyle("Button")
+		MacOptionsButtonKeybindings:SetStyle("Button")
+		MacOptionsFrameDefaults:SetStyle("Button")
+		MacOptionsFrameOkay:SetStyle("Button")
+		MacOptionsFrameCancel:SetStyle("Button")
+		MacOptionsFrameMovieRecording:RemoveTextures()
+		MacOptionsITunesRemote:RemoveTextures()
+		MacOptionsFrameMisc:RemoveTextures()
+		--print('test SystemPanelQue m1')
+		SV.API:Set("DropDown", MacOptionsFrameResolutionDropDown)
+		SV.API:Set("DropDown", MacOptionsFrameFramerateDropDown)
+		SV.API:Set("DropDown", MacOptionsFrameCodecDropDown)
+		SV.API:Set("ScrollBar", MacOptionsFrameQualitySlider)
+		for i = 1, 11 do
+			local this = _G["MacOptionsFrameCheckButton"..i]
+			if(this) then
+				this:SetStyle("CheckButton")
+			end
+		end
+		--print('test SystemPanelQue m2')
+		MacOptionsButtonKeybindings:ClearAllPoints()
+		MacOptionsButtonKeybindings:SetPoint("LEFT", MacOptionsFrameDefaults, "RIGHT", 2, 0)
+		MacOptionsFrameOkay:ClearAllPoints()
+		MacOptionsFrameOkay:SetPoint("LEFT", MacOptionsButtonKeybindings, "RIGHT", 2, 0)
+		MacOptionsFrameCancel:ClearAllPoints()
+		MacOptionsFrameCancel:SetPoint("LEFT", MacOptionsFrameOkay, "RIGHT", 2, 0)
+		MacOptionsFrameCancel:SetWidth(MacOptionsFrameCancel:GetWidth() - 6)
+	end
+
+	--print('test SystemPanelQue 3')
+	ReportCheatingDialog:RemoveTextures()
+	ReportCheatingDialogCommentFrame:RemoveTextures()
+	ReportCheatingDialogReportButton:SetStyle("Button")
+	ReportCheatingDialogCancelButton:SetStyle("Button")
+	ReportCheatingDialog:SetStyle("!_Frame", "Transparent", true)
+	ReportCheatingDialogCommentFrameEditBox:SetStyle("Editbox")
+	ReportPlayerNameDialog:RemoveTextures()
+	ReportPlayerNameDialogCommentFrame:RemoveTextures()
+	ReportPlayerNameDialogCommentFrameEditBox:SetStyle("Editbox")
+	ReportPlayerNameDialog:SetStyle("!_Frame", "Transparent", true)
+	ReportPlayerNameDialogReportButton:SetStyle("Button")
+	ReportPlayerNameDialogCancelButton:SetStyle("Button")
+
+	--print('test SystemPanelQue 4')
+	SideDressUpFrame:RemoveTextures(true)
+	SideDressUpFrame:SetSize(300, 400)
+	SideDressUpModel:RemoveTextures(true)
+	SideDressUpModel:SetAllPoints(SideDressUpFrame)
+	SideDressUpModel:SetStyle("!_Frame", "Model")
+	SideDressUpModelResetButton:SetStyle("Button")
+	SideDressUpModelResetButton:SetPoint("BOTTOM", SideDressUpModel, "BOTTOM", 0, 20)
+	SV.API:Set("CloseButton", SideDressUpModelCloseButton)
+	SV.API:Set("CloseButton", SideDressUpModelCloseButton)
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveCustomStyle(SystemPanelQue)
diff --git a/SVUI_Skins/components/blizzard/talents.lua b/SVUI_Skins/components/blizzard/talents.lua
new file mode 100644
index 0000000..8775e8a
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/talents.lua
@@ -0,0 +1,274 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  	= _G.unpack;
+local select  	= _G.select;
+local ipairs  	= _G.ipairs;
+local pairs   	= _G.pairs;
+local type 		= _G.type;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+HELPERS
+##########################################################
+]]--
+local SpecButtonList = {
+	"PlayerTalentFrameActivateButton",
+	"PlayerTalentFrameSpecializationLearnButton",
+	"PlayerTalentFrameTalentsLearnButton",
+	"PlayerTalentFramePetSpecializationLearnButton"
+};
+
+local function Tab_OnEnter(this)
+	this.backdrop:SetPanelColor("highlight")
+	this.backdrop:SetBackdropBorderColor(0.1, 0.8, 0.8, 1)
+	--this:SetBackdropBorderColor(0.1, 0.8, 0.8, 0.5)
+end
+
+local function Tab_OnLeave(this)
+	this.backdrop:SetPanelColor("dark")
+	this.backdrop:SetBackdropBorderColor(0,0,0,0.5)
+	--this:SetBackdropBorderColor(0,0,0,1)
+end
+
+local function ChangeTabHelper(this)
+	this:RemoveTextures()
+	local nTex = this:GetNormalTexture()
+	if(nTex) then
+		nTex:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+		nTex:InsetPoints()
+	end
+
+	this.pushed = true;
+
+	this.backdrop = CreateFrame("Frame", nil, this)
+	this.backdrop:WrapPoints(this,1,1)
+	this.backdrop:SetFrameLevel(0)
+	this.backdrop:SetBackdrop(SV.media.backdrop.glow);
+    this.backdrop:SetBackdropColor(0,0,0,1)
+	this.backdrop:SetBackdropBorderColor(0,0,0,0.5)
+	this:SetScript("OnEnter", Tab_OnEnter)
+	this:SetScript("OnLeave", Tab_OnLeave)
+end
+
+local function StyleGlyphHolder(holder, offset)
+    if((not holder) or holder.styled) then return end
+    offset = offset or 1;
+
+    holder:RemoveTextures()
+
+    local outer = holder:CreateTexture(nil, "OVERLAY")
+    outer:WrapPoints(holder, offset, offset)
+    outer:SetTexture(SV.media.button.round)
+    outer:SetGradient(unpack(SV.media.gradient.class))
+
+    local hover = holder:CreateTexture(nil, "HIGHLIGHT")
+    hover:WrapPoints(holder, offset, offset)
+    hover:SetTexture(SV.media.button.round)
+    hover:SetGradient(unpack(SV.media.gradient.yellow))
+    holder.hover = hover
+
+    if holder.SetDisabledTexture then
+        local disabled = holder:CreateTexture(nil, "BORDER")
+        disabled:WrapPoints(holder, offset, offset)
+        disabled:SetTexture(SV.media.button.round)
+        disabled:SetGradient(unpack(SV.media.gradient.default))
+        holder:SetDisabledTexture(disabled)
+    end
+
+    local cd = holder:GetName() and _G[holder:GetName().."Cooldown"]
+    if cd then
+        cd:ClearAllPoints()
+        cd:InsetPoints(holder)
+    end
+
+    holder.styled = true
+end
+--[[
+##########################################################
+TALENTFRAME MODR
+##########################################################
+]]--
+local function TalentFrameStyle()
+	--print("TalentFrameStyle")
+	if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.talent ~= true then return end
+
+	SV.API:Set("Window", PlayerTalentFrame)
+	PlayerTalentFrameInset:RemoveTextures()
+	PlayerTalentFrameTalents:RemoveTextures()
+	PlayerTalentFrameSpecialization:DisableDrawLayer("BORDER")
+	PlayerTalentFramePetSpecialization:DisableDrawLayer("BORDER")
+	PlayerTalentFrameSpecializationTutorialButton:Die()
+	PlayerTalentFrameTalentsTutorialButton:Die()
+	PlayerTalentFramePetSpecializationTutorialButton:Die()
+
+	PlayerTalentFrame.Panel:SetPoint("BOTTOMRIGHT", PlayerTalentFrame, "BOTTOMRIGHT", 0, -5)
+
+	PlayerTalentFrameTalents:SetStyle("!_Frame", "Inset")
+	PlayerTalentFrameSpecialization:SetStyle("Frame", "Inset")
+	PlayerTalentFrameSpecialization.Panel:SetPoint("TOPLEFT", PlayerTalentFrameSpecialization, "TOPLEFT", 0, 4)
+	PlayerTalentFrameSpecialization.Panel:SetPoint("BOTTOMRIGHT", PlayerTalentFrameSpecialization, "BOTTOMRIGHT", 3, 0)
+	PlayerTalentFramePetSpecialization:SetStyle("!_Frame", "Inset")
+	PlayerTalentFramePetSpecialization.Panel:SetPoint("TOPLEFT", PlayerTalentFramePetSpecialization, "TOPLEFT", 0, 4)
+	PlayerTalentFramePetSpecialization.Panel:SetPoint("BOTTOMRIGHT", PlayerTalentFramePetSpecialization, "BOTTOMRIGHT", 3, 0)
+
+	SV.API:Set("CloseButton", PlayerTalentFrameCloseButton)
+	SV.API:Set("ScrollBar", PlayerTalentFrameSpecializationSpellScrollFrame)
+	SV.API:Set("ScrollBar", PlayerTalentFramePetSpecializationSpellScrollFrame)
+	for i = 1, 4 do
+		SV.API:Set("Tab", _G["PlayerTalentFrameTab"..i])
+	end
+
+	for _,name in pairs(SpecButtonList)do
+		local button = _G[name];
+		if(button) then
+			button:RemoveTextures()
+			button:SetStyle("Button")
+			local initialAnchor, anchorParent, relativeAnchor, xPosition, yPosition = button:GetPoint()
+			button:SetPoint(initialAnchor, anchorParent, relativeAnchor, xPosition, -28)
+		end
+	end
+
+	local maxTiers = 7
+
+	for i = 1, 7 do
+		local gName = ("PlayerTalentFrameTalentsTalentRow%d"):format(i)
+		local rowFrame = _G[gName]
+		if(rowFrame) then
+			local bgFrame = _G[("%sBg"):format(gName)]
+			if(bgFrame) then bgFrame:Hide() end
+
+			rowFrame:DisableDrawLayer("BORDER")
+			rowFrame:RemoveTextures()
+			rowFrame.TopLine:SetPoint("TOP", 0, 4)
+			rowFrame.BottomLine:SetPoint("BOTTOM", 0, -4)
+
+			for z = 1, 3 do
+				local talentItem = _G[("%sTalent%d"):format(gName, z)]
+				if(talentItem) then
+					SV.API:Set("ItemButton", talentItem)
+				end
+			end
+		end
+	end
+
+	hooksecurefunc("TalentFrame_Update", function()
+		for i = 1, 7 do
+			local gName = ("PlayerTalentFrameTalentsTalentRow%d"):format(i)
+
+			for z = 1, 3 do
+				local talentItem = _G[("%sTalent%d"):format(gName, z)]
+				if(talentItem) then
+					if talentItem.knownSelection:IsShown() then
+						talentItem:SetBackdropBorderColor(0, 1, 0)
+					else
+			 			talentItem:SetBackdropBorderColor(0, 0, 0)
+					end
+				end
+			end
+		end
+	end)
+
+	--[[ PVP TALENTS ]]--
+	PlayerTalentFramePVPTalents:RemoveTextures()
+	PlayerTalentFramePVPTalents.Talents:RemoveTextures()
+	PlayerTalentFramePVPTalents.Talents:SetStyle("!_Frame", "Inset")
+	for i = 1, 6 do
+		local rowFrame = PlayerTalentFramePVPTalents.Talents[("Tier%d"):format(i)]
+		if(rowFrame) then
+			if(rowFrame.Bg) then rowFrame.Bg:Hide() end
+
+			--rowFrame:DisableDrawLayer("BORDER")
+			rowFrame:RemoveTextures()
+			rowFrame.TopLine:SetPoint("TOP", 0, 4)
+			rowFrame.BottomLine:SetPoint("BOTTOM", 0, -4)
+
+			for z = 1, 3 do
+				local talentItem = rowFrame[("Talent%d"):format(z)]
+				if(talentItem) then
+					SV.API:Set("ItemButton", talentItem)
+					talentItem.Cover:SetColorTexture(0,0,0,0.4)
+				end
+			end
+		end
+	end
+
+	hooksecurefunc("PVPTalentFrame_Update", function()
+		for i = 1, 6 do
+			local rowFrame = PlayerTalentFramePVPTalents.Talents[("Tier%d"):format(i)]
+			for z = 1, 3 do
+				local talentItem = rowFrame[("Talent%d"):format(z)]
+				if(talentItem) then
+					if talentItem.knownSelection:IsShown() then
+						talentItem:SetBackdropBorderColor(0, 1, 0)
+					else
+			 			talentItem:SetBackdropBorderColor(0, 0, 0)
+					end
+				end
+			end
+		end
+	end)
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveBlizzardStyle("Blizzard_TalentUI", TalentFrameStyle)
+
+local function GlyphStyle()
+	assert(GlyphFrame, "GlyphFrame Not Loaded")
+
+	GlyphFrame:RemoveTextures()
+	GlyphFrame:SetStyle("!_Frame", "Premium")
+
+	if(GlyphFrameSideInset) then GlyphFrameSideInset:RemoveTextures() end
+	if(GlyphFrameHeader1) then GlyphFrameHeader1:RemoveTextures() end
+	if(GlyphFrameHeader2) then GlyphFrameHeader2:RemoveTextures() end
+	if(GlyphFrameScrollFrame) then GlyphFrameScrollFrame:SetStyle("Frame", "Inset", false, 3, 2, 2) end
+	if(GlyphFrameSearchBox) then GlyphFrameSearchBox:SetStyle("Editbox") end
+
+	if(GlyphFrameClearInfoFrame and GlyphFrameClearInfoFrame.icon) then
+		GlyphFrameClearInfoFrame:RemoveTextures()
+		local w,h = GlyphFrameClearInfoFrame:GetSize()
+		GlyphFrameClearInfoFrame:SetSize((w - 2),(h - 2))
+		GlyphFrameClearInfoFrame:SetPoint("TOPLEFT", GlyphFrame, "BOTTOMLEFT", 6, -10)
+		GlyphFrameClearInfoFrame.icon:SetSize((w - 2),(h - 2))
+		GlyphFrameClearInfoFrame.icon:SetTexCoord(0.1, 0.9, 0.1, 0.9)
+	end
+
+	SV.API:Set("DropDown", GlyphFrameFilterDropDown, 212)
+	SV.API:Set("ScrollBar", GlyphFrameScrollFrame, 5)
+
+	for i = 1, 10 do
+		local button = _G["GlyphFrameScrollFrameButton"..i]
+		if(button) then
+			SV.API:Set("ItemButton", button)
+			local icon = _G["GlyphFrameScrollFrameButton"..i.."Icon"]
+			if(icon) then
+				icon:SetTexCoord(0.1, 0.9, 0.1, 0.9)
+			end
+		end
+	end
+
+	for i = 1, 6 do
+		local glyphHolder = _G["GlyphFrameGlyph"..i]
+		if glyphHolder then
+			if(i % 2 == 0) then
+				StyleGlyphHolder(glyphHolder, 4)
+			else
+				StyleGlyphHolder(glyphHolder, 1)
+			end
+		end
+	end
+end
+
+MOD:SaveBlizzardStyle("Blizzard_GlyphUI", GlyphStyle)
diff --git a/SVUI_Skins/components/blizzard/timemanager.lua b/SVUI_Skins/components/blizzard/timemanager.lua
new file mode 100644
index 0000000..6c1331b
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/timemanager.lua
@@ -0,0 +1,64 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+TIMEMANAGER MODR
+##########################################################
+]]--
+local function TimeManagerStyle()
+	if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.timemanager ~= true then
+		 return
+	end
+
+	SV.API:Set("Window", TimeManagerFrame, true)
+
+	SV.API:Set("CloseButton", TimeManagerFrameCloseButton)
+	TimeManagerFrameInset:Die()
+	SV.API:Set("DropDown", TimeManagerAlarmHourDropDown, 80)
+	SV.API:Set("DropDown", TimeManagerAlarmMinuteDropDown, 80)
+	SV.API:Set("DropDown", TimeManagerAlarmAMPMDropDown, 80)
+	TimeManagerAlarmMessageEditBox:SetStyle("Editbox")
+	TimeManagerAlarmEnabledButton:SetStyle("CheckButton")
+	TimeManagerMilitaryTimeCheck:SetStyle("CheckButton")
+	TimeManagerLocalTimeCheck:SetStyle("CheckButton")
+	TimeManagerStopwatchFrame:RemoveTextures()
+	TimeManagerStopwatchCheck:SetStyle("!_Frame", "Default")
+	TimeManagerStopwatchCheck:GetNormalTexture():SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+	TimeManagerStopwatchCheck:GetNormalTexture():InsetPoints()
+	local sWatch = TimeManagerStopwatchCheck:CreateTexture(nil, "OVERLAY")
+	sWatch:SetColorTexture(1, 1, 1, 0.3)
+	sWatch:SetPoint("TOPLEFT", TimeManagerStopwatchCheck, 2, -2)
+	sWatch:SetPoint("BOTTOMRIGHT", TimeManagerStopwatchCheck, -2, 2)
+	TimeManagerStopwatchCheck:SetHighlightTexture(sWatch)
+
+	StopwatchFrame:RemoveTextures()
+	StopwatchFrame:SetStyle("Frame", 'Transparent')
+	StopwatchFrame.Panel:SetPoint("TOPLEFT", 0, -17)
+	StopwatchFrame.Panel:SetPoint("BOTTOMRIGHT", 0, 2)
+
+	StopwatchTabFrame:RemoveTextures()
+
+	SV.API:Set("CloseButton", StopwatchCloseButton)
+	SV.API:Set("PageButton", StopwatchPlayPauseButton)
+	SV.API:Set("PageButton", StopwatchResetButton)
+	StopwatchPlayPauseButton:SetPoint("RIGHT", StopwatchResetButton, "LEFT", -4, 0)
+	StopwatchResetButton:SetPoint("BOTTOMRIGHT", StopwatchFrame, "BOTTOMRIGHT", -4, 6)
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveBlizzardStyle("Blizzard_TimeManager",TimeManagerStyle)
\ No newline at end of file
diff --git a/SVUI_Skins/components/blizzard/tradeskill.lua b/SVUI_Skins/components/blizzard/tradeskill.lua
new file mode 100644
index 0000000..7ae580f
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/tradeskill.lua
@@ -0,0 +1,162 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+TRADESKILL MODR
+##########################################################
+]]--
+local function TradeSkillStyle()
+	if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.tradeskill ~= true then
+		 return
+	end
+
+	--local curWidth,curHeight = TradeSkillFrame:GetSize()
+	--local enlargedHeight = curHeight + 170;
+	--TradeSkillFrame:SetSize(curWidth + 30, curHeight + 166)
+	--TradeSkillFrame:RemoveTextures(true)
+	SV.API:Set("Window", TradeSkillFrame, true, true)
+
+	TradeSkillFrame.SearchBox:RemoveTextures()
+	TradeSkillFrame.RankFrame:RemoveTextures()
+	TradeSkillFrame.FilterButton:RemoveTextures(true)
+	TradeSkillFrame.LinkNameButton:RemoveTextures(true)
+	--TradeSkillFrame.LinkToButton:RemoveTextures(true)
+	TradeSkillFrame.FilterDropDown:RemoveTextures(true)
+	TradeSkillFrame.LinkToDropDown:RemoveTextures(true)
+
+	TradeSkillFrame.RecipeInset:RemoveTextures()
+	TradeSkillFrame.RecipeList:RemoveTextures()
+	TradeSkillFrame.RecipeList.LearnedTab:RemoveTextures()
+	TradeSkillFrame.RecipeList.UnlearnedTab:RemoveTextures()
+
+	TradeSkillFrame.DetailsInset:RemoveTextures()
+	TradeSkillFrame.DetailsFrame:RemoveTextures()
+	TradeSkillFrame.DetailsFrame.ScrollBar:RemoveTextures()
+	TradeSkillFrame.DetailsFrame.CreateButton:RemoveTextures(true)
+	TradeSkillFrame.DetailsFrame.CreateAllButton:RemoveTextures(true)
+	TradeSkillFrame.DetailsFrame.ExitButton:RemoveTextures(true)
+	TradeSkillFrame.DetailsFrame.ViewGuildCraftersButton:RemoveTextures(true)
+	TradeSkillFrame.DetailsFrame.CreateMultipleInputBox:RemoveTextures(true)
+
+
+	-- for i = 9, 18 do
+	-- 	local lastLine = "TradeSkillSkill" .. (i - 1);
+	-- 	if(lastLine) then
+	-- 		local newLine = CreateFrame("Button", "TradeSkillSkill" .. i, TradeSkillFrame, "TradeSkillSkillButtonTemplate")
+	-- 		newLine:SetPoint("TOPLEFT", lastLine, "BOTTOMLEFT", 0, 0)
+	-- 	end
+	-- end
+	--_G.TRADE_SKILLS_DISPLAYED = 18;
+
+	-- SV.API:Set("Window", TradeSkillGuildFrame)
+
+	-- TradeSkillGuildFrame:SetPoint("BOTTOMLEFT", TradeSkillFrame, "BOTTOMRIGHT", 3, 19)
+	-- TradeSkillGuildFrameContainer:RemoveTextures()
+	-- TradeSkillGuildFrameContainer:SetStyle("Frame", "Inset")
+	-- SV.API:Set("CloseButton", TradeSkillGuildFrameCloseButton)
+
+	SV.API:Set("DropDown", TradeSkillFrame.FilterDropDown)
+	SV.API:Set("DropDown", TradeSkillFrame.LinkToDropDown)
+
+	TradeSkillFrame.RankFrame:SetStyle("Frame", "Bar", true)
+	TradeSkillFrame.RankFrame:SetStatusBarTexture(SV.media.statusbar.default)
+	--print("Test 1")
+
+	--TradeSkillFrame.RecipeList:SetSize(327, 290)
+	TradeSkillFrame.RecipeInset:SetStyle("!_ShadowBox", "Model")
+	--TradeSkillFrame.RecipeList:SetStyle("Frame", "Inset")
+	SV.API:Set("ScrollBar", TradeSkillFrame.RecipeList)
+	--TradeSkillFrame.DetailsFrame:SetSize(327, 180)
+	TradeSkillFrame.DetailsInset:SetStyle("!_ShadowBox", "Model")
+	--TradeSkillFrame.DetailsFrame:SetStyle("Frame", "Inset")
+	SV.API:Set("ScrollBar", TradeSkillFrame.DetailsFrame)
+	SV.API:Set("ScrollBar", TradeSkillFrame.DetailsFrame.Container)
+	SV.API:Set("IconButton", TradeSkillFrame.LinkToButton, [[Interface\CHATFRAME\UI-ChatInput-FocusIcon]])
+--TradeSkillFrame.DetailsFrame.Container
+	TradeSkillFrame.RetrievingFrame:SetStyle("Frame", "Inset")
+	TradeSkillFrame.FilterButton:SetStyle("Button")
+	TradeSkillFrame.LinkNameButton:SetStyle("Button")
+	--TradeSkillFrame.LinkToButton:SetStyle("Button")
+	TradeSkillFrame.RecipeList.LearnedTab:SetStyle("Button")
+	TradeSkillFrame.RecipeList.UnlearnedTab:SetStyle("Button")
+	TradeSkillFrame.DetailsFrame.CreateButton:SetStyle("Button")
+	TradeSkillFrame.DetailsFrame.CreateAllButton:SetStyle("Button")
+	TradeSkillFrame.DetailsFrame.ViewGuildCraftersButton:SetStyle("Button")
+	TradeSkillFrame.DetailsFrame.ExitButton:SetStyle("Button")
+	TradeSkillFrame.DetailsFrame.CreateMultipleInputBox:SetStyle("Editbox")
+	TradeSkillFrame.DetailsFrame.ViewGuildCraftersButton:SetStyle("Button")
+
+	SV.API:Set("PageButton", TradeSkillFrame.DetailsFrame.CreateMultipleInputBox.IncrementButton)
+	SV.API:Set("PageButton", TradeSkillFrame.DetailsFrame.CreateMultipleInputBox.DecrementButton, false, true)
+	SV.API:Set("CloseButton", TradeSkillFrame.CloseButton)
+	--SV.API:Set("ScrollBar", TradeSkillFrame.RecipeList)
+	-- TradeSkillLinkButton:SetSize(17, 14)
+	-- TradeSkillLinkButton:SetPoint("LEFT", TradeSkillLinkFrame, "LEFT", 5, -1)
+	-- TradeSkillLinkButton:SetStyle("Button")
+	-- TradeSkillLinkButton:GetNormalTexture():SetTexCoord(0.25, 0.7, 0.45, 0.8)
+
+	TradeSkillFrame.SearchBox:SetStyle("Editbox")
+	-- TradeSkillInputBox:SetStyle("Editbox")
+
+	-- SV.API:Set("PageButton", TradeSkillDecrementButton)
+	-- SV.API:Set("PageButton", TradeSkillIncrementButton)
+
+	-- TradeSkillIncrementButton:SetPoint("RIGHT", TradeSkillCreateButton, "LEFT", -13, 0)
+	-- SV.API:Set("CloseButton", TradeSkillFrame.CloseButton)
+
+	-- local internalTest = false;
+
+	-- hooksecurefunc("TradeSkillFrame_SetSelection", function(_)
+	-- 	TradeSkillSkillIcon:SetStyle("Icon")
+	-- 	if TradeSkillSkillIcon:GetNormalTexture() then
+	-- 		TradeSkillSkillIcon:GetNormalTexture():SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+	-- 	end
+	-- 	--TradeSkillSkillIconCount:SetFrameLevel(TradeSkillSkillIcon:GetFrameLevel() + 20)
+	-- 	for i=1, MAX_TRADE_SKILL_REAGENTS do
+	-- 		local u = _G["TradeSkillReagent"..i]
+	-- 		local icon = _G["TradeSkillReagent"..i.."IconTexture"]
+	-- 		local a1 = _G["TradeSkillReagent"..i.."Count"]
+	-- 		icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+	-- 		icon:SetDrawLayer("OVERLAY")
+	-- 		if not icon.backdrop then
+	-- 			local a2 = CreateFrame("Frame", nil, u)
+	-- 			if u:GetFrameLevel()-1 >= 0 then
+	-- 				 a2:SetFrameLevel(u:GetFrameLevel()-1)
+	-- 			else
+	-- 				 a2:SetFrameLevel(0)
+	-- 			end
+	-- 			a2:WrapPoints(icon)
+	-- 			a2:SetStyle("Icon")
+	-- 			icon:SetParent(a2)
+	-- 			icon.backdrop = a2
+	-- 		end
+	-- 		a1:SetParent(icon.backdrop)
+	-- 		a1:SetDrawLayer("OVERLAY")
+	-- 		if i > 2 and internalTest == false then
+	-- 			local d, a3, f, g, h = u:GetPoint()
+	-- 			u:ClearAllPoints()
+	-- 			u:SetPoint(d, a3, f, g, h-3)
+	-- 			internalTest = true
+	-- 		end
+	-- 		_G["TradeSkillReagent"..i.."NameFrame"]:Die()
+	-- 	end
+	-- end)
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveBlizzardStyle("Blizzard_TradeSkillUI",TradeSkillStyle)
\ No newline at end of file
diff --git a/SVUI_Skins/components/blizzard/trainer.lua b/SVUI_Skins/components/blizzard/trainer.lua
new file mode 100644
index 0000000..baf5f12
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/trainer.lua
@@ -0,0 +1,90 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  	= _G.unpack;
+local select  	= _G.select;
+local ipairs  	= _G.ipairs;
+local pairs   	= _G.pairs;
+local type 		= _G.type;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+HELPERS
+##########################################################
+]]--
+local ClassTrainerFrameList = {
+	"ClassTrainerFrame",
+	"ClassTrainerScrollFrameScrollChild",
+	"ClassTrainerFrameSkillStepButton",
+	"ClassTrainerFrameBottomInset"
+};
+local ClassTrainerTextureList = {
+	"ClassTrainerFrameInset",
+	"ClassTrainerFramePortrait",
+	"ClassTrainerScrollFrameScrollBarBG",
+	"ClassTrainerScrollFrameScrollBarTop",
+	"ClassTrainerScrollFrameScrollBarBottom",
+	"ClassTrainerScrollFrameScrollBarMiddle"
+};
+--[[
+##########################################################
+TRAINER MODR
+##########################################################
+]]--
+local function TrainerStyle()
+	if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.trainer ~= true then return end
+
+	ClassTrainerFrame:SetHeight(ClassTrainerFrame:GetHeight() + 42)
+	SV.API:Set("Window", ClassTrainerFrame)
+
+	for i=1, 8 do
+		local item = _G["ClassTrainerScrollFrameButton"..i];
+		if item then
+			SV.API:Set("ItemButton", item, nil, true)
+			_G["ClassTrainerScrollFrameButton"..i.."Icon"]:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+			item.selectedTex:SetColorTexture(1, 1, 1, 0.3)
+			item.selectedTex:InsetPoints()
+		end
+	end
+
+	SV.API:Set("ScrollBar", ClassTrainerScrollFrame, 5)
+
+	for _,frame in pairs(ClassTrainerFrameList)do
+		_G[frame]:RemoveTextures()
+	end
+
+	for _,texture in pairs(ClassTrainerTextureList)do
+		_G[texture]:Die()
+	end
+
+	_G["ClassTrainerTrainButton"]:RemoveTextures()
+	_G["ClassTrainerTrainButton"]:SetStyle("Button")
+	SV.API:Set("DropDown", ClassTrainerFrameFilterDropDown, 155)
+	ClassTrainerScrollFrame:SetStyle("!_Frame", "Inset")
+	SV.API:Set("CloseButton", ClassTrainerFrameCloseButton, ClassTrainerFrame)
+	ClassTrainerFrameSkillStepButton.icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+	ClassTrainerFrameSkillStepButton:SetStyle("!_Frame", "Button", true)
+	--ClassTrainerFrameSkillStepButton.Panel:WrapPoints(ClassTrainerFrameSkillStepButton.icon)
+	--ClassTrainerFrameSkillStepButton.icon:SetParent(ClassTrainerFrameSkillStepButton.Panel)
+	ClassTrainerFrameSkillStepButtonHighlight:SetColorTexture(1, 1, 1, 0.3)
+	ClassTrainerFrameSkillStepButton.selectedTex:SetColorTexture(1, 1, 1, 0.3)
+	ClassTrainerStatusBar:RemoveTextures()
+	ClassTrainerStatusBar:SetStatusBarTexture(SV.media.statusbar.gradient)
+	ClassTrainerStatusBar:SetStyle("Frame", "Inset", true, 1, 2, 2)
+	ClassTrainerStatusBar.rankText:ClearAllPoints()
+	ClassTrainerStatusBar.rankText:SetPoint("CENTER", ClassTrainerStatusBar, "CENTER")
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveBlizzardStyle("Blizzard_TrainerUI",TrainerStyle)
diff --git a/SVUI_Skins/components/blizzard/transmog.lua b/SVUI_Skins/components/blizzard/transmog.lua
new file mode 100644
index 0000000..d0fd7f5
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/transmog.lua
@@ -0,0 +1,102 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  	= _G.unpack;
+local select  	= _G.select;
+local ipairs  	= _G.ipairs;
+local pairs   	= _G.pairs;
+local type 		= _G.type;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+HELPERS
+##########################################################
+]]--
+local TransmogFrameList = {
+	"TransmogrifyModelFrameLines",
+	"TransmogrifyModelFrameMarbleBg",
+	"TransmogrifyFrameButtonFrameButtonBorder",
+	"TransmogrifyFrameButtonFrameButtonBottomBorder",
+	"TransmogrifyFrameButtonFrameMoneyLeft",
+	"TransmogrifyFrameButtonFrameMoneyRight",
+	"TransmogrifyFrameButtonFrameMoneyMiddle"
+};
+local TransmogSlotList = {
+	"Head",
+	"Shoulder",
+	"Chest",
+	"Waist",
+	"Legs",
+	"Feet",
+	"Wrist",
+	"Hands",
+	"Back",
+	"MainHand",
+	"SecondaryHand"
+};
+--[[
+##########################################################
+TRANSMOG MODR
+##########################################################
+]]--
+local function TransmogStyle()
+	if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.transmogrify ~= true then return end
+
+	TransmogrifyFrame:SetSize(500, 600)
+	SV.API:Set("Window", TransmogrifyFrame, true)
+
+	for p, texture in pairs(TransmogFrameList)do
+		 _G[texture]:Die()
+	end
+
+	select(2, TransmogrifyModelFrame:GetRegions()):Die()
+
+	TransmogrifyModelFrame:ClearAllPoints()
+	TransmogrifyModelFrame:SetPoint("TOPLEFT", TransmogrifyFrame, "TOPLEFT", 12, -22)
+	TransmogrifyModelFrame:SetPoint("BOTTOMRIGHT", TransmogrifyFrame, "BOTTOMRIGHT", -12, 36)
+	TransmogrifyModelFrame:SetStyle("!_Frame", "Model")
+
+	TransmogrifyFrameButtonFrame:GetRegions():Die()
+	TransmogrifyApplyButton:RemoveTextures()
+	TransmogrifyApplyButton:SetStyle("Button")
+	TransmogrifyApplyButton:SetPoint("BOTTOMRIGHT", TransmogrifyFrame, "BOTTOMRIGHT", -4, 4)
+	SV.API:Set("CloseButton", TransmogrifyArtFrameCloseButton)
+	TransmogrifyArtFrame:RemoveTextures()
+
+	for p, a9 in pairs(TransmogSlotList)do
+		local icon = _G["TransmogrifyFrame"..a9 .."SlotIconTexture"]
+		local a9 = _G["TransmogrifyFrame"..a9 .."Slot"]
+		if a9 then
+			a9:RemoveTextures()
+			a9:SetStyle("ActionSlot")
+			a9:SetFrameLevel(a9:GetFrameLevel()+2)
+
+			a9.Panel:SetAllPoints()
+			icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+			icon:ClearAllPoints()
+			icon:InsetPoints()
+		end
+	end
+
+	TransmogrifyConfirmationPopup:SetParent(UIParent)
+	TransmogrifyConfirmationPopup:RemoveTextures()
+	TransmogrifyConfirmationPopup:SetStyle("Frame", "Pattern")
+	TransmogrifyConfirmationPopup.Button1:SetStyle("Button")
+	TransmogrifyConfirmationPopup.Button2:SetStyle("Button")
+	SV.API:Set("!_ItemButton", TransmogrifyConfirmationPopupItemFrame1)
+	SV.API:Set("!_ItemButton", TransmogrifyConfirmationPopupItemFrame2)
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveBlizzardStyle("Blizzard_ItemAlterationUI", TransmogStyle)
\ No newline at end of file
diff --git a/SVUI_Skins/components/blizzard/voidstorage.lua b/SVUI_Skins/components/blizzard/voidstorage.lua
new file mode 100644
index 0000000..52ea2b2
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/voidstorage.lua
@@ -0,0 +1,156 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack    = _G.unpack;
+local select    = _G.select;
+local ipairs    = _G.ipairs;
+local pairs     = _G.pairs;
+local type    = _G.type;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+HELPERS
+##########################################################
+]]--
+local NO_TEXTURE = SV.NoTexture;
+
+local VoidStorageList = {
+  "VoidStorageBorderFrame",
+  "VoidStorageDepositFrame",
+  "VoidStorageWithdrawFrame",
+  "VoidStorageCostFrame",
+  "VoidStorageStorageFrame",
+  "VoidStoragePurchaseFrame",
+  "VoidItemSearchBox"
+};
+
+local function Tab_OnEnter(this)
+  this.backdrop:SetBackdropColor(0.1, 0.8, 0.8)
+  this.backdrop:SetBackdropBorderColor(0.1, 0.8, 0.8)
+end
+
+local function Tab_OnLeave(this)
+  this.backdrop:SetBackdropColor(0,0,0,1)
+  this.backdrop:SetBackdropBorderColor(0,0,0,1)
+end
+
+local function ChangeTabHelper(this)
+  this:RemoveTextures()
+  local nTex = this:GetNormalTexture()
+  if(nTex) then
+    nTex:SetTexture([[Interface\ICONS\INV_Enchant_VoidSphere]])
+    nTex:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+    nTex:InsetPoints()
+  end
+
+  this.pushed = true;
+
+  this.backdrop = CreateFrame("Frame", nil, this)
+  this.backdrop:WrapPoints(this,1,1)
+  this.backdrop:SetFrameLevel(0)
+  this.backdrop:SetBackdrop(SV.media.backdrop.glow);
+  this.backdrop:SetBackdropColor(0,0,0,1)
+  this.backdrop:SetBackdropBorderColor(0,0,0,1)
+  this:SetScript("OnEnter", Tab_OnEnter)
+  this:SetScript("OnLeave", Tab_OnLeave)
+
+  local a,b,c,d,e = this:GetPoint()
+  this:SetPoint(a,b,c,1,e)
+end
+
+local SlotBorderColor_Hook = function(self, ...)
+  local parent = self:GetParent()
+  if(parent) then
+    parent:SetBackdropBorderColor(...)
+  end
+end
+local SlotBorder_OnHide = function(self, ...)
+  local parent = self:GetParent()
+  if(parent) then
+    parent:SetBackdropBorderColor(0,0,0,0.5)
+  end
+end
+
+local function VoidSlotStyler(name, index)
+  local gName = ("%sButton%d"):format(name, index)
+  local button = _G[gName]
+  local icon = _G[gName .. "IconTexture"]
+  local bg = _G[gName .. "Bg"]
+  if(button) then
+    local border = button.IconBorder
+    if(bg) then bg:Hide() end
+    button:SetStyle("ActionSlot")
+    if(icon) then
+      icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+      icon:InsetPoints(button)
+    end
+    if(border) then
+      border:SetTexture(NO_TEXTURE)
+      hooksecurefunc(border, "Hide", SlotBorder_OnHide)
+      hooksecurefunc(border, "SetVertexColor", SlotBorderColor_Hook)
+    end
+  end
+end
+--[[
+##########################################################
+VOIDSTORAGE MODR
+##########################################################
+]]--
+local function VoidStorageStyle()
+  MOD.Debugging = true
+  if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.voidstorage ~= true then
+     return
+  end
+
+  SV.API:Set("Window", VoidStorageFrame, true)
+
+  for _,gName in pairs(VoidStorageList) do
+    local frame = _G[gName]
+    if(frame) then
+      frame:RemoveTextures()
+    end
+  end
+
+  VoidStoragePurchaseFrame:SetFrameStrata('DIALOG')
+  VoidStoragePurchaseFrame:SetStyle("!_Frame", "Button", true)
+  VoidStorageFrameMarbleBg:Die()
+  VoidStorageFrameLines:Die()
+
+  select(2, VoidStorageFrame:GetRegions()):Die()
+
+  VoidStoragePurchaseButton:SetStyle("Button")
+  VoidStorageHelpBoxButton:SetStyle("Button")
+  VoidStorageTransferButton:SetStyle("Button")
+
+  SV.API:Set("CloseButton", VoidStorageBorderFrame.CloseButton)
+
+  VoidItemSearchBox:SetStyle("Frame", "Inset")
+  VoidItemSearchBox.Panel:SetPoint("TOPLEFT", 10, -1)
+  VoidItemSearchBox.Panel:SetPoint("BOTTOMRIGHT", 4, 1)
+
+  for i = 1, 9 do
+    VoidSlotStyler("VoidStorageDeposit", i)
+    VoidSlotStyler("VoidStorageWithdraw", i)
+  end
+
+  for i = 1, 80 do
+    VoidSlotStyler("VoidStorageStorage", i)
+  end
+
+  ChangeTabHelper(VoidStorageFrame.Page1)
+  ChangeTabHelper(VoidStorageFrame.Page2)
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveBlizzardStyle("Blizzard_VoidStorageUI", VoidStorageStyle)
\ No newline at end of file
diff --git a/SVUI_Skins/components/blizzard/worldmap.lua b/SVUI_Skins/components/blizzard/worldmap.lua
new file mode 100644
index 0000000..6da4d84
--- /dev/null
+++ b/SVUI_Skins/components/blizzard/worldmap.lua
@@ -0,0 +1,196 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack  = _G.unpack;
+local select  = _G.select;
+--[[ ADDON ]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+--[[
+##########################################################
+HELPERS
+##########################################################
+]]--
+local function AdjustMapLevel()
+  if InCombatLockdown()then return end
+    local WorldMapFrame = _G.WorldMapFrame;
+    WorldMapFrame:SetFrameStrata("HIGH");
+    WorldMapTooltip:SetFrameStrata("TOOLTIP");
+    WorldMapPlayerLower:SetFrameStrata("MEDIUM");
+    WorldMapPlayerLower:SetFrameStrata("FULLSCREEN");
+    WorldMapFrame:SetFrameLevel(1)
+    WorldMapDetailFrame:SetFrameLevel(2)
+    WorldMapArchaeologyDigSites:SetFrameLevel(3)
+end
+
+local function WorldMap_SmallView()
+  local WorldMapFrame = _G.WorldMapFrame;
+  WorldMapFrame.Panel:ClearAllPoints()
+  WorldMapFrame.Panel:WrapPoints(WorldMapFrame, 4, 4)
+  --WorldMapFrame.Panel.Panel:WrapPoints(WorldMapFrame.Panel)
+  if(SVUI_WorldMapCoords) then
+    SVUI_WorldMapCoords:SetPoint("BOTTOMLEFT", WorldMapFrame, "BOTTOMLEFT", 5, 5)
+  end
+end
+
+local function WorldMap_FullView()
+  local WorldMapFrame = _G.WorldMapFrame;
+  --WorldMapFrame:ClearAllPoints()
+ -- WorldMapFrame:SetPoint("TOP", SV.Screen, "TOP", 0, 0)
+  WorldMapFrame.Panel:ClearAllPoints()
+  local w, h = WorldMapDetailFrame:GetSize()
+  WorldMapFrame.Panel:SetSize(w + 24, h + 98)
+  WorldMapFrame.Panel:SetPoint("TOP", WorldMapFrame, "TOP", 0, 0)
+  --WorldMapFrame.Panel.Panel:WrapPoints(WorldMapFrame.Panel)
+  if(SVUI_WorldMapCoords) then
+    SVUI_WorldMapCoords:SetPoint("BOTTOMLEFT", WorldMapFrame, "BOTTOMLEFT", 5, 5)
+  end
+end
+
+local function StripQuestMapFrame()
+  local WorldMapFrame = _G.WorldMapFrame;
+
+  WorldMapFrame.BorderFrame:RemoveTextures(true)
+  WorldMapFrame.BorderFrame.ButtonFrameEdge:SetTexture("")
+  WorldMapFrame.BorderFrame.InsetBorderTop:SetTexture("")
+  WorldMapFrame.BorderFrame.Inset:RemoveTextures(true)
+  --print('test StripQuestMapFrame 1')
+  WorldMapTitleButton:RemoveTextures(true)
+  WorldMapFrameNavBar:RemoveTextures(true)
+  WorldMapFrameNavBarOverlay:RemoveTextures(true)
+  --print('test StripQuestMapFrame 2')
+  QuestMapFrame:RemoveTextures(true)
+  QuestMapFrame.DetailsFrame:RemoveTextures(true)
+  QuestScrollFrame:RemoveTextures(true)
+  --QuestScrollFrame.ViewAll:RemoveTextures(true)
+  --print('test StripQuestMapFrame 3')
+  QuestMapFrame.DetailsFrame.CompleteQuestFrame:RemoveTextures(true)
+  QuestMapFrame.DetailsFrame.CompleteQuestFrame.CompleteButton:RemoveTextures(true)
+  QuestMapFrame.DetailsFrame.BackButton:RemoveTextures(true)
+  QuestMapFrame.DetailsFrame.AbandonButton:RemoveTextures(true)
+  QuestMapFrame.DetailsFrame.ShareButton:RemoveTextures(true)
+  QuestMapFrame.DetailsFrame.TrackButton:RemoveTextures(true)
+  QuestMapFrame.DetailsFrame.RewardsFrame:RemoveTextures(true)
+  --print('test StripQuestMapFrame 4')
+  QuestMapFrame.DetailsFrame:SetStyle("Frame", "Paper")
+  QuestMapFrame.DetailsFrame.CompleteQuestFrame.CompleteButton:SetStyle("Button")
+  QuestMapFrame.DetailsFrame.BackButton:SetStyle("Button")
+  QuestMapFrame.DetailsFrame.AbandonButton:SetStyle("Button")
+  QuestMapFrame.DetailsFrame.ShareButton:SetStyle("Button")
+  QuestMapFrame.DetailsFrame.TrackButton:SetStyle("Button")
+
+  SV.API:Set("ScrollBar", QuestMapDetailsScrollFrame)
+  SV.API:Set("Skin", QuestMapFrame.DetailsFrame.RewardsFrame, 0, -10, 0, 0)
+
+  QuestScrollFrame:SetStyle("Frame", "Paper")
+  --QuestScrollFrame.ViewAll:SetStyle("Button")
+  --print('test StripQuestMapFrame 5')
+  local detailWidth = QuestMapFrame.DetailsFrame.RewardsFrame:GetWidth()
+  QuestMapFrame.DetailsFrame:ClearAllPoints()
+  QuestMapFrame.DetailsFrame:SetPoint("BOTTOMRIGHT", QuestMapFrame, "BOTTOMRIGHT", 2, 0)
+  QuestMapFrame.DetailsFrame:SetWidth(detailWidth)
+
+  WorldMapFrameNavBar:ClearAllPoints()
+  WorldMapFrameNavBar:SetPoint("TOPLEFT", WorldMapFrame.Panel, "TOPLEFT", 12, -26)
+  WorldMapFrameTutorialButton:ClearAllPoints()
+  WorldMapFrameTutorialButton:SetPoint("LEFT", WorldMapFrameNavBar.Panel, "RIGHT", -50, 0)
+end
+
+local function WorldMap_OnShow()
+  local WorldMapFrame = _G.WorldMapFrame;
+
+  if WORLDMAP_SETTINGS.size == WORLDMAP_FULLMAP_SIZE then
+    WorldMap_FullView()
+  elseif WORLDMAP_SETTINGS.size == WORLDMAP_WINDOWED_SIZE then
+    WorldMap_SmallView()
+  end
+  -- WorldMap_SmallView()
+  if not SV.db.Maps.tinyWorldMap then
+    BlackoutWorld:SetColorTexture(0,0,0,1)
+  else
+    BlackoutWorld:SetTexture("")
+  end
+
+  WorldMapFrameAreaLabel:SetShadowOffset(2, -2)
+  WorldMapFrameAreaLabel:SetTextColor(0.90, 0.8294, 0.6407)
+  WorldMapFrameAreaDescription:SetShadowOffset(2, -2)
+  WorldMapZoneInfo:SetShadowOffset(2, -2)
+
+  if InCombatLockdown() then return end
+  AdjustMapLevel()
+end
+--[[
+##########################################################
+WORLDMAP MODR
+##########################################################
+]]--
+local function WorldMapStyle()
+  --print('test WorldMapStyle')
+  if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.worldmap ~= true then return end
+
+  SV.API:Set("Window", WorldMapFrame, true, true)
+  SV.API:Set("ScrollBar", QuestScrollFrame)
+  SV.API:Set("ScrollBar", WorldMapQuestScrollFrame)
+  SV.API:Set("ScrollBar", WorldMapQuestDetailScrollFrame, 4)
+  SV.API:Set("ScrollBar", WorldMapQuestRewardScrollFrame, 4)
+
+  --print('test WorldMapStyle 1')
+  WorldMapDetailFrame:SetStyle("Frame", "Blackout")
+
+  WorldMapFrameSizeDownButton:SetFrameLevel(999)
+  WorldMapFrameSizeUpButton:SetFrameLevel(999)
+  WorldMapFrameCloseButton:SetFrameLevel(999)
+
+  --print('test WorldMapStyle 2')
+  SV.API:Set("CloseButton", WorldMapFrameCloseButton)
+  SV.API:Set("ArrowButton", WorldMapFrameSizeDownButton, "down")
+  SV.API:Set("ArrowButton", WorldMapFrameSizeUpButton, "up")
+  SV.API:Set("DropDown", WorldMapLevelDropDown)
+  SV.API:Set("DropDown", WorldMapZoneMinimapDropDown)
+  SV.API:Set("DropDown", WorldMapContinentDropDown)
+  SV.API:Set("DropDown", WorldMapZoneDropDown)
+  SV.API:Set("DropDown", WorldMapShowDropDown)
+  --print('test WorldMapStyle 3')
+  StripQuestMapFrame()
+
+  --WorldMapFrame.UIElementsFrame:SetStyle("Frame", "Blackout")
+
+  WorldMapFrame:HookScript("OnShow", WorldMap_OnShow)
+  hooksecurefunc("WorldMap_ToggleSizeUp", WorldMap_OnShow)
+  BlackoutWorld:SetParent(WorldMapFrame.Panel)
+  --print('test WorldMapStyle 4')
+  WorldMapFrameNavBar:ClearAllPoints()
+  WorldMapFrameNavBar:SetPoint("TOPLEFT", WorldMapFrame.Panel, "TOPLEFT", 12, -26)
+  WorldMapFrameNavBar:SetStyle("Frame", "Inset", true, 2, 2, 1)
+  WorldMapFrameNavBarHomeButton:RemoveTextures(true)
+  WorldMapFrameNavBarHomeButton:SetStyle("Button")
+  WorldMapFrameTutorialButton:Die()
+
+  --SV.API:Set("InfoButton", WorldMapFrameTutorialButton)
+  --WorldMapFrameTutorialButton:SetPoint("LEFT", WorldMapFrameNavBar.Panel, "RIGHT", -50, 0)
+
+  WorldMap_OnShow()
+end
+--[[
+##########################################################
+MOD LOADING
+##########################################################
+]]--
+MOD:SaveCustomStyle(WorldMapStyle)
+
+--[[
+function ArchaeologyDigSiteFrame_OnUpdate()
+    WorldMapArchaeologyDigSites:DrawNone();
+    local numEntries = ArchaeologyMapUpdateAll();
+    for i = 1, numEntries do
+        local blobID = ArcheologyGetVisibleBlobID(i);
+        WorldMapArchaeologyDigSites:DrawBlob(blobID, true);
+    end
+end
+]]
diff --git a/SVUI_Skins/components/docklet.lua b/SVUI_Skins/components/docklet.lua
new file mode 100644
index 0000000..d989397
--- /dev/null
+++ b/SVUI_Skins/components/docklet.lua
@@ -0,0 +1,599 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local type 		= _G.type;
+local tostring 	= _G.tostring;
+local print 	= _G.print;
+local pcall 	= _G.pcall;
+local tinsert 	= _G.tinsert;
+local string 	= _G.string;
+local math 		= _G.math;
+local table 	= _G.table;
+--[[ STRING METHODS ]]--
+local format,find = string.format, string.find;
+--[[ MATH METHODS ]]--
+local floor = math.floor;
+--[[ TABLE METHODS ]]--
+local twipe, tcopy = table.wipe, table.copy;
+local IsAddOnLoaded = _G.IsAddOnLoaded;
+local LoadAddOn = _G.LoadAddOn;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI'];
+local L = SV.L;
+local MOD = SV.Skins;
+local Schema = MOD.Schema;
+local Librarian = _G.Librarian;
+--[[
+##########################################################
+LOCALS
+##########################################################
+]]--
+local TIP_RIGHT_PATTERN = " and %s";
+local DOCK_EMBEDS = {};
+local DOCK_LISTING = {};
+--[[
+##########################################################
+HELPERS
+##########################################################
+]]--
+local function SafeStringFind(request,value)
+	if((not request) or (type(request) == 'table') or (not request.find)) then return false end
+	return request:find(value);
+end
+
+local function RequestEmbedded(addon)
+	local embed1 = SV.private.Docks.Embed1 or "None";
+	local embed2 = SV.private.Docks.Embed2 or "None";
+	local enabled1 = (embed1 ~= "None")
+	local enabled2 = ((embed2 ~= "None") and (embed2 ~= embed1))
+
+	if(addon) then
+		local valid = false;
+		if(embed1:find(addon) or embed2:find(addon)) then
+			valid = true
+		end
+		return valid, enabled1, enabled2
+	end
+
+	return embed1, embed2, enabled1, enabled2
+end
+--[[
+##########################################################
+SKADA
+##########################################################
+]]--
+local Skada_PointLock = function(self, a1, p, a2, x, y)
+	local parent = self:GetParent()
+	if(parent and parent.GetName) then
+		local pname = parent:GetName()
+		if(((x ~= 0) or (y ~= 0)) and pname:find('SVUI')) then
+			self:ClearAllPoints()
+			self:SetPoint("BOTTOM", p, "BOTTOM", 0, 0)
+		end
+	end
+end
+
+local Skada_PointTest = function(self, p1, p2, p3, p4, p5)
+	print(p1 .. ", " .. p2:GetName() .. ", " .. p3 .. ", " .. p4 .. ", " .. p5)
+end
+
+DOCK_EMBEDS["Skada"] = function(self)
+	if((not IsAddOnLoaded("Skada")) or (not _G.Skada)) then return false end
+
+	local assigned,otherAssigned = self:EmbedCheck();
+	local width = self:GetWidth()
+	local height = SV.Dock.BottomRight.Window:GetHeight();
+	local frameLinked = false;
+
+	for index,window in pairs(Skada:GetWindows()) do
+		if(window) then
+			local wname = window.db.name or "Skada"
+			local key = "SkadaBarWindow" .. wname
+			if(assigned ~= 'None' and (assigned:find(key))) then
+				--Librarian:LockLibrary('LibWindow');
+				local db = window.db
+
+				if(db) then
+					local curHeight = 0
+					if(db.enabletitle) then
+						curHeight = db.title.height
+					end
+					db.barspacing = 1;
+					db.barwidth = width - 10;
+					db.background.height = (height - curHeight) - 8;
+					db.spark = false;
+					db.barslocked = true;
+				end
+
+				local parentFrame = window.bargroup:GetParent();
+				if(not window.bargroup.___oldParent) then
+					if(parentFrame ~= self) then
+						window.bargroup.___oldParent = window.bargroup:GetParent()
+					else
+						window.bargroup.___oldParent = UIParent
+					end
+				end
+
+				window.bargroup:SetParent(self)
+				window.bargroup:ClearAllPoints()
+				window.bargroup:SetSize(width, height)
+				window.bargroup:SetPoint("BOTTOM", self, "BOTTOM", 0, 0)
+				window.bargroup:SetFrameStrata('LOW')
+
+				if(not window.bargroup.___skinHooked) then
+					hooksecurefunc(window.bargroup, "SetPoint", Skada_PointLock)
+					window.bargroup.___skinHooked = true;
+				end
+
+				local bgroup = window.bargroup.backdrop;
+				if(bgroup) then
+					bgroup:Show()
+					if(not bgroup.Panel) then
+						bgroup:SetStyle("!_Frame", 'Transparent', true)
+					end
+				end
+
+				self.FrameLink = window;
+				frameLinked = true;
+
+				Skada.displays['bar']:ApplySettings(window)
+
+				return true
+			elseif(not otherAssigned:find(key)) then
+				--Librarian:UnlockLibrary('LibWindow');
+				window.db.barslocked = false;
+				window.bargroup:SetParent(window.bargroup.___oldParent or UIParent)
+			end
+		end
+	end
+
+	if(not frameLinked) then
+		self.FrameLink = nil;
+	end
+
+	return false
+end
+--[[
+##########################################################
+RECOUNT
+##########################################################
+]]--
+DOCK_EMBEDS["Recount"] = function(self)
+	if((not IsAddOnLoaded("Recount")) or (not _G.Recount)) then return false end
+
+	local width = self:GetWidth()
+	local height = SV.Dock.BottomRight.Window:GetHeight();
+
+	Recount.db.profile.Locked = true;
+	Recount.db.profile.Scaling = 1;
+	Recount.db.profile.ClampToScreen = true;
+	Recount.db.profile.FrameStrata = '2-LOW'
+	Recount.MainWindow:ClearAllPoints()
+	Recount.MainWindow:SetParent(self)
+	Recount.MainWindow:SetSize(width, height)
+	Recount.MainWindow:SetPoint("BOTTOM", self, "BOTTOM", 0, 0)
+	Recount:SetStrataAndClamp()
+	Recount:LockWindows(true)
+	Recount:ResizeMainWindow()
+	Recount_MainWindow_ScrollBar:Hide()
+
+	Recount.MainWindow:Show()
+
+	self.Framelink = Recount.MainWindow
+	return true
+end
+--[[
+##########################################################
+OMEN
+##########################################################
+]]--
+DOCK_EMBEDS["Omen"] = function(self)
+	if((not IsAddOnLoaded("Omen")) or (not _G.Omen)) then return false end
+
+	local width = self:GetWidth()
+	local height = SV.Dock.BottomRight.Window:GetHeight();
+	local db = Omen.db;
+
+	--[[ General Settings ]]--
+	db.profile.FrameStrata = '2-LOW';
+	db.profile.Locked = true;
+	db.profile.Scale = 1;
+	db.profile.ShowWith.UseShowWith = false;
+
+	--[[ Background Settings ]]--
+	db.profile.Background.BarInset = 3;
+	db.profile.Background.EdgeSize = 1;
+	db.profile.Background.Texture = "None"
+
+	--[[ Bar Settings ]]--
+	db.profile.Bar.Font = "SVUI Default Font";
+	db.profile.Bar.FontOutline = "None";
+	db.profile.Bar.FontSize = 11;
+	db.profile.Bar.Height = 14;
+	db.profile.Bar.ShowHeadings = false;
+	db.profile.Bar.ShowTPS = false;
+	db.profile.Bar.Spacing = 1;
+	db.profile.Bar.Texture = "SVUI MultiColorBar";
+
+	--[[ Titlebar Settings ]]--
+	db.profile.TitleBar.BorderColor.g = 0;
+	db.profile.TitleBar.BorderColor.r = 0;
+	db.profile.TitleBar.BorderTexture = "None";
+	db.profile.TitleBar.EdgeSize = 1;
+	db.profile.TitleBar.Font = "Arial Narrow";
+	db.profile.TitleBar.FontSize = 12;
+	db.profile.TitleBar.Height = 23;
+	db.profile.TitleBar.ShowTitleBar = true;
+	db.profile.TitleBar.Texture = "None";
+	db.profile.TitleBar.UseSameBG = false;
+
+	Omen:OnProfileChanged(nil,db)
+	OmenTitle:RemoveTextures()
+	OmenTitle.Panel = nil
+	OmenTitle:SetStyle("Frame", "Transparent")
+	--OmenTitle:SetPanelColor("class")
+	--OmenTitle:GetFontString():SetFont(SV.media.font.default, 12, "OUTLINE")
+
+	if(not OmenAnchor.Panel) then
+		OmenBarList:RemoveTextures()
+		OmenAnchor:SetStyle("Frame", 'Transparent')
+	end
+	OmenAnchor:ClearAllPoints()
+	OmenAnchor:SetParent(self)
+	OmenAnchor:SetSize(width, height)
+	OmenAnchor:SetPoint("BOTTOM", self, "BOTTOM", 0, 0)
+
+	self.Framelink = OmenAnchor
+	return true
+end
+--[[
+##########################################################
+ALDAMAGEMETER
+##########################################################
+]]--
+DOCK_EMBEDS["alDamageMeter"] = function(self)
+	if((not IsAddOnLoaded("alDamageMeter")) or (not _G.alDamagerMeterFrame)) then return false end
+
+	local w,h = self:GetSize();
+	local count = dmconf.maxbars or 10;
+	local spacing = dmconf.spacing or 1;
+
+	dmconf.barheight = floor((h / count) - spacing);
+	dmconf.width = w;
+
+	alDamageMeterFrame:ClearAllPoints()
+	alDamageMeterFrame:SetAllPoints(self)
+	alDamageMeterFrame.backdrop:SetStyle("!_Frame", 'Transparent')
+	alDamageMeterFrame.bg:Die()
+	alDamageMeterFrame:SetFrameStrata('LOW')
+
+	self.Framelink = alDamageMeterFrame
+	return true
+end
+--[[
+##########################################################
+TINYDPS
+##########################################################
+]]--
+DOCK_EMBEDS["TinyDPS"] = function(self)
+	if((not IsAddOnLoaded("TinyDPS")) or (not _G.tdpsFrame)) then return false end
+
+	tdps.hideOOC = false;
+	tdps.hideIC = false;
+	tdps.hideSolo = false;
+	tdps.hidePvP = false;
+	tdpsFrame:ClearAllPoints()
+	tdpsFrame:SetAllPoints(self)
+	tdpsFrame:SetParent(self)
+	tdpsRefresh()
+
+	self.Framelink = tdpsFrame
+	return true
+end
+--[[
+##########################################################
+!DETAILS (IN DEVELOPMENT)
+##########################################################
+]]--
+
+-- DOCK_EMBEDS["Details"] = function(self)
+-- 	if(not IsAddOnLoaded("Details")) then return false end
+-- 	local width = self:GetWidth()
+-- 	local height = SV.Dock.BottomRight.Window:GetHeight();
+
+-- 	if(DetailsBaseFrame1) then
+-- 		DetailsBaseFrame1:ClearAllPoints()
+-- 		DetailsBaseFrame1:SetParent(self)
+-- 		DetailsBaseFrame1:SetSize(width - 4, height - 4)
+-- 		DetailsBaseFrame1:SetPoint("BOTTOM", self, "BOTTOM", 0, 2)
+-- 		DetailsBaseFrame1:SetMovable(false);
+-- 		if(DetailsRowFrame1) then
+-- 			DetailsRowFrame1:ClearAllPoints()
+-- 			DetailsRowFrame1:SetParent(self)
+-- 			DetailsRowFrame1:SetAllPoints(DetailsBaseFrame1)
+-- 			self.Framelink = DetailsRowFrame1
+-- 		else
+-- 			self.Framelink = DetailsBaseFrame1
+-- 		end
+-- 		_detalhes.move_janela_func = SV.fubar
+-- 		return true
+-- 	else
+-- 		return false
+-- 	end
+-- end
+
+--[[
+##########################################################
+DOCK EMBED METHODS
+##########################################################
+]]--
+local DOCK_EmbedAddon = function(self, request)
+	if(not request) then return false end
+
+	for addon,fn in pairs(DOCK_EMBEDS) do
+		if(SafeStringFind(request,addon)) then
+			local activated = fn(self)
+			self.Embedded = addon
+			return activated, addon
+		end
+	end
+	self.Embedded = "NONE"
+	return false
+end
+
+local DOCK_EmbedCheck = function(self, ...)
+	local data1 = SV.private.Docks[self.EmbedKey] or 'None';
+	local data2 = SV.private.Docks[self.EmbedOther] or 'None';
+	return data1,data2
+end
+
+local PARENT_IsEmbedded = function(self, request)
+	if(self.Dock1.Embedded ~= "NONE") then
+		if(SafeStringFind(request,self.Dock1.Embedded)) then
+			return true
+		end
+	end
+	if(self.Dock2.Embedded ~= "NONE") then
+		if(SafeStringFind(request,self.Dock2.Embedded)) then
+			return true
+		end
+	end
+	return false
+end
+
+local PARENT_UpdateEmbeds = function(self, ...)
+	if(self.Dock1.Embedded ~= "NONE") then
+		local fn = DOCK_EMBEDS[self.Dock1.Embedded];
+		if(fn) then
+			fn(self.Dock1, ...)
+		end
+	end
+	if(self.Dock2.Embedded ~= "NONE") then
+		local fn = DOCK_EMBEDS[self.Dock2.Embedded];
+		if(fn) then
+			fn(self.Dock2, ...)
+		end
+	end
+end
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+function MOD:FindDockables()
+	local test = false;
+	for addon,_ in pairs(DOCK_EMBEDS) do
+		if IsAddOnLoaded(addon) then
+			test = true;
+		end
+	end
+	self.Docklet:SetDocked(test);
+end
+
+function MOD:SetEmbedHandlers()
+	MOD.Docklet.UpdateEmbeds     = PARENT_UpdateEmbeds;
+	MOD.Docklet.IsEmbedded       = PARENT_IsEmbedded;
+
+	MOD.Docklet.Dock1.EmbedKey   = "Embed1";
+	MOD.Docklet.Dock1.EmbedOther = "Embed2";
+	MOD.Docklet.Dock1.Embedded   = "NONE";
+	MOD.Docklet.Dock1.EmbedAddon = DOCK_EmbedAddon;
+	MOD.Docklet.Dock1.EmbedCheck = DOCK_EmbedCheck;
+
+	MOD.Docklet.Dock2.EmbedKey   = "Embed2";
+	MOD.Docklet.Dock2.EmbedOther = "Embed1";
+	MOD.Docklet.Dock2.Embedded   = "NONE";
+	MOD.Docklet.Dock2.EmbedAddon = DOCK_EmbedAddon;
+	MOD.Docklet.Dock2.EmbedCheck = DOCK_EmbedCheck;
+end
+
+function MOD:RegisterAddonDocklets()
+	-- if(self:FindDockables()) then
+	-- 	self.Docklet:SetDocked(true);
+	-- 	self.Docklet:Enable();
+	-- else
+	-- 	self.Docklet:Disable();
+	-- 	self.Docklet:SetDocked(false);
+	-- 	return
+	-- end
+	local available = false;
+	if(SV.db.Skins.enableAddonDock) then
+		for addon,_ in pairs(DOCK_EMBEDS) do
+			if IsAddOnLoaded(addon) then
+				available = true;
+			end
+		end
+	end
+
+	self.Docklet:SetDocked(available);
+
+	if(available) then
+		local embed1,embed2,enabled1,enabled2 = RequestEmbedded();
+		local addon1, addon2, extraTip = "", "", "";
+		local active1, active2 = false, false;
+
+		self.Docklet.Embedded = {}
+		self.Docklet.Dock1.FrameLink = nil;
+		self.Docklet.Dock1.ExpandCallback = nil;
+		self.Docklet.Dock2.FrameLink = nil;
+		self.Docklet.Dock2.ExpandCallback = nil;
+
+		local width = self.Docklet:GetWidth() - 2;
+		self.Docklet.Dock1:SetWidth(width)
+
+		if(enabled2) then
+			if(enabled1) then
+				self.Docklet.Dock1:SetWidth(width * 0.5)
+			else
+				self.Docklet.Dock1:SetWidth(0.1)
+			end
+
+			self.Docklet.Dock2:ClearAllPoints()
+			self.Docklet.Dock2:SetPoint('TOPLEFT', self.Docklet.Dock1, 'TOPRIGHT', 0, 0);
+			self.Docklet.Dock2:SetPoint('BOTTOMRIGHT', self.Docklet, 'BOTTOMRIGHT', 1, -1);
+
+			active2, addon2 = self.Docklet.Dock2:EmbedAddon(embed2)
+
+			if(not active2) then
+				self.Docklet.Dock1:SetWidth(width)
+			end
+		end
+
+		if(enabled1) then
+			active1, addon1 = self.Docklet.Dock1:EmbedAddon(embed1)
+		end
+
+		if(active1 or active2) then
+			if(active2) then
+				extraTip = TIP_RIGHT_PATTERN:format(addon2)
+				self.Docklet.Dock1:Show()
+				self.Docklet.Dock2:Show()
+			else
+				self.Docklet.Dock1:Show()
+				self.Docklet.Dock2:Hide()
+			end
+
+			self.Docklet.Button:SetAttribute("tipText", ("%s%s"):format(addon1, extraTip));
+		else
+			self.Docklet.Dock1:Hide()
+			self.Docklet.Dock2:Hide()
+		end
+	end
+end
+
+function MOD:GetAddonDockMenu()
+	local t = {};
+
+	local test1 = SV.private.Docks.Embed1 or 'None';
+	local test2 = SV.private.Docks.Embed2 or 'None';
+	local allowed1, allowed2 = false,false;
+
+	for addon,_ in pairs(DOCK_EMBEDS) do
+		if(SafeStringFind(addon,"Skada") and _G.Skada) then
+			for index,window in pairs(_G.Skada:GetWindows()) do
+				local keyName = window.db.name
+			    local key = "SkadaBarWindow" .. keyName
+			    if ((not SafeStringFind(test1,key)) and (not SafeStringFind(test2,key))) then
+				    local name = (keyName == "Skada") and "Skada - Main" or "Skada - " .. keyName;
+				    if(not allowed1) then
+				    	tinsert(t,{ title = "Set Primary", divider = true });
+				    	allowed1 = true;
+				    end
+				    tinsert(t,{text = name, func = function() SV.private.Docks.Embed1 = key; MOD:RegisterAddonDocklets() end});
+				end
+			end
+		else
+			if(IsAddOnLoaded(addon) and (not SafeStringFind(test1,addon)) and (not SafeStringFind(test2,addon))) then
+				if(not allowed1) then
+			    	tinsert(t,{ title = "Set Primary", divider = true });
+			    	allowed1 = true;
+			    end
+				tinsert(t,{text = addon, func = function() SV.private.Docks.Embed1 = addon; MOD:RegisterAddonDocklets() end});
+			end
+		end
+	end
+
+	for addon,_ in pairs(DOCK_EMBEDS) do
+		if(SafeStringFind(addon,"Skada") and _G.Skada) then
+			for index,window in pairs(_G.Skada:GetWindows()) do
+				local keyName = window.db.name
+			    local key = "SkadaBarWindow" .. keyName;
+			    if ((not SafeStringFind(test1,key)) and (not SafeStringFind(test2,key))) then
+				    local name = (keyName == "Skada") and "Skada - Main" or "Skada - " .. keyName;
+				    if(not allowed2) then
+				    	tinsert(t,{ title = "Set Secondary", divider = true });
+				    	allowed2 = true;
+				    end
+				    tinsert(t,{text = name, func = function() SV.private.Docks.Embed2 = key; MOD:RegisterAddonDocklets() end});
+				end
+			end
+		else
+			if(IsAddOnLoaded(addon) and (not SafeStringFind(test1,addon)) and (not SafeStringFind(test2,addon))) then
+				if(not allowed2) then
+			    	tinsert(t,{ title = "Set Secondary", divider = true });
+			    	allowed2 = true;
+			    end
+				tinsert(t,{text = addon, func = function() SV.private.Docks.Embed2 = addon; MOD:RegisterAddonDocklets() end});
+			end
+		end
+	end
+
+	local canRemove1 = (test1 and test1 ~= 'None') or false;
+	local canRemove2 = (test2 and test2 ~= 'None') or false;
+	if(canRemove1 or canRemove2) then
+		tinsert(t,{ title = "Remove", divider = true });
+		if canRemove1 then
+			tinsert(t,{text = "Primary", func = function() SV.private.Docks.Embed1 = "None"; MOD:RegisterAddonDocklets() end});
+		end
+		if canRemove2 then
+			tinsert(t,{text = "Secondary", func = function() SV.private.Docks.Embed2 = "None"; MOD:RegisterAddonDocklets() end});
+		end
+	end
+
+	return t;
+end
+--[[
+##########################################################
+LISTING FOR OPTIONS
+##########################################################
+]]--
+do
+	for addon,_ in pairs(DOCK_EMBEDS) do
+		DOCK_LISTING[addon] = addon;
+	end
+end
+
+function MOD:GetDockables(secondary)
+	local t = {["None"] = L["None"]};
+	local test = SV.private.Docks.Embed2;
+	if(secondary) then test = SV.private.Docks.Embed1; end
+
+	for n,l in pairs(DOCK_LISTING) do
+		if(n:find("Skada") and _G.Skada) then
+			for index,window in pairs(_G.Skada:GetWindows()) do
+			    local name = window.db.name
+			    local key = "SkadaBarWindow"..name
+			    if(not test or test ~= key) then
+			    	t["SkadaBarWindow"..name] = (key == "Skada") and "Skada - Main" or "Skada - "..name;
+			    end
+			end
+		elseif((not test) or (not test:find(n))) then
+			if IsAddOnLoaded(n) or IsAddOnLoaded(l) then t[n] = l end
+		end
+	end
+
+	return t;
+end
diff --git a/SVUI_Tooltip/LICENSE.txt b/SVUI_Tooltip/LICENSE.txt
new file mode 100644
index 0000000..05ceba8
--- /dev/null
+++ b/SVUI_Tooltip/LICENSE.txt
@@ -0,0 +1,31 @@
+
+The MIT License
+
+Copyright (c) 2010, Failcoder (Steve Jackson)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy
+of this software and associated documentation files (the "Software"), to
+deal
+in the Software without restriction, including without limitation the
+rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/SVUI_Tooltip/Loader.lua b/SVUI_Tooltip/Loader.lua
new file mode 100644
index 0000000..0eb149a
--- /dev/null
+++ b/SVUI_Tooltip/Loader.lua
@@ -0,0 +1,185 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+
+local SV = _G["SVUI"];
+local L = SV.L
+local MOD = SV:NewModule(...);
+local Schema = MOD.Schema;
+local LSM = _G.LibStub("LibSharedMedia-3.0");
+
+MOD.media = {}
+MOD.media.backgroundArt = [[Interface\DialogFrame\UI-DialogBox-Background-Dark]];
+MOD.media.topArt = [[Interface\AddOns\SVUI_Tooltip\assets\TT-TOP]];
+MOD.media.bottomArt = [[Interface\AddOns\SVUI_Tooltip\assets\TT-BOTTOM]];
+MOD.media.rightArt = [[Interface\AddOns\SVUI_Tooltip\assets\TT-RIGHT]];
+MOD.media.leftArt = [[Interface\AddOns\SVUI_Tooltip\assets\TT-LEFT]];
+
+SV.defaults[Schema] = {
+	["themed"] = true,
+	["cursorAnchor"] = false,
+	["targetInfo"] = true,
+	["playerTitles"] = true,
+	["playerGender"] = false,
+	["guildRanks"] = true,
+	["inspectInfo"] = false,
+	["itemCount"] = true,
+	["spellID"] = false,
+	["progressInfo"] = true,
+	["visibility"] = {
+		["unitFrames"] = "NONE",
+		["combat"] = false,
+	},
+	["healthBar"] = {
+		["text"] = true,
+		["height"] = 10,
+		["font"] = "SVUI Default Font",
+		["fontSize"] = 10,
+	},
+};
+
+SV:AssignMedia("font", "tipdialog", "SVUI Default Font", 12, "OUTLINE");
+SV:AssignMedia("font", "tipheader", "SVUI Default Font", 14, "OUTLINE");
+
+function MOD:LoadOptions()
+	local tipFonts = {
+		["tipdialog"] = {
+			order = 1,
+			name = "Tooltip Dialog",
+			desc = "Default font used in tooltips"
+		},
+	    ["tipheader"] = {
+			order = 2,
+			name = "Tooltip Headers",
+			desc = "Font used in tooltips to display large names."
+		},
+	};
+
+	SV:GenerateFontOptionGroup("Tooltip", 8, "Fonts used in tooltips.", tipFonts)
+
+	SV.Options.args[Schema] = {
+		type = "group",
+		name = Schema,
+		childGroups = "tab",
+		get = function(a)return SV.db[Schema][a[#a]] end,
+		set = function(a, b) MOD:ChangeDBVar(b,a[#a]); end,
+		args = {
+			commonGroup = {
+				order = 1,
+				type = "group",
+				name = L["Tooltip Options"],
+				guiInline = true,
+				args = {
+					intro = {
+						order = 1,
+						type = "description",
+						name = L["TOOLTIP_DESC"]
+					},
+					common = {
+						order = 3,
+						type = "group",
+						name = L["General"],
+						guiInline = true,
+						args = {
+							cursorAnchor = {
+								order = 1,
+								type = "toggle",
+								name = L["Cursor Anchor"],
+								desc = L["Should tooltip be anchored to mouse cursor"]
+							},
+							targetInfo = {
+								order = 2,
+								type = "toggle",
+								name = L["Target Info"],
+								desc = L["When in a raid group display if anyone in your raid is targeting the current tooltip unit."]
+							},
+							playerTitles = {
+								order = 3,
+								type = "toggle",
+								name = L["Player Titles"],
+								desc = L["Display player titles."]
+							},
+							playerGender = {
+								order = 4,
+								type = "toggle",
+								name = L["Player Gender"],
+								desc = L["Display player gender."]
+							},
+							guildRanks = {
+								order = 5,
+								type = "toggle",
+								name = L["Guild Ranks"],
+								desc = L["Display guild ranks if a unit is guilded."]
+							},
+							inspectInfo = {
+								order = 6,
+								type = "toggle",
+								name = L["Talent Spec"],
+								desc = L["Display the players talent spec in the tooltip, this may not immediately update when mousing over a unit."]
+							},
+							spellID = {
+								order = 7,
+								type = "toggle",
+								name = L["Spell/Item IDs"],
+								desc = L["Display the spell or item ID when mousing over a spell or item tooltip."],
+								get = function(a)return SV.db[Schema].spellID end,
+								set = function(a, b) MOD:ChangeDBVar(b, "spellID") end,
+							},
+							itemCount = {
+								order = 8,
+								type = "toggle",
+								name = L["Item Counts"],
+								desc = L["Display the total owned of an item across all recently played characters."],
+								get = function(a)return SV.db[Schema].itemCount end,
+								set = function(a, b) MOD:ChangeDBVar(b, "itemCount") end,
+							},
+						}
+
+					},
+					visibility={
+						order=100,
+						type="group",
+						guiInline = true,
+						name=L["Visibility"],
+						get=function(a)return SV.db[Schema].visibility[a[#a]]end,
+						set=function(a,b)SV.db[Schema].visibility[a[#a]]=b end,
+						args={
+							combat={order=1,type='toggle',name=COMBAT,desc=L["Hide tooltip while in combat."]},
+							unitFrames={order=2,type='select',name=L['Unitframes'],desc=L["Don't display the tooltip when mousing over a unitframe."],values={['ALL']=L['Always Hide'],['NONE']=L['Never Hide'],['SHIFT']=SHIFT_KEY,['ALT']=ALT_KEY,['CTRL']=CTRL_KEY}}
+						}
+					},
+					healthBar={
+						order=200,
+						type="group",
+						guiInline = true,
+						name=L["Health Bar"],
+						get=function(a)return SV.db[Schema].healthBar[a[#a]]end,
+						set=function(a,b)SV.db[Schema].healthBar[a[#a]]=b end,
+						args={
+							height = {
+								order = 1,
+								name = L["Height"],
+								type = "range",
+								min = 1,
+								max = 15,
+								step = 1,
+								width = "full",
+								set = function(a,b)SV.db[Schema].healthBar.height = b;GameTooltipStatusBar:SetHeight(b)end
+							},
+						}
+					}
+				}
+			}
+		}
+	}
+end
diff --git a/SVUI_Tooltip/SVUI_Tooltip.lua b/SVUI_Tooltip/SVUI_Tooltip.lua
new file mode 100644
index 0000000..526c34c
--- /dev/null
+++ b/SVUI_Tooltip/SVUI_Tooltip.lua
@@ -0,0 +1,957 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack 	= _G.unpack;
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local tinsert 	= _G.tinsert;
+local tremove 	= _G.tremove;
+local string 	= _G.string;
+local math 		= _G.math;
+local table 	= _G.table;
+--[[ STRING METHODS ]]--
+local find, format, match, sub, gsub = string.find, string.format, string.match, string.sub, string.gsub;
+--[[ MATH METHODS ]]--
+local floor,min = math.floor, math.min;
+--[[ TABLE METHODS ]]--
+local wipe, tconcat = table.wipe, table.concat;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local MOD = SV.Tooltip;
+if(not MOD) then return end;
+
+MOD.Holder = CreateFrame("Frame", "SVUI_ToolTip", UIParent)
+MOD.DefaultPadding = 24;
+--[[
+##########################################################
+LOCAL VARIABLES
+##########################################################
+]]--
+local _G = getfenv(0);
+local ID = _G.ID;
+local GameTooltip = _G.GameTooltip;
+local GameTooltipStatusBar = _G.GameTooltipStatusBar;
+local NewHook = _G.hooksecurefunc;
+local playerGUID = UnitGUID("player");
+local targetList, inspectCache = {}, {};
+
+local GENDER = {"", "Male ", "Female "};
+local NIL_COLOR = { r = 0, g = 0, b = 0 };
+local TAPPED_COLOR = { r = .6, g = .6, b = .6 };
+local SKULL_ICON = "|TInterface\\TARGETINGFRAME\\UI-TargetingFrame-Skull.blp:16:16|t";
+local TAMABLE_INDICATOR = "|cffFFFF00Tamable|r";
+
+local TAMABLE_FAMILIES = {
+	["Basilisk"] = true, 	 ["Bat"] = true, 		  ["Bear"] = true, 		   ["Beetle"] = true,
+	["Bird of Prey"] = true, ["Boar"] = true, 		  ["Carrion Bird"] = true, ["Cat"] = true,
+	["Chimaera"] = true, 	 ["Core Hound"] = true,   ["Crab"] = true, 		   ["Crane"] = true,
+	["Crocolisk"] = true, 	 ["Devilsaur"] = true, 	  ["Direhorn"] = true, 	   ["Dog"] = true,
+	["Dragonhawk"] = true, 	 ["Fox"] = true, 		  ["Goat"] = true, 		   ["Gorilla"] = true,
+	["Wasp"] = true, 		 ["Hydra"] = true, 		  ["Hyena"] = true, 	   ["Monkey"] = true,
+	["Moth"] = true, 		 ["Nether Ray"] = true,   ["Porcupine"] = true,    ["Quilen"] = true,
+	["Raptor"] = true, 		 ["Ravager"] = true, 	  ["Rhino"] = true, 	   ["Riverbeast"] = true,
+	["Scorpid"] = true, 	 ["Shale Spider"] = true, ["Spirit Beast"] = true, ["Serpent"] = true,
+	["Silithid"] = true, 	 ["Spider"] = true, 	  ["Sporebat"] = true, 	   ["Tallstrider"] = true,
+	["Turtle"] = true,		 ["Warp Stalker"] = true, ["Wasp"] = true, 		   ["Water strider"] = true,
+	["Wind Serpent"] = true, ["Wolf"] = true, 		  ["Worm"] = true
+};
+
+local tooltips = {
+	GameTooltip, ItemRefTooltip, ItemRefShoppingTooltip1,
+	ItemRefShoppingTooltip2, ItemRefShoppingTooltip3, AutoCompleteBox,
+	FriendsTooltip, ConsolidatedBuffsTooltip, ShoppingTooltip1,
+	ShoppingTooltip2, ShoppingTooltip3, WorldMapTooltip,
+	WorldMapCompareTooltip1, WorldMapCompareTooltip2,
+	WorldMapCompareTooltip3, DropDownList1MenuBackdrop,
+	DropDownList2MenuBackdrop, DropDownList3MenuBackdrop, BNToastFrame,
+	PetBattlePrimaryAbilityTooltip, PetBattlePrimaryUnitTooltip,
+	BattlePetTooltip, FloatingBattlePetTooltip, FloatingPetBattleAbilityTooltip, FloatingGarrisonFollowerTooltip,
+	GarrisonMissionMechanicTooltip, GarrisonFollowerTooltip,
+	GarrisonMissionMechanicFollowerCounterTooltip, GarrisonFollowerAbilityTooltip,
+	SmallTextTooltip, BrowserSettingsTooltip, QueueStatusFrame, EventTraceTooltip,
+	ItemSocketingDescription
+};
+
+-- local ignored_tooltips = {
+-- 	FrameStackTooltip
+-- };
+
+local classification = {
+	worldboss = format("|cffAF5050%s|r", BOSS),
+	rareelite = format("|cffAF5050+%s|r", ITEM_QUALITY3_DESC),
+	elite = "|cffAF5050+|r",
+	rare = format("|cffAF5050%s|r", ITEM_QUALITY3_DESC)
+};
+--[[
+##########################################################
+LOCAL UPVALUES
+##########################################################
+]]--
+local COMIC_TIPS = true;
+local TIP_ICONS = true;
+local SPELL_IDS = false;
+local ON_CURSOR = false;
+local TARGET_INFO = true;
+local PLAYER_INFO = true;
+local GENDER_INFO = false;
+local INSPECT_INFO = false;
+local GUILD_INFO = true;
+local VISIBILITY_UNITS = "NONE";
+local VISIBILITY_COMBAT = false;
+local BAR_TEXT = true;
+local BAR_HEIGHT = 10;
+local ITEM_COUNTS = true;
+
+local VisibilityTest = {
+	NONE = function() return false end,
+	ALL = function() return true end,
+	SHIFT = function() return (not IsShiftKeyDown()) end,
+	CTRL = function() return (not IsControlKeyDown()) end,
+	ALT = function() return (not IsAltKeyDown()) end,
+};
+--[[
+##########################################################
+LOCAL FUNCTIONS
+##########################################################
+]]--
+local function Pinpoint(parent)
+    local centerX,centerY = parent:GetCenter()
+    local screenWidth = GetScreenWidth()
+    local screenHeight = GetScreenHeight()
+    local result;
+    if not centerX or not centerY then
+        return "CENTER"
+    end
+    local heightTop = screenHeight * 0.75;
+    local heightBottom = screenHeight * 0.25;
+    local widthLeft = screenWidth * 0.25;
+    local widthRight = screenWidth * 0.75;
+    if(((centerX > widthLeft) and (centerX < widthRight)) and (centerY > heightTop)) then
+        result="TOP"
+    elseif((centerX < widthLeft) and (centerY > heightTop)) then
+        result="TOPLEFT"
+    elseif((centerX > widthRight) and (centerY > heightTop)) then
+        result="TOPRIGHT"
+    elseif(((centerX > widthLeft) and (centerX < widthRight)) and centerY < heightBottom) then
+        result="BOTTOM"
+    elseif((centerX < widthLeft) and (centerY < heightBottom)) then
+        result="BOTTOMLEFT"
+    elseif((centerX > widthRight) and (centerY < heightBottom)) then
+        result="BOTTOMRIGHT"
+    elseif((centerX < widthLeft) and (centerY > heightBottom) and (centerY < heightTop)) then
+        result="LEFT"
+    elseif((centerX > widthRight) and (centerY < heightTop) and (centerY > heightBottom)) then
+        result="RIGHT"
+    else
+        result="CENTER"
+    end
+    return result
+end
+
+local function TruncateString(value)
+    if value >= 1e9 then
+        return ("%.1fb"):format(value/1e9):gsub("%.?0+([kmb])$","%1")
+    elseif value >= 1e6 then
+        return ("%.1fm"):format(value/1e6):gsub("%.?0+([kmb])$","%1")
+    elseif value >= 1e3 or value <= -1e3 then
+        return ("%.1fk"):format(value/1e3):gsub("%.?0+([kmb])$","%1")
+    else
+        return value
+    end
+end
+
+local function GetTalentSpec(unit,isPlayer)
+	local spec;
+	if isPlayer then
+		spec = GetSpecialization()
+	else
+		spec = GetInspectSpecialization(unit)
+	end
+	if spec ~= nil and spec > 0 then
+		if not isPlayer then
+			local byRole = GetSpecializationRoleByID(spec)
+			if byRole ~= nil then
+				local _,byRoleData = GetSpecializationInfoByID(spec)
+				return byRoleData
+			end
+		else
+			local _,specData = GetSpecializationInfo(spec)
+			return specData
+		end
+	end
+end
+
+local function AddIcon(self, icon)
+	if((not TIP_ICONS) or (not icon)) then return end
+	local title = _G[self:GetName() .. "TextLeft1"]
+	if(title) then
+		local text = title:GetText() or '';
+		if((not text) or (not text:find("|T" .. icon))) then
+			title:SetFormattedText("|T%s:20:20:0:0:64:64:5:59:5:59:%d|t  %s", icon, 20, text)
+		end
+	end
+end
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+local SetMaskBorderColor = function(self, r, g, b, hasStatusBar)
+	if(self:GetAlpha() == 0) then
+		self:FadeIn()
+	end
+	--self:SetBackdropColor(0, 0, 0, 0.8)
+	-- if(COMIC_TIPS) then
+	-- 	local a = self.ToggleAlpha
+	-- 	if(hasStatusBar) then
+	-- 		self[1]:SetVertexColor(r, g, b, a)
+	-- 		self[2]:SetVertexColor(r, g, b, a)
+	-- 		self[3]:SetVertexColor(0, 0, 0, 0)
+	-- 		self[4]:SetVertexColor(0, 0, 0, 0)
+	-- 	else
+	-- 		self[1]:SetVertexColor(0, 0, 0, 0)
+	-- 		self[2]:SetVertexColor(0, 0, 0, 0)
+	-- 		self[3]:SetVertexColor(r, g, b, a)
+	-- 		self[4]:SetVertexColor(r, g, b, a)
+	-- 	end
+	-- end
+	r,g,b = (r * 0.5),(g * 0.5),(b * 0.5)
+	self[5]:SetTexture(r, g, b, 1)
+	self[6]:SetTexture(r, g, b, 1)
+	self[7]:SetTexture(r, g, b, 1)
+	self[8]:SetTexture(r, g, b, 1)
+	--print('Set Color')
+end
+
+local ClearMaskColors = function(self, hide)
+	--self[1]:SetVertexColor(0, 0, 0, 0)
+	--self[2]:SetVertexColor(0, 0, 0, 0)
+	--self[3]:SetVertexColor(0, 0, 0, 0)
+	--self[4]:SetVertexColor(0, 0, 0, 0)
+
+	self[5]:SetColorTexture(0, 0, 0, 0)
+	self[6]:SetColorTexture(0, 0, 0, 0)
+	self[7]:SetColorTexture(0, 0, 0, 0)
+	self[8]:SetColorTexture(0, 0, 0, 0)
+
+	-- if(hide) then
+	-- 	self:SetBackdropColor(0, 0, 0, 0)
+	-- end
+end
+
+function MOD:INSPECT_READY(event, GUID)
+	if(MOD.lastGUID ~= GUID) then return end
+	local unit = "mouseover"
+	if(UnitExists(unit)) then
+		local itemLevel = SV:ParseGearSlots(unit, true)
+		local spec = GetTalentSpec(unit)
+		inspectCache[GUID] = {time = GetTime()}
+		if(spec) then
+			inspectCache[GUID].talent = spec
+		end
+		if(itemLevel) then
+			inspectCache[GUID].itemLevel = itemLevel
+		end
+		GameTooltip:SetUnit(unit)
+	end
+	MOD:UnregisterEvent("INSPECT_READY")
+end
+
+local function ShowInspectInfo(this, unit, unitLevel, r, g, b, iteration)
+	local inspectable = CanInspect(unit)
+	if((not inspectable) or (unitLevel < 10) or (iteration > 2)) then return end
+	local GUID = UnitGUID(unit)
+	if(GUID == playerGUID) then
+		this:AddDoubleLine(L["Talent Specialization:"], GetTalentSpec(unit, true), nil, nil, nil, r, g, b)
+		this:AddDoubleLine(L["Item Level:"], floor(select(2, GetAverageItemLevel())), nil, nil, nil, 1, 1, 1)
+	elseif(inspectCache[GUID]) then
+		local talent = inspectCache[GUID].talent;
+		local itemLevel = inspectCache[GUID].itemLevel;
+		if(((GetTime() - inspectCache[GUID].time) > 900) or not talent or not itemLevel) then
+			inspectCache[GUID] = nil;
+			return ShowInspectInfo(this,unit,unitLevel,r,g,b,iteration+1)
+		end
+		this:AddDoubleLine(L["Talent Specialization:"],talent,nil,nil,nil,r,g,b)
+		this:AddDoubleLine(L["Item Level:"],itemLevel,nil,nil,nil,1,1,1)
+	else
+		if((not inspectable) or (InspectFrame and InspectFrame:IsShown())) then
+			return
+		end
+		MOD.lastGUID = GUID;
+		NotifyInspect(unit)
+		MOD:RegisterEvent("INSPECT_READY")
+	end
+end
+
+local function tipcleaner(this)
+	for i=3, this:NumLines() do
+		local tip = _G["GameTooltipTextLeft"..i]
+		local tipText = tip:GetText()
+		if(tipText and (tipText:find(PVP) or tipText:find(FACTION_ALLIANCE) or tipText:find(FACTION_HORDE))) then
+			tip:SetText(nil)
+			tip:Hide()
+		end
+	end
+end
+
+local function tiplevel(this, start)
+	for i = start, this:NumLines() do
+		local tip = _G["GameTooltipTextLeft"..i]
+		if tip:GetText() and tip:GetText():find(LEVEL) then
+			return tip
+		end
+	end
+end
+
+local function tipbackground(this)
+	this:SetBackdropColor(0, 0, 0, 0.8)
+	--this:SetBackdropBorderColor(0, 0, 0, 1)
+	if(this.SuperBorder) then
+		--this.SuperBorder:SetBackdropColor(0, 0, 0, 0.8)
+		if(not GameTooltipStatusBar:IsShown()) then
+			this.SuperBorder:ClearAllPoints()
+			this.SuperBorder:SetPoint("TOPLEFT", this, "TOPLEFT", -1, 1)
+			this.SuperBorder:SetPoint("BOTTOMRIGHT", this, "BOTTOMRIGHT", 1, -1)
+		end
+	end
+end
+
+local function tipupdate(this, color, hasStatusBar)
+	if(hasStatusBar) then
+		local barColor = color or TAPPED_COLOR
+		GameTooltipStatusBar:SetStatusBarColor(barColor.r, barColor.g, barColor.b)
+	end
+	if(this.SuperBorder) then
+		local mask = this.SuperBorder
+		local borderColor = color or NIL_COLOR
+		local yOffset = (hasStatusBar) and mask.ToggleHeight or 0;
+		mask:ClearAllPoints()
+		mask:SetPoint("TOPLEFT", this, "TOPLEFT", -1, 1)
+		mask:SetPoint("BOTTOMRIGHT", this, "BOTTOMRIGHT", 1, yOffset)
+		mask:SetMaskBorderColor(borderColor.r, borderColor.g, borderColor.b, hasStatusBar)
+	end
+end
+
+local _hook_GameTooltip_OnTooltipSetUnit = function(self)
+	--print('SetUnit: ' .. self:GetName())
+	if(not self) then return end
+	tipbackground(self)
+
+	local unit = select(2, self:GetUnit())
+
+	-- local TamablePet;
+	if(self:GetOwner() ~= UIParent) then
+		if(VisibilityTest[VISIBILITY_UNITS] and VisibilityTest[VISIBILITY_UNITS]()) then
+			self:Hide()
+			return
+		end
+	end
+	if not unit then
+		local mFocus = GetMouseFocus()
+		if mFocus and mFocus:GetAttribute("unit") then
+			unit = mFocus:GetAttribute("unit")
+		end
+		if not unit or not UnitExists(unit) then return end
+	end
+
+	tipcleaner(self)
+	local unitLevel = UnitLevel(unit)
+	local colors, qColor, totColor;
+	local lvlLine;
+	local lineIncrement = 2;
+	local isShiftKeyDown = IsShiftKeyDown()
+
+	if UnitIsPlayer(unit) then
+		local className, classToken = UnitClass(unit)
+		local unitName, unitRealm = UnitName(unit)
+		local guildName, guildRankName, _, guildRealm = GetGuildInfo(unit)
+		local gender = GENDER[UnitSex(unit)];
+		local realmRelation = UnitRealmRelationship(unit)
+		local nameString = "";
+		colors = RAID_CLASS_COLORS[classToken] or CUSTOM_CLASS_COLORS[classToken] or RAID_CLASS_COLORS['ROGUE']
+
+		if(PLAYER_INFO) then
+			nameString = UnitPVPName(unit) or unitName
+		else
+			nameString = unitName
+		end
+
+		if unitRealm and unitRealm ~= "" then
+			if(isShiftKeyDown) then
+				nameString = nameString.."-"..unitRealm
+			elseif(realmRelation == LE_REALM_RELATION_COALESCED) then
+				nameString = nameString..FOREIGN_SERVER_LABEL
+			elseif(realmRelation == LE_REALM_RELATION_VIRTUAL) then
+				nameString = nameString..INTERACTIVE_SERVER_LABEL
+			end
+		end
+
+		if(UnitIsAFK(unit)) then
+			GameTooltipTextLeft1:SetFormattedText("[|cffFF0000%s|r] |c%s%s|r ", L["AFK"], colors.colorStr, nameString)
+		elseif(UnitIsDND(unit)) then
+			GameTooltipTextLeft1:SetFormattedText("[|cffFF9900%s|r] |c%s%s|r ", L["DND"], colors.colorStr, nameString)
+		else
+			GameTooltipTextLeft1:SetFormattedText("|c%s%s|r", colors.colorStr, nameString)
+		end
+
+		if(guildName) then
+			if(guildRealm and isShiftKeyDown) then
+				guildName = guildName.."-"..guildRealm
+			end
+
+			if(guildRankName and GUILD_INFO) then
+				GameTooltipTextLeft2:SetText(("<|cff00ff10%s|r> [|cff00ff10%s|r]"):format(guildName, guildRankName))
+			else
+				GameTooltipTextLeft2:SetText(("<|cff00ff10%s|r>"):format(guildName))
+			end
+			lineIncrement = lineIncrement + 1
+		end
+
+		lvlLine = tiplevel(self, lineIncrement)
+
+		if(lvlLine and className) then
+			qColor = GetQuestDifficultyColor(unitLevel)
+			local race, englishRace = UnitRace(unit)
+			local _, factionGroup = UnitFactionGroup(unit)
+
+			if(factionGroup and englishRace == "Pandaren") then
+				race = factionGroup.." "..race
+			end
+
+			if(GENDER_INFO) then
+				local gender = GENDER[UnitSex(unit)];
+				if(gender) then race = race .. " " .. gender end
+			end
+			lvlLine:SetFormattedText("|cff%02x%02x%02x%s|r %s |c%s%s|r", qColor.r * 255, qColor.g * 255, qColor.b * 255, unitLevel > 0 and unitLevel or SKULL_ICON, race or "", colors.colorStr, className)
+		end
+
+		if(not IsAddOnLoaded("HealBot") and (INSPECT_INFO or isShiftKeyDown)) then
+			ShowInspectInfo(self, unit, unitLevel, colors.r, colors.g, colors.b, 0)
+		end
+	else
+		if UnitIsTapDenied(unit) then
+			colors = TAPPED_COLOR
+		else
+			colors = FACTION_BAR_COLORS[UnitReaction(unit, "player")]
+		end
+
+		lvlLine = tiplevel(self, 2)
+
+		if(lvlLine) then
+			local creatureClassification = UnitClassification(unit)
+			local creatureType = UnitCreatureType(unit)
+			local temp = ""
+			if(UnitIsWildBattlePet(unit) or UnitIsBattlePetCompanion(unit)) then
+				unitLevel = UnitBattlePetLevel(unit)
+				local ab = C_PetJournal.GetPetTeamAverageLevel()
+				if ab then
+					qColor = GetRelativeDifficultyColor(ab, unitLevel)
+				else
+					qColor = GetQuestDifficultyColor(unitLevel)
+				end
+			else
+				qColor = GetQuestDifficultyColor(unitLevel)
+			end
+
+			if UnitIsPVP(unit) then
+				temp = format(" (%s)", PVP)
+			end
+
+			if(creatureType) then
+				local family = UnitCreatureFamily(unit) or creatureType
+				if(SV.class == "HUNTER" and creatureType == PET_TYPE_SUFFIX[8] and (family and TAMABLE_FAMILIES[family])) then
+					local hunterLevel = UnitLevel("player")
+					-- if(unitLevel <= hunterLevel) then
+					-- 	TamablePet = true
+					-- end
+				end
+				creatureType = family
+			else
+				creatureType = ""
+			end
+
+			lvlLine:SetFormattedText("|cff%02x%02x%02x%s|r %s %s%s", qColor.r * 255, qColor.g * 255, qColor.b * 255, unitLevel > 0 and unitLevel or "??", classification[creatureClassification] or "", creatureType, temp)
+		end
+	end
+	-- if(TamablePet) then
+	-- 	self:AddLine(TAMABLE_INDICATOR)
+	-- end
+	if(TARGET_INFO) then
+		local unitTarget = unit.."target"
+		if(unit ~= "player" and UnitExists(unitTarget)) then
+			if UnitIsPlayer(unitTarget) and not UnitHasVehicleUI(unitTarget) then
+				totColor = RAID_CLASS_COLORS[select(2, UnitClass(unitTarget))]
+			else
+				totColor = FACTION_BAR_COLORS[UnitReaction(unitTarget, "player")]
+			end
+			self:AddDoubleLine(format("%s:", TARGET), format("|cff%02x%02x%02x%s|r", totColor.r * 255, totColor.g * 255, totColor.b * 255, UnitName(unitTarget)))
+		end
+		if IsInGroup() then
+			for i = 1, GetNumGroupMembers() do
+				local groupedUnit = IsInRaid() and "raid"..i or "party"..i;
+				if UnitIsUnit(groupedUnit.."target", unit) and not UnitIsUnit(groupedUnit, "player") then
+					local _, classToken = UnitClass(groupedUnit)
+					tinsert(targetList, format("|c%s%s|r", RAID_CLASS_COLORS[classToken].colorStr, UnitName(groupedUnit)))
+				end
+			end
+			local maxTargets = #targetList;
+			if maxTargets > 0 then
+				self:AddLine(format("%s (|cffffffff%d|r): %s", L["Targeted By:"], maxTargets, tconcat(targetList, ", ")), nil, nil, nil, true)
+				wipe(targetList)
+			end
+		end
+	end
+
+	tipupdate(self, colors, GameTooltipStatusBar:IsShown())
+end
+
+local _hook_GameTooltipStatusBar_OnValueChanged = function(self, value)
+	if((not value) or (not BAR_TEXT) or (not self.text)) then return end
+	local tooltip = self:GetParent()
+	local unit = select(2, tooltip:GetUnit())
+	if not unit then
+		local mFocus = GetMouseFocus()
+		if mFocus and mFocus:GetAttribute("unit") then
+			unit = mFocus:GetAttribute("unit")
+		end
+	end
+	local min,max = self:GetMinMaxValues()
+	if((value > 0) and (max == 1)) then
+		self.text:SetText(format("%d%%",floor(value * 100)))
+		self:SetStatusBarColor(TAPPED_COLOR.r,TAPPED_COLOR.g,TAPPED_COLOR.b)
+	elseif((value == 0) or (unit and UnitIsDeadOrGhost(unit))) then
+		self.text:SetText(DEAD)
+	else
+		self.text:SetText(TruncateString(value).." / "..TruncateString(max))
+	end
+end
+
+
+local _hook_GameTooltip_OnTooltipSetItem = function(self)
+	tipbackground(self)
+	local key,itemLink = self:GetItem()
+	if(key and (not self.itemCleared)) then
+		if(itemLink) then
+			local itemName, _, quality, _, _, _, _, _, equipSlot, icon = GetItemInfo(itemLink)
+			AddIcon(self, icon)
+			if(quality) then
+				local r,g,b = GetItemQualityColor(quality)
+				self.SuperBorder:SetMaskBorderColor(r, g, b)
+			end
+		end
+
+		if(ITEM_COUNTS and SV.SetLootTooltip) then
+			SV:SetLootTooltip(self, key)
+		end
+
+		if(SPELL_IDS and (itemLink ~= nil)) then
+			self:AddLine(" ")
+			local left = "|cFFCA3C3CSpell ID: |r"
+			local itemID = ("|cFFCA3C3C%s|r %s"):format(left, itemLink):match(":(%w+)")
+			self:AddLine(("|cFFCA3C3C%s# %d|r"):format(ID, itemID))
+		end
+
+		-- self:AddLine(("|cffFFFF00 Equip: %s|r"):format(equipSlot))
+		-- self:AddLine(("|cffFFFF00 Quality: %s|r"):format(quality))
+
+		if(self.InjectedDouble and self.InjectedDouble[8]) then
+			self:AddLine(" ");
+			self:AddDoubleLine(unpack(self.InjectedDouble));
+		end
+
+		self.itemCleared = true
+	end
+end
+
+local _hook_GameTooltip_ShowStatusBar = function(self, ...)
+	local name = self:GetName()
+	local barName = ("%sStatusBar%d"):format(name, self.shownStatusBars)
+	local bar = _G[barName]
+	if bar and not bar.styled then
+		bar:RemoveTextures()
+		bar:SetStatusBarTexture(SV.media.statusbar.default)
+		bar:SetStyle("!_Frame", 'Inset',true)
+		if not bar.border then
+			local border=CreateFrame("Frame",nil,bar)
+			border:WrapPoints(bar,1,1)
+			border:SetFrameLevel(bar:GetFrameLevel() - 1)
+			border:SetBackdrop({
+				edgeFile=[[Interface\BUTTONS\WHITE8X8]],
+				edgeSize=1,
+				insets={left=1,right=1,top=1,bottom=1}
+			})
+			border:SetBackdropBorderColor(0,0,0,1)
+			bar.border=border
+		end
+		bar.styled=true
+	end
+end
+
+local _hook_OnSetUnitAura = function(self, unit, index, filter)
+	tipbackground(self)
+	local _, _, _, _, _, _, _, caster, _, _, spellID = UnitAura(unit, index, filter)
+	if(spellID) then
+		if caster then
+			local name = UnitName(caster)
+			local _, class = UnitClass(caster)
+			local color = RAID_CLASS_COLORS[class]
+			if(color) then
+				self.SuperBorder:SetMaskBorderColor(color.r, color.g, color.b)
+				self:AddDoubleLine(("|c%sCast By|r"):format(color.colorStr), format("|c%s%s|r", color.colorStr, name))
+			end
+		end
+		if(SPELL_IDS) then
+			self:AddLine(("|cFFCA3C3C%s# %d|r"):format(ID, spellID))
+		end
+		self:Show()
+	end
+end
+
+local _hook_OnSetHyperUnitAura = function(self, unit, index, filter)
+	tipbackground(self)
+	if unit ~= "player" then return end
+	local auraName, _, _, _, _, _, _, caster, _, shouldConsolidate, spellID = UnitAura(unit, index, filter)
+	if shouldConsolidate then
+		if caster then
+			local name = UnitName(caster)
+			local _, class = UnitClass(caster)
+			local color = RAID_CLASS_COLORS[class]
+			if color then
+				self.SuperBorder:SetMaskBorderColor(color.r, color.g, color.b)
+				self:AddDoubleLine(("|cFFCA3C3C%s|r"):format(auraName), format("|c%s%s|r", color.colorStr, name))
+			end
+		else
+			self:AddLine(("|cFFCA3C3C%s|r"):format(auraName))
+		end
+		self:Show()
+	end
+end
+
+local _hook_GameTooltip_OnTooltipSetSpell = function(self)
+	local ref = select(3, self:GetSpell())
+	if not ref then return end
+	local text = ("|cFFCA3C3C%s# %d|r"):format(ID, ref)
+	local max = self:NumLines()
+	local check;
+	for i = 1, max do
+		local tip = _G[("GameTooltipTextLeft%d"):format(i)]
+		if tip and tip:GetText() and tip:GetText():find(text) then
+			check = true;
+			break
+		end
+	end
+	if not check then
+		tipbackground(self)
+		self:AddLine(text)
+		self:Show()
+	end
+end
+
+local _hook_GameTooltip_SetDefaultAnchor = function(self, parent)
+	tipbackground(self)
+	if(self:GetAnchorType() ~= "ANCHOR_NONE") then return end
+	if(InCombatLockdown() and VISIBILITY_COMBAT) then
+		self:Hide()
+		return
+	end
+	if parent then
+		if(ON_CURSOR) then
+			self:SetOwner(parent, "ANCHOR_CURSOR")
+			return
+		else
+			self:SetOwner(parent, "ANCHOR_NONE")
+		end
+	end
+	if(MOD.Holder.Grip and (not MOD.Holder.Grip:HasMoved())) then
+		self:ClearAllPoints()
+		if(SV.Inventory and SV.Inventory.MasterFrame and SV.Inventory.MasterFrame:IsShown()) then
+			self:SetPoint("BOTTOMLEFT", SV.Inventory.MasterFrame, "TOPLEFT", 0, MOD.DefaultPadding)
+		elseif(SV.Dock.BottomRight:GetAlpha() == 1 and SV.Dock.BottomRight:IsShown()) then
+			self:SetPoint("BOTTOMLEFT", SV.Dock.BottomRight.Window, "TOPLEFT", 0, MOD.DefaultPadding)
+		else
+			self:SetPoint("BOTTOMLEFT", SV.Dock.BottomRight.Bar, "TOPLEFT", 0, MOD.DefaultPadding)
+		end
+	else
+		local point = Pinpoint(MOD.Holder.Grip)
+		self:ClearAllPoints()
+		if(point == "TOPLEFT") then
+			self:SetPoint("TOPLEFT", MOD.Holder.Grip, "TOPLEFT", 0, 0)
+		elseif(point == "TOPRIGHT") then
+			self:SetPoint("TOPRIGHT", MOD.Holder.Grip, "TOPRIGHT", 0, 0)
+		elseif(point == "BOTTOMLEFT" or point == "LEFT" )then
+			self:SetPoint("BOTTOMLEFT", MOD.Holder.Grip, "BOTTOMLEFT", 0, 0)
+		else
+			self:SetPoint("BOTTOMRIGHT", MOD.Holder.Grip, "BOTTOMRIGHT", 0, 0)
+		end
+	end
+end
+
+MOD.GameTooltip_SetDefaultAnchor = _hook_GameTooltip_SetDefaultAnchor
+
+local _hook_BNToastOnShow = function(self,anchor,parent,relative,x,y)
+	if parent ~= BNToastFrame_MOVE then
+		BNToastFrame:ClearAllPoints()
+		BNToastFrame:SetPoint('TOPLEFT',BNToastFrame_MOVE,'TOPLEFT')
+	end
+end
+
+local _hook_OnItemRef = function(link, text, button, chatFrame)
+	if link:find("^spell:") then
+		local ref = sub(link,7)
+		ItemRefTooltip:AddLine(("|cFFCA3C3C%s|r %d"):format(ID, ref))
+		ItemRefTooltip:Show()
+	end
+end
+
+local TooltipModifierChangeHandler = function(self, event, mod)
+	if (mod == "LSHIFT" or mod == "RSHIFT") and UnitExists("mouseover") then
+		GameTooltip:SetUnit("mouseover")
+	end
+end
+
+local Override_BGColor = function(self, r, g, b, a)
+	if((r ~= 0) and (g ~= 0) and (b ~= 0)) then
+		self:SetBackdropColor(0, 0, 0, 0.8)
+		--self.SuperBorder:SetBackdropColor(r, g, b, 0.8)
+	end
+end
+
+local Override_BorderColor = function(self, r, g, b, a)
+	self.SuperBorder:SetMaskBorderColor(r, g, b, 1)
+end
+
+local _hook_OnTipCleared = function(self)
+	tipbackground(self)
+	self.SuperBorder:ClearMaskColors()
+	self.itemCleared = nil
+end
+
+local _hook_OnTipShow = function(self)
+	--print('Showing: ' .. self:GetName())
+	tipbackground(self)
+end
+
+local _hook_OnTipHide = function(self)
+	--print('Hide')
+	tipbackground(self)
+	self.SuperBorder:ClearMaskColors(true)
+	if(self.InjectedDouble) then
+		wipe(self.InjectedDouble)
+	end
+end
+
+local _hook_OnSizeChanged = function(self)
+	if((not COMIC_TIPS) or (not self.SuperBorder)) then return; end
+	local height = self:GetHeight() or 32
+	local heightScale = min(64, height)
+	local width = self:GetWidth() or 64
+	local widthScale = min(128, width)
+	self.SuperBorder[1]:SetSize(widthScale,(widthScale * 0.35))
+	self.SuperBorder[2]:SetSize(widthScale,(widthScale * 0.35))
+	self.SuperBorder[3]:SetSize(heightScale,heightScale)
+	self.SuperBorder[4]:SetSize(heightScale,heightScale)
+end
+
+function MOD:SetCustomStyle(tooltip)
+	if(not tooltip) then return end
+	local barHeight = GameTooltipStatusBar:GetHeight()
+	local barOffset = 0
+    local alpha = 0.2
+    if(tooltip == GameTooltip) then
+        barOffset = (barHeight + 6) * -1
+        alpha = 0.5
+    end
+
+    local mask = CreateFrame("Frame", nil, tooltip)
+    mask:SetPoint("TOPLEFT", tooltip, "TOPLEFT", -1, 1)
+    mask:SetPoint("BOTTOMRIGHT", tooltip, "BOTTOMRIGHT", 1, barOffset)
+    mask:SetFrameLevel(0)
+    mask.ToggleHeight = barOffset
+    mask.ToggleAlpha = alpha
+
+    --[[ STARBURST TOP ]]
+    mask[1] = mask:CreateTexture(nil, "BACKGROUND")
+    mask[1]:SetPoint("BOTTOMLEFT", mask, "TOPLEFT", 0, 0)
+    mask[1]:SetHeight(mask:GetWidth() * 0.25)
+    mask[1]:SetWidth(mask:GetWidth() * 0.25)
+    -- mask[1]:SetTexture(MOD.media.topArt)
+    -- mask[1]:SetVertexColor(0,0,0)
+    -- mask[1]:SetBlendMode("BLEND")
+    -- mask[1]:SetAlpha(alpha)
+    --[[ STARBURST BOTTOM ]]
+    mask[2] = mask:CreateTexture(nil, "BACKGROUND")
+    mask[2]:SetPoint("TOPRIGHT", mask, "BOTTOMRIGHT", 0, 0)
+    mask[2]:SetHeight(mask:GetWidth() * 0.25)
+    mask[2]:SetWidth(mask:GetWidth() * 0.25)
+    --mask[2]:SetTexture(MOD.media.bottomArt)
+    --mask[2]:SetVertexColor(0,0,0)
+    --mask[2]:SetBlendMode("BLEND")
+    --mask[2]:SetAlpha(alpha)
+    --[[ HALFTONE RIGHT ]]
+    mask[3] = mask:CreateTexture(nil, "BACKGROUND")
+    mask[3]:SetPoint("LEFT", mask, "RIGHT", 0, 0)
+    mask[3]:SetSize(64,64)
+    -- mask[3]:SetTexture(MOD.media.rightArt)
+    -- mask[3]:SetVertexColor(0,0,0)
+    -- mask[3]:SetBlendMode("BLEND")
+    -- mask[3]:SetAlpha(alpha)
+    --[[ HALFTONE LEFT ]]
+    mask[4] = mask:CreateTexture(nil, "BACKGROUND")
+    mask[4]:SetPoint("RIGHT", mask, "LEFT", 0, 0)
+    mask[4]:SetSize(64,64)
+    -- mask[4]:SetTexture(MOD.media.leftArt)
+    -- mask[4]:SetVertexColor(0,0,0)
+    -- mask[4]:SetBlendMode("BLEND")
+    -- mask[4]:SetAlpha(alpha)
+
+    --[[ BORDER TOP ]]
+    mask[5] = mask:CreateTexture(nil, "OVERLAY")
+    mask[5]:SetPoint("TOPLEFT", mask, "TOPLEFT", 0, 0)
+    mask[5]:SetPoint("TOPRIGHT", mask, "TOPRIGHT", 0, 0)
+    mask[5]:SetHeight(1)
+    mask[5]:SetColorTexture(0,0,0)
+    --[[ BORDER BOTTOM ]]
+    mask[6] = mask:CreateTexture(nil, "OVERLAY")
+    mask[6]:SetPoint("BOTTOMLEFT", mask, "BOTTOMLEFT", 0, 0)
+    mask[6]:SetPoint("BOTTOMRIGHT", mask, "BOTTOMRIGHT", 0, 0)
+    mask[6]:SetHeight(1)
+    mask[6]:SetColorTexture(0,0,0)
+    --[[ BORDER RIGHT ]]
+    mask[7] = mask:CreateTexture(nil, "OVERLAY")
+    mask[7]:SetPoint("TOPRIGHT", mask, "TOPRIGHT", 0, 0)
+    mask[7]:SetPoint("BOTTOMRIGHT", mask, "BOTTOMRIGHT", 0, 0)
+    mask[7]:SetWidth(1)
+    mask[7]:SetColorTexture(0,0,0)
+    --[[ BORDER LEFT ]]
+    mask[8] = mask:CreateTexture(nil, "OVERLAY")
+    mask[8]:SetPoint("TOPLEFT", mask, "TOPLEFT", 0, 0)
+    mask[8]:SetPoint("BOTTOMLEFT", mask, "BOTTOMLEFT", 0, 0)
+    mask[8]:SetWidth(1)
+    mask[8]:SetColorTexture(0,0,0)
+
+    mask:SetBackdrop(SV.media.backdrop.tooltip)
+    --mask:SetBackdropBorderColor(0, 0, 0)
+
+    mask.SetMaskBorderColor = SetMaskBorderColor
+	mask.ClearMaskColors = ClearMaskColors
+
+	tooltip.SuperBorder = mask;
+
+    SV.API:Set("Tooltip", tooltip)
+
+	NewHook(tooltip, "SetBackdropColor", Override_BGColor)
+	--NewHook(tooltip, "SetBackdropBorderColor", Override_BorderColor)
+	tooltip:HookScript("OnShow", _hook_OnTipShow)
+	tooltip:HookScript("OnHide", _hook_OnTipHide)
+	tooltip:HookScript("OnSizeChanged", _hook_OnSizeChanged)
+end
+
+
+local function ApplyTooltipSkins()
+	for i, tooltip in pairs(tooltips) do
+		if(not tooltip) then return end
+		if(not tooltip.InjectedDouble) then
+			tooltip.InjectedDouble = {}
+		end
+		if(not tooltip.SuperBorder) then
+			MOD:SetCustomStyle(tooltip)
+			tremove(tooltips, i)
+		end
+	end
+end
+
+local function Throttled_Styling()
+	if(#tooltips > 0) then
+		ApplyTooltipSkins()
+	end
+end
+
+function MOD:UpdateLocals()
+	COMIC_TIPS = SV.db.Tooltip.themed;
+	VISIBILITY_COMBAT = SV.db.Tooltip.visibility.combat;
+	BAR_HEIGHT = SV.db.Tooltip.healthBar.height;
+	SPELL_IDS = SV.db.Tooltip.spellID;
+	ON_CURSOR = SV.db.Tooltip.cursorAnchor;
+	BAR_TEXT = SV.db.Tooltip.healthBar.text;
+	TARGET_INFO = SV.db.Tooltip.targetInfo;
+	PLAYER_INFO = SV.db.Tooltip.playerTitles;
+	GENDER_INFO = SV.db.Tooltip.playerGender;
+	INSPECT_INFO = SV.db.Tooltip.inspectInfo;
+	GUILD_INFO = SV.db.Tooltip.guildRanks;
+	VISIBILITY_UNITS = SV.db.Tooltip.visibility.unitFrames;
+	ITEM_COUNTS = SV.db.Tooltip.itemCount;
+end
+
+function MOD:ReLoad()
+	Throttled_Styling()
+end
+
+function MOD:Load()
+	self:UpdateLocals()
+
+	self.Holder:SetPoint("BOTTOMLEFT", SV.Dock.BottomRight, "TOPLEFT", 0, 56)
+	self.Holder:SetSize(130, 20)
+	self.Holder:SetFrameLevel(self.Holder:GetFrameLevel() + 50)
+	SV:NewAnchor(self.Holder, L["Tooltip"])
+
+	GameTooltipStatusBar:SetHeight(BAR_HEIGHT)
+	GameTooltipStatusBar:SetStatusBarTexture(SV.media.statusbar.default)
+
+	BNToastFrame:ClearAllPoints()
+	BNToastFrame:SetPoint("BOTTOMRIGHT", SV.Dock.BottomLeft, "TOPRIGHT", 0, 20)
+	--SV:NewAnchor(BNToastFrame, L["BattleNet Frame"], nil, nil, "BattleNetToasts")
+	SV:NewAnchor(BNToastFrame, L["BattleNet Frame"])
+	NewHook(BNToastFrame, "SetPoint", _hook_BNToastOnShow)
+
+	ApplyTooltipSkins()
+
+	GameTooltipStatusBar:ClearAllPoints()
+	GameTooltipStatusBar:SetPoint("BOTTOMLEFT", GameTooltip.SuperBorder, "BOTTOMLEFT", 3, 3)
+	GameTooltipStatusBar:SetPoint("BOTTOMRIGHT", GameTooltip.SuperBorder, "BOTTOMRIGHT", -3, 3)
+	GameTooltipStatusBar.text = GameTooltipStatusBar:CreateFontString(nil, "OVERLAY")
+	GameTooltipStatusBar.text:SetPoint("CENTER", GameTooltipStatusBar, "CENTER", 0, 0)
+	GameTooltipStatusBar.text:SetFontObject(SVUI_Font_Default)
+
+
+	if not GameTooltipStatusBar.border then
+		local border = CreateFrame("Frame", nil, GameTooltipStatusBar)
+		border:WrapPoints(GameTooltipStatusBar, 1, 1)
+		border:SetFrameLevel(GameTooltipStatusBar:GetFrameLevel() - 1)
+		border:SetBackdrop({edgeFile = [[Interface\BUTTONS\WHITE8X8]], edgeSize = 1})
+		border:SetBackdropBorderColor(0, 0, 0, 1)
+		GameTooltipStatusBar.border = border
+	end
+
+	NewHook("GameTooltip_SetDefaultAnchor", _hook_GameTooltip_SetDefaultAnchor)
+	NewHook("GameTooltip_ShowStatusBar", _hook_GameTooltip_ShowStatusBar)
+
+	NewHook("GameTooltip_ShowCompareItem", Throttled_Styling)
+
+	NewHook(GameTooltip, "SetUnitAura", _hook_OnSetUnitAura)
+	NewHook(GameTooltip, "SetUnitBuff", _hook_OnSetUnitAura)
+	NewHook(GameTooltip, "SetUnitDebuff", _hook_OnSetUnitAura)
+	--NewHook(GameTooltip, "SetUnitConsolidatedBuff", _hook_OnSetHyperUnitAura)
+
+	if(SPELL_IDS) then
+		NewHook("SetItemRef", _hook_OnItemRef)
+		GameTooltip:HookScript("OnTooltipSetSpell", _hook_GameTooltip_OnTooltipSetSpell)
+	end
+
+	GameTooltip:HookScript("OnTooltipCleared", _hook_OnTipCleared)
+	GameTooltip:HookScript("OnTooltipSetItem", _hook_GameTooltip_OnTooltipSetItem)
+	GameTooltip:HookScript("OnTooltipSetUnit", _hook_GameTooltip_OnTooltipSetUnit)
+	GameTooltipStatusBar:HookScript("OnValueChanged", _hook_GameTooltipStatusBar_OnValueChanged)
+	self:RegisterEvent("MODIFIER_STATE_CHANGED", TooltipModifierChangeHandler)
+end
diff --git a/SVUI_Tooltip/SVUI_Tooltip.toc b/SVUI_Tooltip/SVUI_Tooltip.toc
new file mode 100644
index 0000000..6411ff0
--- /dev/null
+++ b/SVUI_Tooltip/SVUI_Tooltip.toc
@@ -0,0 +1,16 @@
+## Interface: 70000
+## Author: Failcoder
+## Version: 1.3.5
+## Title: |cffFF9900SuperVillain UI: |r|cffFFEF00Tooltip|r
+## Notes: Tooltip Plugin for [|cff9911FFSVUI|r].
+## OptionalDeps: LibSharedMedia-3.0
+## RequiredDeps: SVUI_!Core
+## X-SVUIName: Tooltip
+## X-SVUISchema: Tooltip
+## X-Email: munglunch@gmail.com
+## X-Website: http://www.supervillainui.com
+## X-Donate: PayPal:munglunch@gmail.com
+## X-License: MIT
+## X-Category: Interface Enhancements
+
+SVUI_Tooltip.xml
diff --git a/SVUI_Tooltip/SVUI_Tooltip.xml b/SVUI_Tooltip/SVUI_Tooltip.xml
new file mode 100644
index 0000000..4cbf2dd
--- /dev/null
+++ b/SVUI_Tooltip/SVUI_Tooltip.xml
@@ -0,0 +1,4 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+	<Script file='Loader.lua'/>
+	<Script file='SVUI_Tooltip.lua'/>
+</Ui>
\ No newline at end of file
diff --git a/SVUI_Tooltip/assets/MINITIP-BG.blp b/SVUI_Tooltip/assets/MINITIP-BG.blp
new file mode 100644
index 0000000..45c6751
Binary files /dev/null and b/SVUI_Tooltip/assets/MINITIP-BG.blp differ
diff --git a/SVUI_Tooltip/assets/MINITIP-LEFT.blp b/SVUI_Tooltip/assets/MINITIP-LEFT.blp
new file mode 100644
index 0000000..8a2a8cc
Binary files /dev/null and b/SVUI_Tooltip/assets/MINITIP-LEFT.blp differ
diff --git a/SVUI_Tooltip/assets/MINITIP-RIGHT.blp b/SVUI_Tooltip/assets/MINITIP-RIGHT.blp
new file mode 100644
index 0000000..842e349
Binary files /dev/null and b/SVUI_Tooltip/assets/MINITIP-RIGHT.blp differ
diff --git a/SVUI_Tooltip/assets/TOOLTIP.blp b/SVUI_Tooltip/assets/TOOLTIP.blp
new file mode 100644
index 0000000..bfa8130
Binary files /dev/null and b/SVUI_Tooltip/assets/TOOLTIP.blp differ
diff --git a/SVUI_Tooltip/assets/TT-BOTTOM.blp b/SVUI_Tooltip/assets/TT-BOTTOM.blp
new file mode 100644
index 0000000..2355a00
Binary files /dev/null and b/SVUI_Tooltip/assets/TT-BOTTOM.blp differ
diff --git a/SVUI_Tooltip/assets/TT-LEFT.blp b/SVUI_Tooltip/assets/TT-LEFT.blp
new file mode 100644
index 0000000..4758ac8
Binary files /dev/null and b/SVUI_Tooltip/assets/TT-LEFT.blp differ
diff --git a/SVUI_Tooltip/assets/TT-RIGHT.blp b/SVUI_Tooltip/assets/TT-RIGHT.blp
new file mode 100644
index 0000000..0ad4a82
Binary files /dev/null and b/SVUI_Tooltip/assets/TT-RIGHT.blp differ
diff --git a/SVUI_Tooltip/assets/TT-TOP.blp b/SVUI_Tooltip/assets/TT-TOP.blp
new file mode 100644
index 0000000..6b41e74
Binary files /dev/null and b/SVUI_Tooltip/assets/TT-TOP.blp differ
diff --git a/SVUI_TrackOMatic/Bindings.xml b/SVUI_TrackOMatic/Bindings.xml
new file mode 100644
index 0000000..3295b0f
--- /dev/null
+++ b/SVUI_TrackOMatic/Bindings.xml
@@ -0,0 +1,5 @@
+<Bindings>
+  <Binding name="SVUITRACK_DOODAD" category="ADDONS" header="SVUITRACK" runOnUp="false">
+    SVUIToggleTrackingDoodad()
+  </Binding>
+</Bindings>
\ No newline at end of file
diff --git a/SVUI_TrackOMatic/License.txt b/SVUI_TrackOMatic/License.txt
new file mode 100644
index 0000000..69d4d04
--- /dev/null
+++ b/SVUI_TrackOMatic/License.txt
@@ -0,0 +1,31 @@
+
+The MIT License
+
+Copyright (c) 2010, Failcoder (Steve Jackson)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy
+of this software and associated documentation files (the "Software"), to
+deal
+in the Software without restriction, including without limitation the
+rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN
+THE SOFTWARE.
diff --git a/SVUI_TrackOMatic/Loader.lua b/SVUI_TrackOMatic/Loader.lua
new file mode 100644
index 0000000..9d3e724
--- /dev/null
+++ b/SVUI_TrackOMatic/Loader.lua
@@ -0,0 +1,64 @@
+--[[
+##########################################################
+S V U I   By: S.Jackson
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+
+local SV = _G["SVUI"];
+local L = SV.L;
+local PLUGIN = SV:NewPlugin(...);
+local Schema = PLUGIN.Schema;
+
+SV.defaults[Schema] = {
+    ["size"] = 75,
+    ["groups"] = true,
+    ["proximity"] = false,
+}
+
+SV:AssignMedia("font", "tracking", "SVUI Number Font", 12, "OUTLINE");
+SV:AssignMedia("globalfont", "tracking", "SVUI_Font_Tracking");
+
+function PLUGIN:LoadOptions()
+    local trackFonts = {
+        ["tracking"] = {
+            order = 1,
+            name = "Track-O-Matic Text",
+            desc = "Font used for all tracking text."
+        },
+    };
+
+    SV:GenerateFontOptionGroup("Track-O-Matic", 12, "Font used for tracking devices.", trackFonts)
+
+    SV.Options.args[Schema] = {
+        type = "group",
+        name = Schema,
+        get = function(a)return SV.db[Schema][a[#a]]end,
+        set = function(a,b)PLUGIN:ChangeDBVar(b,a[#a]); end,
+        args = {
+            groups = {
+                order = 1,
+                name = L["GPS"],
+                desc = L["Use group frame GPS elements"],
+                type = "toggle",
+                get = function(key) return SV.db[Schema].groups end,
+                set = function(key,value) SV.db[Schema].groups = value; end
+            },
+            proximity = {
+                order = 2,
+                name = L["GPS Proximity"],
+                desc = L["Only point to closest low health unit (if one is in range)."],
+                type = "toggle",
+                get = function(key) return SV.db[Schema].proximity end,
+                set = function(key,value) SV.db[Schema].proximity = value; end
+            }
+        }
+    }
+end
\ No newline at end of file
diff --git a/SVUI_TrackOMatic/SVUI_TrackOMatic.lua b/SVUI_TrackOMatic/SVUI_TrackOMatic.lua
new file mode 100644
index 0000000..69e96ff
--- /dev/null
+++ b/SVUI_TrackOMatic/SVUI_TrackOMatic.lua
@@ -0,0 +1,321 @@
+--[[
+##########################################################
+S V U I   By: S.Jackson
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack    = _G.unpack;
+local select    = _G.select;
+local pairs     = _G.pairs;
+local type      = _G.type;
+local tostring  = _G.tostring;
+local tonumber  = _G.tonumber;
+local tinsert   = _G.tinsert;
+local tremove   = _G.tremove;
+local string    = _G.string;
+local math      = _G.math;
+local bit       = _G.bit;
+local table     = _G.table;
+--[[ STRING METHODS ]]--
+local format, find, lower, match = string.format, string.find, string.lower, string.match;
+--[[ MATH METHODS ]]--
+local abs, ceil, floor, round = math.abs, math.ceil, math.floor, math.round;  -- Basic
+local fmod, modf, sqrt = math.fmod, math.modf, math.sqrt;   -- Algebra
+local atan2, cos, deg, rad, sin = math.atan2, math.cos, math.deg, math.rad, math.sin;  -- Trigonometry
+local min, huge, random = math.min, math.huge, math.random;  -- Uncommon
+local sqrt2, max = math.sqrt(2), math.max;
+--[[ TABLE METHODS ]]--
+local tcopy, twipe, tsort, tconcat, tdump = table.copy, table.wipe, table.sort, table.concat, table.dump;
+--[[ BINARY METHODS ]]--
+local band = bit.band;
+--BLIZZARD API
+local InCombatLockdown      = _G.InCombatLockdown;
+local CreateFrame           = _G.CreateFrame;
+local SetMapToCurrentZone   = _G.SetMapToCurrentZone;
+local GetTime               = _G.GetTime;
+local GameTooltip           = _G.GameTooltip;
+local UnitName              = _G.UnitName;
+local UnitRace              = _G.UnitRace;
+local UnitAura              = _G.UnitAura;
+local UnitLevel             = _G.UnitLevel;
+local UnitClass             = _G.UnitClass;
+local UnitIsUnit            = _G.UnitIsUnit;
+local UnitExists            = _G.UnitExists;
+local UnitInRaid            = _G.UnitInRaid;
+local UnitInParty           = _G.UnitInParty;
+local UnitGUID              = _G.UnitGUID;
+local UnitIsPVP             = _G.UnitIsPVP;
+local UnitIsDND             = _G.UnitIsDND;
+local UnitIsAFK             = _G.UnitIsAFK;
+local GetItemInfo           = _G.GetItemInfo;
+local GetItemCount          = _G.GetItemCount;
+local GetItemQualityColor   = _G.GetItemQualityColor;
+local ERR_NOT_IN_COMBAT     = _G.ERR_NOT_IN_COMBAT;
+local RAID_CLASS_COLORS     = _G.RAID_CLASS_COLORS;
+local CUSTOM_CLASS_COLORS   = _G.CUSTOM_CLASS_COLORS;
+
+--[[  CONSTANTS ]]--
+
+_G.BINDING_HEADER_SVUITRACK = "Supervillain UI: Track-O-Matic";
+_G.BINDING_NAME_SVUITRACK_DOODAD = "Toggle Tracking Device";
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G["SVUI"];
+local L = SV.L;
+local PLUGIN = select(2, ...)
+local CONFIGS = SV.defaults[PLUGIN.Schema];
+--[[
+##########################################################
+LOCALS
+##########################################################
+]]--
+local NewHook = hooksecurefunc;
+local playerGUID = UnitGUID('player')
+local classColor = RAID_CLASS_COLORS
+--[[
+##########################################################
+BUILD
+##########################################################
+]]--
+function SVUIToggleTrackingDoodad()
+    if(not SVUI_UnitTrackingCompass.Trackable) then
+        SVUI_UnitTrackingCompass.Trackable = true
+        if((UnitInParty("target") or UnitInRaid("target")) and not UnitIsUnit("target", "player")) then
+            SVUI_UnitTrackingCompass:Show()
+        end
+        SV:AddonMessage("Tracking Device |cff00FF00Enabled|r")
+    else
+        SVUI_UnitTrackingCompass.Trackable = false
+        SVUI_UnitTrackingCompass:Hide()
+        SV:AddonMessage("Tracking Device |cffFF0000Disabled|r")
+    end
+end
+--[[
+##########################################################
+MAIN MOVABLE TRACKER
+##########################################################
+]]--
+function PLUGIN:PLAYER_TARGET_CHANGED()
+    if not SVUI_UnitTrackingCompass then return end
+    if((UnitInParty("target") or UnitInRaid("target")) and not UnitIsUnit("target", "player")) then
+        SVUI_UnitTrackingCompass.Trackable = true
+        SVUI_UnitTrackingCompass:Show()
+    else
+        SVUI_UnitTrackingCompass.Trackable = false
+        SVUI_UnitTrackingCompass:Hide()
+    end
+end
+
+local Rotate_Arrow = function(self, angle)
+    local radius, ULx, ULy, LLx, LLy, URx, URy, LRx, LRy
+
+    radius = angle - 0.785398163
+    URx = 0.5 + cos(radius) / sqrt2
+    URy =  0.5 + sin(radius) / sqrt2
+    -- (-1)
+    radius = angle + 0.785398163
+    LRx = 0.5 + cos(radius) / sqrt2
+    LRy =  0.5 + sin(radius) / sqrt2
+    -- 1
+    radius = angle + 2.35619449
+    LLx = 0.5 + cos(radius) / sqrt2
+    LLy =  0.5 + sin(radius) / sqrt2
+    -- 3
+    radius = angle + 3.92699082
+    ULx = 0.5 + cos(radius) / sqrt2
+    ULy =  0.5 + sin(radius) / sqrt2
+    -- 5
+
+    self.Arrow:SetTexCoord(ULx, ULy, LLx, LLy, URx, URy, LRx, LRy);
+end
+
+local UnitTracker_OnUpdate = function(self, elapsed)
+    if self.elapsed and self.elapsed > (self.throttle or 0.08) then
+        if(self.Trackable) then
+            local distance, angle = TriangulateUnit("target", true)
+            if not angle then
+                self.throttle = 4
+                self.Arrow:SetAlpha(0)
+                self.Radar:SetVertexColor(0.8,0.1,0.1,0.15)
+                -- self.Border:SetVertexColor(1,0,0,0.15)
+                self.BG:SetVertexColor(1,0,0,0.15)
+            else
+                self.throttle = 0.08
+                local range = floor(distance)
+                self:Spin(angle)
+                if(range > 0) then
+                    self.Arrow:SetAlpha(1)
+                    self.Radar:SetAlpha(1)
+                    self.Border:Show()
+                    self.BG:SetAlpha(1)
+                    if(range > 100) then
+                        self.Arrow:SetVertexColor(1,0.1,0.1,0.4)
+                        self.Radar:SetVertexColor(0.8,0.1,0.1,0.25)
+                        -- self.Border:SetVertexColor(0.5,0.2,0.1,0.25)
+                        self.BG:SetVertexColor(0.8,0.4,0.1,0.6)
+                    elseif(range > 40) then
+                        self.Arrow:SetVertexColor(1,0.8,0.1,0.6)
+                        self.Radar:SetVertexColor(0.8,0.8,0.1,0.5)
+                        -- self.Border:SetVertexColor(0.5,0.5,0.1,0.8)
+                        self.BG:SetVertexColor(0.4,0.8,0.1,0.5)
+                    else
+                        self.Arrow:SetVertexColor(0.1,1,0.8,0.9)
+                        self.Radar:SetVertexColor(0.1,0.8,0.8,0.75)
+                        -- self.Border:SetVertexColor(0.1,0.5,0.1,1)
+                        self.BG:SetVertexColor(0.1,0.8,0.1,0.75)
+                    end
+                    self.Range:SetText(range)
+                else
+                    self.Arrow:SetVertexColor(0.1,0.1,0.1,0)
+                    self.Radar:SetVertexColor(0.1,0.1,0.1,0)
+                    -- self.Border:SetVertexColor(0.1,0.1,0.1,0)
+                    self.BG:SetVertexColor(0.1,0.1,0.1,0)
+                    self.Arrow:SetAlpha(0)
+                    self.Radar:SetAlpha(0)
+                    self.Border:Hide()
+                    self.BG:SetAlpha(0)
+                    self.Range:SetText("")
+                end
+            end
+        else
+            self:Hide()
+        end
+        self.elapsed = 0
+    else
+        self.elapsed = (self.elapsed or 0) + elapsed
+    end
+end
+
+local QuestTracker_OnUpdate = function(self, elapsed)
+    if self.elapsed and self.elapsed > (self.throttle or 0.08) then
+        if(self.questID) then
+            local distance, angle = TriangulateQuest(self.questID)
+            --print(angle)
+            if not angle then
+                self.questID = nil
+                self.throttle = 4
+                self.Arrow:SetAlpha(0)
+                self.BG:SetVertexColor(0.1,0.1,0.1,0)
+                self.Range:SetTextColor(1,1,1,1)
+            else
+                self.throttle = 0.08
+                local range = floor(distance)
+                self:Spin(angle)
+                if(range > 25) then
+                    self.Arrow:SetAlpha(1)
+                    self.BG:SetAlpha(1)
+                    if(range > 100) then
+                        self.BG:SetVertexColor(0.8,0.1,0.1,1)
+                        self.Range:SetTextColor(1,0.5,0.5,1)
+                    elseif(range > 40) then
+                        self.BG:SetVertexColor(0.8,0.8,0.1,1)
+                        self.Range:SetTextColor(1,1,0.5,1)
+                    else
+                        self.BG:SetVertexColor(0.1,0.8,0.1,1)
+                        self.Range:SetTextColor(0.5,1,0.5,1)
+                    end
+                    self.Range:SetText("Distance: " .. range .. " Yards")
+                else
+                    self.BG:SetVertexColor(0.1,0.1,0.1,0)
+                    self.Range:SetTextColor(1,1,1,1)
+                    self.Arrow:SetAlpha(0)
+                    self.BG:SetAlpha(0)
+                    self.Range:SetText("")
+                end
+            end
+        else
+            self:Hide()
+            self:SetScript("OnUpdate", nil)
+        end
+        self.elapsed = 0
+    else
+        self.elapsed = (self.elapsed or 0) + elapsed
+    end
+end
+
+local StartTrackingQuest = function(self, questID)
+    if(questID) then
+        if(not WorldMapFrame:IsShown()) then
+            SetMapToCurrentZone()
+        end
+        self.Compass.questID = questID
+        self.Compass:Show()
+        self.Compass:SetScript("OnUpdate", QuestTracker_OnUpdate)
+    else
+        self.Compass.questID = nil
+        self.Compass:Hide()
+        self.Compass:SetScript("OnUpdate", nil)
+    end
+end
+
+function SV:AddQuestCompass(parent, anchor)
+    if anchor.Compass then return end
+    local compass = CreateFrame("Frame", nil, parent)
+    compass:SetAllPoints(anchor)
+    compass:SetFrameLevel(anchor:GetFrameLevel() + 99)
+    compass.BG = compass:CreateTexture(nil, 'BACKGROUND')
+    compass.BG:InsetPoints(compass)
+    compass.BG:SetTexture([[Interface\AddOns\SVUI_TrackOMatic\artwork\QUEST-COMPASS-BG]])
+    compass.BG:SetVertexColor(0.1, 0.3, 0.4)
+    compass.Arrow = compass:CreateTexture(nil, 'BORDER')
+    compass.Arrow:SetAllPoints(compass)
+    compass.Arrow:SetTexture([[Interface\AddOns\SVUI_TrackOMatic\artwork\QUEST-COMPASS-ARROW]])
+    compass.Range = compass:CreateFontString(nil, 'ARTWORK')
+    compass.Range:SetPoint("CENTER", compass, "CENTER", 0, 0)
+    compass.Range:SetFontObject(SVUI_Font_Tracking);
+    compass.Range:SetTextColor(1, 1, 1, 0.75)
+    compass.Spin = Rotate_Arrow
+    compass:Hide()
+
+    anchor.Compass = compass
+    anchor.StartTracking = StartTrackingQuest
+    anchor.StopTracking = function(self) self.Compass:SetScript("OnUpdate", nil) end
+end
+--[[
+##########################################################
+CORE
+##########################################################
+]]--
+function PLUGIN:ReLoad()
+    local frameSize = CONFIGS.size or 70
+    local arrowSize = frameSize * 0.5
+    local frame = _G["SVUI_UnitTrackingCompass"]
+
+    frame:SetSize(frameSize, frameSize)
+    frame.Arrow:SetSize(arrowSize, arrowSize)
+end
+
+function PLUGIN:Load()
+    CONFIGS = SV.db[self.Schema];
+    local UNIT_TRACKER = SVUI_UnitTrackingCompass
+    local TRACKER_TARGET = SVUI_Target
+
+    if(UNIT_TRACKER) then
+        UNIT_TRACKER.Border:SetGradient(unpack(SV.media.gradient.special))
+        UNIT_TRACKER.Arrow:SetVertexColor(0.1, 0.8, 0.8)
+        UNIT_TRACKER.Range:SetTextColor(1, 1, 1, 0.75)
+        UNIT_TRACKER.Spin = Rotate_Arrow
+
+        UNIT_TRACKER:RegisterForDrag("LeftButton");
+        UNIT_TRACKER:SetScript("OnUpdate", UnitTracker_OnUpdate)
+
+        SV.Animate:Orbit(UNIT_TRACKER.Radar, 8, true)
+
+        UNIT_TRACKER:Hide()
+
+        if(TRACKER_TARGET) then
+            UNIT_TRACKER:SetParent(TRACKER_TARGET)
+        end
+        UNIT_TRACKER:SetPoint("CENTER", UIParent, "CENTER", 0, -200)
+
+        self:RegisterEvent("PLAYER_TARGET_CHANGED")
+    end
+
+    self:EnableGPS()
+end
diff --git a/SVUI_TrackOMatic/SVUI_TrackOMatic.toc b/SVUI_TrackOMatic/SVUI_TrackOMatic.toc
new file mode 100644
index 0000000..eb6b985
--- /dev/null
+++ b/SVUI_TrackOMatic/SVUI_TrackOMatic.toc
@@ -0,0 +1,16 @@
+## Interface: 60000
+## Author: S.Jackson
+## Version: 1.0.0
+## Title: |cffFF9900SVUI Plugin: |r|cffFF69B4Track-O-Matic|r
+## Notes: Supervillain UI [|cff9911FFRaid & Party Member Tracking|r].
+## RequiredDeps: SVUI_!Core
+## OptionalDeps: LibSharedMedia-3.0
+## X-SVUIName: Track-O-Matic
+## X-SVUISchema: TrackOMatic
+## X-Email: munglunch@gmail.com
+## X-Website: http://www.supervillainui.com
+## X-Donate: PayPal:munglunch@gmail.com
+## X-License: All Rights Reserved
+## X-Category: Interface Enhancements
+
+SVUI_TrackOMatic.xml
diff --git a/SVUI_TrackOMatic/SVUI_TrackOMatic.xml b/SVUI_TrackOMatic/SVUI_TrackOMatic.xml
new file mode 100644
index 0000000..8c648c8
--- /dev/null
+++ b/SVUI_TrackOMatic/SVUI_TrackOMatic.xml
@@ -0,0 +1,82 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+    <Font name="SVUI_Font_Tracking" font="Fonts\skurri.ttf" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="12"/>
+        </FontHeight>
+    </Font>
+	  <Frame name="SVUI_UnitTrackingCompass" movable="true" frameStrata="DIALOG" hidden="true">
+        <Size x="70" y="70"/>
+        <Anchors>
+            <Anchor point="CENTER" relativeTo="UIParent" relativePoint="CENTER"/>
+        </Anchors>
+        <Layers>
+            <Layer level="BACKGROUND">
+                <Texture parentKey="BG" setAllPoints="true" file="Interface\AddOns\SVUI_TrackOMatic\artwork\DOODAD-BG"/>
+            </Layer>
+            <Layer level="BORDER">
+                <Texture parentKey="Border" setAllPoints="true" file="Interface\AddOns\SVUI_TrackOMatic\artwork\DOODAD-BORDER"/>
+                <Texture parentKey="Arrow" file="Interface\AddOns\SVUI_TrackOMatic\artwork\DOODAD-ARROW">
+                    <Size x="35" y="35"/>
+                    <Anchors>
+                        <Anchor point="CENTER" relativeTo="$parent" relativePoint="CENTER"/>
+                    </Anchors>
+                </Texture>
+            </Layer>
+            <Layer level="OVERLAY">
+                <Texture parentKey="Radar" setAllPoints="true" file="Interface\AddOns\SVUI_TrackOMatic\artwork\DOODAD-RADAR"/>
+            </Layer>
+            <Layer level="ARTWORK">
+                <FontString parentKey="Range" inherits="SVUI_Font_Tracking">
+                    <Anchors>
+                        <Anchor point="TOP" relativeTo="$parent" relativePoint="BOTTOM"/>
+                    </Anchors>
+                </FontString>
+            </Layer>
+        </Layers>
+        <Scripts>
+            <OnDragStart>
+                _G["SVUI_UnitTrackingCompass"].moving = true;
+                _G["SVUI_UnitTrackingCompass"]:StartMoving();
+            </OnDragStart>
+            <OnDragStop>
+                _G["SVUI_UnitTrackingCompass"].moving = nil;
+                _G["SVUI_UnitTrackingCompass"]:StopMovingOrSizing();
+            </OnDragStop>
+        </Scripts>
+    </Frame>
+
+    <Frame name="SVUI_TrackingCompassTemplate" frameStrata="DIALOG" virtual="true" >
+        <Layers>
+            <Layer level="BACKGROUND">
+                <Texture parentKey="BG" setAllPoints="true" file="Interface\AddOns\SVUI_TrackOMatic\artwork\QUEST-COMPASS-BG"/>
+            </Layer>
+            <Layer level="BORDER">
+                <Texture parentKey="Arrow" file="Interface\AddOns\SVUI_TrackOMatic\artwork\QUEST-COMPASS-ARROW">
+                    <Anchors>
+                        <Anchor point="CENTER" relativeTo="$parent" relativePoint="CENTER"/>
+                    </Anchors>
+                </Texture>
+            </Layer>
+            <Layer level="OVERLAY">
+                <Texture parentKey="Radar" setAllPoints="true" file="Interface\AddOns\SVUI_TrackOMatic\artwork\DOODAD-RADAR"/>
+            </Layer>
+            <Layer level="ARTWORK">
+                <FontString parentKey="Range" inherits="SVUI_Font_Tracking">
+                    <Anchors>
+                        <Anchor point="CENTER" relativeTo="$parent" relativePoint="CENTER"/>
+                    </Anchors>
+                </FontString>
+            </Layer>
+        </Layers>
+    </Frame>
+
+    <Script file='Loader.lua'/>
+    <Include file='components\_load.xml'/>
+    <Script file='SVUI_TrackOMatic.lua'/>
+</Ui>
diff --git a/SVUI_TrackOMatic/artwork/DOODAD-ARROW.blp b/SVUI_TrackOMatic/artwork/DOODAD-ARROW.blp
new file mode 100644
index 0000000..b20f63d
Binary files /dev/null and b/SVUI_TrackOMatic/artwork/DOODAD-ARROW.blp differ
diff --git a/SVUI_TrackOMatic/artwork/DOODAD-BG.blp b/SVUI_TrackOMatic/artwork/DOODAD-BG.blp
new file mode 100644
index 0000000..7f60ca2
Binary files /dev/null and b/SVUI_TrackOMatic/artwork/DOODAD-BG.blp differ
diff --git a/SVUI_TrackOMatic/artwork/DOODAD-BORDER.blp b/SVUI_TrackOMatic/artwork/DOODAD-BORDER.blp
new file mode 100644
index 0000000..c69bd6a
Binary files /dev/null and b/SVUI_TrackOMatic/artwork/DOODAD-BORDER.blp differ
diff --git a/SVUI_TrackOMatic/artwork/DOODAD-RADAR.blp b/SVUI_TrackOMatic/artwork/DOODAD-RADAR.blp
new file mode 100644
index 0000000..53d920b
Binary files /dev/null and b/SVUI_TrackOMatic/artwork/DOODAD-RADAR.blp differ
diff --git a/SVUI_TrackOMatic/artwork/GPS-ARROW.blp b/SVUI_TrackOMatic/artwork/GPS-ARROW.blp
new file mode 100644
index 0000000..9fb0a32
Binary files /dev/null and b/SVUI_TrackOMatic/artwork/GPS-ARROW.blp differ
diff --git a/SVUI_TrackOMatic/artwork/QUEST-COMPASS-ARROW.blp b/SVUI_TrackOMatic/artwork/QUEST-COMPASS-ARROW.blp
new file mode 100644
index 0000000..9ebcfd2
Binary files /dev/null and b/SVUI_TrackOMatic/artwork/QUEST-COMPASS-ARROW.blp differ
diff --git a/SVUI_TrackOMatic/artwork/QUEST-COMPASS-BG.blp b/SVUI_TrackOMatic/artwork/QUEST-COMPASS-BG.blp
new file mode 100644
index 0000000..da92dab
Binary files /dev/null and b/SVUI_TrackOMatic/artwork/QUEST-COMPASS-BG.blp differ
diff --git a/SVUI_TrackOMatic/components/_load.xml b/SVUI_TrackOMatic/components/_load.xml
new file mode 100644
index 0000000..620029a
--- /dev/null
+++ b/SVUI_TrackOMatic/components/_load.xml
@@ -0,0 +1,5 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+	<Script file="triangulate.lua"/>
+	<Script file="unitframe_gps.lua"/>
+	<Script file="guides.lua"/>
+</Ui>
diff --git a/SVUI_TrackOMatic/components/guides.lua b/SVUI_TrackOMatic/components/guides.lua
new file mode 100644
index 0000000..8e329a3
--- /dev/null
+++ b/SVUI_TrackOMatic/components/guides.lua
@@ -0,0 +1,84 @@
+--[[
+##########################################################
+S V U I   By: S.Jackson
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack            = _G.unpack;
+local select            = _G.select;
+local assert            = _G.assert;
+local type              = _G.type;
+local error             = _G.error;
+local pcall             = _G.pcall;
+local print             = _G.print;
+local ipairs            = _G.ipairs;
+local pairs             = _G.pairs;
+local next              = _G.next;
+local tostring          = _G.tostring;
+local tonumber          = _G.tonumber;
+local collectgarbage    = _G.collectgarbage;
+local tinsert   = _G.tinsert;
+local tremove   = _G.tremove;
+local string    = _G.string;
+local math      = _G.math;
+local bit       = _G.bit;
+local table     = _G.table;
+--[[ STRING METHODS ]]--
+local format, find, lower, match = string.format, string.find, string.lower, string.match;
+--[[ MATH METHODS ]]--
+local abs, ceil, floor, round = math.abs, math.ceil, math.floor, math.round;  -- Basic
+local fmod, modf, sqrt = math.fmod, math.modf, math.sqrt;   -- Algebra
+local atan2, cos, deg, rad, sin = math.atan2, math.cos, math.deg, math.rad, math.sin;  -- Trigonometry
+local min, huge, random = math.min, math.huge, math.random;  -- Uncommon
+local sqrt2, max = math.sqrt(2), math.max;
+--[[ TABLE METHODS ]]--
+local tcopy, twipe, tsort, tconcat, tdump = table.copy, table.wipe, table.sort, table.concat, table.dump;
+--[[ BINARY METHODS ]]--
+local band = bit.band;
+--BLIZZARD API
+local InCombatLockdown      = _G.InCombatLockdown;
+local CreateFrame           = _G.CreateFrame;
+local IsInRaid              = _G.IsInRaid;
+local IsInGroup             = _G.IsInGroup;
+local IsInInstance          = _G.IsInInstance;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G["SVUI"];
+local L = SV.L;
+local PLUGIN = select(2, ...);
+local CONFIGS = SV.defaults[PLUGIN.Schema];
+
+local JOURNAL_CACHE = {};
+
+local function CacheEncounterData()
+	local instanceID = EJ_GetCurrentInstance()
+	local difficultyID = GetDungeonDifficultyID()
+	EJ_SetDifficulty(difficultyID)
+	local bossIndex = 1;
+	local _, _, encounterID = EJ_GetEncounterInfoByIndex(bossIndex);
+	while encounterID do
+		local stack, encounter, _, _, curSectionID = {}, EJ_GetEncounterInfo(encounterID);
+
+		repeat
+			local title, desc, _, _, _, siblingID, nextSectionID = EJ_GetSectionInfo(curSectionID)
+			JOURNAL_CACHE[curSectionID] = {title, desc}
+			table.insert(stack, siblingID)
+			table.insert(stack, nextSectionID)
+			curSectionID = table.remove(stack)
+		until not curSectionID
+
+		bossIndex = bossIndex + 1;
+		_, _, encounterID = EJ_GetEncounterInfoByIndex(bossIndex);
+	end
+end
+
+function PLUGIN:InitializeGuides()
+	LoadAddOn("Blizzard_EncounterJournal")
+	CacheEncounterData()
+end
diff --git a/SVUI_TrackOMatic/components/triangulate.lua b/SVUI_TrackOMatic/components/triangulate.lua
new file mode 100644
index 0000000..87d8c0e
--- /dev/null
+++ b/SVUI_TrackOMatic/components/triangulate.lua
@@ -0,0 +1,496 @@
+--[[
+##########################################################
+S V U I   By: S.Jackson
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack    = _G.unpack;
+local select    = _G.select;
+local pairs     = _G.pairs;
+local type      = _G.type;
+local tostring  = _G.tostring;
+local tonumber  = _G.tonumber;
+local rawset    = _G.rawset;
+local rawget    = _G.rawget;
+local tinsert   = _G.tinsert;
+local tremove   = _G.tremove;
+local string    = _G.string;
+local math      = _G.math;
+local bit       = _G.bit;
+local table     = _G.table;
+--[[ STRING METHODS ]]--
+local format, find, lower, match = string.format, string.find, string.lower, string.match;
+--[[ MATH METHODS ]]--
+local abs, ceil, floor, round = math.abs, math.ceil, math.floor, math.round;  -- Basic
+local fmod, modf, sqrt = math.fmod, math.modf, math.sqrt;   -- Algebra
+local atan2, cos, deg, rad, sin = math.atan2, math.cos, math.deg, math.rad, math.sin;  -- Trigonometry
+local min, huge, random = math.min, math.huge, math.random;  -- Uncommon
+local sqrt2, max = math.sqrt(2), math.max;
+--[[ TABLE METHODS ]]--
+local tcopy, twipe, tsort, tconcat, tdump = table.copy, table.wipe, table.sort, table.concat, table.dump;
+--[[ BINARY METHODS ]]--
+local band = bit.band;
+--BLIZZARD API
+local InCombatLockdown      = _G.InCombatLockdown;
+local SetMapZoom            = _G.SetMapZoom;
+local SetMapToCurrentZone   = _G.SetMapToCurrentZone;
+local ZoomOut               = _G.ZoomOut;
+local SetMapByID            = _G.SetMapByID;
+local SetDungeonMapLevel    = _G.SetDungeonMapLevel;
+local QuestPOIGetIconInfo   = _G.QuestPOIGetIconInfo;
+local WORLDMAP_WORLD_ID     = _G.WORLDMAP_WORLD_ID;
+local WorldMapFrame         = _G.WorldMapFrame;
+local GetCurrentMapDungeonLevel   = _G.GetCurrentMapDungeonLevel;
+--[[
+##########################################################
+LOCALS
+##########################################################
+]]--
+local radian90 = (3.141592653589793 / 2) * -1;
+local WORLDMAPAREA_DEFAULT_DUNGEON_FLOOR_IS_TERRAIN = 0x00000004
+local WORLDMAPAREA_VIRTUAL_CONTINENT = 0x00000008
+local DUNGEONMAP_MICRO_DUNGEON = 0x00000001
+--[[
+##########################################################
+LOCALIZED BLIZZARD FUNCTIONS
+##########################################################
+]]--
+local GetMapInfo = GetMapInfo
+local GetMapZones = GetMapZones
+local GetPlayerFacing = GetPlayerFacing
+local GetCurrentMapZone = GetCurrentMapZone
+local GetCurrentMapAreaID = GetCurrentMapAreaID
+local GetPlayerMapPosition = GetPlayerMapPosition
+local GetNumDungeonMapLevels = GetNumDungeonMapLevels
+local GetCurrentMapContinent = GetCurrentMapContinent
+local GetWorldMapTransformInfo = GetWorldMapTransformInfo
+--[[
+##########################################################
+MAPPING DATA STORAGE
+##########################################################
+]]--
+local DUNGEON_DATA = {};
+local GEOGRAPHICAL_DATA = {
+    [0] = {
+        height = 22266.74312,
+        system = -1,
+        width = 33400.121,
+        xOffset = 0,
+        yOffset = 0,
+        [1] = {
+            xOffset = -10311.71318,
+            yOffset = -19819.33898,
+            scale = 0.56089997291565,
+        },
+        [0] = {
+            xOffset = -48226.86993,
+            yOffset = -16433.90283,
+            scale = 0.56300002336502,
+        },
+        [571] = {
+            xOffset = -29750.89905,
+            yOffset = -11454.50802,
+            scale = 0.5949000120163,
+        },
+        [870] = {
+            xOffset = -27693.71178,
+            yOffset = -29720.0585,
+            scale = 0.65140002965927,
+        },
+    },
+}
+
+
+do
+    local backup_cache, temp_cache, swap_cache = {}, {}, {};
+
+    local meta_backup = {
+        xOffset = 0,
+        height = 1,
+        yOffset = 0,
+        width = 1,
+        __index = function(t, k)
+            if(type(k) == "number") then
+                return backup_cache;
+            else
+                return rawget(backup_cache, k);
+            end
+        end
+    };
+
+    setmetatable(backup_cache, meta_backup);
+    setmetatable(GEOGRAPHICAL_DATA, backup_cache);
+
+    local transforms = GetWorldMapTransforms()
+
+    for _,id in ipairs(transforms) do
+        local terrain, newterrain, _, _, transformMinY, transformMaxY, transformMinX, transformMaxX, offsetY, offsetX = GetWorldMapTransformInfo(id)
+        if ( offsetX ~= 0 or offsetY ~= 0 ) then
+            swap_cache[id] = {
+                terrain = terrain,
+                newterrain = newterrain,
+                BRy = -transformMinY,
+                TLy = -transformMaxY,
+                BRx = -transformMinX,
+                TLx = -transformMaxX,
+                offsetY = offsetY,
+                offsetX = offsetX,
+            }
+        end
+    end
+
+    local function SetTempData()
+        local map = {}
+        local mapName = GetMapInfo();
+        local id = GetCurrentMapAreaID();
+        local numFloors = GetNumDungeonMapLevels();
+        map.mapName = mapName;
+        map.cont = (GetCurrentMapContinent()) or -100;
+        map.zone = (GetCurrentMapZone()) or -100;
+        map.numFloors = numFloors;
+        local _, TLx, TLy, BRx, BRy = GetCurrentMapZone();
+        if(TLx and TLy and BRx and BRy and (TLx~=0 or TLy~=0 or BRx~=0 or BRy~=0)) then
+            map[0] = {};
+            map[0].TLx = TLx;
+            map[0].TLy = TLy;
+            map[0].BRx = BRx;
+            map[0].BRy = BRy;
+        end
+        if(not map[0] and numFloors == 0 and (GetCurrentMapDungeonLevel()) == 1) then
+            numFloors = 1;
+            map.hiddenFloor = true;
+        end
+        if(numFloors > 0) then
+            for i = 1, numFloors do
+                SetDungeonMapLevel(i);
+                local _, TLx, TLy, BRx, BRy = GetCurrentMapDungeonLevel();
+                if(TLx and TLy and BRx and BRy) then
+                    map[i] = {};
+                    map[i].TLx = TLx;
+                    map[i].TLy = TLy;
+                    map[i].BRx = BRx;
+                    map[i].BRy = BRy;
+                end
+            end
+        end
+
+        temp_cache[id] = map;
+    end
+
+    local continent_map_data = { GetMapContinents() };
+
+    for continent in pairs(continent_map_data) do
+        local zone_map_data = { GetMapZones(continent) };
+        continent_map_data[continent] = zone_map_data;
+        local pass, error = pcall(SetMapZoom, continent, 0)
+        if(pass) then
+            zone_map_data[0] = GetCurrentMapAreaID();
+            SetTempData();
+            for zone in ipairs(zone_map_data) do
+                SetMapZoom(continent, zone);
+                zone_map_data[zone] = GetCurrentMapAreaID();
+                SetTempData();
+            end
+        end
+    end
+
+    local area_maps = GetAreaMaps()
+
+    for _,id in ipairs(area_maps) do
+        if((not temp_cache[id]) and SetMapByID(id)) then
+            SetTempData();
+        end
+    end
+
+    for id, map in pairs(temp_cache) do
+        local terrain, _, _, _, _, _, _, _, _, flags = GetAreaMapInfo(id)
+        local origin = terrain;
+        local data = GEOGRAPHICAL_DATA[id];
+        if not (data) then data = {}; end
+        if(map.numFloors > 0 or map.hiddenFloor) then
+            for f, coords in pairs(map) do
+                if(type(f) == "number" and f > 0) then
+                    if not (data[f]) then
+                        data[f] = {};
+                    end
+                    local flr = data[f]
+                    local TLx, TLy, BRx, BRy = -coords.BRx, -coords.BRy, -coords.TLx, -coords.TLy
+                    if not (flr.width) then
+                        flr.width = BRx - TLx
+                    end
+                    if not (flr.height) then
+                        flr.height = BRy - TLy
+                    end
+                    if not (flr.xOffset) then
+                        flr.xOffset = TLx
+                    end
+                    if not (flr.yOffset) then
+                        flr.yOffset = TLy
+                    end
+                end
+            end
+            for f = 1, map.numFloors do
+                if not (data[f]) then
+                    if(f == 1 and map[0] and map[0].TLx and map[0].TLy and map[0].BRx and map[0].BRy and
+                      band(flags, WORLDMAPAREA_DEFAULT_DUNGEON_FLOOR_IS_TERRAIN) == WORLDMAPAREA_DEFAULT_DUNGEON_FLOOR_IS_TERRAIN) then
+                        data[f] = {};
+                        local flr = data[f]
+                        local coords = map[0]
+                        local TLx, TLy, BRx, BRy = -coords.TLx, -coords.TLy, -coords.BRx, -coords.BRy
+                        flr.width = BRx - TLx
+                        flr.height = BRy - TLy
+                        flr.xOffset = TLx
+                        flr.yOffset = TLy
+                    end
+                end
+            end
+            if(map.hiddenFloor) then
+                data.width = data[1].width
+                data.height = data[1].height
+                data.xOffset = data[1].xOffset
+                data.yOffset = data[1].yOffset
+            end
+        else
+            local coords = map[0]
+            if(coords ~= nil) then
+                local TLx, TLy, BRx, BRy = -coords.TLx, -coords.TLy, -coords.BRx, -coords.BRy
+                for _, trans in pairs(swap_cache) do
+                    if(trans.terrain == terrain) then
+                        if((trans.TLx < TLx and BRx < trans.BRx) and (trans.TLy < TLy and BRy < trans.BRy)) then
+                            TLx = TLx - trans.offsetX;
+                            BRx = BRx - trans.offsetX;
+                            BRy = BRy - trans.offsetY;
+                            TLy = TLy - trans.offsetY;
+                            terrain = trans.newterrain;
+                            break;
+                        end
+                    end
+                end
+                if not (TLx==0 and TLy==0 and BRx==0 and BRy==0) then
+                    if not (TLx < BRx) then
+                        printError("Bad x-axis Orientation (Zone): ", id, TLx, BRx);
+                    end
+                    if not (TLy < BRy) then
+                        printError("Bad y-axis Orientation (Zone): ", id, TLy, BRy);
+                    end
+                end
+                if not (data.width) then
+                    data.width = BRx - TLx
+                end
+                if not (data.height) then
+                    data.height = BRy - TLy
+                end
+                if not (data.xOffset) then
+                    data.xOffset = TLx
+                end
+                if not (data.yOffset) then
+                    data.yOffset = TLy
+                end
+            end
+        end
+
+        if(not next(data, nil)) then
+            data = { xOffset = 0, height = 1, yOffset = 0, width = 1 };
+        end
+
+        if(not data.origin) then
+            data.origin = origin;
+        end
+
+        GEOGRAPHICAL_DATA[id] = data;
+
+        if(data and data ~= backup_cache) then
+            if(not data.system) then
+                data.system = terrain;
+            end
+            if(map.cont > 0 and map.zone > 0) then
+                DUNGEON_DATA[terrain] = {}
+            end
+            setmetatable(data, backup_cache);
+        end
+    end
+end
+
+local function GetCoordinates(map, mapFloor, x, y)
+    if not map then return 0,0 end
+    if (mapFloor ~= 0) then
+        map = rawget(map, mapFloor) or DUNGEON_DATA[map.origin][mapFloor];
+    end
+    if not map then return 0,0 end
+    x = x * map.width + map.xOffset;
+    y = y * map.height + map.yOffset;
+    return x, y;
+end
+
+local function GetDistance(map1, floor1, x1, y1, map2, floor2, x2, y2)
+    if not (map1 and map2) then return end
+    floor1 = floor1 or min(#GEOGRAPHICAL_DATA[map1], 1);
+    floor2 = floor2 or min(#GEOGRAPHICAL_DATA[map2], 1);
+    local dist, xDelta, yDelta, angle;
+    if(map1 == map2 and floor1 == floor2) then
+        local chunk = GEOGRAPHICAL_DATA[map1];
+        if(not chunk) then
+            xDelta = 0;
+            yDelta = 0;
+        else
+            local tmp = chunk
+            if(floor1 ~= 0) then
+                tmp = rawget(chunk, floor1)
+            end
+            local w,h = 1,1
+            if(not tmp) then
+                if(DUNGEON_DATA[chunk.origin] and DUNGEON_DATA[chunk.origin][floor1]) then
+                    chunk = DUNGEON_DATA[chunk.origin][floor1]
+                    w = chunk.width
+                    h = chunk.height
+                else
+                    w = 1
+                    h = 1
+                end
+            else
+                w = chunk.width
+                h = chunk.height
+            end
+            xDelta = (x2 - x1) * (w or 1);
+            yDelta = (y2 - y1) * (h or 1);
+        end
+    else
+        local mapX = GEOGRAPHICAL_DATA[map1];
+        local mapY = GEOGRAPHICAL_DATA[map2];
+
+        if(mapX.system == mapY.system) then
+            x1, y1 = GetCoordinates(mapX, floor1, x1, y1);
+            x2, y2 = GetCoordinates(mapY, floor2, x2, y2);
+            xDelta = (x2 - x1);
+            yDelta = (y2 - y1);
+        else
+            local s1 = mapX.system;
+            local s2 = mapY.system;
+            if((mapX==0 or GEOGRAPHICAL_DATA[0][s1]) and (mapY == 0 or GEOGRAPHICAL_DATA[0][s2])) then
+                x1, y1 = GetCoordinates(mapX, floor1, x1, y1);
+                x2, y2 = GetCoordinates(mapY, floor2, x2, y2);
+                if(mapX ~= 0) then
+                    local cont1 = GEOGRAPHICAL_DATA[0][s1];
+                    x1 = (x1 - cont1.xOffset) * cont1.scale;
+                    y1 = (y1 - cont1.yOffset) * cont1.scale;
+                end
+                if(mapY ~= 0) then
+                    local cont2 = GEOGRAPHICAL_DATA[0][s2];
+                    x2 = (x2 - cont2.xOffset) * cont2.scale;
+                    y2 = (y2 - cont2.yOffset) * cont2.scale;
+                end
+                xDelta = x2 - x1;
+                yDelta = y2 - y1;
+            end
+        end
+    end
+
+    if(xDelta and yDelta) then
+        local playerAngle = GetPlayerFacing()
+        dist = sqrt(xDelta * xDelta + yDelta * yDelta);
+        angle = (radian90 - playerAngle) - atan2(yDelta, xDelta)
+    end
+
+    return dist, angle;
+end
+
+_G.TriangulateUnit = function(unit, noMapLocation)
+    if(WorldMapFrame and WorldMapFrame:IsShown()) then return end
+
+    local plot1, plot2, plot3, plot4, plot5, plot6, plot7, plot8;
+
+    plot3, plot4 = GetPlayerMapPosition("player");
+
+    if(plot3 <= 0 and plot4 <= 0) then
+        SetMapToCurrentZone();
+        plot3, plot4 = GetPlayerMapPosition("player");
+        if(plot3 <= 0 and plot4 <= 0) then
+                if(ZoomOut()) then
+                elseif(GetCurrentMapZone() ~= WORLDMAP_WORLD_ID) then
+                    SetMapZoom(GetCurrentMapContinent());
+                else
+                    SetMapZoom(WORLDMAP_WORLD_ID);
+                end
+            plot3, plot4 = GetPlayerMapPosition("player");
+            if(plot3 <= 0 and plot4 <= 0) then
+                return;
+            end
+        end
+    end
+
+    plot1 = GetCurrentMapAreaID()
+    plot2 = GetCurrentMapDungeonLevel()
+    plot7, plot8 = GetPlayerMapPosition(unit);
+
+    if(noMapLocation and (plot7 <= 0 and plot8 <= 0)) then
+        local lastMapID, lastFloor = GetCurrentMapAreaID(), GetCurrentMapDungeonLevel();
+        SetMapToCurrentZone();
+        plot7, plot8 = GetPlayerMapPosition(unit);
+
+        if(plot7 <= 0 and plot8 <= 0) then
+                if(ZoomOut()) then
+                elseif(GetCurrentMapZone() ~= WORLDMAP_WORLD_ID) then
+                    SetMapZoom(GetCurrentMapContinent());
+                else
+                    SetMapZoom(WORLDMAP_WORLD_ID);
+                end
+            plot7, plot8 = GetPlayerMapPosition(unit);
+            if(plot7 <= 0 and plot8 <= 0) then
+                return;
+            end
+        end
+
+        plot5, plot6 = GetCurrentMapAreaID(), GetCurrentMapDungeonLevel();
+
+        if(plot5 ~= lastMapID or plot6 ~= lastFloor) then
+            SetMapByID(lastMapID);
+            SetDungeonMapLevel(lastFloor);
+        end
+
+        return GetDistance(plot1, plot2, plot3, plot4, plot5, plot6, plot7, plot8)
+    end
+
+    return GetDistance(plot1, plot2, plot3, plot4, plot1, plot2, plot7, plot8)
+end
+
+--QuestPOIGetIconInfo(questID)
+
+_G.TriangulateQuest = function(questID)
+    --print(questID)
+    if(WorldMapFrame and WorldMapFrame:IsShown()) then return end
+
+    local _, debug, plot1, plot2, plot3, plot4, plot5, plot6, plot7, plot8;
+
+    plot3, plot4 = GetPlayerMapPosition("player");
+
+    if(plot3 <= 0 and plot4 <= 0) then
+        SetMapToCurrentZone();
+        plot3, plot4 = GetPlayerMapPosition("player");
+        if(plot3 <= 0 and plot4 <= 0) then
+                if(ZoomOut()) then
+                elseif(GetCurrentMapZone() ~= WORLDMAP_WORLD_ID) then
+                    SetMapZoom(GetCurrentMapContinent());
+                else
+                    SetMapZoom(WORLDMAP_WORLD_ID);
+                end
+            plot3, plot4 = GetPlayerMapPosition("player");
+            if(plot3 <= 0 and plot4 <= 0) then
+                return;
+            end
+        end
+    end
+
+    plot1 = GetCurrentMapAreaID()
+    plot2 = GetCurrentMapDungeonLevel()
+    _, plot7, plot8, _ = QuestPOIGetIconInfo(questID);
+    if((not plot7) or (not plot8)) then
+        local mapID, floorNumber = GetQuestWorldMapAreaID(questID)
+        SetMapByID(mapID)
+        _, plot7, plot8, _ = QuestPOIGetIconInfo(questID);
+        if((not plot7) or (not plot8)) then return end
+    end
+    return GetDistance(plot1, plot2, plot3, plot4, plot1, plot2, plot7, plot8)
+end
diff --git a/SVUI_TrackOMatic/components/unitframe_gps.lua b/SVUI_TrackOMatic/components/unitframe_gps.lua
new file mode 100644
index 0000000..21609d0
--- /dev/null
+++ b/SVUI_TrackOMatic/components/unitframe_gps.lua
@@ -0,0 +1,351 @@
+--[[
+##########################################################
+S V U I   By: S.Jackson
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack            = _G.unpack;
+local select            = _G.select;
+local assert            = _G.assert;
+local type              = _G.type;
+local error             = _G.error;
+local pcall             = _G.pcall;
+local print             = _G.print;
+local ipairs            = _G.ipairs;
+local pairs             = _G.pairs;
+local next              = _G.next;
+local tostring          = _G.tostring;
+local tonumber          = _G.tonumber;
+local collectgarbage    = _G.collectgarbage;
+local tinsert   = _G.tinsert;
+local tremove   = _G.tremove;
+local string    = _G.string;
+local math      = _G.math;
+local bit       = _G.bit;
+local table     = _G.table;
+--[[ STRING METHODS ]]--
+local format, find, lower, match = string.format, string.find, string.lower, string.match;
+--[[ MATH METHODS ]]--
+local abs, ceil, floor, round = math.abs, math.ceil, math.floor, math.round;  -- Basic
+local fmod, modf, sqrt = math.fmod, math.modf, math.sqrt;   -- Algebra
+local atan2, cos, deg, rad, sin = math.atan2, math.cos, math.deg, math.rad, math.sin;  -- Trigonometry
+local min, huge, random = math.min, math.huge, math.random;  -- Uncommon
+local sqrt2, max = math.sqrt(2), math.max;
+--[[ TABLE METHODS ]]--
+local tcopy, twipe, tsort, tconcat, tdump = table.copy, table.wipe, table.sort, table.concat, table.dump;
+--[[ BINARY METHODS ]]--
+local band = bit.band;
+--BLIZZARD API
+local InCombatLockdown      = _G.InCombatLockdown;
+local CreateFrame           = _G.CreateFrame;
+local IsInRaid              = _G.IsInRaid;
+local IsInGroup             = _G.IsInGroup;
+local IsInInstance          = _G.IsInInstance;
+local UnitName              = _G.UnitName;
+local UnitAura              = _G.UnitAura;
+local UnitBuff              = _G.UnitBuff;
+local UnitStat              = _G.UnitStat;
+local UnitRace              = _G.UnitRace;
+local UnitLevel             = _G.UnitLevel;
+local UnitClass             = _G.UnitClass;
+local UnitReaction          = _G.UnitReaction;
+local UnitExists            = _G.UnitExists;
+local UnitIsUnit            = _G.UnitIsUnit;
+local UnitInRaid            = _G.UnitInRaid;
+local UnitInParty           = _G.UnitInParty;
+local UnitInRange           = _G.UnitInRange;
+local GetMouseFocus         = _G.GetMouseFocus;
+local UnitIsConnected       = _G.UnitIsConnected;
+local GetNumGroupMembers    = _G.GetNumGroupMembers;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G["SVUI"];
+local L = SV.L;
+local PLUGIN = select(2, ...);
+local CONFIGS = SV.defaults[PLUGIN.Schema];
+
+local GPS_UpdateHandler = CreateFrame("Frame");
+
+local playerGUID = UnitGUID("player")
+local _FRAMES, _PROXIMITY = {}, {}
+local minThrottle = 0.02
+local numArrows, inRange, GPS
+local TriangulateUnit = TriangulateUnit
+local NewHook = hooksecurefunc;
+--[[
+##########################################################
+GPS CONSTRUCTOR
+##########################################################
+]]--
+local GPS_Rotate_Arrow = function(self, angle)
+    local radius, ULx, ULy, LLx, LLy, URx, URy, LRx, LRy
+
+    radius = angle - 0.785398163
+    URx = 0.5 + cos(radius) / sqrt2
+    URy =  0.5 + sin(radius) / sqrt2
+    -- (-1)
+    radius = angle + 0.785398163
+    LRx = 0.5 + cos(radius) / sqrt2
+    LRy =  0.5 + sin(radius) / sqrt2
+    -- 1
+    radius = angle + 2.35619449
+    LLx = 0.5 + cos(radius) / sqrt2
+    LLy =  0.5 + sin(radius) / sqrt2
+    -- 3
+    radius = angle + 3.92699082
+    ULx = 0.5 + cos(radius) / sqrt2
+    ULy =  0.5 + sin(radius) / sqrt2
+    -- 5
+
+    self.Arrow:SetTexCoord(ULx, ULy, LLx, LLy, URx, URy, LRx, LRy);
+end
+
+local function CreateGPS(frame)
+    if not frame then return end
+    local size = 32
+
+    local gps = CreateFrame("Frame", nil, frame.TextGrip)
+    gps:SetFrameLevel(99)
+    gps:SetSize(size, size)
+    gps.DefaultSize = size
+    gps:SetPoint("RIGHT", frame, "RIGHT", 0, 0)
+
+    gps.Arrow = gps:CreateTexture(nil, "OVERLAY", nil, 7)
+    gps.Arrow:SetTexture([[Interface\AddOns\SVUI_TrackOMatic\artwork\GPS-ARROW]])
+    gps.Arrow:SetSize(size, size)
+    gps.Arrow:SetPoint("CENTER", gps, "CENTER", 0, 0)
+    gps.Arrow:SetVertexColor(0.1, 0.8, 0.8)
+    --gps.Arrow:SetBlendMode("ADD")
+
+    gps.onMouseOver = true
+    gps.OnlyProximity = false
+
+    gps.Spin = GPS_Rotate_Arrow
+
+    frame.GPS = gps
+end
+
+local RefreshGPS = function(self, frame, template)
+    if(template:find("raid") or template:find("party")) then
+        if not frame.GPS then CreateGPS(frame) end
+        if(CONFIGS.groups) then
+            frame.GPS.OnlyProximity = CONFIGS.proximity
+            local actualSz = min(frame.GPS.DefaultSize, (frame:GetHeight() + 2))
+            frame.GPS:SetSize(actualSz, actualSz)
+            frame.GPS.Arrow:SetSize(actualSz, actualSz)
+            if(not frame:IsElementEnabled("GPS")) then
+                frame:EnableElement("GPS")
+            end
+        else
+            if(frame:IsElementEnabled("GPS")) then
+                frame:DisableElement("GPS")
+            end
+        end
+    end
+end
+--[[
+##########################################################
+GPS ELEMENT
+##########################################################
+]]--
+local sortFunc = function(a,b) return a[1] < b[1] end
+
+local Update = function(self, elapsed)
+	if self.elapsed and self.elapsed > (self.throttle or minThrottle) then
+		numArrows = 0
+		twipe(_PROXIMITY)
+		for _, object in next, _FRAMES do
+			if(object:IsShown()) then
+				GPS = object.GPS
+				local unit = object.unit
+				if(unit) then
+					if(GPS.PreUpdate) then GPS:PreUpdate(object) end
+
+					local outOfRange = GPS.outOfRange and UnitInRange(unit) or false
+
+					if(not unit or not (UnitInParty(unit) or UnitInRaid(unit)) or UnitIsUnit(unit, "player") or not UnitIsConnected(unit) or (not GPS.OnlyProximity and ((GPS.onMouseOver and (GetMouseFocus() ~= object)) or outOfRange))) then
+						GPS:Hide()
+					else
+						local distance, angle = self.Track(unit)
+						if not angle then
+							GPS:Hide()
+						else
+							if(GPS.OnlyProximity == false) then
+								GPS:Show()
+							else
+								GPS:Hide()
+							end
+
+							if GPS.Arrow then
+								if(distance > 40) then
+									GPS.Arrow:SetVertexColor(1,0.1,0.1)
+								else
+									if(distance > 30) then
+										GPS.Arrow:SetVertexColor(0.4,0.8,0.1)
+									else
+										GPS.Arrow:SetVertexColor(0.1,1,0.1)
+									end
+									if(GPS.OnlyProximity and object.Health.percent and object.Health.percent < 80) then
+										local value = object.Health.percent + distance
+										_PROXIMITY[#_PROXIMITY + 1] = {value, GPS}
+									end
+								end
+								GPS:Spin(angle)
+							end
+
+							if GPS.Text then
+								GPS.Text:SetText(floor(distance))
+							end
+
+							if(GPS.PostUpdate) then GPS:PostUpdate(object, distance, angle) end
+							numArrows = numArrows + 1
+						end
+					end
+				else
+					GPS:Hide()
+				end
+			end
+		end
+
+        if(_PROXIMITY[1]) then
+        	tsort(_PROXIMITY, sortFunc)
+        	if(_PROXIMITY[1][2]) then
+	        	_PROXIMITY[1][2]:Show()
+	        end
+        end
+
+		self.elapsed = 0
+		self.throttle = max(minThrottle, 0.005 * numArrows)
+	else
+		self.elapsed = (self.elapsed or 0) + elapsed
+	end
+end
+
+local Enable = function(self)
+	if(self.GPS) then
+		tinsert(_FRAMES, self)
+		GPS_UpdateHandler:Show()
+		return true
+	end
+end
+
+local Disable = function(self)
+	local GPS = self.GPS
+	if GPS then
+		for k, frame in next, _FRAMES do
+			if(frame == self) then
+				tremove(_FRAMES, k)
+				GPS:Hide()
+				break
+			end
+		end
+
+		if #_FRAMES == 0 and GPS_UpdateHandler then
+			GPS_UpdateHandler:Hide()
+		end
+	end
+end
+
+local taggedUnits = {}
+local groupTagManager = CreateFrame("Frame")
+function PLUGIN:EnableGPS()
+    if(not SV.UnitFrames) then print("No Units") return end;
+    local oUF = SV.UnitFrames.oUF
+    if(not oUF) then print("No OUF") return end;
+
+    CONFIGS = SV.db[self.Schema];
+
+    groupTagManager:RegisterEvent("GROUP_ROSTER_UPDATE")
+    groupTagManager:SetScript("OnEvent", function()
+        local group, count;
+        twipe(taggedUnits)
+        if IsInRaid() then
+            group = "raid"
+            count = GetNumGroupMembers()
+        elseif IsInGroup() then
+            group = "party"
+            count = GetNumGroupMembers() - 1;
+            taggedUnits["player"] = true
+        else
+            group = "solo"
+            count = 1
+        end
+        for i = 1, count do
+            local realName = group..i;
+            if not UnitIsUnit(realName, "player") then
+                taggedUnits[realName] = true
+            end
+        end
+    end);
+
+    oUF.Tags.OnUpdateThrottle['nearbyplayers:8'] = 0.25
+    oUF.Tags.Methods["nearbyplayers:8"] = function(unit)
+        local unitsInRange, distance = 0;
+        if UnitIsConnected(unit)then
+            for taggedUnit, _ in pairs(taggedUnits)do
+                if not UnitIsUnit(unit, taggedUnit) and UnitIsConnected(taggedUnit)then
+                    distance = TriangulateUnit(unit, taggedUnit, true)
+                    if distance and distance <= 8 then
+                        unitsInRange = unitsInRange + 1
+                    end
+                end
+            end
+        end
+        return unitsInRange
+    end
+
+    oUF.Tags.OnUpdateThrottle['nearbyplayers:10'] = 0.25
+    oUF.Tags.Methods["nearbyplayers:10"] = function(unit)
+        local unitsInRange, distance = 0;
+        if UnitIsConnected(unit)then
+            for taggedUnit, _ in pairs(taggedUnits)do
+                if not UnitIsUnit(unit, taggedUnit) and UnitIsConnected(taggedUnit)then
+                    distance = TriangulateUnit(unit, taggedUnit, true)
+                    if distance and distance <= 10 then
+                        unitsInRange = unitsInRange + 1
+                    end
+                end
+            end
+        end
+        return unitsInRange
+    end
+
+    oUF.Tags.OnUpdateThrottle['nearbyplayers:30'] = 0.25
+    oUF.Tags.Methods["nearbyplayers:30"] = function(unit)
+        local unitsInRange, distance = 0;
+        if UnitIsConnected(unit)then
+            for taggedUnit, _ in pairs(taggedUnits)do
+                if not UnitIsUnit(unit, taggedUnit) and UnitIsConnected(taggedUnit)then
+                    distance = TriangulateUnit(unit, taggedUnit, true)
+                    if distance and distance <= 30 then
+                        unitsInRange = unitsInRange + 1
+                    end
+                end
+            end
+        end
+        return unitsInRange
+    end
+
+    oUF.Tags.OnUpdateThrottle['distance'] = 0.25
+    oUF.Tags.Methods["distance"] = function(unit)
+        if not UnitIsConnected(unit) or UnitIsUnit(unit, "player")then return "" end
+        local dst = TriangulateUnit("player", unit, true)
+        if dst and dst > 0 then
+            return format("%d", dst)
+        end
+        return ""
+    end
+
+    GPS_UpdateHandler.Track = TriangulateUnit
+    GPS_UpdateHandler:SetScript("OnUpdate", Update)
+
+    oUF:AddElement('GPS', nil, Enable, Disable)
+
+    NewHook(SV.UnitFrames, "RefreshUnitLayout", RefreshGPS)
+end
diff --git a/SVUI_UnitFrames/LICENSE.txt b/SVUI_UnitFrames/LICENSE.txt
new file mode 100644
index 0000000..05ceba8
--- /dev/null
+++ b/SVUI_UnitFrames/LICENSE.txt
@@ -0,0 +1,31 @@
+
+The MIT License
+
+Copyright (c) 2010, Failcoder (Steve Jackson)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy
+of this software and associated documentation files (the "Software"), to
+deal
+in the Software without restriction, including without limitation the
+rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/SVUI_UnitFrames/Loader.lua b/SVUI_UnitFrames/Loader.lua
new file mode 100644
index 0000000..d17e592
--- /dev/null
+++ b/SVUI_UnitFrames/Loader.lua
@@ -0,0 +1,2316 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+
+local SV = _G["SVUI"];
+local L = SV.L
+local MOD = SV:NewModule(...);
+local Schema = MOD.Schema;
+
+local unitframeColors = {
+	["health"]       = {0.3, 0.5, 0.3},
+	["healthBackdrop"] = {0.1, 0.1, 0.1},
+	["power"]        = {
+		["MANA"]         = {0.31, 0.75, 1},
+		["RAGE"]         = {1, 0.31, 0.31},
+		["FOCUS"]        = {1, 0.63, 0.27},
+		["ENERGY"]       = {0.85, 0.83, 0.25},
+		["RUNES"]        = {0.55, 0.57, 0.61},
+		["RUNIC_POWER"]  = {0, 0.82, 1}
+	},
+	["reaction"]     = {
+		[1] = {0.92, 0.15, 0.15},
+		[2] = {0.92, 0.15, 0.15},
+		[3] = {0.92, 0.15, 0.15},
+		[4] = {0.85, 0.85, 0.13},
+		[5] = {0.19, 0.85, 0.13},
+		[6] = {0.19, 0.85, 0.13},
+		[7] = {0.19, 0.85, 0.13},
+		[8] = {0.19, 0.85, 0.13},
+	},
+	["tapped"]           = {0.55, 0.57, 0.61},
+	["disconnected"]     = {0.84, 0.75, 0.65},
+	["casting"]          = {0, 0.92, 1},
+	["spark"]            = {0, 0.42, 1},
+	["interrupt"]        = {0.78, 0, 1},
+	["shield_bars"]      = {0.56, 0.4, 0.62},
+	["buff_bars"]        = {0.04, 0.52, 0.95},
+	["debuff_bars"]      = {0.8, 0.1, 0.1},
+	["predict"]          = {
+		["personal"]         = {0, 1, 0.5, 0.25},
+		["others"]           = {0, 1, 0, 0.25},
+		["absorbs"]          = {1, 1, 0, 0.25}
+	}
+};
+
+for power, color in next, PowerBarColor do
+	if(type(power) == 'string' and (not unitframeColors.power[power])) then
+		unitframeColors.power[power] = {color.r, color.g, color.b}
+	end
+end
+
+MOD.media = {}
+MOD.media.groupNumbers = {
+	[[Interface\AddOns\SVUI_UnitFrames\assets\GroupNumbers\1]],
+	[[Interface\AddOns\SVUI_UnitFrames\assets\GroupNumbers\2]],
+	[[Interface\AddOns\SVUI_UnitFrames\assets\GroupNumbers\3]],
+	[[Interface\AddOns\SVUI_UnitFrames\assets\GroupNumbers\4]],
+	[[Interface\AddOns\SVUI_UnitFrames\assets\GroupNumbers\5]],
+	[[Interface\AddOns\SVUI_UnitFrames\assets\GroupNumbers\6]],
+	[[Interface\AddOns\SVUI_UnitFrames\assets\GroupNumbers\7]],
+	[[Interface\AddOns\SVUI_UnitFrames\assets\GroupNumbers\8]],
+};
+MOD.media.lml = [[Interface\AddOns\SVUI_UnitFrames\assets\UNIT-LML]];
+MOD.media.roles = [[Interface\AddOns\SVUI_UnitFrames\assets\UNIT-ROLES]];
+MOD.media.buddy = [[Interface\AddOns\SVUI_UnitFrames\assets\UNIT-FRIENDSHIP]];
+MOD.media.playerstate = [[Interface\AddOns\SVUI_UnitFrames\assets\UNIT-PLAYER-STATE]];
+
+SV:AssignMedia("font", "unitprimary", "SVUI Number Font", 11, "OUTLINE");
+SV:AssignMedia("font", "unitsecondary", "SVUI Number Font", 11, "OUTLINE");
+SV:AssignMedia("font", "unitaura", "SVUI Default Font", 14, "OUTLINE");
+SV:AssignMedia("font", "unitaurabar", "SVUI Caps Font", 12, "NONE");
+SV:AssignMedia("font", "unitaurasmall", "SVUI Pixel Font", 8, "MONOCHROMEOUTLINE");
+SV:AssignMedia("globalfont", "unitprimary", "SVUI_Font_Unit");
+SV:AssignMedia("globalfont", "unitsecondary", "SVUI_Font_Unit_Small");
+SV:AssignMedia("globalfont", "unitaura", "SVUI_Font_UnitAura");
+SV:AssignMedia("globalfont", "unitaurabar", "SVUI_Font_UnitAura_Bar");
+SV:AssignMedia("globalfont", "unitaurasmall", "SVUI_Font_UnitAura_Small");
+SV:AssignMedia("template", "ActionPanel", "SVUI_StyleTemplate_ActionPanel");
+SV:AssignMedia("extended", "unitframes", unitframeColors);
+
+SV.defaults[Schema] = {
+	["themed"] = true,
+	["disableBlizzard"] = true,
+	["smoothbars"] = false,
+	["infoBackgrounds"] = true,
+	["statusbar"] = "SVUI MultiColorBar",
+	["auraBarStatusbar"] = "SVUI MultiColorBar",
+	["font"] = "SVUI Number Font",
+	["fontSize"] = 10,
+	["fontOutline"] = "NONE",
+	["auraFont"] = "SVUI Alert Font",
+	["auraFontSize"] = 10,
+	["auraFontOutline"] = "NONE",
+	["OORAlpha"] = 0.4,
+	["groupOORAlpha"] = 0.2,
+	["combatFadeRoles"] = true,
+	["combatFadeNames"] = true,
+	["debuffHighlighting"] = true,
+	["fastClickTarget"] = false,
+	["healglow"] = true,
+	["glowtime"] = 0.8,
+	["glowcolor"] = {1, 1, 0},
+	["autoRoleSet"] = false,
+	["forceHealthColor"] = false,
+	["overlayAnimation"] = true,
+	["powerclass"] = false,
+	["auraBarByType"] = true,
+	["auraBarShield"] = true,
+	["castClassColor"] = false,
+	["xrayFocus"] = true,
+	["resolveBar"] = false,
+	["player"] = {
+		["enable"] = true,
+		["width"] = 215,
+		["height"] = 40,
+		["combatfade"] = false,
+		["predict"] = false,
+		["threatEnabled"] = true,
+		["playerExpBar"] = false,
+		["playerRepBar"] = false,
+		["reverseLayout"] = false,
+		["formatting"] = {
+			["power_colored"] = true,
+			["power_type"] = "none",
+			["power_class"] = false,
+			["power_alt"] = false,
+			["health_colored"] = true,
+			["health_type"] = "current",
+			["name_colored"] = true,
+			["name_length"] = 21,
+			["smartlevel"] = false,
+			["absorbs"] = false,
+			["threat"] = false,
+			["incoming"] = false,
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+		},
+		["misc"] = {
+			["tags"] = ""
+		},
+		["health"] =
+		{
+			["tags"] = "[health:color][health:current]",
+			["position"] = "INNERRIGHT",
+			["orientation"] = "HORIZONTAL",
+			["xOffset"] = 0,
+			["yOffset"] = 0,
+			["reversed"] = false,
+			["fontSize"] = 11,
+			["classColor"] = true,
+			["valueColor"] = true,
+			["classBackdrop"] = true,
+		},
+		["power"] =
+		{
+			["enable"] = true,
+			["tags"] = "",
+			["height"] = 7,
+			["width"] = 215,
+			["detached"] = false,
+			["anchor"] = "BOTTOM",
+			["position"] = "INNERLEFT",
+			["orientation"] = "HORIZONTAL",
+			["hideonnpc"] = false,
+			["xOffset"] = 0,
+			["yOffset"] = 0,
+			["druidMana"] = true,
+			["fontSize"] = 11,
+			["classColor"] = false,
+		},
+		["name"] =
+		{
+			["position"] = "CENTER",
+			["tags"] = "",
+			["xOffset"] = 0,
+			["yOffset"] = 0,
+			["font"] = SV.DialogFontDefault,
+			["fontSize"] = 10,
+			["fontOutline"] = "OUTLINE",
+		},
+		["pvp"] =
+		{
+			["font"] = "SVUI Number Font",
+			["fontSize"] = 12,
+			["fontOutline"] = "OUTLINE",
+			["position"] = "BOTTOM",
+			["tags"] = "||cFFB04F4F[pvptimer][mouseover]||r",
+			["xOffset"] = 0,
+			["yOffset"] = 0,
+		},
+		["portrait"] =
+		{
+			["enable"] = true,
+			["width"] = 50,
+			["camDistanceScale"] = 1.6,
+			["rotation"] = 0,
+			["style"] = "3DOVERLAY",
+		},
+		["buffs"] =
+		{
+			["enable"] = true,
+			["useBars"] = false,
+			["barSize"] = 16,
+			["barCount"] = 8,
+			["perrow"] = 8,
+			["numrows"] = 1,
+			["attachTo"] = "FRAME",
+			["anchorPoint"] = "TOPLEFT",
+			["verticalGrowth"] = "UP",
+			["horizontalGrowth"] = "RIGHT",
+			["filterWhiteList"] = false,
+			["filterPlayer"] = true,
+			["filterRaid"] = true,
+			["filterAll"] = false,
+			["filterInfinite"] = true,
+			["filterDispellable"] = false,
+			["useFilter"] = "",
+			["xOffset"] = 0,
+			["yOffset"] = 8,
+			["sizeOverride"] = 0,
+			["barWidthOverride"] = 0,
+			["spacing"] = 2,
+			["sort"] = "TIME_REMAINING",
+		},
+		["debuffs"] =
+		{
+			["enable"] = true,
+			["useBars"] = false,
+			["barSize"] = 16,
+			["barCount"] = 8,
+			["perrow"] = 8,
+			["numrows"] = 1,
+			["attachTo"] = "BUFFS",
+			["anchorPoint"] = "TOPLEFT",
+			["verticalGrowth"] = "UP",
+			["horizontalGrowth"] = "RIGHT",
+			["filterWhiteList"] = false,
+			["filterPlayer"] = false,
+			["filterAll"] = false,
+			["filterInfinite"] = false,
+			["filterDispellable"] = false,
+			["useFilter"] = "",
+			["xOffset"] =  0,
+			["yOffset"] = 8,
+			["sizeOverride"] = 0,
+			["barWidthOverride"] = 0,
+			["spacing"] = 2,
+			["sort"] = "TIME_REMAINING",
+		},
+		["castbar"] =
+		{
+			["enable"] = true,
+			["width"] = 215,
+			["height"] = 20,
+			["matchFrameWidth"] = true,
+			["icon"] = true,
+			["latency"] = false,
+			["format"] = "REMAINING",
+			["ticks"] = false,
+			["spark"] = true,
+			["displayTarget"] = false,
+			["useCustomColor"] = false,
+			["castingColor"] = {0.8, 0.8, 0},
+			["sparkColor"] = {1, 0.72, 0},
+		},
+		["classbar"] =
+		{
+			["enable"] = true,
+			["inset"] = "inset",
+			["height"] = 25,
+			["detachFromFrame"] = false,
+			["enableStagger"] = true,
+			["enableAltMana"] = true,
+			["enableCat"] = true,
+			["enableChicken"] = true,
+			["altRunes"] = false,
+			["altComboPoints"] = false,
+		},
+		["icons"] =
+		{
+			["raidicon"] =
+			{
+				["enable"] = true,
+				["size"] = 25,
+				["attachTo"] = "INNERBOTTOMRIGHT",
+				["xOffset"] = 0,
+				["yOffset"] = 0,
+			},
+			["aggroIcon"] = {
+				["enable"] = true,
+				["size"] = 50,
+				["attachTo"] = "TOPRIGHT",
+				["xOffset"] = 45,
+				["yOffset"] = -10,
+			},
+			["combatIcon"] = {
+				["enable"] = true,
+				["size"] = 26,
+				["attachTo"] = "TOPRIGHT",
+				["xOffset"] = 22,
+				["yOffset"] = -5,
+			},
+			["restIcon"] = {
+				["enable"] = true,
+				["size"] = 22,
+				["attachTo"] = "INNERBOTTOMRIGHT",
+				["xOffset"] = 0,
+				["yOffset"] = 0,
+			},
+		},
+	},
+	["target"] = {
+		["enable"] = true,
+		["width"] = 215,
+		["height"] = 40,
+		["threatEnabled"] = true,
+		["rangeCheck"] = true,
+		["predict"] = false,
+		["middleClickFocus"] = true,
+		["reverseLayout"] = true,
+		["formatting"] = {
+			["power_colored"] = true,
+			["power_type"] = "none",
+			["power_class"] = false,
+			["power_alt"] = false,
+			["health_colored"] = true,
+			["health_type"] = "current",
+			["name_colored"] = true,
+			["name_length"] = 18,
+			["smartlevel"] = true,
+			["absorbs"] = false,
+			["threat"] = false,
+			["incoming"] = false,
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+		},
+		["misc"] = {
+			["tags"] = ""
+		},
+		["health"] =
+		{
+			["tags"] = "[health:color][health:current]",
+			["position"] = "INNERLEFT",
+			["orientation"] = "HORIZONTAL",
+			["xOffset"] = 0,
+			["yOffset"] = 0,
+			["reversed"] = true,
+			["fontSize"] = 11,
+			["classColor"] = true,
+			["valueColor"] = true,
+			["classBackdrop"] = true,
+		},
+		["power"] =
+		{
+			["enable"] = true,
+			["tags"] = "[power:color][power:current]",
+			["height"] = 7,
+			["width"] = 215,
+			["detached"] = false,
+			["anchor"] = "BOTTOM",
+			["position"] = "INNERRIGHT",
+			["orientation"] = "HORIZONTAL",
+			["hideonnpc"] = true,
+			["xOffset"] = 0,
+			["yOffset"] = 0,
+			["fontSize"] = 11,
+			["classColor"] = false,
+		},
+		["name"] =
+		{
+			["position"] = "TOPRIGHT",
+			["tags"] = "[name:color][name:18][smartlevel]",
+			["xOffset"] = -2,
+			["yOffset"] = 9,
+			["font"] = SV.DialogFontDefault,
+			["fontSize"] = 10,
+			["fontOutline"] = "OUTLINE",
+		},
+		["portrait"] =
+		{
+			["enable"] = true,
+			["width"] = 50,
+			["overlay"] = true,
+			["rotation"] = 0,
+			["camDistanceScale"] = 1.6,
+			["style"] = "3DOVERLAY",
+		},
+		["buffs"] =
+		{
+			["enable"] = true,
+			["useBars"] = false,
+			["barSize"] = 16,
+			["barCount"] = 8,
+			["perrow"] = 8,
+			["numrows"] = 1,
+			["attachTo"] = "FRAME",
+			["anchorPoint"] = "TOPRIGHT",
+			["verticalGrowth"] = "UP",
+			["horizontalGrowth"] = "LEFT",
+			["filterWhiteList"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["filterPlayer"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["filterRaid"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["filterAll"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["filterInfinite"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["filterDispellable"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["useFilter"] = "",
+			["xOffset"] = 0,
+			["yOffset"] = 8,
+			["sizeOverride"] = 0,
+			["barWidthOverride"] = 0,
+			["spacing"] = 2,
+			["sort"] = "TIME_REMAINING",
+		},
+		["debuffs"] =
+		{
+			["enable"] = true,
+			["useBars"] = false,
+			["barSize"] = 16,
+			["barCount"] = 8,
+			["perrow"] = 8,
+			["numrows"] = 1,
+			["attachTo"] = "BUFFS",
+			["anchorPoint"] = "TOPRIGHT",
+			["verticalGrowth"] = "UP",
+			["horizontalGrowth"] = "LEFT",
+			["filterWhiteList"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["filterPlayer"] =
+			{
+				friendly = false,
+				enemy = true,
+			},
+			["filterAll"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["filterInfinite"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["filterDispellable"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["useFilter"] = "",
+			["xOffset"] = 0,
+			["yOffset"] = 8,
+			["sizeOverride"] = 0,
+			["barWidthOverride"] = 0,
+			["spacing"] = 2,
+			["sort"] = "TIME_REMAINING",
+		},
+		["castbar"] =
+		{
+			["enable"] = true,
+			["width"] = 215,
+			["height"] = 20,
+			["matchFrameWidth"] = true,
+			["icon"] = true,
+			["format"] = "REMAINING",
+			["spark"] = true,
+			["useCustomColor"] = false,
+			["castingColor"] = {0.8, 0.8, 0},
+			["sparkColor"] = {1, 0.72, 0},
+		},
+		["combobar"] =
+		{
+			["enable"] = true,
+			["height"] = 30,
+			["smallIcons"] = false,
+			["hudStyle"] = false,
+			["hudScale"] = 64,
+			["autoHide"] = true,
+		},
+		["icons"] =
+		{
+			["classIcon"] =
+			{
+				["enable"] = false,
+				["size"] = 26,
+				["attachTo"] = "INNERBOTTOMLEFT",
+				["xOffset"] = 0,
+				["yOffset"] = 0,
+			},
+			["raidicon"] =
+			{
+				["enable"] = true,
+				["size"] = 30,
+				["attachTo"] = "INNERLEFT",
+				["xOffset"] = 0,
+				["yOffset"] = 0,
+			}
+		},
+	},
+	["targettarget"] = {
+		["enable"] = true,
+		["rangeCheck"] = true,
+		["threatEnabled"] = false,
+		["width"] = 110,
+		["height"] = 40,
+		["reverseLayout"] = true,
+		["formatting"] = {
+			["power_colored"] = true,
+			["power_type"] = "none",
+			["power_class"] = false,
+			["power_alt"] = false,
+			["health_colored"] = true,
+			["health_type"] = "none",
+			["name_colored"] = true,
+			["name_length"] = 10,
+			["smartlevel"] = false,
+			["absorbs"] = false,
+			["threat"] = false,
+			["incoming"] = false,
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+		},
+		["misc"] = {
+			["tags"] = ""
+		},
+		["health"] =
+		{
+			["tags"] = "",
+			["position"] = "INNERRIGHT",
+			["orientation"] = "HORIZONTAL",
+			["xOffset"] = 0,
+			["yOffset"] = 0,
+			["reversed"] = false,
+			["fontSize"] = 9,
+			["classColor"] = true,
+			["valueColor"] = true,
+			["classBackdrop"] = true,
+		},
+		["power"] =
+		{
+			["enable"] = false,
+			["tags"] = "",
+			["height"] = 7,
+			["width"] = 110,
+			["detached"] = false,
+			["anchor"] = "BOTTOM",
+			["position"] = "INNERLEFT",
+			["orientation"] = "HORIZONTAL",
+			["hideonnpc"] = false,
+			["xOffset"] = 0,
+			["yOffset"] = 0,
+			["fontSize"] = 9,
+			["classColor"] = false,
+		},
+		["name"] =
+		{
+			["position"] = "CENTER",
+			["tags"] = "[name:color][name:10]",
+			["xOffset"] = 0,
+			["yOffset"] = 1,
+			["font"] = SV.DialogFontDefault,
+			["fontSize"] = 10,
+			["fontOutline"] = "OUTLINE",
+		},
+		["portrait"] =
+		{
+			["enable"] = true,
+			["width"] = 45,
+			["overlay"] = true,
+			["rotation"] = 0,
+			["camDistanceScale"] = 1,
+			["style"] = "3DOVERLAY",
+		},
+		["buffs"] =
+		{
+			["enable"] = false,
+			["perrow"] = 7,
+			["numrows"] = 1,
+			["attachTo"] = "FRAME",
+			["anchorPoint"] = "TOPRIGHT",
+			["verticalGrowth"] = "UP",
+			["horizontalGrowth"] = "LEFT",
+			["filterWhiteList"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["filterPlayer"] =
+			{
+				friendly = true,
+				enemy = false,
+			},
+			["filterRaid"] =
+			{
+				friendly = true,
+				enemy = false,
+			},
+			["filterAll"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["filterInfinite"] =
+			{
+				friendly = true,
+				enemy = false,
+			},
+			["filterDispellable"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["useFilter"] = "",
+			["xOffset"] =  0,
+			["yOffset"] =  4,
+			["sizeOverride"] = 0,
+			["barWidthOverride"] = 0,
+			["spacing"] = 2,
+		},
+		["debuffs"] =
+		{
+			["enable"] = false,
+			["perrow"] = 5,
+			["numrows"] = 1,
+			["attachTo"] = "BUFFS",
+			["anchorPoint"] = "TOPRIGHT",
+			["verticalGrowth"] = "UP",
+			["horizontalGrowth"] = "LEFT",
+			["filterWhiteList"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["filterPlayer"] =
+			{
+				friendly = false,
+				enemy = true,
+			},
+			["filterAll"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["filterInfinite"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["filterDispellable"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["useFilter"] = "",
+			["xOffset"] =  0,
+			["yOffset"] =  4,
+			["sizeOverride"] = 0,
+			["barWidthOverride"] = 0,
+			["spacing"] = 2,
+		},
+		["icons"] =
+		{
+			["raidicon"] =
+			{
+				["enable"] = true,
+				["size"] = 18,
+				["attachTo"] = "INNERRIGHT",
+				["xOffset"] = 0,
+				["yOffset"] = 0,
+			},
+		},
+	},
+	["focus"] = {
+		["enable"] = true,
+		["rangeCheck"] = true,
+		["threatEnabled"] = true,
+		["width"] = 170,
+		["height"] = 30,
+		["predict"] = false,
+		["reverseLayout"] = true,
+		["formatting"] = {
+			["power_colored"] = true,
+			["power_type"] = "none",
+			["power_class"] = false,
+			["power_alt"] = false,
+			["health_colored"] = true,
+			["health_type"] = "none",
+			["name_colored"] = true,
+			["name_length"] = 15,
+			["smartlevel"] = false,
+			["absorbs"] = false,
+			["threat"] = false,
+			["incoming"] = false,
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+		},
+		["misc"] = {
+			["tags"] = ""
+		},
+		["health"] =
+		{
+			["tags"] = "",
+			["position"] = "INNERRIGHT",
+			["orientation"] = "HORIZONTAL",
+			["xOffset"] = 0,
+			["yOffset"] = 0,
+			["reversed"] = false,
+			["fontSize"] = 10,
+			["classColor"] = true,
+			["valueColor"] = true,
+			["classBackdrop"] = true,
+		},
+		["power"] =
+		{
+			["enable"] = true,
+			["tags"] = "",
+			["height"] = 7,
+			["width"] = 170,
+			["detached"] = false,
+			["anchor"] = "BOTTOM",
+			["position"] = "INNERLEFT",
+			["orientation"] = "HORIZONTAL",
+			["hideonnpc"] = false,
+			["xOffset"] = 0,
+			["yOffset"] = 0,
+			["fontSize"] = 10,
+			["classColor"] = false,
+		},
+		["name"] =
+		{
+			["position"] = "CENTER",
+			["tags"] = "[name:color][name:15]",
+			["xOffset"] = 0,
+			["yOffset"] = 0,
+			["font"] = SV.DialogFontDefault,
+			["fontSize"] = 10,
+			["fontOutline"] = "OUTLINE",
+		},
+		["castbar"] =
+		{
+			["enable"] = true,
+			["width"] = 170,
+			["height"] = 10,
+			["icon"] = false,
+			["matchFrameWidth"] = true,
+			["format"] = "REMAINING",
+			["spark"] = true,
+			["useCustomColor"] = false,
+			["castingColor"] = {0.8, 0.8, 0},
+			["sparkColor"] = {1, 0.72, 0},
+		},
+		["buffs"] =
+		{
+			["enable"] = true,
+			["useBars"] = false,
+			["barSize"] = 16,
+			["barCount"] = 8,
+			["perrow"] = 7,
+			["numrows"] = 1,
+			["attachTo"] = "FRAME",
+			["anchorPoint"] = "TOPRIGHT",
+			["verticalGrowth"] = "UP",
+			["horizontalGrowth"] = "LEFT",
+			["filterWhiteList"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["filterPlayer"] =
+			{
+				friendly = true,
+				enemy = false,
+			},
+			["filterRaid"] =
+			{
+				friendly = true,
+				enemy = false,
+			},
+			["filterAll"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["filterInfinite"] =
+			{
+				friendly = true,
+				enemy = false,
+			},
+			["filterDispellable"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["useFilter"] = "",
+			["xOffset"] = 0,
+			["yOffset"] = 4,
+			["sizeOverride"] = 0,
+			["barWidthOverride"] = 0,
+			["spacing"] = 2,
+			["sort"] = "TIME_REMAINING",
+		},
+		["debuffs"] =
+		{
+			["enable"] = true,
+			["useBars"] = false,
+			["barSize"] = 16,
+			["barCount"] = 8,
+			["perrow"] = 5,
+			["numrows"] = 1,
+			["attachTo"] = "FRAME",
+			["anchorPoint"] = "LEFT",
+			["verticalGrowth"] = "UP",
+			["horizontalGrowth"] = "LEFT",
+			["filterWhiteList"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["filterPlayer"] =
+			{
+				friendly = false,
+				enemy = true,
+			},
+			["filterAll"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["filterInfinite"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["filterDispellable"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["useFilter"] = "",
+			["xOffset"] = -4,
+			["yOffset"] = 0,
+			["sizeOverride"] = 0,
+			["barWidthOverride"] = 0,
+			["spacing"] = 2,
+			["sort"] = "TIME_REMAINING",
+		},
+		["auraWatch"] =
+		{
+			["enable"] = true,
+			["size"] = 8,
+		},
+		["icons"] =
+		{
+			["raidicon"] =
+			{
+				["enable"] = true,
+				["size"] = 18,
+				["attachTo"] = "INNERLEFT",
+				["xOffset"] = 0,
+				["yOffset"] = 0,
+			},
+		},
+	},
+	["focustarget"] = {
+		["enable"] = true,
+		["rangeCheck"] = true,
+		["threatEnabled"] = false,
+		["width"] = 150,
+		["height"] = 26,
+		["reverseLayout"] = true,
+		["formatting"] = {
+			["power_colored"] = true,
+			["power_type"] = "none",
+			["power_class"] = false,
+			["power_alt"] = false,
+			["health_colored"] = true,
+			["health_type"] = "none",
+			["name_colored"] = true,
+			["name_length"] = 15,
+			["smartlevel"] = false,
+			["absorbs"] = false,
+			["threat"] = false,
+			["incoming"] = false,
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+		},
+		["misc"] = {
+			["tags"] = ""
+		},
+		["health"] =
+		{
+			["tags"] = "",
+			["position"] = "INNERRIGHT",
+			["orientation"] = "HORIZONTAL",
+			["xOffset"] = 0,
+			["yOffset"] = 0,
+			["reversed"] = false,
+			["fontSize"] = 10,
+			["classColor"] = true,
+			["valueColor"] = true,
+			["classBackdrop"] = true,
+		},
+		["power"] =
+		{
+			["enable"] = false,
+			["tags"] = "",
+			["height"] = 7,
+			["width"] = 150,
+			["detached"] = false,
+			["anchor"] = "BOTTOM",
+			["position"] = "INNERLEFT",
+			["orientation"] = "HORIZONTAL",
+			["hideonnpc"] = false,
+			["xOffset"] = 0,
+			["yOffset"] = 0,
+			["fontSize"] = 10,
+			["classColor"] = false,
+		},
+		["name"] =
+		{
+			["position"] = "CENTER",
+			["tags"] = "[name:color][name:15]",
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+			["font"] = SV.DialogFontDefault,
+			["fontSize"] = 10,
+			["fontOutline"] = "OUTLINE",
+		},
+		["buffs"] =
+		{
+			["enable"] = true,
+			["perrow"] = 7,
+			["numrows"] = 1,
+			["attachTo"] = "FRAME",
+			["anchorPoint"] = "TOPRIGHT",
+			["verticalGrowth"] = "UP",
+			["horizontalGrowth"] = "LEFT",
+			["filterWhiteList"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["filterPlayer"] =
+			{
+				friendly = true,
+				enemy = false,
+			},
+			["filterRaid"] =
+			{
+				friendly = true,
+				enemy = false,
+			},
+			["filterAll"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["filterInfinite"] =
+			{
+				friendly = true,
+				enemy = false,
+			},
+			["filterDispellable"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["useFilter"] = "",
+			["xOffset"] = 0,
+			["yOffset"] = 4,
+			["sizeOverride"] = 0,
+			["barWidthOverride"] = 0,
+			["spacing"] = 2,
+		},
+		["debuffs"] =
+		{
+			["enable"] = true,
+			["perrow"] = 5,
+			["numrows"] = 1,
+			["attachTo"] = "FRAME",
+			["anchorPoint"] = "LEFT",
+			["verticalGrowth"] = "UP",
+			["horizontalGrowth"] = "LEFT",
+			["filterWhiteList"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["filterPlayer"] =
+			{
+				friendly = false,
+				enemy = true,
+			},
+			["filterAll"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["filterInfinite"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["filterDispellable"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["useFilter"] = "",
+			["xOffset"] = -4,
+			["yOffset"] = 0,
+			["sizeOverride"] = 0,
+			["barWidthOverride"] = 0,
+			["spacing"] = 2,
+		},
+		["icons"] =
+		{
+			["raidicon"] =
+			{
+				["enable"] = true,
+				["size"] = 18,
+				["attachTo"] = "INNERLEFT",
+				["xOffset"] = 0,
+				["yOffset"] = 0,
+			},
+		},
+	},
+	["pet"] = {
+		["enable"] = true,
+		["rangeCheck"] = true,
+		["threatEnabled"] = true,
+		["width"] = 110,
+		["height"] = 40,
+		["predict"] = false,
+		["reverseLayout"] = false,
+		["formatting"] = {
+			["power_colored"] = true,
+			["power_type"] = "none",
+			["power_class"] = false,
+			["power_alt"] = false,
+			["health_colored"] = true,
+			["health_type"] = "none",
+			["name_colored"] = true,
+			["name_length"] = 10,
+			["smartlevel"] = false,
+			["absorbs"] = false,
+			["threat"] = false,
+			["incoming"] = false,
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+		},
+		["misc"] = {
+			["tags"] = ""
+		},
+		["health"] =
+		{
+			["tags"] = "",
+			["position"] = "INNERRIGHT",
+			["orientation"] = "HORIZONTAL",
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+			["reversed"] = false,
+			["fontSize"] = 10,
+			["classColor"] = true,
+			["valueColor"] = true,
+			["classBackdrop"] = true,
+		},
+		["power"] =
+		{
+			["enable"] = true,
+			["tags"] = "",
+			["height"] = 7,
+			["width"] = 110,
+			["detached"] = false,
+			["anchor"] = "BOTTOM",
+			["position"] = "INNERLEFT",
+			["orientation"] = "HORIZONTAL",
+			["hideonnpc"] = false,
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+			["fontSize"] = 10,
+			["classColor"] = false,
+		},
+		["name"] =
+		{
+			["position"] = "CENTER",
+			["tags"] = "[name:color][name:8]",
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+			["font"] = SV.DialogFontDefault,
+			["fontSize"] = 10,
+			["fontOutline"] = "OUTLINE",
+		},
+		["portrait"] =
+		{
+			["enable"] = true,
+			["width"] = 40,
+			["overlay"] = true,
+			["rotation"] = 0,
+			["camDistanceScale"] = 1,
+			["style"] = "3DOVERLAY",
+		},
+		["buffs"] =
+		{
+			["enable"] = true,
+			["perrow"] = 4,
+			["numrows"] = 1,
+			["attachTo"] = "FRAME",
+			["anchorPoint"] = "TOPLEFT",
+			["verticalGrowth"] = "UP",
+			["horizontalGrowth"] = "RIGHT",
+			["filterWhiteList"] = false,
+			["filterPlayer"] = true,
+			["filterRaid"] = true,
+			["filterAll"] = true,
+			["filterInfinite"] = true,
+			["filterDispellable"] = false,
+			["useFilter"] = "",
+			["xOffset"] = 0,
+			["yOffset"] = 4,
+			["sizeOverride"] = 0,
+			["barWidthOverride"] = 0,
+			["spacing"] = 2,
+		},
+		["debuffs"] =
+		{
+			["enable"] = true,
+			["perrow"] = 4,
+			["numrows"] = 1,
+			["attachTo"] = "BUFFS",
+			["anchorPoint"] = "TOPLEFT",
+			["verticalGrowth"] = "UP",
+			["horizontalGrowth"] = "RIGHT",
+			["filterWhiteList"] = false,
+			["filterPlayer"] = false,
+			["filterAll"] = false,
+			["filterInfinite"] = false,
+			["filterDispellable"] = false,
+			["useFilter"] = "",
+			["xOffset"] = 0,
+			["yOffset"] = 4,
+			["sizeOverride"] = 0,
+			["barWidthOverride"] = 0,
+			["spacing"] = 2,
+		},
+		["castbar"] =
+		{
+			["enable"] = true,
+			["width"] = 130,
+			["height"] = 8,
+			["icon"] = false,
+			["matchFrameWidth"] = true,
+			["format"] = "REMAINING",
+			["spark"] = false,
+			["useCustomColor"] = false,
+			["castingColor"] = {0.8, 0.8, 0},
+			["sparkColor"] = {1, 0.72, 0},
+		},
+		["auraWatch"] =
+		{
+			["enable"] = true,
+			["size"] = 8,
+		},
+	},
+	["pettarget"] = {
+		["enable"] = false,
+		["rangeCheck"] = true,
+		["threatEnabled"] = false,
+		["width"] = 130,
+		["height"] = 26,
+		["reverseLayout"] = false,
+		["formatting"] = {
+			["power_colored"] = true,
+			["power_type"] = "none",
+			["power_class"] = false,
+			["power_alt"] = false,
+			["health_colored"] = true,
+			["health_type"] = "none",
+			["name_colored"] = true,
+			["name_length"] = 15,
+			["smartlevel"] = false,
+			["absorbs"] = false,
+			["threat"] = false,
+			["incoming"] = false,
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+		},
+		["misc"] = {
+			["tags"] = ""
+		},
+		["health"] =
+		{
+			["tags"] = "",
+			["position"] = "INNERRIGHT",
+			["orientation"] = "HORIZONTAL",
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+			["reversed"] = false,
+			["fontSize"] = 10,
+			["classColor"] = true,
+			["valueColor"] = true,
+			["classBackdrop"] = true,
+		},
+		["power"] =
+		{
+			["enable"] = false,
+			["orientation"] = "HORIZONTAL",
+			["tags"] = "",
+			["height"] = 7,
+			["width"] = 130,
+			["detached"] = false,
+			["anchor"] = "BOTTOM",
+			["position"] = "INNERLEFT",
+			["hideonnpc"] = false,
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+			["fontSize"] = 10,
+			["classColor"] = false,
+		},
+		["name"] =
+		{
+			["position"] = "CENTER",
+			["tags"] = "[name:color][name:15]",
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+			["font"] = SV.DialogFontDefault,
+			["fontSize"] = 10,
+			["fontOutline"] = "OUTLINE",
+		},
+		["buffs"] =
+		{
+			["enable"] = false,
+			["perrow"] = 7,
+			["numrows"] = 1,
+			["attachTo"] = "FRAME",
+			["anchorPoint"] = "BOTTOMLEFT",
+			["verticalGrowth"] = "DOWN",
+			["horizontalGrowth"] = "RIGHT",
+			["filterWhiteList"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["filterPlayer"] =
+			{
+				friendly = true,
+				enemy = false,
+			},
+			["filterRaid"] =
+			{
+				friendly = true,
+				enemy = false,
+			},
+			["filterAll"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["filterInfinite"] =
+			{
+				friendly = true,
+				enemy = false,
+			},
+			["filterDispellable"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["useFilter"] = "",
+			["xOffset"] = 0,
+			["yOffset"] = -8,
+			["sizeOverride"] = 0,
+			["barWidthOverride"] = 0,
+			["spacing"] = 2,
+		},
+		["debuffs"] =
+		{
+			["enable"] = false,
+			["perrow"] = 5,
+			["numrows"] = 1,
+			["attachTo"] = "FRAME",
+			["anchorPoint"] = "BOTTOMRIGHT",
+			["verticalGrowth"] = "DOWN",
+			["horizontalGrowth"] = "LEFT",
+			["filterWhiteList"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["filterPlayer"] =
+			{
+				friendly = false,
+				enemy = true,
+			},
+			["filterAll"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["filterInfinite"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["filterDispellable"] =
+			{
+				friendly = false,
+				enemy = false,
+			},
+			["useFilter"] = "",
+			["xOffset"] = 0,
+			["yOffset"] = 8,
+			["sizeOverride"] = 0,
+			["barWidthOverride"] = 0,
+			["spacing"] = 2,
+		},
+	},
+	["boss"] = {
+		["enable"] = true,
+		["rangeCheck"] = true,
+		["showBy"] = "UP",
+		["width"] = 200,
+		["height"] = 45,
+		["reverseLayout"] = true,
+		["formatting"] = {
+			["power_colored"] = true,
+			["power_type"] = "none",
+			["power_class"] = false,
+			["power_alt"] = false,
+			["health_colored"] = true,
+			["health_type"] = "current",
+			["name_colored"] = true,
+			["name_length"] = 15,
+			["smartlevel"] = false,
+			["absorbs"] = false,
+			["threat"] = false,
+			["incoming"] = false,
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+		},
+		["misc"] = {
+			["tags"] = ""
+		},
+		["health"] =
+		{
+			["tags"] = "[health:color][health:current]",
+			["position"] = "INNERTOPRIGHT",
+			["orientation"] = "HORIZONTAL",
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+			["reversed"] = false,
+			["fontSize"] = 10,
+			["classColor"] = true,
+			["valueColor"] = true,
+			["classBackdrop"] = true,
+		},
+		["power"] =
+		{
+			["enable"] = true,
+			["tags"] = "[power:color][power:current]",
+			["height"] = 7,
+			["width"] = 200,
+			["detached"] = false,
+			["anchor"] = "BOTTOM",
+			["position"] = "INNERBOTTOMRIGHT",
+			["orientation"] = "HORIZONTAL",
+			["hideonnpc"] = false,
+			["yOffset"] = 7,
+			["xOffset"] = 0,
+			["fontSize"] = 10,
+			["classColor"] = false,
+		},
+		["portrait"] =
+		{
+			["enable"] = true,
+			["width"] = 35,
+			["overlay"] = true,
+			["rotation"] = 0,
+			["camDistanceScale"] = 1,
+			["style"] = "3DOVERLAY",
+		},
+		["name"] =
+		{
+			["position"] = "INNERLEFT",
+			["tags"] = "[name:color][name:15]",
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+			["font"] = SV.DialogFontDefault,
+			["fontSize"] = 10,
+			["fontOutline"] = "OUTLINE",
+		},
+		["buffs"] =
+		{
+			["enable"] = true,
+			["perrow"] = 4,
+			["numrows"] = 1,
+			["attachTo"] = "FRAME",
+			["anchorPoint"] = "LEFTBOTTOM",
+			["verticalGrowth"] = "UP",
+			["horizontalGrowth"] = "LEFT",
+			["filterWhiteList"] = false,
+			["filterPlayer"] = false,
+			["filterRaid"] = false,
+			["filterAll"] = false,
+			["filterInfinite"] = false,
+			["filterDispellable"] = false,
+			["useFilter"] = "",
+			["xOffset"] =  -6,
+			["yOffset"] =  0,
+			["sizeOverride"] = 20,
+			["spacing"] = 2,
+		},
+		["debuffs"] =
+		{
+			["enable"] = true,
+			["perrow"] = 4,
+			["numrows"] = 1,
+			["attachTo"] = "FRAME",
+			["anchorPoint"] = "LEFTTOP",
+			["verticalGrowth"] = "UP",
+			["horizontalGrowth"] = "LEFT",
+			["filterWhiteList"] = false,
+			["filterPlayer"] = true,
+			["filterAll"] = false,
+			["filterInfinite"] = false,
+			["filterDispellable"] = false,
+			["useFilter"] = "",
+			["xOffset"] =  -6,
+			["yOffset"] =  0,
+			["sizeOverride"] = 20,
+			["spacing"] = 2,
+		},
+		["castbar"] =
+		{
+			["enable"] = true,
+			["width"] = 200,
+			["height"] = 18,
+			["icon"] = true,
+			["matchFrameWidth"] = true,
+			["format"] = "REMAINING",
+			["spark"] = true,
+			["useCustomColor"] = false,
+			["castingColor"] = {0.8, 0.8, 0},
+			["sparkColor"] = {1, 0.72, 0},
+		},
+		["icons"] =
+		{
+			["raidicon"] =
+			{
+				["enable"] = true,
+				["size"] = 22,
+				["attachTo"] = "CENTER",
+				["xOffset"] = 0,
+				["yOffset"] = 0,
+			},
+		},
+	},
+	["arena"] = {
+		["enable"] = true,
+		["rangeCheck"] = true,
+		["showBy"] = "UP",
+		["width"] = 215,
+		["height"] = 45,
+		["predict"] = false,
+		["reverseLayout"] = true,
+		["formatting"] = {
+			["power_colored"] = true,
+			["power_type"] = "none",
+			["power_class"] = false,
+			["power_alt"] = false,
+			["health_colored"] = true,
+			["health_type"] = "current",
+			["name_colored"] = true,
+			["name_length"] = 15,
+			["smartlevel"] = false,
+			["absorbs"] = false,
+			["threat"] = false,
+			["incoming"] = false,
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+		},
+		["misc"] = {
+			["tags"] = ""
+		},
+		["health"] =
+		{
+			["tags"] = "[health:color][health:current]",
+			["position"] = "INNERTOPRIGHT",
+			["orientation"] = "HORIZONTAL",
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+			["reversed"] = false,
+			["fontSize"] = 10,
+			["classColor"] = true,
+			["valueColor"] = true,
+			["classBackdrop"] = true,
+		},
+		["power"] =
+		{
+			["enable"] = true,
+			["tags"] = "[power:color][power:current]",
+			["height"] = 7,
+			["width"] = 215,
+			["detached"] = false,
+			["anchor"] = "BOTTOM",
+			["position"] = "INNERBOTTOMRIGHT",
+			["orientation"] = "HORIZONTAL",
+			["hideonnpc"] = false,
+			["yOffset"] = 7,
+			["xOffset"] = 0,
+			["fontSize"] = 10,
+			["classColor"] = false,
+		},
+		["name"] =
+		{
+			["position"] = "INNERLEFT",
+			["tags"] = "[name:color][name:15]",
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+			["font"] = SV.DialogFontDefault,
+			["fontSize"] = 10,
+			["fontOutline"] = "OUTLINE",
+		},
+		["portrait"] =
+		{
+			["enable"] = true,
+			["width"] = 45,
+			["overlay"] = true,
+			["rotation"] = 0,
+			["camDistanceScale"] = 1,
+			["style"] = "3DOVERLAY",
+		},
+		["buffs"] =
+		{
+			["enable"] = true,
+			["perrow"] = 8,
+			["numrows"] = 1,
+			["attachTo"] = "FRAME",
+			["anchorPoint"] = "LEFTBOTTOM",
+			["verticalGrowth"] = "UP",
+			["horizontalGrowth"] = "LEFT",
+			["filterWhiteList"] = false,
+			["filterPlayer"] = false,
+			["filterRaid"] = false,
+			["filterAll"] = false,
+			["filterInfinite"] = false,
+			["filterDispellable"] = false,
+			["useFilter"] = "",
+			["xOffset"] =  -6,
+			["yOffset"] =  0,
+			["sizeOverride"] = 20,
+			["spacing"] = 2,
+		},
+		["debuffs"] =
+		{
+			["enable"] = true,
+			["perrow"] = 8,
+			["numrows"] = 1,
+			["attachTo"] = "FRAME",
+			["anchorPoint"] = "LEFTTOP",
+			["verticalGrowth"] = "UP",
+			["horizontalGrowth"] = "LEFT",
+			["filterWhiteList"] = false,
+			["filterPlayer"] = false,
+			["filterAll"] = false,
+			["filterInfinite"] = false,
+			["filterDispellable"] = false,
+			["useFilter"] = "",
+			["xOffset"] =  -6,
+			["yOffset"] =  0,
+			["sizeOverride"] = 20,
+			["spacing"] = 2,
+		},
+		["castbar"] =
+		{
+			["enable"] = true,
+			["width"] = 215,
+			["height"] = 18,
+			["icon"] = true,
+			["matchFrameWidth"] = true,
+			["format"] = "REMAINING",
+			["spark"] = true,
+			["useCustomColor"] = false,
+			["castingColor"] = {0.8, 0.8, 0},
+			["sparkColor"] = {1, 0.72, 0},
+		},
+		["pvp"] =
+		{
+			["enable"] = true,
+			["trinketPosition"] = "LEFT",
+			["trinketSize"] = 45,
+			["trinketX"] = -2,
+			["trinketY"] = 0,
+			["specPosition"] = "RIGHT",
+			["specSize"] = 45,
+			["specX"] = 2,
+			["specY"] = 0,
+		},
+	},
+	["party"] = {
+		["enable"] = true,
+		["rangeCheck"] = true,
+		["threatEnabled"] = true,
+		["visibility"] = "[group:party,nogroup:raid] show;hide",
+		["raid5Visibility"] = "[group:party,nogroup:raid] show;hide",
+		["noRaid5Visibility"] = "[group:party,nogroup:raid][@raid6,noexists,group:raid] show;hide",
+		["useFor5man"] = true,
+		["showBy"] = "UP_RIGHT",
+		["wrapXOffset"] = 9,
+		["wrapYOffset"] = 24,
+		["allowedGroup"] = {
+			[1] = true,
+		},
+		["gRowCol"] = 1,
+		["sortMethod"] = "GROUP",
+		["sortDir"] = "ASC",
+		["invertGroupingOrder"] = false,
+		["showPlayer"] = true,
+		["predict"] = false,
+		["width"] = 115,
+		["height"] = 50,
+		["reverseLayout"] = false,
+		["grid"] = {
+			["enable"] = false,
+			["size"] = 45,
+			["fontsize"] = 12,
+			["iconSize"] = 12,
+			["powerEnable"] = false
+		},
+		["formatting"] = {
+			["power_colored"] = true,
+			["power_type"] = "none",
+			["power_class"] = false,
+			["power_alt"] = false,
+			["health_colored"] = true,
+			["health_type"] = "none",
+			["name_colored"] = true,
+			["name_length"] = 10,
+			["smartlevel"] = false,
+			["absorbs"] = false,
+			["threat"] = false,
+			["incoming"] = false,
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+		},
+		["misc"] = {
+			["tags"] = ""
+		},
+		["health"] =
+		{
+			["tags"] = "",
+			["position"] = "BOTTOM",
+			["orientation"] = "HORIZONTAL",
+			["frequentUpdates"] = false,
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+			["reversed"] = false,
+			["fontSize"] = 10,
+			["classColor"] = true,
+			["valueColor"] = true,
+			["classBackdrop"] = true,
+		},
+		["power"] =
+		{
+			["enable"] = false,
+			["tags"] = "",
+			["anchor"] = "BOTTOM",
+			["orientation"] = "HORIZONTAL",
+			["frequentUpdates"] = false,
+			["height"] = 8,
+			["width"] = 115,
+			["detached"] = false,
+			["position"] = "BOTTOMRIGHT",
+			["hideonnpc"] = false,
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+			["fontSize"] = 10,
+			["classColor"] = false,
+		},
+		["name"] =
+		{
+			["position"] = "BOTTOMLEFT",
+			["tags"] = "[name:color][name:10]",
+			["yOffset"] = -2,
+			["xOffset"] = 0,
+			["font"] = SV.DialogFontDefault,
+			["fontSize"] = 10,
+			["fontOutline"] = "NONE",
+		},
+		["buffs"] =
+		{
+			["enable"] = true,
+			["perrow"] = 2,
+			["numrows"] = 1,
+			["attachTo"] = "FRAME",
+			["anchorPoint"] = "RIGHTBOTTOM",
+			["verticalGrowth"] = "DOWN",
+			["horizontalGrowth"] = "RIGHT",
+			["filterWhiteList"] = false,
+			["filterPlayer"] = true,
+			["filterRaid"] = true,
+			["filterAll"] = false,
+			["filterInfinite"] = true,
+			["filterDispellable"] = false,
+			["useFilter"] = "",
+			["xOffset"] = 8,
+			["yOffset"] = 0,
+			["sizeOverride"] = 20,
+			["spacing"] = 2,
+		},
+		["debuffs"] =
+		{
+			["enable"] = true,
+			["perrow"] = 4,
+			["numrows"] = 1,
+			["attachTo"] = "FRAME",
+			["anchorPoint"] = "RIGHTTOP",
+			["verticalGrowth"] = "UP",
+			["horizontalGrowth"] = "RIGHT",
+			["filterWhiteList"] = false,
+			["filterPlayer"] = false,
+			["filterAll"] = false,
+			["filterInfinite"] = false,
+			["filterDispellable"] = true,
+			["useFilter"] = "",
+			["xOffset"] = 8,
+			["yOffset"] = 0,
+			["sizeOverride"] = 22,
+			["spacing"] = 2,
+		},
+		["rdebuffs"] =
+		{
+			["enable"] = true,
+			["size"] = 35,
+			["xOffset"] = 0,
+			["yOffset"] = 0,
+		},
+		["auraWatch"] =
+		{
+			["enable"] = true,
+			["size"] = 8,
+			["fontSize"] = 11,
+		},
+		["petsGroup"] =
+		{
+			["enable"] = false,
+			["width"] = 30,
+			["height"] = 30,
+			["gridAllowed"] = true,
+			["anchorPoint"] = "BOTTOMLEFT",
+			["xOffset"] =  - 1,
+			["yOffset"] = 0,
+			["name_length"] = 3,
+			["tags"] = "[name:3]",
+			["portrait"] =
+			{
+				["enable"] = true,
+				["width"] = 45,
+				["overlay"] = true,
+				["rotation"] = 0,
+				["camDistanceScale"] = 1,
+				["style"] = "3DOVERLAY",
+			},
+		},
+		["targetsGroup"] =
+		{
+			["enable"] = false,
+			["width"] = 30,
+			["height"] = 30,
+			["gridAllowed"] = true,
+			["anchorPoint"] = "TOPLEFT",
+			["xOffset"] =  - 1,
+			["yOffset"] = 0,
+			["name_length"] = 3,
+			["tags"] = "[name:3]",
+		},
+		["icons"] =
+		{
+			["raidicon"] =
+			{
+				["enable"] = true,
+				["size"] = 25,
+				["attachTo"] = "INNERBOTTOMLEFT",
+				["xOffset"] = 0,
+				["yOffset"] = 0,
+			},
+			["roleIcon"] =
+			{
+				["enable"] = true,
+				["size"] = 15,
+				["attachTo"] = "BOTTOMRIGHT",
+				["xOffset"] = 0,
+				["yOffset"] = -2,
+			},
+			["raidRoleIcons"] =
+			{
+				["enable"] = true,
+				["size"] = 25,
+				["attachTo"] = "TOPLEFT",
+				["xOffset"] = 0,
+				["yOffset"] = -4,
+			},
+		},
+		["portrait"] =
+		{
+			["enable"] = true,
+			["width"] = 45,
+			["overlay"] = true,
+			["rotation"] = 0,
+			["camDistanceScale"] = 1,
+			["style"] = "3DOVERLAY",
+		},
+	},
+	["raid"] = {
+		["enable"] = true,
+		["rangeCheck"] = true,
+		["threatEnabled"] = true,
+		["visibility"] = "[group:raid] show;hide",
+		["noRaid5Visibility"] = "[group:raid] show;hide",
+		["raid5Visibility"] = "[@raid6,exists,group:raid] show;hide",
+		["showBy"] = "RIGHT_DOWN",
+		["wrapXOffset"] = 8,
+		["wrapYOffset"] = 8,
+		["showGroupNumber"] = false,
+		["allowedGroup"] = {
+			[1] = true, [2] = true, [3] = true, [4] = true, [5] = true, [6] = true, [7] = true, [8] = true,
+		},
+		["gRowCol"] = 1,
+		["sortMethod"] = "GROUP",
+		["sortDir"] = "ASC",
+		["showPlayer"] = true,
+		["predict"] = false,
+		["width"] = 50,
+		["height"] = 30,
+		["reverseLayout"] = false,
+		["grid"] = {
+			["enable"] = false,
+			["size"] = 30,
+			["fontsize"] = 12,
+			["iconSize"] = 12,
+			["powerEnable"] = false
+		},
+		["formatting"] = {
+			["power_colored"] = true,
+			["power_type"] = "none",
+			["power_class"] = false,
+			["power_alt"] = false,
+			["health_colored"] = true,
+			["health_type"] = "none",
+			["name_colored"] = true,
+			["name_length"] = 4,
+			["smartlevel"] = false,
+			["absorbs"] = false,
+			["threat"] = false,
+			["incoming"] = false,
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+		},
+		["misc"] = {
+			["tags"] = ""
+		},
+		["health"] =
+		{
+			["tags"] = "",
+			["position"] = "BOTTOM",
+			["orientation"] = "HORIZONTAL",
+			["frequentUpdates"] = false,
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+			["reversed"] = false,
+			["fontSize"] = 10,
+			["classColor"] = true,
+			["valueColor"] = true,
+			["classBackdrop"] = true,
+		},
+		["power"] =
+		{
+			["enable"] = false,
+			["tags"] = "",
+			["frequentUpdates"] = false,
+			["height"] = 8,
+			["width"] = 50,
+			["detached"] = false,
+			["anchor"] = "BOTTOM",
+			["position"] = "BOTTOMRIGHT",
+			["hideonnpc"] = false,
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+			["fontSize"] = 10,
+			["classColor"] = false,
+		},
+		["name"] =
+		{
+			["position"] = "INNERTOPLEFT",
+			["tags"] = "[name:color][name:4]",
+			["yOffset"] = 0,
+			["xOffset"] = 8,
+			["font"] = "SVUI Default Font",
+			["fontSize"] = 10,
+			["fontOutline"] = "OUTLINE",
+		},
+		["buffs"] =
+		{
+			["enable"] = false,
+			["perrow"] = 3,
+			["numrows"] = 1,
+			["attachTo"] = "FRAME",
+			["anchorPoint"] = "RIGHT",
+			["verticalGrowth"] = "UP",
+			["horizontalGrowth"] = "RIGHT",
+			["filterWhiteList"] = false,
+			["filterPlayer"] = true,
+			["filterRaid"] = true,
+			["filterAll"] = false,
+			["filterInfinite"] = true,
+			["filterDispellable"] = false,
+			["useFilter"] = "",
+			["xOffset"] = 8,
+			["yOffset"] = 0,
+			["sizeOverride"] = 0,
+			["barWidthOverride"] = 0,
+			["spacing"] = 2,
+		},
+		["debuffs"] =
+		{
+			["enable"] = false,
+			["perrow"] = 3,
+			["numrows"] = 1,
+			["attachTo"] = "FRAME",
+			["anchorPoint"] = "RIGHT",
+			["verticalGrowth"] = "UP",
+			["horizontalGrowth"] = "RIGHT",
+			["filterWhiteList"] = false,
+			["filterPlayer"] = false,
+			["filterAll"] = false,
+			["filterInfinite"] = false,
+			["filterDispellable"] = false,
+			["useFilter"] = "",
+			["xOffset"] = 8,
+			["yOffset"] = 0,
+			["sizeOverride"] = 0,
+			["barWidthOverride"] = 0,
+			["spacing"] = 2,
+		},
+		["rdebuffs"] =
+		{
+			["enable"] = true,
+			["size"] = 25,
+			["xOffset"] = 0,
+			["yOffset"] = 0,
+		},
+		["auraWatch"] =
+		{
+			["enable"] = true,
+			["size"] = 8,
+		},
+		["icons"] =
+		{
+			["raidicon"] =
+			{
+				["enable"] = true,
+				["size"] = 15,
+				["attachTo"] = "INNERBOTTOMRIGHT",
+				["xOffset"] = -8,
+				["yOffset"] = 0,
+			},
+			["roleIcon"] =
+			{
+				["enable"] = true,
+				["size"] = 12,
+				["attachTo"] = "INNERBOTTOMLEFT",
+				["xOffset"] = 8,
+				["yOffset"] = 0,
+			},
+			["raidRoleIcons"] =
+			{
+				["enable"] = true,
+				["size"] = 18,
+				["attachTo"] = "TOPLEFT",
+				["xOffset"] = 8,
+				["yOffset"] = -4,
+			},
+		},
+	},
+	["raidpet"] = {
+		["enable"] = false,
+		["rangeCheck"] = true,
+		["threatEnabled"] = true,
+		["visibility"] = "[group:raid] show;hide",
+		["showBy"] = "DOWN_RIGHT",
+		["wrapXOffset"] = 3,
+		["wrapYOffset"] = 3,
+		["allowedGroup"] = {
+			[1] = true, [2] = true,
+		},
+		["gRowCol"] = 1,
+		["sortMethod"] = "PETNAME",
+		["sortDir"] = "ASC",
+		["invertGroupingOrder"] = false,
+		["predict"] = false,
+		["width"] = 80,
+		["height"] = 30,
+		["reverseLayout"] = false,
+		["grid"] = {
+			["enable"] = false,
+			["size"] = 30,
+			["fontsize"] = 12,
+			["iconSize"] = 12,
+			["powerEnable"] = false
+		},
+		["formatting"] = {
+			["power_colored"] = true,
+			["power_type"] = "none",
+			["power_class"] = false,
+			["power_alt"] = false,
+			["health_colored"] = true,
+			["health_type"] = "deficit",
+			["name_colored"] = true,
+			["name_length"] = 4,
+			["smartlevel"] = false,
+			["absorbs"] = false,
+			["threat"] = false,
+			["incoming"] = false,
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+		},
+		["misc"] = {
+			["tags"] = ""
+		},
+		["health"] =
+		{
+			["tags"] = "[health:color][health:deficit]",
+			["position"] = "INNERBOTTOMRIGHT",
+			["orientation"] = "HORIZONTAL",
+			["frequentUpdates"] = false,
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+			["reversed"] = false,
+			["fontSize"] = 10,
+			["classColor"] = true,
+			["valueColor"] = true,
+			["classBackdrop"] = true,
+		},
+		["name"] =
+		{
+			["position"] = "INNERTOPLEFT",
+			["tags"] = "[name:color][name:4]",
+			["yOffset"] = 4,
+			["xOffset"] = -4,
+			["font"] = "SVUI Default Font",
+			["fontSize"] = 10,
+			["fontOutline"] = "OUTLINE",
+		},
+		["buffs"] =
+		{
+			["enable"] = false,
+			["perrow"] = 3,
+			["numrows"] = 1,
+			["attachTo"] = "FRAME",
+			["anchorPoint"] = "RIGHT",
+			["verticalGrowth"] = "UP",
+			["horizontalGrowth"] = "RIGHT",
+			["filterWhiteList"] = false,
+			["filterPlayer"] = true,
+			["filterRaid"] = true,
+			["filterAll"] = false,
+			["filterInfinite"] = true,
+			["filterDispellable"] = false,
+			["useFilter"] = "",
+			["xOffset"] = 8,
+			["yOffset"] = 0,
+			["sizeOverride"] = 0,
+			["barWidthOverride"] = 0,
+			["spacing"] = 2,
+		},
+		["debuffs"] =
+		{
+			["enable"] = false,
+			["perrow"] = 3,
+			["numrows"] = 1,
+			["attachTo"] = "FRAME",
+			["anchorPoint"] = "RIGHT",
+			["verticalGrowth"] = "UP",
+			["horizontalGrowth"] = "RIGHT",
+			["filterWhiteList"] = false,
+			["filterPlayer"] = false,
+			["filterAll"] = false,
+			["filterInfinite"] = false,
+			["filterDispellable"] = false,
+			["useFilter"] = "",
+			["xOffset"] = 8,
+			["yOffset"] = 0,
+			["sizeOverride"] = 0,
+			["barWidthOverride"] = 0,
+			["spacing"] = 2,
+		},
+		["auraWatch"] =
+		{
+			["enable"] = true,
+			["size"] = 8,
+		},
+		["rdebuffs"] =
+		{
+			["enable"] = true,
+			["size"] = 26,
+			["xOffset"] = 0,
+			["yOffset"] = 2,
+		},
+		["icons"] =
+		{
+			["raidicon"] =
+			{
+				["enable"] = true,
+				["size"] = 18,
+				["attachTo"] = "INNERTOPLEFT",
+				["xOffset"] = 0,
+				["yOffset"] = 0,
+			},
+		},
+	},
+	["tank"] = {
+		["enable"] = true,
+		["threatEnabled"] = true,
+		["visibility"] = "[group:raid] show;hide",
+		["rangeCheck"] = true,
+		["width"] = 120,
+		["height"] = 28,
+		["reverseLayout"] = false,
+		["grid"] = {
+			["enable"] = false,
+			["size"] = 45,
+			["fontsize"] = 12,
+			["iconSize"] = 12,
+			["powerEnable"] = false
+		},
+		["formatting"] = {
+			["power_colored"] = true,
+			["power_type"] = "none",
+			["power_class"] = false,
+			["power_alt"] = false,
+			["health_colored"] = true,
+			["health_type"] = "deficit",
+			["name_colored"] = true,
+			["name_length"] = 8,
+			["smartlevel"] = false,
+			["absorbs"] = false,
+			["threat"] = false,
+			["incoming"] = false,
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+		},
+		["misc"] = {
+			["tags"] = ""
+		},
+		["health"] =
+		{
+			["tags"] = "[health:color][health:deficit]",
+			["position"] = "INNERRIGHT",
+			["orientation"] = "HORIZONTAL",
+			["frequentUpdates"] = false,
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+			["reversed"] = false,
+			["fontSize"] = 10,
+			["classColor"] = true,
+			["valueColor"] = true,
+			["classBackdrop"] = true,
+		},
+		["name"] =
+		{
+			["position"] = "INNERLEFT",
+			["tags"] = "[name:color][name:8]",
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+			["font"] = "SVUI Default Font",
+			["fontSize"] = 10,
+			["fontOutline"] = "OUTLINE",
+		},
+		["targetsGroup"] =
+		{
+			["enable"] = false,
+			["anchorPoint"] = "RIGHT",
+			["xOffset"] = 1,
+			["yOffset"] = 0,
+			["width"] = 120,
+			["height"] = 28,
+		},
+	},
+	["assist"] = {
+		["enable"] = true,
+		["threatEnabled"] = true,
+		["visibility"] = "[group:raid] show;hide",
+		["rangeCheck"] = true,
+		["width"] = 120,
+		["height"] = 28,
+		["reverseLayout"] = false,
+		["grid"] = {
+			["enable"] = false,
+			["size"] = 45,
+			["fontsize"] = 12,
+			["iconSize"] = 12,
+			["powerEnable"] = false
+		},
+		["formatting"] = {
+			["power_colored"] = true,
+			["power_type"] = "none",
+			["power_class"] = false,
+			["power_alt"] = false,
+			["health_colored"] = true,
+			["health_type"] = "deficit",
+			["name_colored"] = true,
+			["name_length"] = 8,
+			["smartlevel"] = false,
+			["absorbs"] = false,
+			["threat"] = false,
+			["incoming"] = false,
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+		},
+		["misc"] = {
+			["tags"] = ""
+		},
+		["health"] =
+		{
+			["tags"] = "[health:color][health:deficit]",
+			["position"] = "INNERRIGHT",
+			["orientation"] = "HORIZONTAL",
+			["frequentUpdates"] = false,
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+			["reversed"] = false,
+			["fontSize"] = 10,
+			["classColor"] = true,
+			["valueColor"] = true,
+			["classBackdrop"] = true,
+		},
+		["name"] =
+		{
+			["position"] = "INNERLEFT",
+			["tags"] = "[name:color][name:8]",
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+			["font"] = "SVUI Default Font",
+			["fontSize"] = 10,
+			["fontOutline"] = "OUTLINE",
+		},
+		["targetsGroup"] =
+		{
+			["enable"] = false,
+			["anchorPoint"] = "RIGHT",
+			["xOffset"] = 1,
+			["yOffset"] = 0,
+			["width"] = 120,
+			["height"] = 28,
+		},
+	},
+	["bodyguard"] = {
+		["enable"] = true,
+		["width"] = 200,
+		["height"] = 28,
+		["reverseLayout"] = false,
+		["health"] =
+		{
+			["position"] = "INNERRIGHT",
+			["orientation"] = "HORIZONTAL",
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+			["reversed"] = false,
+			["fontSize"] = 10,
+		},
+		["name"] =
+		{
+			["position"] = "INNERLEFT",
+			["yOffset"] = 0,
+			["xOffset"] = 0,
+			["font"] = "SVUI Default Font",
+			["fontSize"] = 10,
+			["fontOutline"] = "OUTLINE",
+		},
+	},
+};
diff --git a/SVUI_UnitFrames/SVUI_UnitFrames.lua b/SVUI_UnitFrames/SVUI_UnitFrames.lua
new file mode 100644
index 0000000..519e8b4
--- /dev/null
+++ b/SVUI_UnitFrames/SVUI_UnitFrames.lua
@@ -0,0 +1,1424 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+local _G            	= _G;
+--LUA
+local unpack            = _G.unpack;
+local select            = _G.select;
+local assert            = _G.assert;
+local type              = _G.type;
+local error             = _G.error;
+local pcall             = _G.pcall;
+local print             = _G.print;
+local ipairs            = _G.ipairs;
+local pairs             = _G.pairs;
+local next              = _G.next;
+local tostring          = _G.tostring;
+local tonumber          = _G.tonumber;
+local collectgarbage    = _G.collectgarbage;
+--BLIZZARD
+local tinsert       = _G.tinsert;
+local tremove       = _G.tremove;
+local twipe         = _G.wipe;
+--STRING
+local string        = string;
+local format        = string.format;
+local find          = string.find;
+local match         = string.match;
+--MATH
+local math          = math;
+local min, random   = math.min, math.random;
+--TABLE
+local table         = table;
+--BLIZZARD API
+local hooksecurefunc 			= _G.hooksecurefunc;
+local InCombatLockdown      	= _G.InCombatLockdown;
+local CreateFrame           	= _G.CreateFrame;
+local IsAddOnLoaded         	= _G.IsAddOnLoaded;
+local IsInInstance          	= _G.IsInInstance;
+local GetActiveSpecGroup    	= _G.GetActiveSpecGroup;
+local GetSpellInfo    			= _G.GetSpellInfo;
+local oUF_RaidDebuffs       	= _G.oUF_RaidDebuffs;
+local MAX_BOSS_FRAMES       	= _G.MAX_BOSS_FRAMES;
+local RAID_CLASS_COLORS     	= _G.RAID_CLASS_COLORS;
+local FACTION_BAR_COLORS    	= _G.FACTION_BAR_COLORS;
+local CUSTOM_CLASS_COLORS   	= _G.CUSTOM_CLASS_COLORS;
+local RegisterStateDriver       = _G.RegisterStateDriver;
+local UnregisterStateDriver     = _G.UnregisterStateDriver;
+local RegisterAttributeDriver   = _G.RegisterAttributeDriver;
+--[[
+##########################################################
+GET ADDON DATA AND TEST FOR oUF
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L;
+local LSM = _G.LibStub("LibSharedMedia-3.0");
+--[[
+##########################################################
+MODULE AND INNER CLASSES
+##########################################################
+]]--
+local MOD = SV.UnitFrames;
+local oUF_SVUI = MOD.oUF
+assert(oUF_SVUI, "SVUI UnitFrames: unable to locate oUF.")
+MOD.Units = {}
+MOD.Headers = {}
+MOD.Dispellable = {}
+--[[
+##########################################################
+LOCALS
+##########################################################
+]]--
+local LoadedUnitFrames, LoadedGroupHeaders;
+
+local function FindAnchorFrame(frame, anchor, badPoint)
+	if badPoint or anchor == 'FRAME' then
+		if(frame.Gladiator and frame.Gladiator:IsShown()) then
+			return frame.Gladiator
+		else
+			return frame
+		end
+	elseif(anchor == 'TRINKET' and frame.Gladiator and frame.Gladiator:IsShown()) then
+		return frame.Gladiator
+	elseif(anchor == 'BUFFS' and frame.Buffs and frame.Buffs:IsShown()) then
+		return frame.Buffs
+	elseif(anchor == 'DEBUFFS' and frame.Debuffs and frame.Debuffs:IsShown()) then
+		return frame.Debuffs
+	else
+		return frame
+	end
+end
+--[[
+##########################################################
+CORE FUNCTIONS
+##########################################################
+]]--
+do
+	local dummy = CreateFrame("Frame", nil)
+	dummy:Hide()
+
+	local function deactivate(unitName)
+		local frame;
+		if type(unitName) == "string" then frame = _G[unitName] else frame = unitName end
+		if frame then
+			frame:UnregisterAllEvents()
+			frame:Hide()
+			frame:SetParent(dummy)
+			if frame.healthbar then frame.healthbar:UnregisterAllEvents() end
+			if frame.manabar then frame.manabar:UnregisterAllEvents() end
+			if frame.spellbar then frame.spellbar:UnregisterAllEvents() end
+			if frame.powerBarAlt then frame.powerBarAlt:UnregisterAllEvents() end
+		end
+	end
+
+	function oUF_SVUI:DisableBlizzard(unit)
+		if (not unit) or InCombatLockdown() then return end
+
+		if (unit == "player") then
+			PlayerFrame:UnregisterAllEvents()
+			PlayerFrame:SetAlpha(0)
+			--PlayerFrame:Hide()
+			PlayerFrame:EnableMouse(false)
+			if PlayerFrame.healthbar then PlayerFrame.healthbar:UnregisterAllEvents() end
+			if PlayerFrame.manabar then PlayerFrame.manabar:UnregisterAllEvents() end
+			if PlayerFrame.spellbar then PlayerFrame.spellbar:UnregisterAllEvents() end
+			if PlayerFrame.powerBarAlt then PlayerFrame.powerBarAlt:UnregisterAllEvents() end
+			PlayerFrame:RegisterUnitEvent("UNIT_ENTERING_VEHICLE", "player")
+			PlayerFrame:RegisterUnitEvent("UNIT_ENTERED_VEHICLE", "player")
+			PlayerFrame:RegisterUnitEvent("UNIT_EXITING_VEHICLE", "player")
+			PlayerFrame:RegisterUnitEvent("UNIT_EXITED_VEHICLE", "player")
+			PlayerFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
+			PlayerFrame:SetUserPlaced(true)
+			PlayerFrame:SetDontSavePosition(true)
+			RuneFrame:SetParent(PlayerFrame)
+		elseif(unit == "pet") then
+			deactivate(PetFrame)
+		elseif(unit == "target") then
+			deactivate(TargetFrame)
+			deactivate(ComboFrame)
+		elseif(unit == "focus") then
+			deactivate(FocusFrame)
+			deactivate(TargetofFocusFrame)
+		elseif(unit == "targettarget") then
+			deactivate(TargetFrameToT)
+		elseif(unit:match("(boss)%d?$") == "boss") then
+			local id = unit:match("boss(%d)")
+			if(id) then
+				deactivate("Boss"..id.."TargetFrame")
+			else
+				for i = 1, 4 do
+					deactivate(("Boss%dTargetFrame"):format(i))
+				end
+			end
+		elseif(unit:match("(party)%d?$") == "party") then
+			local id = unit:match("party(%d)")
+			if(id) then
+				deactivate("PartyMemberFrame"..id)
+			else
+				for i = 1, 4 do
+					deactivate(("PartyMemberFrame%d"):format(i))
+				end
+			end
+		elseif(unit:match("(arena)%d?$") == "arena") then
+			local id = unit:match("arena(%d)")
+			if(id) then
+				deactivate("ArenaEnemyFrame"..id)
+				deactivate("ArenaPrepFrame"..id)
+				deactivate("ArenaEnemyFrame"..id.."PetFrame")
+			else
+				for i = 1, 5 do
+					deactivate(("ArenaEnemyFrame%d"):format(i))
+					deactivate(("ArenaPrepFrame%d"):format(i))
+					deactivate(("ArenaEnemyFrame%dPetFrame"):format(i))
+				end
+			end
+		end
+	end
+end
+
+function MOD:GetActiveSize(db, token)
+	local width, height, best = 0,0,0
+	if(db.grid and db.grid.enable) then
+		width = db.grid.size
+		height = width
+		best = width
+	elseif(db) then
+		width = db.width
+		height = db.height
+		best = min(width, height);
+	end
+
+	return width, height, best
+end
+
+function MOD:ResetUnitOptions(unit)
+	SV:ResetData("UnitFrames", unit)
+	self:RefreshUnitFrames()
+end
+
+function MOD:RefreshUnitColors()
+	if(not SV.db.general.customClassColor) then
+		for eclass, color in next, RAID_CLASS_COLORS do
+			oUF_SVUI.colors.class[eclass] = {color.r, color.g, color.b}
+		end
+	else
+		for eclass, color in next, CUSTOM_CLASS_COLORS do
+			oUF_SVUI.colors.class[eclass] = {color.r, color.g, color.b}
+		end
+	end
+	local db = SV.media.extended.unitframes
+	for i, setting in pairs(db) do
+		if setting and type(setting) == "table" then
+			if(setting[1]) then
+				oUF_SVUI.colors[i] = setting
+			else
+				local bt = {}
+				for x, color in pairs(setting) do
+					if(color)then
+						bt[x] = color
+					end
+					oUF_SVUI.colors[i] = bt
+				end
+			end
+		elseif setting then
+			oUF_SVUI.colors[i] = setting
+		end
+	end
+	local r, g, b = db.health[1], db.health[2], db.health[3]
+	oUF_SVUI.colors.smooth = {1, 0, 0, 1, 1, 0, r, g, b}
+	SV.Events:Trigger("UNITFRAME_COLORS_UPDATED");
+end
+
+function MOD:RefreshAllUnitMedia()
+	if(not SV.db.UnitFrames) then return end
+	self:RefreshUnitColors()
+	for unit,frame in pairs(self.Units)do
+		if SV.db.UnitFrames[frame.___key].enable then
+			frame:MediaUpdate()
+			frame:UpdateAllElements()
+		end
+	end
+	for _,group in pairs(self.Headers) do
+		group:MediaUpdate()
+	end
+	collectgarbage("collect")
+end
+
+function MOD:RefreshUnitFrames()
+	if(InCombatLockdown()) then self:RegisterEvent("PLAYER_REGEN_ENABLED"); return end
+	self:RefreshUnitColors()
+	for unit,frame in pairs(self.Units)do
+		if(SV.db.UnitFrames[frame.___key].enable) then
+			frame:Enable()
+			frame:Update()
+		else
+			frame:Disable()
+		end
+	end
+	local _,groupType = IsInInstance()
+	local raidDebuffs = SV.oUF_RaidDebuffs or oUF_RaidDebuffs;
+	if raidDebuffs then
+		raidDebuffs:ResetDebuffData()
+		if groupType == "party" or groupType == "raid" then
+		  raidDebuffs:RegisterDebuffs(SV.db.Filters["Raid"])
+		else
+		  raidDebuffs:RegisterDebuffs(SV.db.Filters["CC"])
+		end
+	end
+
+	for _,group in pairs(self.Headers) do
+		group:Update()
+		if(group.Configure) then
+		  group:Configure()
+		end
+	end
+	if SV.db.UnitFrames.disableBlizzard then
+		oUF_SVUI:DisableBlizzard('party')
+	end
+
+	if(self.BodyGuard) then
+		self.BodyGuard:UpdateSettings()
+	end
+	collectgarbage("collect")
+end
+
+local function UpdateUnitFrames()
+	MOD:RefreshUnitFrames()
+end
+
+function MOD:RefreshUnitMedia(unitName)
+    local db = SV.db.UnitFrames
+    local key = unitName or self.___key
+    if((not db) or (not self)) then return end
+    local CURRENT_BAR_TEXTURE = LSM:Fetch("statusbar", db.statusbar)
+    local unitDB = db[key]
+    if(unitDB and unitDB.enable) then
+        local panel = self.TextGrip
+        if(panel) then
+          if(panel.Name and unitDB.name) then
+          	if(unitDB.grid and unitDB.grid.enable) then
+          		panel.Name:SetFont(SV.media.font.pixel, 8, "MONOCHROMEOUTLINE")
+          		panel.Name:SetShadowOffset(0, -1)
+							panel.Name:SetShadowColor(0, 0, 0, 1)
+          	else
+              panel.Name:SetFont(LSM:Fetch("font", unitDB.name.font), unitDB.name.fontSize, unitDB.name.fontOutline)
+							if(key == 'raid') then
+								panel.Name:SetShadowOffset(0, -1)
+								panel.Name:SetShadowColor(0, 0, 0, 1)
+							else
+								if(unitDB.name.fontOutline == 'NONE') then
+									panel.Name:SetShadowColor(0, 0, 0, 1)
+								else
+									panel.Name:SetShadowColor(0, 0, 0, 0.5)
+								end
+								panel.Name:SetShadowOffset(1, -1)
+							end
+            end
+          end
+        end
+        if(self.Health) then
+            self.Health:SetStatusBarTexture(CURRENT_BAR_TEXTURE)
+        end
+        if(self.Power and (unitDB.power and unitDB.power.enable)) then
+            self.Power:SetStatusBarTexture(CURRENT_BAR_TEXTURE)
+        end
+        if(self.Castbar and (unitDB.castbar)) then
+            if(unitDB.castbar.useCustomColor) then
+				self.Castbar.CastColor = unitDB.castbar.castingColor
+				self.Castbar.SparkColor = unitDB.castbar.sparkColor
+			else
+				self.Castbar.CastColor = oUF_SVUI.colors.casting
+				self.Castbar.SparkColor = oUF_SVUI.colors.spark
+			end
+        end
+    end
+end
+
+local POWER_ANCHORS = {
+	["BOTTOM"] = {"BOTTOMLEFT", "BOTTOMLEFT", 1, 1, "BOTTOMRIGHT", "BOTTOMRIGHT", -1, 1},
+	["TOP"] = {"TOPLEFT", "TOPLEFT", 1, -1, "TOPRIGHT", "TOPRIGHT", -1, -1},
+	["LEFT"] = {"TOPLEFT", "TOPLEFT", 1, -1, "BOTTOMLEFT", "BOTTOMLEFT", 1, 1},
+	["RIGHT"] = {"TOPRIGHT", "TOPRIGHT", -1, -1, "BOTTOMRIGHT", "BOTTOMRIGHT", -1, 1},
+}
+
+local POWER_DETACHED_ANCHORS = {
+	["BOTTOM"] = {"TOP", "BOTTOM", 0, -1},
+	["TOP"] = {"BOTTOM", "TOP", 0, 1},
+	["LEFT"] = {"RIGHT", "LEFT", -1, 0},
+	["RIGHT"] = {"LEFT", "RIGHT", 1, 0},
+}
+
+function MOD:RefreshUnitLayout(frame, template)
+	local db = SV.db.UnitFrames[template]
+	if(not db) then return end
+
+	local TOP_ANCHOR1, TOP_ANCHOR2, TOP_MODIFIER = "TOPRIGHT", "TOPLEFT", 1;
+	local BOTTOM_ANCHOR1, BOTTOM_ANCHOR2, BOTTOM_MODIFIER = "BOTTOMLEFT", "BOTTOMRIGHT", -1;
+	local REVERSED_LAYOUT = db.reverseLayout;
+	if(REVERSED_LAYOUT) then
+		TOP_ANCHOR1 = "TOPLEFT"
+		TOP_ANCHOR2 = "TOPRIGHT"
+		TOP_MODIFIER = -1
+		BOTTOM_ANCHOR1 = "BOTTOMRIGHT"
+		BOTTOM_ANCHOR2 = "BOTTOMLEFT"
+		BOTTOM_MODIFIER = 1
+	end
+
+	local MASTER_GRIP = frame.ActionPanel;
+	local TEXT_GRIP = frame.TextGrip;
+
+	local UNIT_WIDTH, UNIT_HEIGHT, BEST_SIZE = self:GetActiveSize(db);
+	local GRID_MODE = (db.grid and db.grid.enable);
+	local MINI_GRID = (GRID_MODE and BEST_SIZE < 26);
+	local RESIZE_NEEDED = false;
+	local MASTER_X1_OFFSET, MASTER_X2_OFFSET, MASTER_TOP_OFFSET, MASTER_BOTTOM_OFFSET = 0, 0, 0, 0;
+
+	local POWER_GRIP = frame.Power;
+	local POWER_POINT;
+	local POWER_ENABLED, POWER_DETACHED = false, false;
+	local POWER_HEIGHT, POWER_WIDTH = 1, UNIT_WIDTH;
+	if(POWER_GRIP and db.power) then
+		POWER_ENABLED = (GRID_MODE and db.grid.powerEnable) or db.power.enable;
+		POWER_DETACHED = db.power.detached;
+		RESIZE_NEEDED = POWER_DETACHED
+		if(POWER_ENABLED) then
+			if(db.power.height) then POWER_HEIGHT = db.power.height - 1; end
+			if(db.power.width and POWER_DETACHED) then POWER_WIDTH = db.power.width; end
+		end
+		if(db.power.anchor) then
+			POWER_POINT = POWER_DETACHED and POWER_DETACHED_ANCHORS[db.power.anchor] or POWER_ANCHORS[db.power.anchor]
+			if(POWER_DETACHED) then
+				if(db.power.anchor == "TOP") then
+					MASTER_TOP_OFFSET = POWER_HEIGHT
+				elseif(db.power.anchor == "BOTTOM") then
+					MASTER_BOTTOM_OFFSET = POWER_HEIGHT
+				else
+					if((REVERSED_LAYOUT and db.power.anchor == "LEFT") or ((not REVERSED_LAYOUT) and db.power.anchor == "RIGHT")) then
+						MASTER_X2_OFFSET = MASTER_X2_OFFSET + POWER_WIDTH
+					else
+						MASTER_X1_OFFSET = MASTER_X1_OFFSET + POWER_WIDTH
+					end
+				end
+			end
+		end
+	end
+
+	local PORTRAIT_GRIP = false;
+	local PORTRAIT_ENABLED = false;
+	local PORTRAIT_OVERLAY = false;
+	local PORTRAIT_OVERLAY_ANIMATION = false;
+	local PORTRAIT_WIDTH = 0;
+	local PORTRAIT_STYLE = 'None';
+	if(db.portrait) then
+		PORTRAIT_ENABLED = (not GRID_MODE and db.portrait.enable);
+		PORTRAIT_STYLE = db.portrait.style;
+		PORTRAIT_OVERLAY = (not GRID_MODE and PORTRAIT_ENABLED and PORTRAIT_STYLE == '3DOVERLAY');
+		PORTRAIT_OVERLAY_ANIMATION = (PORTRAIT_OVERLAY) and SV.db.UnitFrames.overlayAnimation or false;
+		if(PORTRAIT_ENABLED and (not PORTRAIT_OVERLAY)) then
+			if(PORTRAIT_STYLE == '2D') then
+				PORTRAIT_WIDTH = UNIT_HEIGHT;
+			else
+				PORTRAIT_WIDTH = db.portrait.width;
+			end
+			RESIZE_NEEDED = true
+		end
+
+		if(frame.PortraitModel) then
+			frame.PortraitModel:Hide()
+			frame.PortraitModel:ClearAllPoints()
+		end
+
+		if(frame.PortraitTexture) then
+			local parent2D = frame.PortraitTexture:GetParent();
+			parent2D:Hide()
+			parent2D:ClearAllPoints()
+		end
+
+		if(frame.PortraitTexture and frame.PortraitModel) then
+			if(PORTRAIT_STYLE == '2D') then
+				frame.Portrait = frame.PortraitTexture
+				PORTRAIT_GRIP = frame.PortraitTexture:GetParent();
+			else
+				frame.PortraitModel.UserRotation = db.portrait.rotation;
+				frame.PortraitModel.UserCamDistance = db.portrait.camDistanceScale;
+				frame.Portrait = frame.PortraitModel
+				PORTRAIT_GRIP = frame.PortraitModel;
+			end
+		else
+			PORTRAIT_GRIP = frame.Portrait;
+		end
+	end
+
+	local BUFF_GRIP = frame.Buffs;
+	local BUFF_ENABLED = (db.buffs and db.buffs.enable) or false;
+	local DEBUFF_GRIP = frame.Debuffs;
+	local DEBUFF_ENABLED = (db.debuffs and db.debuffs.enable) or false;
+	local RAID_DEBUFFS = frame.RaidDebuffs;
+	local RAID_DEBUFFS_ENABLED = (db.rdebuffs and db.rdebuffs.enable) or false;
+
+	if(RESIZE_NEEDED) then
+		frame:SetSize(UNIT_WIDTH + (MASTER_X1_OFFSET + MASTER_X2_OFFSET), UNIT_HEIGHT + (MASTER_TOP_OFFSET + MASTER_BOTTOM_OFFSET))
+		if(frame.Grip) then frame.Grip:SetSize(frame:GetSize()) end
+	end
+
+	MASTER_GRIP:ClearAllPoints();
+	MASTER_GRIP:SetPoint(TOP_ANCHOR2, frame, TOP_ANCHOR2, ((MASTER_X1_OFFSET + PORTRAIT_WIDTH) * TOP_MODIFIER), MASTER_TOP_OFFSET);
+	MASTER_GRIP:SetPoint(BOTTOM_ANCHOR2, frame, BOTTOM_ANCHOR2, (MASTER_X2_OFFSET * BOTTOM_MODIFIER), MASTER_BOTTOM_OFFSET);
+	self:UpdateStatusMedia(frame)
+
+	if(frame.InfoPanelBG) then
+		if(SV.db.UnitFrames.infoBackgrounds) then
+			frame.InfoPanelBG:SetColorTexture(1,1,1,1)
+			frame.InfoPanelLeft:SetColorTexture(1,1,1,1)
+			frame.InfoPanelRight:SetColorTexture(1,1,1,1)
+		else
+			frame.InfoPanelBG:SetColorTexture(0,0,0,0)
+			frame.InfoPanelLeft:SetColorTexture(0,0,0,0)
+			frame.InfoPanelRight:SetColorTexture(0,0,0,0)
+		end
+	end
+
+	--[[ THREAT LAYOUT ]]--
+
+	if frame.Threat then
+		local threat = frame.Threat;
+		if db.threatEnabled then
+			if not frame:IsElementEnabled('Threat')then
+				frame:EnableElement('Threat')
+			end
+		elseif frame:IsElementEnabled('Threat')then
+			frame:DisableElement('Threat')
+		end
+	end
+
+	--[[ TARGETGLOW LAYOUT ]]--
+
+	if frame.TargetGlow then
+		local glow = frame.TargetGlow;
+		glow:ClearAllPoints()
+		glow:SetPoint("TOPLEFT", -3, 3)
+		glow:SetPoint("TOPRIGHT", 3, 3)
+		glow:SetPoint("BOTTOMLEFT", -3, -3)
+		glow:SetPoint("BOTTOMRIGHT", 3, -3)
+	end
+
+	--[[ INFO TEXTS ]]--
+	local point,cX,cY;
+
+	if(TEXT_GRIP.Name and db.name) then
+		local nametext = TEXT_GRIP.Name
+		if(GRID_MODE) then
+			nametext:ClearAllPoints()
+			nametext:SetPoint("CENTER", frame, "CENTER", 0, 0)
+			nametext:SetJustifyH("CENTER")
+			nametext:SetJustifyV("MIDDLE")
+			if(db.name.tags ~= nil and db.name.tags ~= '') then
+				frame:Tag(nametext, "[name:grid]")
+			end
+		else
+			point = db.name.position
+			cX = db.name.xOffset
+			cY = db.name.yOffset
+			nametext:ClearAllPoints()
+			SV:SetReversePoint(nametext, point, TEXT_GRIP, cX, cY)
+
+			if(nametext.initialAnchor:find("RIGHT")) then
+				nametext:SetJustifyH("RIGHT")
+			elseif(nametext.initialAnchor:find("LEFT")) then
+				nametext:SetJustifyH("LEFT")
+			else
+				nametext:SetJustifyH("CENTER")
+			end
+
+			if(nametext.initialAnchor:find("TOP")) then
+				nametext:SetJustifyV("TOP")
+			elseif(nametext.initialAnchor:find("BOTTOM")) then
+				nametext:SetJustifyV("BOTTOM")
+			else
+				nametext:SetJustifyV("MIDDLE")
+			end
+
+			frame:Tag(nametext, db.name.tags)
+		end
+	end
+
+	if(frame.Health and TEXT_GRIP.Health and db.health) then
+		if(GRID_MODE) then
+			TEXT_GRIP.Health:Hide()
+		else
+			if(not TEXT_GRIP.Health:IsShown()) then TEXT_GRIP.Health:Show() end
+			local healthtext = TEXT_GRIP.Health
+			point = db.health.position
+			cX = db.health.xOffset
+			cY = db.health.yOffset
+			healthtext:ClearAllPoints()
+			SV:SetReversePoint(healthtext, point, TEXT_GRIP, cX, cY)
+			frame:Tag(healthtext, db.health.tags)
+		end
+	end
+
+	if(POWER_GRIP and TEXT_GRIP.Power and db.power) then
+		if(GRID_MODE) then
+			TEXT_GRIP.Power:Hide()
+		else
+			if(not TEXT_GRIP.Power:IsShown()) then TEXT_GRIP.Power:Show() end
+			local powertext = TEXT_GRIP.Power
+			if(db.power.tags ~= nil and db.power.tags ~= '') then
+				point = db.power.position
+				cX = db.power.xOffset
+				cY = db.power.yOffset
+				powertext:ClearAllPoints()
+				SV:SetReversePoint(powertext, point, TEXT_GRIP, cX, cY)
+			end
+			frame:Tag(powertext, db.power.tags)
+		end
+	end
+
+	if(TEXT_GRIP.Misc and db.misc) then
+		if(GRID_MODE) then
+			TEXT_GRIP.Misc:Hide()
+		else
+			if(not TEXT_GRIP.Misc:IsShown()) then TEXT_GRIP.Misc:Show() end
+			frame:Tag(TEXT_GRIP.Misc, db.misc.tags)
+		end
+	end
+
+	--[[ HEALTH LAYOUT ]]--
+
+	do
+		local health = frame.Health;
+		if(db.health and (db.health.reversed  ~= nil)) then
+			health.fillInverted = db.health.reversed;
+		else
+			health.fillInverted = false
+		end
+
+		health.Smooth = SV.db.UnitFrames.smoothbars;
+		health.colorSmooth = nil;
+		health.colorHealth = nil;
+		health.colorClass = nil;
+		health.colorBackdrop = nil;
+		health.colorReaction = nil;
+		health.colorOverlay = nil;
+		health.overlayAnimation = PORTRAIT_OVERLAY_ANIMATION;
+
+		if((not GRID_MODE) and frame.HealPrediction) then
+			frame.HealPrediction["frequentUpdates"] = health.frequentUpdates
+		end
+
+		if((not GRID_MODE) and PORTRAIT_OVERLAY and SV.db.UnitFrames.forceHealthColor) then
+			health.colorOverlay = true;
+		else
+			local CLASSCOLOR = db.health.classColor or false;
+			local VALUECOLOR = (not CLASSCOLOR and db.health.valueColor) or false;
+
+			health.colorClass = CLASSCOLOR;
+			health.colorReaction = CLASSCOLOR;
+			health.colorSmooth = VALUECOLOR;
+			health.colorHealth = ((not CLASSCOLOR) and (not VALUECOLOR)) or false;
+			health.colorBackdrop = db.health.classBackdrop;
+		end
+
+		health:ClearAllPoints()
+		health:SetAllPoints(MASTER_GRIP)
+
+		health.gridMode = GRID_MODE;
+
+		if(db.health and db.health.orientation) then
+			health:SetOrientation(GRID_MODE and "VERTICAL" or db.health.orientation)
+		end
+
+		if(frame.RefreshHealthBar) then
+			frame:RefreshHealthBar(PORTRAIT_OVERLAY)
+		end
+	end
+
+	--[[ POWER LAYOUT ]]--
+
+	do
+		if(POWER_GRIP) then
+			if(POWER_ENABLED) then
+				if(not frame:IsElementEnabled('Power')) then
+					frame:EnableElement('Power')
+					POWER_GRIP:Show()
+				end
+
+				POWER_GRIP.Smooth = SV.db.UnitFrames.smoothbars;
+
+				POWER_GRIP.colorClass = nil;
+				POWER_GRIP.colorReaction = nil;
+				POWER_GRIP.colorPower = nil;
+
+				local CLASSCOLOR = db.power.classColor or false;
+				POWER_GRIP.colorClass = CLASSCOLOR;
+				POWER_GRIP.colorReaction = CLASSCOLOR;
+				POWER_GRIP.colorPower = (not CLASSCOLOR);
+				POWER_GRIP.frequentUpdates = db.power.frequentUpdates;
+
+				POWER_GRIP:ClearAllPoints()
+
+				if(db.power and POWER_POINT) then
+					local a1,a2,ax,ay,b1,b2,bx,by = unpack(POWER_POINT)
+
+					POWER_GRIP:SetPoint(a1, MASTER_GRIP, a2, ax, ay)
+					if(b1) then
+						POWER_GRIP:SetPoint(b1, MASTER_GRIP, b2, bx, by)
+					end
+					POWER_GRIP:SetSize((POWER_WIDTH - 2), (POWER_HEIGHT - 2))
+					POWER_GRIP.Panel:ClearAllPoints()
+
+					if(POWER_DETACHED) then
+						POWER_GRIP.Panel:WrapPoints(POWER_GRIP,2,2)
+						if(frame.InfoPanel) then
+							frame.InfoPanel:ClearAllPoints()
+							if(db.power.anchor == "BOTTOM") then
+								frame.InfoPanel:SetPoint("TOPLEFT", POWER_GRIP, "BOTTOMLEFT", 0, 1)
+								frame.InfoPanel:SetPoint("TOPRIGHT", POWER_GRIP, "BOTTOMRIGHT", 0, 1)
+							else
+								frame.InfoPanel:SetPoint("TOPLEFT", frame, "BOTTOMLEFT", 0, 1)
+								frame.InfoPanel:SetPoint("TOPRIGHT", frame, "BOTTOMRIGHT", 0, 1)
+							end
+						end
+					else
+						POWER_GRIP.Panel:WrapPoints(POWER_GRIP)
+					end
+				else
+					POWER_GRIP:SetHeight(POWER_HEIGHT - 2)
+					POWER_GRIP:SetPoint(BOTTOM_ANCHOR1, MASTER_GRIP, BOTTOM_ANCHOR1, (1 * TOP_MODIFIER), 1)
+					POWER_GRIP:SetPoint(BOTTOM_ANCHOR2, MASTER_GRIP, BOTTOM_ANCHOR2, (1 * BOTTOM_MODIFIER), 1)
+				end
+
+				if(db.power and db.power.orientation) then
+					POWER_GRIP:SetOrientation(db.power.orientation)
+				end
+			elseif(frame:IsElementEnabled('Power')) then
+				frame:DisableElement('Power')
+				POWER_GRIP:Hide()
+			end
+		end
+
+		--[[ ALTPOWER LAYOUT ]]--
+
+		if(frame.AltPowerBar) then
+			local altPower = frame.AltPowerBar;
+			if(db.power.enable) then
+				local Alt_OnShow = function()
+					if(not POWER_DETACHED) then
+						MASTER_GRIP:SetPoint(TOP_ANCHOR2, frame, TOP_ANCHOR2, PORTRAIT_WIDTH, -(POWER_HEIGHT + 1))
+					end
+				end
+
+				local Alt_OnHide = function()
+					if(not POWER_DETACHED) then
+						MASTER_GRIP:SetPoint(TOP_ANCHOR2, frame, TOP_ANCHOR2, PORTRAIT_WIDTH, -1)
+					end
+					altPower.text:SetText("")
+				end
+
+				frame:EnableElement('AltPowerBar')
+				if(TEXT_GRIP.Health) then
+					altPower.text:SetFont(TEXT_GRIP.Health:GetFont())
+				end
+				altPower.text:SetAlpha(1)
+				altPower:SetPoint(TOP_ANCHOR2, frame, TOP_ANCHOR2, PORTRAIT_WIDTH, -1)
+				altPower:SetPoint(TOP_ANCHOR1, frame, TOP_ANCHOR1, (1 * BOTTOM_MODIFIER), -1)
+				altPower:SetHeight(POWER_HEIGHT)
+				altPower.Smooth = SV.db.UnitFrames.smoothbars;
+				altPower:HookScript("OnShow", Alt_OnShow)
+				altPower:HookScript("OnHide", Alt_OnHide)
+			else
+				frame:DisableElement('AltPowerBar')
+				altPower.text:SetAlpha(0)
+				altPower:Hide()
+			end
+		end
+	end
+
+	--[[ PORTRAIT LAYOUT ]]--
+
+	if(PORTRAIT_GRIP) then
+		local PORTRAIT = frame.Portrait;
+
+		if(PORTRAIT and PORTRAIT_ENABLED) then
+			if not frame:IsElementEnabled('Portrait')then
+				frame:EnableElement('Portrait')
+			end
+
+			PORTRAIT_GRIP:SetAlpha(1)
+			PORTRAIT_GRIP:ClearAllPoints()
+			if(PORTRAIT_OVERLAY) then
+				PORTRAIT_GRIP:InsetPoints(MASTER_GRIP,2,2)
+				PORTRAIT_GRIP.Outline:Hide()
+			else
+				PORTRAIT_GRIP:SetPoint(TOP_ANCHOR1, MASTER_GRIP, TOP_ANCHOR2, 0, -2)
+				PORTRAIT_GRIP:SetPoint(BOTTOM_ANCHOR2, MASTER_GRIP, BOTTOM_ANCHOR1, 0, 2)
+				PORTRAIT_GRIP:SetWidth(PORTRAIT_WIDTH - 2)
+				PORTRAIT_GRIP.Outline:Show()
+			end
+
+			if(PORTRAIT.ForceUpdate) then PORTRAIT:ForceUpdate() end
+
+			PORTRAIT_GRIP:Show()
+		else
+			PORTRAIT_GRIP:Hide()
+
+			if frame:IsElementEnabled('Portrait') then
+				frame:DisableElement('Portrait')
+			end
+		end
+	end
+
+	--[[ CASTBAR LAYOUT ]]--
+
+	if(db.castbar and frame.Castbar) then
+		local castbar = frame.Castbar;
+		local castHeight = db.castbar.height;
+		local castWidth
+		if(db.castbar.matchFrameWidth) then
+			castWidth = UNIT_WIDTH
+		else
+			castWidth = db.castbar.width
+		end
+		local sparkSize = castHeight * 3;
+		--local adjustedWidth = castWidth - 2;
+		local lazerScale = castHeight * 1.8;
+
+		if(db.castbar.format) then castbar.TimeFormat = db.castbar.format end
+
+		if(not castbar.pewpew) then
+			castbar:SetSize(castWidth, castHeight)
+		elseif(castbar:GetHeight() ~= lazerScale) then
+			castbar:SetSize(castWidth, lazerScale)
+		end
+
+		if castbar.Spark then
+			if(db.castbar.spark) then
+				castbar.Spark:Show()
+				castbar.Spark:SetSize(sparkSize, sparkSize)
+				if castbar.Spark[1] and castbar.Spark[2] then
+					castbar.Spark[1]:SetAllPoints(castbar.Spark)
+					castbar.Spark[2]:InsetPoints(castbar.Spark, 4, 4)
+				end
+				castbar.Spark.SetHeight = SV.fubar
+			else
+				castbar.Spark:Hide()
+			end
+		end
+		castbar:SetFrameStrata("HIGH")
+		if castbar.Holder then
+			castbar.Holder:SetSize((castWidth + 2), (castHeight + 6))
+			local holderUpdate = castbar.Holder:GetScript('OnSizeChanged')
+			if holderUpdate then
+				holderUpdate(castbar.Holder)
+			end
+		end
+		castbar:GetStatusBarTexture():SetHorizTile(false)
+		if db.castbar.latency then
+			castbar.SafeZone = castbar.LatencyTexture;
+			castbar.LatencyTexture:Show()
+		else
+			castbar.SafeZone = nil;
+			castbar.LatencyTexture:Hide()
+		end
+
+		if castbar.Organizer then
+			local orgSize = castHeight + 2
+			castbar.Organizer:SetSize(orgSize, orgSize)
+		end
+
+		if castbar.Icon then
+			if db.castbar.icon then
+				castbar.Organizer.Icon:SetAllPoints(castbar.Organizer)
+				castbar.Organizer.Icon:Show()
+			else
+				castbar.Organizer.Icon:Hide()
+			end
+		end
+
+		local cr,cg,cb
+		if(db.castbar.useCustomColor) then
+			cr,cg,cb = db.castbar.castingColor[1], db.castbar.castingColor[2], db.castbar.castingColor[3];
+			castbar.CastColor = {cr,cg,cb}
+			cr,cg,cb = db.castbar.sparkColor[1], db.castbar.sparkColor[2], db.castbar.sparkColor[3];
+			castbar.SparkColor = {cr,cg,cb}
+		else
+			castbar.CastColor = oUF_SVUI.colors.casting
+			castbar.SparkColor = oUF_SVUI.colors.spark
+		end
+
+		if db.castbar.enable and not frame:IsElementEnabled('Castbar')then
+			frame:EnableElement('Castbar')
+		elseif not db.castbar.enable and frame:IsElementEnabled('Castbar')then
+			frame:DisableElement('Castbar')
+		end
+	end
+
+	--[[ AURA LAYOUT ]]--
+
+	if(BUFF_GRIP or DEBUFF_GRIP) then
+		if((not BUFF_ENABLED) and (not DEBUFF_ENABLED)) then
+			if(frame:IsElementEnabled('Aura')) then
+				frame:DisableElement('Aura')
+			end
+			BUFF_GRIP:Hide()
+			DEBUFF_GRIP:Hide()
+		else
+			if(not frame:IsElementEnabled('Aura')) then
+				frame:EnableElement('Aura')
+			end
+
+			if(BUFF_GRIP) then
+				if(BUFF_ENABLED) then
+					BUFF_GRIP:Show()
+
+					local rows 		= db.buffs.numrows;
+					local columns = db.buffs.perrow;
+					local spacing = db.buffs.spacing;
+					local count 	= columns * rows;
+					local auraSize;
+
+					if(BUFF_GRIP.Bars and BUFF_GRIP.Icons) then
+						BUFF_GRIP.UseBars = db.buffs.useBars or false;
+						--if(template == 'player') then print(db.buffs.useBars) end
+						if(BUFF_GRIP.UseBars and (BUFF_GRIP.UseBars == true)) then
+							count = db.buffs.barCount;
+							if(db.buffs.anchorPoint == "BELOW") then
+								BUFF_GRIP.down = true
+							else
+								BUFF_GRIP.down = false
+							end
+							--if(template == 'player') then print('WIPING BUFF ICONS') end
+							for i = 1, #BUFF_GRIP.Icons do
+								BUFF_GRIP.Icons[i]:Hide()
+							end
+						else
+							--if(template == 'player') then print('WIPING BUFF BARS') end
+							for i = 1, #BUFF_GRIP.Bars do
+								BUFF_GRIP.Bars[i]:Hide()
+							end
+						end
+					end
+
+					if(db.buffs.sizeOverride and db.buffs.sizeOverride > 0) then
+						auraSize = db.buffs.sizeOverride
+						BUFF_GRIP.barHeight = db.buffs.sizeOverride
+					else
+						local tempSize = (((UNIT_WIDTH + spacing) - (spacing * (columns - 1))) / columns);
+						auraSize = min(BEST_SIZE, tempSize)
+						BUFF_GRIP.barHeight = 16
+					end
+
+					if(db.buffs.barWidthOverride and db.buffs.barWidthOverride > 0) then
+						BUFF_GRIP.barWidth = db.buffs.barWidthOverride
+					else
+						BUFF_GRIP.barWidth = nil
+					end
+
+					BUFF_GRIP.spacing  		= spacing;
+					BUFF_GRIP.auraSize  	= auraSize;
+					BUFF_GRIP.maxCount 		= GRID_MODE and 0 or count;
+					BUFF_GRIP.maxRows 		= rows;
+					BUFF_GRIP.maxColumns 	= columns;
+					BUFF_GRIP.forceShow 	= frame.forceShowAuras;
+
+					local attachTo = db.buffs.attachTo;
+					if(attachTo == 'DEBUFFS' and (not DEBUFF_ENABLED)) then
+						attachTo = 'FRAME'
+					end
+
+					local attachAnchor = FindAnchorFrame(frame, attachTo, attachTo == 'DEBUFFS' and db.debuffs.attachTo == 'BUFFS')
+					BUFF_GRIP:ClearAllPoints()
+					SV:SetReversePoint(BUFF_GRIP, db.buffs.anchorPoint, attachAnchor, db.buffs.xOffset + BOTTOM_MODIFIER, db.buffs.yOffset)
+					BUFF_GRIP["growth-y"] = db.buffs.verticalGrowth;
+					BUFF_GRIP["growth-x"] = db.buffs.horizontalGrowth;
+					BUFF_GRIP:SetSorting(db.buffs.sort)
+					BUFF_GRIP:ForceUpdate()
+				else
+					BUFF_GRIP:Hide()
+				end
+			end
+			if(DEBUFF_GRIP) then
+				if(DEBUFF_ENABLED) then
+					DEBUFF_GRIP:Show()
+					local rows 		= db.debuffs.numrows;
+					local columns = db.debuffs.perrow;
+					local spacing = db.debuffs.spacing;
+					local count 	= columns * rows;
+					local auraSize;
+
+					if(DEBUFF_GRIP.Bars and DEBUFF_GRIP.Icons) then
+						DEBUFF_GRIP.UseBars = db.debuffs.useBars or false;
+						if(DEBUFF_GRIP.UseBars and (DEBUFF_GRIP.UseBars == true)) then
+							count = db.debuffs.barCount;
+							if(db.debuffs.anchorPoint == "BELOW") then
+								DEBUFF_GRIP.down = true
+							else
+								DEBUFF_GRIP.down = false
+							end
+							for i = 1, #DEBUFF_GRIP.Icons do
+								DEBUFF_GRIP.Icons[i]:Hide()
+							end
+						else
+							for i = 1, #DEBUFF_GRIP.Bars do
+								DEBUFF_GRIP.Bars[i]:Hide()
+							end
+						end
+					end
+
+					if(db.debuffs.sizeOverride and db.debuffs.sizeOverride > 0) then
+						auraSize = db.debuffs.sizeOverride
+						DEBUFF_GRIP.barHeight = db.debuffs.sizeOverride
+					else
+						local tempSize = (((UNIT_WIDTH + spacing) - (spacing * (columns - 1))) / columns);
+						auraSize = min(BEST_SIZE, tempSize)
+						DEBUFF_GRIP.barHeight = 16
+					end
+
+					if(db.debuffs.barWidthOverride and db.debuffs.barWidthOverride > 0) then
+						DEBUFF_GRIP.barWidth = db.debuffs.barWidthOverride
+					else
+						DEBUFF_GRIP.barWidth = nil
+					end
+
+					DEBUFF_GRIP.spacing  = spacing;
+					DEBUFF_GRIP.auraSize  	= auraSize;
+					DEBUFF_GRIP.maxRows 	= rows;
+					DEBUFF_GRIP.maxColumns 	= columns;
+					DEBUFF_GRIP.maxCount 	= GRID_MODE and 0 or count;
+					DEBUFF_GRIP.forceShow 	= frame.forceShowAuras;
+
+					local attachTo = db.debuffs.attachTo;
+					if(attachTo == 'BUFFS' and (not BUFF_ENABLED)) then
+						attachTo = 'FRAME'
+					end
+
+					local attachAnchor = FindAnchorFrame(frame, attachTo, attachTo == 'BUFFS' and db.buffs.attachTo == 'DEBUFFS')
+					DEBUFF_GRIP:ClearAllPoints()
+					SV:SetReversePoint(DEBUFF_GRIP, db.debuffs.anchorPoint, attachAnchor, db.debuffs.xOffset + BOTTOM_MODIFIER, db.debuffs.yOffset)
+					DEBUFF_GRIP["growth-y"] = db.debuffs.verticalGrowth;
+					DEBUFF_GRIP["growth-x"] = db.debuffs.horizontalGrowth;
+					DEBUFF_GRIP:SetSorting(db.debuffs.sort)
+					DEBUFF_GRIP:ForceUpdate()
+				else
+					DEBUFF_GRIP:Hide()
+				end
+			end
+		end
+	end
+
+	if(RAID_DEBUFFS) then
+		if RAID_DEBUFFS_ENABLED then
+			RAID_DEBUFFS.forceShow 	= frame.forceShowAuras;
+			if(not frame:IsElementEnabled("RaidDebuffs")) then
+				frame:EnableElement("RaidDebuffs")
+			end
+			local actualSz = db.rdebuffs.size
+			RAID_DEBUFFS:SetSize(actualSz, actualSz)
+			RAID_DEBUFFS:SetPoint("CENTER", frame, "CENTER", db.rdebuffs.xOffset, db.rdebuffs.yOffset)
+			RAID_DEBUFFS:Show()
+		else
+			RAID_DEBUFFS.forceShow 	= nil;
+			frame:DisableElement("RaidDebuffs")
+			RAID_DEBUFFS:Hide()
+		end
+	end
+
+	--[[ ICON LAYOUTS ]]--
+
+	do
+		if db.icons then
+			local ico = db.icons;
+
+			--[[ CLASS ICON ]]--
+
+			if(ico.classIcon and frame.ActionPanel.class) then
+				local classIcon = frame.ActionPanel.class;
+				if ico.classIcon.enable then
+					classIcon:Show()
+					local size = ico.classIcon.size;
+					classIcon:ClearAllPoints()
+
+					classIcon:SetAlpha(1)
+					classIcon:SetSize(size, size)
+					SV:SetReversePoint(classIcon, ico.classIcon.attachTo, MASTER_GRIP, ico.classIcon.xOffset, ico.classIcon.yOffset)
+				else
+					classIcon:Hide()
+				end
+			end
+
+			--[[ RAIDICON ]]--
+
+			if(ico.raidicon and frame.RaidIcon) then
+				local raidIcon = frame.RaidIcon;
+				if ico.raidicon.enable then
+					raidIcon:Show()
+					frame:EnableElement('RaidIcon')
+					local size = ico.raidicon.size;
+					raidIcon:ClearAllPoints()
+
+					if(GRID_MODE) then
+						raidIcon:SetAlpha(0.7)
+						raidIcon:SetSize(10, 10)
+						raidIcon:SetPoint("TOP", MASTER_GRIP, "TOP", 0, 0)
+					else
+						raidIcon:SetAlpha(1)
+						raidIcon:SetSize(size, size)
+						SV:SetReversePoint(raidIcon, ico.raidicon.attachTo, MASTER_GRIP, ico.raidicon.xOffset, ico.raidicon.yOffset)
+					end
+				else
+					frame:DisableElement('RaidIcon')
+					raidIcon:Hide()
+				end
+			end
+
+			--[[ ROLEICON ]]--
+
+			if(ico.roleIcon and frame.LFDRole) then
+				local lfd = frame.LFDRole;
+				if(not MINI_GRID and ico.roleIcon.enable) then
+					lfd:Show()
+					frame:EnableElement('LFDRole')
+					local size = ico.roleIcon.size;
+					lfd:ClearAllPoints()
+
+					if(GRID_MODE) then
+						lfd:SetAlpha(0.7)
+						lfd:SetSize(10, 10)
+						lfd:SetPoint("BOTTOM", MASTER_GRIP, "BOTTOM", 0, 0)
+					else
+						lfd:SetAlpha(1)
+						lfd:SetSize(size, size)
+						SV:SetReversePoint(lfd, ico.roleIcon.attachTo, MASTER_GRIP, ico.roleIcon.xOffset, ico.roleIcon.yOffset)
+					end
+				else
+					frame:DisableElement('LFDRole')
+					lfd:Hide()
+				end
+			end
+
+			--[[ RAIDROLEICON ]]--
+
+			if(ico.raidRoleIcons and frame.RaidRoleFramesAnchor) then
+				local roles = frame.RaidRoleFramesAnchor;
+				if(not MINI_GRID and ico.raidRoleIcons.enable) then
+					roles:Show()
+					frame:EnableElement('Leader')
+					frame:EnableElement('MasterLooter')
+					local size = ico.raidRoleIcons.size;
+					roles:ClearAllPoints()
+
+					if(GRID_MODE) then
+						roles:SetAlpha(0.7)
+						roles:SetSize(10, 10)
+						roles:SetPoint("CENTER", MASTER_GRIP, "TOPLEFT", 0, 2)
+					else
+						roles:SetAlpha(1)
+						roles:SetSize(size, size)
+						SV:SetReversePoint(roles, ico.raidRoleIcons.attachTo, MASTER_GRIP, ico.raidRoleIcons.xOffset, ico.raidRoleIcons.yOffset)
+					end
+				else
+					roles:Hide()
+					frame:DisableElement('Leader')
+					frame:DisableElement('MasterLooter')
+				end
+			end
+
+		end
+	end
+
+	--[[ HEAL PREDICTION LAYOUT ]]--
+
+	if frame.HealPrediction then
+		if db.predict then
+			if not frame:IsElementEnabled('HealPrediction')then
+				frame:EnableElement('HealPrediction')
+			end
+		else
+			if frame:IsElementEnabled('HealPrediction')then
+				frame:DisableElement('HealPrediction')
+			end
+		end
+	end
+
+	--[[ DEBUFF HIGHLIGHT LAYOUT ]]--
+
+	if frame.Afflicted then
+		if SV.db.UnitFrames.debuffHighlighting then
+			frame.Afflicted.forceShow 	= frame.forceShowHighlights;
+			frame.Afflicted:ClearAllPoints()
+			frame.Afflicted:SetAllPoints(MASTER_GRIP)
+			-- if(template ~= "player" and template ~= "target" and template ~= "focus") then
+			-- 	frame.Afflicted.Texture:SetTexture(SV.BaseTexture)
+			-- end
+			frame:EnableElement('Afflicted')
+		else
+			frame.Afflicted.forceShow 	= nil;
+			frame:DisableElement('Afflicted')
+		end
+	end
+
+	--[[ RANGE CHECK LAYOUT ]]--
+
+	if frame.Range then
+		if(template:find("raid") or template:find("party")) then
+			frame.Range.outsideAlpha = SV.db.UnitFrames.groupOORAlpha or 1
+		else
+			frame.Range.outsideAlpha = SV.db.UnitFrames.OORAlpha or 1
+		end
+
+		if db.rangeCheck then
+			if not frame:IsElementEnabled('Range')then
+				frame:EnableElement('Range')
+			end
+		else
+			if frame:IsElementEnabled('Range')then
+				frame:DisableElement('Range')
+			end
+		end
+	end
+
+	--[[ AURA WATCH LAYOUT ]]--
+
+	if(frame.AuraWatch) then
+		if(db.auraWatch) then
+			if db.auraWatch.enable then
+				if not frame:IsElementEnabled('AuraWatch')then
+					frame:EnableElement('AuraWatch')
+				end
+				frame.AuraWatch:ForceUpdate()
+			else
+				if frame:IsElementEnabled('AuraWatch')then
+					frame:DisableElement('AuraWatch')
+				end
+			end
+		end
+	end
+
+	if(frame.XRay) then
+        if(SV.db.UnitFrames.xrayFocus) then
+            frame.XRay:Show()
+        else
+            frame.XRay:Hide()
+        end
+    end
+
+	if(self.PostRefreshUpdate) then
+		self:PostRefreshUpdate(frame, template)
+	end
+end
+--[[
+##########################################################
+EVENTS AND INITIALIZE
+##########################################################
+]]--
+function MOD:FrameForge()
+	if not LoadedUnitFrames then
+		self:SetUnitFrame("player")
+		self:SetUnitFrame("pet")
+		self:SetUnitFrame("pettarget")
+		self:SetUnitFrame("target")
+		self:SetUnitFrame("targettarget")
+		self:SetUnitFrame("focus")
+		self:SetUnitFrame("focustarget")
+		self:SetEnemyFrame("boss", MAX_BOSS_FRAMES)
+		self:SetEnemyFrame("arena", 5)
+		LoadedUnitFrames = true;
+	end
+	if not LoadedGroupHeaders then
+		self:SetGroupFrame("tank")
+		self:SetGroupFrame("assist")
+		self:SetGroupFrame("raid")
+		self:SetGroupFrame("raidpet")
+		self:SetGroupFrame("party")
+		LoadedGroupHeaders = true
+	end
+	if(self.PostFrameForge) then
+		self:PostFrameForge()
+	end
+end
+
+function MOD:KillBlizzardRaidFrames()
+	if(InCombatLockdown()) then return end
+	if((not _G.CompactRaidFrameManager) or (not _G.CompactRaidFrameContainer) or (not _G.CompactUnitFrameProfiles)) then return end
+	_G.CompactRaidFrameManager:Die()
+	_G.CompactRaidFrameContainer:Die()
+	_G.CompactUnitFrameProfiles:Die()
+	local crfmTest = CompactRaidFrameManager_GetSetting("IsShown")
+	if crfmTest and crfmTest ~= "0" then
+		CompactRaidFrameManager_SetSetting("IsShown", "0")
+	end
+end
+
+function MOD:PLAYER_REGEN_DISABLED()
+	for _,frame in pairs(self.Headers) do
+		if frame and frame.forceShow then
+			self:ViewGroupFrames(frame)
+		end
+	end
+
+	for _,frame in pairs(self.Units) do
+		if(frame and frame.forceShow and frame.Restrict) then
+			frame:Restrict()
+		end
+	end
+end
+
+function MOD:PLAYER_REGEN_ENABLED()
+	self:UnregisterEvent("PLAYER_REGEN_ENABLED");
+	self:RefreshUnitFrames()
+end
+
+function MOD:ADDON_LOADED(event, addon)
+	self:KillBlizzardRaidFrames()
+	if addon == 'Blizzard_ArenaUI' then
+		oUF_SVUI:DisableBlizzard('arena')
+		self:UnregisterEvent("ADDON_LOADED")
+	end
+end
+
+function MOD:PLAYER_ENTERING_WORLD()
+	if(not SV.NeedsFrameAudit) then
+		self:RefreshUnitFrames()
+	end
+end
+
+local UnitFrameThreatIndicator_Hook = function(unit, unitFrame)
+	unitFrame:UnregisterAllEvents()
+end
+--[[
+##########################################################
+CLASS SPECIFIC INFO
+##########################################################
+]]--
+local RefMagicSpec;
+local PlayerClass = select(2,UnitClass("player"));
+local droodSpell1, droodSpell2 = GetSpellInfo(110309), GetSpellInfo(4987);
+
+if(PlayerClass == "PRIEST") then
+    MOD.Dispellable = {["Magic"] = true, ["Disease"] = true}
+elseif(PlayerClass == "MAGE") then
+    MOD.Dispellable = {["Curse"] = true}
+elseif(PlayerClass == "DRUID") then
+    RefMagicSpec = 4
+    MOD.Dispellable = {["Curse"] = true, ["Poison"] = true}
+elseif(PlayerClass == "SHAMAN") then
+    RefMagicSpec = 3
+    MOD.Dispellable = {["Curse"] = true}
+elseif(PlayerClass == "MONK") then
+    RefMagicSpec = 2
+    MOD.Dispellable = {["Disease"] = true, ["Poison"] = true}
+elseif(PlayerClass == "PALADIN") then
+    RefMagicSpec = 1
+    MOD.Dispellable = {["Poison"] = true, ["Disease"] = true}
+end
+
+local function GetTalentInfo(arg)
+    if type(arg) == "number" then
+        return arg == GetActiveSpecGroup();
+    else
+        return false;
+    end
+end
+
+function MOD:CanClassDispel()
+	if RefMagicSpec then
+    if(GetTalentInfo(RefMagicSpec)) then
+      self.Dispellable["Magic"] = true
+    elseif(self.Dispellable["Magic"]) then
+      self.Dispellable["Magic"] = nil
+    end
+  end
+end
+
+function MOD:SPELLS_CHANGED()
+	if (PlayerClass ~= "DRUID") then
+		self:UnregisterEvent("SPELLS_CHANGED")
+		return
+	end
+	if GetSpellInfo(droodSpell1) == droodSpell2 then
+		self.Dispellable["Disease"] = true
+	elseif(self.Dispellable["Disease"]) then
+		self.Dispellable["Disease"] = nil
+	end
+end
+--[[
+##########################################################
+BUILD FUNCTION / UPDATE
+##########################################################
+]]--
+function MOD:ReLoad()
+	self:RefreshUnitFrames()
+end
+
+function MOD:Load()
+	self:RefreshUnitColors()
+
+	local SVUI_UnitFrameParent = CreateFrame("Frame", "SVUI_UnitFrameParent", SV.Screen, "SecureHandlerStateTemplate")
+	RegisterStateDriver(SVUI_UnitFrameParent, "visibility", "[petbattle] hide; show")
+
+	self:CanClassDispel()
+
+	self:FrameForge()
+	self:RegisterEvent("PLAYER_ENTERING_WORLD")
+	self:RegisterEvent("PLAYER_REGEN_DISABLED")
+	self:RegisterEvent("SPELLS_CHANGED")
+
+	self:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED", "CanClassDispel")
+	self:RegisterEvent("PLAYER_TALENT_UPDATE", "CanClassDispel")
+	self:RegisterEvent("CHARACTER_POINTS_CHANGED", "CanClassDispel")
+	self:RegisterEvent("UNIT_INVENTORY_CHANGED", "CanClassDispel")
+	self:RegisterEvent("UPDATE_BONUS_ACTIONBAR", "CanClassDispel")
+
+	if(SV.db.UnitFrames.disableBlizzard) then
+		self:KillBlizzardRaidFrames()
+		hooksecurefunc("CompactUnitFrame_RegisterEvents", CompactUnitFrame_UnregisterEvents)
+		hooksecurefunc("UnitFrameThreatIndicator_Initialize", UnitFrameThreatIndicator_Hook)
+
+		--[[
+		InterfaceOptionsFrameCategoriesButton10:SetScale(0.0001)
+		InterfaceOptionsFrameCategoriesButton11:SetScale(0.0001)
+		InterfaceOptionsStatusTextPanelPlayer:SetScale(0.0001)
+		InterfaceOptionsStatusTextPanelTarget:SetScale(0.0001)
+		InterfaceOptionsStatusTextPanelParty:SetScale(0.0001)
+		InterfaceOptionsStatusTextPanelPet:SetScale(0.0001)
+		InterfaceOptionsStatusTextPanelPlayer:SetAlpha(0)
+		InterfaceOptionsStatusTextPanelTarget:SetAlpha(0)
+		InterfaceOptionsStatusTextPanelParty:SetAlpha(0)
+		InterfaceOptionsStatusTextPanelPet:SetAlpha(0)
+		InterfaceOptionsCombatPanelEnemyCastBarsOnPortrait:SetAlpha(0)
+		InterfaceOptionsCombatPanelEnemyCastBarsOnPortrait:EnableMouse(false)
+		InterfaceOptionsCombatPanelTargetOfTarget:SetScale(0.0001)
+		InterfaceOptionsCombatPanelTargetOfTarget:SetAlpha(0)
+		InterfaceOptionsCombatPanelEnemyCastBarsOnNameplates:ClearAllPoints()
+		InterfaceOptionsCombatPanelEnemyCastBarsOnNameplates:SetPoint(InterfaceOptionsCombatPanelEnemyCastBarsOnPortrait:GetPoint())
+		InterfaceOptionsDisplayPanelShowAggroPercentage:SetScale(0.0001)
+		InterfaceOptionsDisplayPanelShowAggroPercentage:SetAlpha(0)
+		]]--
+
+		if not IsAddOnLoaded("Blizzard_ArenaUI") then
+			self:RegisterEvent("ADDON_LOADED")
+		else
+			oUF_SVUI:DisableBlizzard("arena")
+		end
+
+		self:RegisterEvent("GROUP_ROSTER_UPDATE", "KillBlizzardRaidFrames")
+		UIParent:UnregisterEvent("GROUP_ROSTER_UPDATE")
+	elseif(CompactUnitFrameProfiles) then
+		CompactUnitFrameProfiles:RegisterEvent("VARIABLES_LOADED")
+	end
+
+	SV.Events:On("AURA_FILTER_OPTIONS_CHANGED", UpdateUnitFrames, true);
+
+	self:InitializeBodyGuard()
+
+	local rDebuffs = SV.oUF_RaidDebuffs or oUF_RaidDebuffs;
+	if not rDebuffs then return end
+	rDebuffs.ShowDispelableDebuff = true;
+	rDebuffs.FilterDispellableDebuff = true;
+	rDebuffs.MatchBySpellName = true;
+end
diff --git a/SVUI_UnitFrames/SVUI_UnitFrames.toc b/SVUI_UnitFrames/SVUI_UnitFrames.toc
new file mode 100644
index 0000000..10b60af
--- /dev/null
+++ b/SVUI_UnitFrames/SVUI_UnitFrames.toc
@@ -0,0 +1,17 @@
+## Interface: 70000
+## Author: Failcoder
+## Version: 1.3.5
+## Title: |cffFF9900SuperVillain UI: |r|cffFFEF00UnitFrames|r
+## Notes: UnitFrames Plugin for [|cff9911FFSVUI|r].
+## OptionalDeps: LibSharedMedia-3.0
+## RequiredDeps: SVUI_!Core
+## X-SVUIName: UnitFrames
+## X-SVUISchema: UnitFrames
+## X-oUF: oUF_SVUI
+## X-Email: munglunch@gmail.com
+## X-Website: http://www.supervillainui.com
+## X-Donate: PayPal:munglunch@gmail.com
+## X-License: MIT
+## X-Category: Interface Enhancements
+
+SVUI_UnitFrames.xml
diff --git a/SVUI_UnitFrames/SVUI_UnitFrames.xml b/SVUI_UnitFrames/SVUI_UnitFrames.xml
new file mode 100644
index 0000000..30f67b6
--- /dev/null
+++ b/SVUI_UnitFrames/SVUI_UnitFrames.xml
@@ -0,0 +1,142 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+    <Font name="SVUI_Font_Unit" font="Fonts\MORPHEUS.ttf" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="11"/>
+        </FontHeight>
+    </Font>
+
+    <Font name="SVUI_Font_Unit_Small" font="Fonts\MORPHEUS.ttf" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="11"/>
+        </FontHeight>
+    </Font>
+
+    <Font name="SVUI_Font_UnitAura" font="Fonts\ARIALN.TTF" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="10"/>
+        </FontHeight>
+    </Font>
+
+    <Font name="SVUI_Font_UnitAura_Bar" font="Fonts\skurri.ttf" virtual="true">
+        <Shadow>
+            <Offset>
+                <AbsDimension x="1" y="-1"/>
+            </Offset>
+            <Color r="0" g="0" b="0" a="0.25"/>
+        </Shadow>
+        <FontHeight>
+            <AbsValue val="10"/>
+        </FontHeight>
+    </Font>
+
+    <Font name="SVUI_Font_UnitAura_Small" font="Fonts\skurri.ttf" monochrome="true" virtual="true">
+        <FontHeight>
+            <AbsValue val="8"/>
+        </FontHeight>
+    </Font>
+
+    <Frame name="SVUI_StyleTemplate_ActionPanel" virtual="true">
+        <Attributes>
+            <Attribute name="panelID" type="string" value="actionpanel" />
+            <Attribute name="panelPadding" type="number" value="1" />
+            <Attribute name="panelColor" type="string" value="darkest" />
+            <Attribute name="panelGradient" type="boolean" value="false" />
+            <Attribute name="panelTexUpdate" type="boolean" value="false" />
+            <Attribute name="panelSkipUpdate" type="boolean" value="false" />
+        </Attributes>
+        <Backdrop bgFile="Interface\AddOns\SVUI_!Core\assets\textures\EMPTY" edgeFile="Interface\BUTTONS\WHITE8X8" tile="false">
+            <EdgeSize val="2" />
+            <TileSize val="0" />
+            <BackgroundInsets left="0" right="0" top="0" bottom="0" />
+            <Color r="0" g="0" b="0" a="0" />
+            <BorderColor r="0" g="0" b="0" a="1" />
+        </Backdrop>
+    </Frame>
+
+    <Button name="SVUI_UNITTARGET" inherits="SecureUnitButtonTemplate" hidden="true" virtual="true">
+        <Frames>
+            <Button name="$parentTarget" inherits="SecureUnitButtonTemplate">
+                <Anchors>
+                    <Anchor point="TOPLEFT" relativePoint="TOPRIGHT" relativeTo="$parent">
+                        <Offset>
+                            <AbsDimension x="7" y="0"/>
+                        </Offset>
+                    </Anchor>
+                </Anchors>
+                <Attributes>
+                    <Attribute name="unitsuffix" type="string" value="target"/>
+                    <Attribute name="useparent-unit" type="boolean" value="true"/>
+                    <Attribute name="type1" type="string" value="target"/>
+                    <Attribute name="initial-unitWatch" type="boolean" value="true"/>
+                </Attributes>
+            </Button>
+        </Frames>
+    </Button>
+
+    <Button name="SVUI_UNITPET" inherits="SecureUnitButtonTemplate" hidden="true" virtual="true">
+        <Frames>
+            <Button name="$parentPet" inherits="SecureUnitButtonTemplate">
+                <Anchors>
+                    <Anchor point="BOTTOM" relativePoint="TOP" relativeTo="$parent">
+                        <Offset>
+                            <AbsDimension x="0" y="1"/>
+                        </Offset>
+                    </Anchor>
+                </Anchors>
+                <Attributes>
+                    <Attribute name="unitsuffix" type="string" value="pet"/>
+                    <Attribute name="useparent-unit" type="boolean" value="true"/>
+                    <Attribute name="type1" type="string" value="target"/>
+                    <Attribute name="initial-unitWatch" type="boolean" value="true"/>
+                </Attributes>
+            </Button>
+        </Frames>
+    </Button>
+
+    <Script file="Loader.lua"/>
+    <Include file="libs\_load.xml"/>
+
+	<Script file="SVUI_UnitFrames.lua"/>
+
+	<Script file="elements\tags.lua"/>
+    <Script file="elements\essentials.lua"/>
+    <Script file="elements\castbar.lua"/>
+    <Script file="elements\auras.lua"/>
+    <Script file="elements\misc.lua"/>
+
+    <Script file="class_resources\deathknight.lua"/>
+    <Script file="class_resources\demonhunter.lua"/>
+    <Script file="class_resources\druid.lua"/>
+    <Script file="class_resources\hunter.lua"/>
+    <Script file="class_resources\mage.lua"/>
+    <Script file="class_resources\monk.lua"/>
+    <Script file="class_resources\paladin.lua"/>
+    <Script file="class_resources\priest.lua"/>
+    <Script file="class_resources\rogue.lua"/>
+    <Script file="class_resources\shaman.lua"/>
+    <Script file="class_resources\warlock.lua"/>
+    <Script file="class_resources\warrior.lua"/>
+
+    <Script file="frames.lua"/>
+    <Script file="groups.lua"/>
+    <Script file="view.lua"/>
+    <Script file="bodyguard.lua"/>
+</Ui>
diff --git a/SVUI_UnitFrames/assets/Border/ELITE-BOTTOM.blp b/SVUI_UnitFrames/assets/Border/ELITE-BOTTOM.blp
new file mode 100644
index 0000000..d56e49a
Binary files /dev/null and b/SVUI_UnitFrames/assets/Border/ELITE-BOTTOM.blp differ
diff --git a/SVUI_UnitFrames/assets/Border/ELITE-RIGHT.blp b/SVUI_UnitFrames/assets/Border/ELITE-RIGHT.blp
new file mode 100644
index 0000000..44b54a7
Binary files /dev/null and b/SVUI_UnitFrames/assets/Border/ELITE-RIGHT.blp differ
diff --git a/SVUI_UnitFrames/assets/Border/ELITE-TOP.blp b/SVUI_UnitFrames/assets/Border/ELITE-TOP.blp
new file mode 100644
index 0000000..6d79c92
Binary files /dev/null and b/SVUI_UnitFrames/assets/Border/ELITE-TOP.blp differ
diff --git a/SVUI_UnitFrames/assets/Castbar/CHANNEL-REVERSED.blp b/SVUI_UnitFrames/assets/Castbar/CHANNEL-REVERSED.blp
new file mode 100644
index 0000000..fcea6e7
Binary files /dev/null and b/SVUI_UnitFrames/assets/Castbar/CHANNEL-REVERSED.blp differ
diff --git a/SVUI_UnitFrames/assets/Castbar/CHANNEL.blp b/SVUI_UnitFrames/assets/Castbar/CHANNEL.blp
new file mode 100644
index 0000000..7d4ed7c
Binary files /dev/null and b/SVUI_UnitFrames/assets/Castbar/CHANNEL.blp differ
diff --git a/SVUI_UnitFrames/assets/Castbar/HADOUKEN-REVERSED.blp b/SVUI_UnitFrames/assets/Castbar/HADOUKEN-REVERSED.blp
new file mode 100644
index 0000000..b95b941
Binary files /dev/null and b/SVUI_UnitFrames/assets/Castbar/HADOUKEN-REVERSED.blp differ
diff --git a/SVUI_UnitFrames/assets/Castbar/HADOUKEN.blp b/SVUI_UnitFrames/assets/Castbar/HADOUKEN.blp
new file mode 100644
index 0000000..094f561
Binary files /dev/null and b/SVUI_UnitFrames/assets/Castbar/HADOUKEN.blp differ
diff --git a/SVUI_UnitFrames/assets/Castbar/SHIELD.blp b/SVUI_UnitFrames/assets/Castbar/SHIELD.blp
new file mode 100644
index 0000000..c84d8f4
Binary files /dev/null and b/SVUI_UnitFrames/assets/Castbar/SHIELD.blp differ
diff --git a/SVUI_UnitFrames/assets/Castbar/SKULLS-REVERSED.blp b/SVUI_UnitFrames/assets/Castbar/SKULLS-REVERSED.blp
new file mode 100644
index 0000000..52aa46e
Binary files /dev/null and b/SVUI_UnitFrames/assets/Castbar/SKULLS-REVERSED.blp differ
diff --git a/SVUI_UnitFrames/assets/Castbar/SKULLS.blp b/SVUI_UnitFrames/assets/Castbar/SKULLS.blp
new file mode 100644
index 0000000..ee4b50d
Binary files /dev/null and b/SVUI_UnitFrames/assets/Castbar/SKULLS.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/COMBO-ANIMATION.blp b/SVUI_UnitFrames/assets/Class/COMBO-ANIMATION.blp
new file mode 100644
index 0000000..6ba0d90
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/COMBO-ANIMATION.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/COMBO-POINT-SMALL.blp b/SVUI_UnitFrames/assets/Class/COMBO-POINT-SMALL.blp
new file mode 100644
index 0000000..f226600
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/COMBO-POINT-SMALL.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/DEATHKNIGHT-BLOOD.blp b/SVUI_UnitFrames/assets/Class/DEATHKNIGHT-BLOOD.blp
new file mode 100644
index 0000000..888bfac
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/DEATHKNIGHT-BLOOD.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/DEATHKNIGHT-DEATH.blp b/SVUI_UnitFrames/assets/Class/DEATHKNIGHT-DEATH.blp
new file mode 100644
index 0000000..c561573
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/DEATHKNIGHT-DEATH.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/DEATHKNIGHT-FROST.blp b/SVUI_UnitFrames/assets/Class/DEATHKNIGHT-FROST.blp
new file mode 100644
index 0000000..48cbb57
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/DEATHKNIGHT-FROST.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/DEATHKNIGHT-UNHOLY.blp b/SVUI_UnitFrames/assets/Class/DEATHKNIGHT-UNHOLY.blp
new file mode 100644
index 0000000..f1bca4a
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/DEATHKNIGHT-UNHOLY.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/DRUID-BITE.blp b/SVUI_UnitFrames/assets/Class/DRUID-BITE.blp
new file mode 100644
index 0000000..863d93d
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/DRUID-BITE.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/DRUID-CLAW-DOWN.blp b/SVUI_UnitFrames/assets/Class/DRUID-CLAW-DOWN.blp
new file mode 100644
index 0000000..ec9fce3
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/DRUID-CLAW-DOWN.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/DRUID-CLAW-UP.blp b/SVUI_UnitFrames/assets/Class/DRUID-CLAW-UP.blp
new file mode 100644
index 0000000..e7818f6
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/DRUID-CLAW-UP.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/DRUID-MOON.blp b/SVUI_UnitFrames/assets/Class/DRUID-MOON.blp
new file mode 100644
index 0000000..0c51858
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/DRUID-MOON.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/DRUID-SUN.blp b/SVUI_UnitFrames/assets/Class/DRUID-SUN.blp
new file mode 100644
index 0000000..b30d8d1
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/DRUID-SUN.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/HUNTER-TRAP-BG.blp b/SVUI_UnitFrames/assets/Class/HUNTER-TRAP-BG.blp
new file mode 100644
index 0000000..33c9691
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/HUNTER-TRAP-BG.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/HUNTER-TRAP.blp b/SVUI_UnitFrames/assets/Class/HUNTER-TRAP.blp
new file mode 100644
index 0000000..9fd68db
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/HUNTER-TRAP.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/MAGE-CHARGE.blp b/SVUI_UnitFrames/assets/Class/MAGE-CHARGE.blp
new file mode 100644
index 0000000..ed032c4
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/MAGE-CHARGE.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/MAGE-ICICLE-1.blp b/SVUI_UnitFrames/assets/Class/MAGE-ICICLE-1.blp
new file mode 100644
index 0000000..fc58a3e
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/MAGE-ICICLE-1.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/MAGE-ICICLE-2.blp b/SVUI_UnitFrames/assets/Class/MAGE-ICICLE-2.blp
new file mode 100644
index 0000000..5457703
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/MAGE-ICICLE-2.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/MAGE-ICICLE-3.blp b/SVUI_UnitFrames/assets/Class/MAGE-ICICLE-3.blp
new file mode 100644
index 0000000..2d8abdc
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/MAGE-ICICLE-3.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/MAGE-ICICLE-4.blp b/SVUI_UnitFrames/assets/Class/MAGE-ICICLE-4.blp
new file mode 100644
index 0000000..b07dc24
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/MAGE-ICICLE-4.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/MAGE-ICICLE-5.blp b/SVUI_UnitFrames/assets/Class/MAGE-ICICLE-5.blp
new file mode 100644
index 0000000..6cfe93c
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/MAGE-ICICLE-5.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/MONK-STAGGER-BAR.blp b/SVUI_UnitFrames/assets/Class/MONK-STAGGER-BAR.blp
new file mode 100644
index 0000000..d7ed883
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/MONK-STAGGER-BAR.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/MONK-STAGGER-BG.blp b/SVUI_UnitFrames/assets/Class/MONK-STAGGER-BG.blp
new file mode 100644
index 0000000..b7561c7
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/MONK-STAGGER-BG.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/MONK-STAGGER-FG.blp b/SVUI_UnitFrames/assets/Class/MONK-STAGGER-FG.blp
new file mode 100644
index 0000000..597765c
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/MONK-STAGGER-FG.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/MONK-STAGGER-ICON.blp b/SVUI_UnitFrames/assets/Class/MONK-STAGGER-ICON.blp
new file mode 100644
index 0000000..7fd8832
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/MONK-STAGGER-ICON.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/MONK.blp b/SVUI_UnitFrames/assets/Class/MONK.blp
new file mode 100644
index 0000000..6f98643
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/MONK.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/ORB-BG.blp b/SVUI_UnitFrames/assets/Class/ORB-BG.blp
new file mode 100644
index 0000000..726b595
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/ORB-BG.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/ORB.blp b/SVUI_UnitFrames/assets/Class/ORB.blp
new file mode 100644
index 0000000..27d34fd
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/ORB.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/PALADIN-HAMMER-BG.blp b/SVUI_UnitFrames/assets/Class/PALADIN-HAMMER-BG.blp
new file mode 100644
index 0000000..6440caf
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/PALADIN-HAMMER-BG.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/PALADIN-HAMMER-FG.blp b/SVUI_UnitFrames/assets/Class/PALADIN-HAMMER-FG.blp
new file mode 100644
index 0000000..9d77922
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/PALADIN-HAMMER-FG.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/PRIEST.blp b/SVUI_UnitFrames/assets/Class/PRIEST.blp
new file mode 100644
index 0000000..a442947
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/PRIEST.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/ROGUE-ANTICIPATION.blp b/SVUI_UnitFrames/assets/Class/ROGUE-ANTICIPATION.blp
new file mode 100644
index 0000000..3c849a7
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/ROGUE-ANTICIPATION.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/ROGUE-SMOKE.blp b/SVUI_UnitFrames/assets/Class/ROGUE-SMOKE.blp
new file mode 100644
index 0000000..248af68
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/ROGUE-SMOKE.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/ROGUE.blp b/SVUI_UnitFrames/assets/Class/ROGUE.blp
new file mode 100644
index 0000000..fd22d25
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/ROGUE.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/RUNES-BG.blp b/SVUI_UnitFrames/assets/Class/RUNES-BG.blp
new file mode 100644
index 0000000..b83d793
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/RUNES-BG.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/RUNES-FG.blp b/SVUI_UnitFrames/assets/Class/RUNES-FG.blp
new file mode 100644
index 0000000..37ebffb
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/RUNES-FG.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/SHAMAN-AIR.blp b/SVUI_UnitFrames/assets/Class/SHAMAN-AIR.blp
new file mode 100644
index 0000000..b4e2537
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/SHAMAN-AIR.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/SHAMAN-EARTH.blp b/SVUI_UnitFrames/assets/Class/SHAMAN-EARTH.blp
new file mode 100644
index 0000000..5a1babe
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/SHAMAN-EARTH.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/SHAMAN-FIRE.blp b/SVUI_UnitFrames/assets/Class/SHAMAN-FIRE.blp
new file mode 100644
index 0000000..f187cda
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/SHAMAN-FIRE.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/SHAMAN-WATER.blp b/SVUI_UnitFrames/assets/Class/SHAMAN-WATER.blp
new file mode 100644
index 0000000..3186dc3
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/SHAMAN-WATER.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/SWIRL.blp b/SVUI_UnitFrames/assets/Class/SWIRL.blp
new file mode 100644
index 0000000..4f30ab8
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/SWIRL.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/VORTEX.blp b/SVUI_UnitFrames/assets/Class/VORTEX.blp
new file mode 100644
index 0000000..8c3b469
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/VORTEX.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/WARLOCK-EMBER-FG.blp b/SVUI_UnitFrames/assets/Class/WARLOCK-EMBER-FG.blp
new file mode 100644
index 0000000..5a184b0
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/WARLOCK-EMBER-FG.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/WARLOCK-EMBER.blp b/SVUI_UnitFrames/assets/Class/WARLOCK-EMBER.blp
new file mode 100644
index 0000000..6a23ef1
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/WARLOCK-EMBER.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/WARLOCK-SHARD-BG.blp b/SVUI_UnitFrames/assets/Class/WARLOCK-SHARD-BG.blp
new file mode 100644
index 0000000..dc16667
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/WARLOCK-SHARD-BG.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/WARLOCK-SHARD-FG.blp b/SVUI_UnitFrames/assets/Class/WARLOCK-SHARD-FG.blp
new file mode 100644
index 0000000..5343b82
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/WARLOCK-SHARD-FG.blp differ
diff --git a/SVUI_UnitFrames/assets/Class/WARLOCK-SHARD.blp b/SVUI_UnitFrames/assets/Class/WARLOCK-SHARD.blp
new file mode 100644
index 0000000..f37398d
Binary files /dev/null and b/SVUI_UnitFrames/assets/Class/WARLOCK-SHARD.blp differ
diff --git a/SVUI_UnitFrames/assets/GroupNumbers/0.blp b/SVUI_UnitFrames/assets/GroupNumbers/0.blp
new file mode 100644
index 0000000..2b91673
Binary files /dev/null and b/SVUI_UnitFrames/assets/GroupNumbers/0.blp differ
diff --git a/SVUI_UnitFrames/assets/GroupNumbers/1.blp b/SVUI_UnitFrames/assets/GroupNumbers/1.blp
new file mode 100644
index 0000000..1a1e852
Binary files /dev/null and b/SVUI_UnitFrames/assets/GroupNumbers/1.blp differ
diff --git a/SVUI_UnitFrames/assets/GroupNumbers/2.blp b/SVUI_UnitFrames/assets/GroupNumbers/2.blp
new file mode 100644
index 0000000..d20cb32
Binary files /dev/null and b/SVUI_UnitFrames/assets/GroupNumbers/2.blp differ
diff --git a/SVUI_UnitFrames/assets/GroupNumbers/3.blp b/SVUI_UnitFrames/assets/GroupNumbers/3.blp
new file mode 100644
index 0000000..be13782
Binary files /dev/null and b/SVUI_UnitFrames/assets/GroupNumbers/3.blp differ
diff --git a/SVUI_UnitFrames/assets/GroupNumbers/4.blp b/SVUI_UnitFrames/assets/GroupNumbers/4.blp
new file mode 100644
index 0000000..7eca69c
Binary files /dev/null and b/SVUI_UnitFrames/assets/GroupNumbers/4.blp differ
diff --git a/SVUI_UnitFrames/assets/GroupNumbers/5.blp b/SVUI_UnitFrames/assets/GroupNumbers/5.blp
new file mode 100644
index 0000000..eb3b98a
Binary files /dev/null and b/SVUI_UnitFrames/assets/GroupNumbers/5.blp differ
diff --git a/SVUI_UnitFrames/assets/GroupNumbers/6.blp b/SVUI_UnitFrames/assets/GroupNumbers/6.blp
new file mode 100644
index 0000000..10547de
Binary files /dev/null and b/SVUI_UnitFrames/assets/GroupNumbers/6.blp differ
diff --git a/SVUI_UnitFrames/assets/GroupNumbers/7.blp b/SVUI_UnitFrames/assets/GroupNumbers/7.blp
new file mode 100644
index 0000000..c54fe0c
Binary files /dev/null and b/SVUI_UnitFrames/assets/GroupNumbers/7.blp differ
diff --git a/SVUI_UnitFrames/assets/GroupNumbers/8.blp b/SVUI_UnitFrames/assets/GroupNumbers/8.blp
new file mode 100644
index 0000000..09a73cc
Binary files /dev/null and b/SVUI_UnitFrames/assets/GroupNumbers/8.blp differ
diff --git a/SVUI_UnitFrames/assets/GroupNumbers/9.blp b/SVUI_UnitFrames/assets/GroupNumbers/9.blp
new file mode 100644
index 0000000..d8416e1
Binary files /dev/null and b/SVUI_UnitFrames/assets/GroupNumbers/9.blp differ
diff --git a/SVUI_UnitFrames/assets/RAID-ICONS.blp b/SVUI_UnitFrames/assets/RAID-ICONS.blp
new file mode 100644
index 0000000..6f6a1b8
Binary files /dev/null and b/SVUI_UnitFrames/assets/RAID-ICONS.blp differ
diff --git a/SVUI_UnitFrames/assets/TARGET-DC.blp b/SVUI_UnitFrames/assets/TARGET-DC.blp
new file mode 100644
index 0000000..4bdf0bf
Binary files /dev/null and b/SVUI_UnitFrames/assets/TARGET-DC.blp differ
diff --git a/SVUI_UnitFrames/assets/TARGET-DEAD.blp b/SVUI_UnitFrames/assets/TARGET-DEAD.blp
new file mode 100644
index 0000000..899d7fd
Binary files /dev/null and b/SVUI_UnitFrames/assets/TARGET-DEAD.blp differ
diff --git a/SVUI_UnitFrames/assets/TARGET-TAPPED.blp b/SVUI_UnitFrames/assets/TARGET-TAPPED.blp
new file mode 100644
index 0000000..f6a2c3c
Binary files /dev/null and b/SVUI_UnitFrames/assets/TARGET-TAPPED.blp differ
diff --git a/SVUI_UnitFrames/assets/UNIT-AFFLICTED.blp b/SVUI_UnitFrames/assets/UNIT-AFFLICTED.blp
new file mode 100644
index 0000000..1f5a94b
Binary files /dev/null and b/SVUI_UnitFrames/assets/UNIT-AFFLICTED.blp differ
diff --git a/SVUI_UnitFrames/assets/UNIT-AGGRO.blp b/SVUI_UnitFrames/assets/UNIT-AGGRO.blp
new file mode 100644
index 0000000..35ad289
Binary files /dev/null and b/SVUI_UnitFrames/assets/UNIT-AGGRO.blp differ
diff --git a/SVUI_UnitFrames/assets/UNIT-DC.blp b/SVUI_UnitFrames/assets/UNIT-DC.blp
new file mode 100644
index 0000000..059a508
Binary files /dev/null and b/SVUI_UnitFrames/assets/UNIT-DC.blp differ
diff --git a/SVUI_UnitFrames/assets/UNIT-DEAD.blp b/SVUI_UnitFrames/assets/UNIT-DEAD.blp
new file mode 100644
index 0000000..fb712a6
Binary files /dev/null and b/SVUI_UnitFrames/assets/UNIT-DEAD.blp differ
diff --git a/SVUI_UnitFrames/assets/UNIT-FRIENDS-BAR.blp b/SVUI_UnitFrames/assets/UNIT-FRIENDS-BAR.blp
new file mode 100644
index 0000000..e714ad1
Binary files /dev/null and b/SVUI_UnitFrames/assets/UNIT-FRIENDS-BAR.blp differ
diff --git a/SVUI_UnitFrames/assets/UNIT-FRIENDS-BG.blp b/SVUI_UnitFrames/assets/UNIT-FRIENDS-BG.blp
new file mode 100644
index 0000000..59ac87a
Binary files /dev/null and b/SVUI_UnitFrames/assets/UNIT-FRIENDS-BG.blp differ
diff --git a/SVUI_UnitFrames/assets/UNIT-FRIENDSHIP.blp b/SVUI_UnitFrames/assets/UNIT-FRIENDSHIP.blp
new file mode 100644
index 0000000..05e83b4
Binary files /dev/null and b/SVUI_UnitFrames/assets/UNIT-FRIENDSHIP.blp differ
diff --git a/SVUI_UnitFrames/assets/UNIT-HEALTH-ANIMATION.blp b/SVUI_UnitFrames/assets/UNIT-HEALTH-ANIMATION.blp
new file mode 100644
index 0000000..3e5d9ad
Binary files /dev/null and b/SVUI_UnitFrames/assets/UNIT-HEALTH-ANIMATION.blp differ
diff --git a/SVUI_UnitFrames/assets/UNIT-LML.blp b/SVUI_UnitFrames/assets/UNIT-LML.blp
new file mode 100644
index 0000000..f788b88
Binary files /dev/null and b/SVUI_UnitFrames/assets/UNIT-LML.blp differ
diff --git a/SVUI_UnitFrames/assets/UNIT-PLAYER-STATE.blp b/SVUI_UnitFrames/assets/UNIT-PLAYER-STATE.blp
new file mode 100644
index 0000000..0edd322
Binary files /dev/null and b/SVUI_UnitFrames/assets/UNIT-PLAYER-STATE.blp differ
diff --git a/SVUI_UnitFrames/assets/UNIT-ROLES.blp b/SVUI_UnitFrames/assets/UNIT-ROLES.blp
new file mode 100644
index 0000000..278428e
Binary files /dev/null and b/SVUI_UnitFrames/assets/UNIT-ROLES.blp differ
diff --git a/SVUI_UnitFrames/assets/UNIT-STUNNED-LG.blp b/SVUI_UnitFrames/assets/UNIT-STUNNED-LG.blp
new file mode 100644
index 0000000..07dcd94
Binary files /dev/null and b/SVUI_UnitFrames/assets/UNIT-STUNNED-LG.blp differ
diff --git a/SVUI_UnitFrames/assets/UNIT-STUNNED.blp b/SVUI_UnitFrames/assets/UNIT-STUNNED.blp
new file mode 100644
index 0000000..fef5a9f
Binary files /dev/null and b/SVUI_UnitFrames/assets/UNIT-STUNNED.blp differ
diff --git a/SVUI_UnitFrames/assets/UNIT-TAPPED.blp b/SVUI_UnitFrames/assets/UNIT-TAPPED.blp
new file mode 100644
index 0000000..d2654b0
Binary files /dev/null and b/SVUI_UnitFrames/assets/UNIT-TAPPED.blp differ
diff --git a/SVUI_UnitFrames/assets/UNIT-XRAY-CLOSE.blp b/SVUI_UnitFrames/assets/UNIT-XRAY-CLOSE.blp
new file mode 100644
index 0000000..309a501
Binary files /dev/null and b/SVUI_UnitFrames/assets/UNIT-XRAY-CLOSE.blp differ
diff --git a/SVUI_UnitFrames/assets/UNIT-XRAY.blp b/SVUI_UnitFrames/assets/UNIT-XRAY.blp
new file mode 100644
index 0000000..7ae156f
Binary files /dev/null and b/SVUI_UnitFrames/assets/UNIT-XRAY.blp differ
diff --git a/SVUI_UnitFrames/bodyguard.lua b/SVUI_UnitFrames/bodyguard.lua
new file mode 100644
index 0000000..6581a16
--- /dev/null
+++ b/SVUI_UnitFrames/bodyguard.lua
@@ -0,0 +1,443 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pcall         = _G.pcall;
+local print         = _G.print;
+local ipairs        = _G.ipairs;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local rawset        = _G.rawset;
+local rawget        = _G.rawget;
+local tostring      = _G.tostring;
+local tonumber      = _G.tonumber;
+local getmetatable  = _G.getmetatable;
+local setmetatable  = _G.setmetatable;
+local tinsert       = _G.tinsert;
+local tremove       = _G.tremove;
+local twipe         = _G.wipe;
+--STRING
+local string        = _G.string;
+local format        = string.format;
+local find          = string.find;
+local match         = string.match;
+--MATH
+local math          = _G.math;
+local min, random   = math.min, math.random;
+--TABLE
+local table         = _G.table;
+local bit 					= _G.bit;
+local band, bor 		= bit.band, bit.bor
+--[[ LOCALIZED BLIZZ FUNCTIONS ]]--
+local NewHook = hooksecurefunc;
+--[[
+##########################################################
+GET ADDON DATA AND TEST FOR oUF
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L;
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local MOD = SV.UnitFrames
+
+if(not MOD) then return end
+
+local oUF_SVUI = MOD.oUF
+assert(oUF_SVUI, "SVUI UnitFrames: unable to locate oUF.")
+--[[
+##########################################################
+LOCALS
+##########################################################
+]]--
+local BodyGuard = {
+  CurrentName = false,
+  CurrentHealth = 1,
+  CurrentMaxHealth = 1,
+  CurrentStatus = 0,
+  Initialized = false,
+};
+BodyGuard.UF = CreateFrame("Button", "SVUI_BodyGuard", UIParent, "SecureActionButtonTemplate")
+local EventListener = CreateFrame("Frame");
+local CONTINENT_DRAENOR = 7;
+local BODYGUARD_IDS, BODYGUARD_NAMES, BARRACKS_LIST, BODYGUARD_BANNED_ZONES = {}, {}, {[27]=true,[28]=true}, {[978]=true,[1009]=true,[1011]=true};
+local FLAGMASK = bor(COMBATLOG_OBJECT_TYPE_GUARDIAN, COMBATLOG_OBJECT_CONTROL_PLAYER, COMBATLOG_OBJECT_REACTION_FRIENDLY, COMBATLOG_OBJECT_AFFILIATION_MINE);
+
+do
+  local AURA_SEARCH = {
+    [173663]=true,[173662]=true,[173664]=true,[173977]=true,[173665]=true,[173656]=true,[173666]=true,
+    [173660]=true,[173657]=true,[173658]=true,[173976]=true,[173659]=true,[173649]=true,[173661]=true
+  };
+  for id, _ in pairs(AURA_SEARCH) do
+    local spellName = GetSpellInfo(id)
+    local name = spellName:match("^([%w%s]+) %w+")
+    if name then
+      BODYGUARD_NAMES[name] = true
+      BODYGUARD_IDS[id] = name
+    end
+  end
+end
+
+local function ZoneTest()
+  SetMapToCurrentZone()
+  if(GetCurrentMapContinent() ~= 7) then return false; end
+  local zone = GetCurrentMapAreaID()
+  if(BODYGUARD_BANNED_ZONES[zone]) then return false; end
+  return true
+end
+
+function BodyGuard:RefreshData()
+  self.CurrentName = false
+  self.CurrentHealth = 1
+  self.CurrentMaxHealth = 1
+  self.CurrentStatus = 0
+  self.Initialized = true
+
+  local buildings = C_Garrison.GetBuildings(LE_GARRISON_TYPE_6_0)
+
+  for i = 1, #buildings do
+    local building = buildings[i]
+    local building_id = building.buildingID
+    if(building_id and BARRACKS_LIST[building_id]) then
+      local name, level, quality, displayID, followerID, garrFollowerID, status, portraitIconID = C_Garrison.GetFollowerInfoForBuilding(building.plotID)
+      if(not name) then
+        self.CurrentStatus = 0;
+        self:StatusUpdate()
+        return
+      end
+      self.CurrentName = name
+      self.CurrentStatus = 2
+      self:NameUpdate()
+      break
+    end
+  end
+end
+
+function BodyGuard:GARRISON_BUILDINGS_SWAPPED()
+  self:RefreshData()
+end
+
+function BodyGuard:GARRISON_BUILDING_ACTIVATED()
+  self:RefreshData()
+end
+
+function BodyGuard:GARRISON_BUILDING_UPDATE(buildingID)
+  if BARRACKS_LIST[buildingID] then self:RefreshData() end
+end
+
+function BodyGuard:GARRISON_FOLLOWER_REMOVED()
+  self:RefreshData()
+end
+
+function BodyGuard:GARRISON_FOLLOWER_ADDED()
+  self:RefreshData()
+end
+
+function BodyGuard:GARRISON_UPDATE()
+  self:RefreshData()
+end
+
+function BodyGuard:PLAYER_TARGET_CHANGED(arg)
+  if(not self.CurrentName) then return end
+  if((arg ~= "LeftButton") and (arg ~= "up")) then return end
+  local unit = "target"
+  if(self.CurrentName ~= UnitName(unit)) then return end
+  self.CurrentHealth = UnitHealth(unit)
+  self.CurrentMaxHealth = UnitHealthMax(unit)
+  self:HealthUpdate()
+end
+
+function BodyGuard:UPDATE_MOUSEOVER_UNIT()
+  if(not self.CurrentName) then return end
+  local unit = "mouseover"
+  local mouseover_name = UnitName(unit)
+  if(self.CurrentName == mouseover_name) then
+    local tip = _G["GameTooltipTextLeft2"]
+    if tip and tip.GetText then
+      local text = tip:GetText()
+      if(text:find("Bodyguard")) then
+        if(self.CurrentStatus == 2) then self.CurrentStatus = 1 end
+      else
+        self.CurrentStatus = 0
+      end
+    end
+    if(self.CurrentStatus == 1) then
+      self.CurrentHealth = UnitHealth(unit)
+      self.CurrentMaxHealth = UnitHealthMax(unit)
+    end
+    self:StatusUpdate()
+  end
+end
+
+function BodyGuard:UNIT_HEALTH(unit)
+  if(not self.CurrentName) then return end
+  if(self.CurrentName ~= UnitName(unit)) then return end
+  self.CurrentHealth = UnitHealth(unit)
+  self.CurrentMaxHealth = UnitHealthMax(unit)
+  self:HealthUpdate()
+end
+
+function BodyGuard:COMBAT_LOG_EVENT_UNFILTERED(timestamp, event, hideCaster, sourceGUID, sourceName, sourceFlags, sourceRaidFlags, destGUID, destName, destFlags, destRaidFlags, ...)
+  if(not self.CurrentName) then return end
+  if(sourceName and (sourceName == self.CurrentName)) then
+    if(not band(sourceFlags, FLAGMASK) == FLAGMASK) then return end
+    self.CurrentStatus = 1
+    self:StatusUpdate()
+  elseif(destName and (destName == self.CurrentName)) then
+    if(not band(destFlags, FLAGMASK) == FLAGMASK) then return end
+    local prefix, suffix = event:match("^([A-Z_]+)_([A-Z]+)$")
+    local value, updated = 0;
+
+    if prefix:match("^SPELL") then
+      value = select(4, ...);
+    elseif prefix == "ENVIRONMENTAL" then
+      value = select(2, ...);
+    else
+      value = select(1, ...);
+    end
+
+    if suffix == "DAMAGE" then
+      self.CurrentHealth = self.CurrentHealth - value
+      updated = true
+    elseif suffix == "HEAL" then
+      self.CurrentHealth = self.CurrentHealth + value
+      if self.CurrentMaxHealth <= self.CurrentHealth then
+        self.CurrentHealth = self.CurrentMaxHealth
+      end
+      updated = true
+    elseif suffix == "INSTAKILL" then
+      self.CurrentHealth = 0
+      updated = true
+    end
+
+    if(updated) then
+      if self.CurrentHealth <= 0 then
+        self.CurrentHealth = 0
+        self.CurrentStatus = 2
+      else
+        self.CurrentStatus = 1
+      end
+      self:HealthUpdate()
+    end
+
+    self:StatusUpdate()
+  end
+end
+
+function BodyGuard:PLAYER_REGEN_ENABLED()
+  if(self.CurrentHealth <= 0) then return end
+  self.CurrentHealth = self.CurrentMaxHealth
+  self:HealthUpdate()
+end
+
+function BodyGuard:UNIT_AURA()
+  for i = 1, 40 do
+    local _, _, _, _, _, duration, expireTime, _, _, _, id = UnitDebuff("player", i)
+    if not BODYGUARD_IDS[id] then return end
+    local name = BODYGUARD_IDS[id]
+    if name == self.CurrentName then
+      self.CurrentStatus = 0
+      self.CurrentHealth = 0
+      self:HealthUpdate()
+      self:StatusUpdate()
+      return
+    end
+  end
+end
+
+function BodyGuard:PLAYER_ENTERING_WORLD()
+  local showing = self:IsShowing()
+
+  if(not self.Initialized) then
+    self:RefreshData()
+  end
+
+  if((not self.CurrentName) or (self.CurrentStatus == 0)) then
+    self:ToggleVisibility("Hide")
+    return
+  end
+  if(not ZoneTest()) then
+    self:ToggleVisibility("Hide")
+  elseif showing then
+    self:UpdateSettings()
+  elseif self.CurrentStatus == 1 then
+    self:ToggleVisibility("Show")
+  end
+end
+
+function BodyGuard:ZONE_CHANGED_NEW_AREA()
+  if(not ZoneTest()) then
+    if not self:IsShowing() then return end
+    self:ToggleVisibility("Hide")
+  elseif self.CurrentStatus == 1 then
+    self:ToggleVisibility("Show")
+  end
+end
+
+function BodyGuard:IsShowing()
+  if(self.UF and (self.UF:IsShown() or self.UF.VisualState == "Show")) then
+    return true
+  else
+    return false
+  end
+end
+
+function BodyGuard:ToggleVisibility(state)
+  if(InCombatLockdown()) then
+    self.UF:RegisterEvent("PLAYER_REGEN_ENABLED")
+    self.UF.VisualState = state
+    return
+  elseif(self.UF:IsEventRegistered("PLAYER_REGEN_ENABLED")) then
+    self.UF:UnregisterEvent("PLAYER_REGEN_ENABLED")
+  end
+  if(state == "Hide") then self.UF:Hide() else self.UF:Show() end
+end
+
+function BodyGuard:UpdateSettings()
+  if(not self.UF) then return end
+  if(SV.db.UnitFrames.bodyguard.enable) then
+    self.UF:SetParent(SV.Screen)
+  else
+    self.UF:SetParent(SV.Hidden)
+  end
+
+  self:HealthUpdate()
+  self.UF:SetWidth(SV.db.UnitFrames.bodyguard.width)
+  self.UF:SetHeight(SV.db.UnitFrames.bodyguard.height)
+end
+
+function BodyGuard:StatusUpdate()
+  if self.CurrentStatus == 1 then
+    self:NameUpdate()
+    self:HealthUpdate()
+    self:ToggleVisibility("Show")
+  else
+    self:ToggleVisibility("Hide")
+  end
+end
+
+function BodyGuard:NameUpdate()
+  if(not InCombatLockdown() and self.CurrentName) then
+    self.UF:SetAttribute("macrotext1", "/targetexact " .. self.CurrentName)
+  end
+  if(not self.UF.Name) then return end
+  self.UF.Name:SetText(self.CurrentName)
+end
+
+function BodyGuard:HealthUpdate()
+  if(not self.UF) then return end
+  local health = self.CurrentHealth;
+  local maxHealth = self.CurrentMaxHealth;
+
+  self.UF.Health:SetMinMaxValues(0, maxHealth)
+  self.UF.Health:SetValue(health)
+
+  local r, g, b = unpack(oUF_SVUI.colors.health)
+  r, g, b = oUF_SVUI.ColorGradient(health, maxHealth, 1, 0, 0, 1, 1, 0, r, g, b)
+
+  self.UF.Health:SetStatusBarColor(r, g, b)
+  self.UF.Health.bg:SetVertexColor(r * 0.25, g * 0.25, b * 0.25)
+end
+
+-- LOAD
+
+local EventListener_OnEvent = function(self, event, ...)
+    local fn = BodyGuard[event]
+    if(fn and type(fn) == "function") then
+        local _, catch = pcall(fn, BodyGuard, ...)
+        if(catch) then
+            SV:HandleError("UnitFrames [BodyGuard]", event, catch)
+        end
+    end
+end
+
+local _hook_GOSSIP_CONFIRM = function(...)
+  if(not BodyGuard:IsShowing()) then return end
+  BodyGuard.CurrentStatus = 0
+  BodyGuard.CurrentHealth = BodyGuard.CurrentMaxHealth
+  BodyGuard:StatusUpdate()
+  BodyGuard:HealthUpdate()
+end
+
+function MOD:InitializeBodyGuard()
+  BodyGuard.UF.VisualState = "Hide"
+  BodyGuard.UF:SetPoint("BOTTOMRIGHT", SV.Dock.BottomLeft, "TOPRIGHT", 0, 10)
+  BodyGuard.UF:SetWidth(SV.db.UnitFrames.bodyguard.width)
+  BodyGuard.UF:SetHeight(SV.db.UnitFrames.bodyguard.height)
+  BodyGuard.UF:SetScript("OnEvent", function(self, event)
+    if(event == "PLAYER_REGEN_ENABLED") then
+      BodyGuard:ToggleVisibility(self.VisualState)
+    elseif(event == "PLAYER_TARGET_CHANGED") then
+      if(UnitExists("target") and UnitName("target") == BodyGuard.CurrentName) then
+        self.TargetGlow:Show()
+      else
+        self.TargetGlow:Hide()
+      end
+    end
+  end)
+  BodyGuard.UF:SetStyle("Frame", "Icon")
+
+  BodyGuard.UF.TargetGlow = BodyGuard.UF.Panel.Shadow
+  BodyGuard.UF.TargetGlow:SetBackdropBorderColor(0, 1, 0, 0.5)
+  BodyGuard.UF.TargetGlow:Hide()
+
+  BodyGuard.UF:RegisterEvent("PLAYER_TARGET_CHANGED")
+  BodyGuard.UF.Health = CreateFrame("StatusBar", nil, BodyGuard.UF)
+  BodyGuard.UF.Health:InsetPoints(BodyGuard.UF)
+  BodyGuard.UF.Health:SetMinMaxValues(0, 1)
+  BodyGuard.UF.Health:SetValue(1)
+  BodyGuard.UF.Health:SetStatusBarTexture(LSM:Fetch("statusbar", SV.db.UnitFrames.statusbar))
+
+  BodyGuard.UF.Health.bg = BodyGuard.UF.Health:CreateTexture(nil, "BORDER")
+  BodyGuard.UF.Health.bg:SetAllPoints()
+  BodyGuard.UF.Health.bg:SetTexture(SV.media.statusbar.gradient)
+  BodyGuard.UF.Health.bg:SetVertexColor(0.1, 0.1, 0.1)
+
+  BodyGuard.UF.Name = BodyGuard.UF.Health:CreateFontString(nil, 'OVERLAY')
+  SV:FontManager(BodyGuard.UF.Name, "unitsecondary")
+  BodyGuard.UF.Name:SetPoint("CENTER", BodyGuard.UF, "CENTER")
+  BodyGuard.UF.Name:SetTextColor(unpack(oUF_SVUI.colors.reaction[5]))
+
+  SV:NewAnchor(BodyGuard.UF, L["BodyGuard Frame"])
+
+  BodyGuard.UF:SetAttribute("type1", "macro")
+  if BodyGuard.CurrentName then
+    BodyGuard.UF:SetAttribute("macrotext1", "/targetexact " .. BodyGuard.CurrentName)
+  end
+  BodyGuard:RefreshData()
+  BodyGuard:HealthUpdate()
+  BodyGuard.UF:Hide()
+
+  EventListener:SetScript("OnEvent", EventListener_OnEvent)
+
+  EventListener:RegisterEvent("GARRISON_BUILDINGS_SWAPPED")
+  EventListener:RegisterEvent("GARRISON_BUILDING_ACTIVATED")
+  EventListener:RegisterEvent("GARRISON_BUILDING_UPDATE")
+  EventListener:RegisterEvent("GARRISON_FOLLOWER_REMOVED")
+  EventListener:RegisterEvent("GARRISON_FOLLOWER_ADDED")
+  EventListener:RegisterEvent("GARRISON_UPDATE")
+  EventListener:RegisterEvent("PLAYER_TARGET_CHANGED")
+  EventListener:RegisterEvent("UPDATE_MOUSEOVER_UNIT")
+  EventListener:RegisterEvent("UNIT_HEALTH")
+  EventListener:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
+  EventListener:RegisterEvent("PLAYER_REGEN_ENABLED")
+  EventListener:RegisterEvent("PLAYER_ENTERING_WORLD")
+  EventListener:RegisterEvent("ZONE_CHANGED_NEW_AREA")
+  EventListener:RegisterUnitEvent("UNIT_AURA", "player")
+
+  hooksecurefunc(StaticPopupDialogs.GOSSIP_CONFIRM, "OnAccept", _hook_GOSSIP_CONFIRM)
+end
+
+BodyGuard:RefreshData()
+MOD.BodyGuard = BodyGuard;
diff --git a/SVUI_UnitFrames/class_resources/deathknight.lua b/SVUI_UnitFrames/class_resources/deathknight.lua
new file mode 100644
index 0000000..9c95585
--- /dev/null
+++ b/SVUI_UnitFrames/class_resources/deathknight.lua
@@ -0,0 +1,232 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack    = _G.unpack;
+local select    = _G.select;
+local pairs     = _G.pairs;
+local ipairs    = _G.ipairs;
+local type      = _G.type;
+local error     = _G.error;
+local pcall     = _G.pcall;
+local tostring  = _G.tostring;
+local tonumber  = _G.tonumber;
+local assert 	= _G.assert;
+local math 		= _G.math;
+--[[ MATH METHODS ]]--
+local random = math.random;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L;
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local MOD = SV.UnitFrames
+
+if(not MOD) then return end
+
+local oUF_SVUI = MOD.oUF
+assert(oUF_SVUI, "SVUI UnitFrames: unable to locate oUF.")
+if(SV.class ~= "DEATHKNIGHT") then return end
+--[[
+##########################################################
+LOCALS
+##########################################################
+]]--
+SV.SpecialFX:Register("rune_blood", [[Spells\Monk_drunkenhaze_impact.m2]], 0, 0, 0, 0, 0.00001, 0, 0.3)
+SV.SpecialFX:Register("rune_frost", [[Spells\Ice_cast_low_hand.m2]], 0, 0, 0, 0, 0.00001, -0.2, 0.4)
+SV.SpecialFX:Register("rune_unholy", [[Spells\Poison_impactdot_med_chest.m2]], 0, 0, 0, 0, 0.13, -0.3, -0.2)
+SV.SpecialFX:Register("rune_death", [[Spells\Shadow_strikes_state_hand.m2]], 0, 0, 0, 0, 0.001, 0, -0.25)
+local specEffects = {
+	[1] = "rune_blood",
+	[2] = "rune_frost",
+	[3] = "rune_unholy",
+	[4] = "rune_death"
+};
+local RUNE_FG = [[Interface\AddOns\SVUI_UnitFrames\assets\Class\RUNES-FG]];
+local RUNE_BG = [[Interface\AddOns\SVUI_UnitFrames\assets\Class\RUNES-BG]];
+local runeColors = {
+	{0.75, 0, 0},   -- blood
+	{0, 0.75, 1},   -- frost
+	{0.1, 0.75, 0},  -- unholy
+	{1, 1, 1}, -- death
+};
+local runeTextures = {
+	[[Interface\AddOns\SVUI_UnitFrames\assets\Class\DEATHKNIGHT-BLOOD]],
+	[[Interface\AddOns\SVUI_UnitFrames\assets\Class\DEATHKNIGHT-FROST]],
+	[[Interface\AddOns\SVUI_UnitFrames\assets\Class\DEATHKNIGHT-UNHOLY]],
+	[[Interface\AddOns\SVUI_UnitFrames\assets\Class\DEATHKNIGHT-DEATH]]
+};
+local runeClassic = {
+	runeTextures[1],
+	runeTextures[1],
+	runeTextures[2],
+	runeTextures[2],
+	runeTextures[3],
+	runeTextures[3]
+};
+--[[
+##########################################################
+POSITIONING
+##########################################################
+]]--
+local OnMove = function()
+	SV.db.UnitFrames.player.classbar.detachFromFrame = true
+end
+
+local RuneChange = function(self, ...)
+	local spec = GetSpecialization()
+	self.FX:SetEffect(specEffects[spec])
+end
+
+local ClassicRuneChange = function(self, ...)
+	local spec = GetSpecialization()
+	local graphic = runeTextures[spec]
+	local colors = runeColors[spec]
+	self:SetStatusBarColor(colors[1], colors[2], colors[3])
+	self.bg:SetTexture(graphic)
+	self:SetStatusBarTexture(graphic)
+	self.FX:SetEffect(specEffects[spec])
+end
+
+local Reposition = function(self)
+	local db = SV.db.UnitFrames.player
+	local bar = self.Necromancy;
+	local max = self.MaxClassPower;
+	local size = db.classbar.height
+	local inset = size * 0.1
+	local width = size * max;
+
+	local spec = GetSpecialization()
+
+	bar.Holder:SetSize(width, size)
+    if(not db.classbar.detachFromFrame) then
+    	SV:ResetAnchors(L["Classbar"])
+    end
+    local holderUpdate = bar.Holder:GetScript('OnSizeChanged')
+    if holderUpdate then
+        holderUpdate(bar.Holder)
+    end
+
+    bar:ClearAllPoints()
+    bar:SetAllPoints(bar.Holder)
+
+	if(db.classbar.altRunes) then
+		for i = 1, max do
+			local graphic = runeTextures[spec]
+			bar[i]:ClearAllPoints()
+			bar[i]:SetHeight(size)
+			bar[i]:SetWidth(size)
+			bar[i].bar:GetStatusBarTexture():SetHorizTile(false)
+			if i == 1 then
+				bar[i]:SetPoint("TOPLEFT", bar, "TOPLEFT", 0, 0)
+			elseif i == 2 then
+				bar[i]:SetPoint("LEFT", bar[1], "RIGHT", -6, 0)
+			else
+				bar[i]:SetPoint("LEFT", bar[i - 1], "RIGHT", -2, 0)
+			end
+			bar[i].bar:ClearAllPoints()
+			bar[i].bar:SetAllPoints(bar[i].holder)
+			bar[i].bar.bg:SetTexture(graphic)
+			bar[i].bar.bg:SetAlpha(0.5)
+			bar[i].bar.bg.multiplier = 0.1
+			bar[i].fg:SetColorTexture(0,0,0,0)
+			bar[i].fg:SetAlpha(0)
+			bar[i].bar.FX:SetAlpha(0.2)
+			bar[i].bar:SetStatusBarTexture(graphic)
+			bar[i].bar.Change = ClassicRuneChange;
+		end
+	else
+		for i = 1, max do
+			bar[i]:ClearAllPoints()
+			bar[i]:SetHeight(size + 4)
+			bar[i]:SetWidth(size)
+			bar[i].bar:GetStatusBarTexture():SetHorizTile(false)
+			if i==1 then
+				bar[i]:SetPoint("TOPLEFT", bar, "TOPLEFT", 0, 1)
+			else
+				bar[i]:SetPoint("LEFT", bar[i - 1], "RIGHT", -6, 0)
+			end
+			bar[i].bar:ClearAllPoints()
+			bar[i].bar:InsetPoints(bar[i].holder,inset,inset)
+			bar[i].bar.bg:SetTexture(RUNE_BG)
+			bar[i].bar.bg:SetAlpha(1)
+			bar[i].bar.bg.multiplier = 1
+			bar[i].fg:SetTexture(RUNE_FG)
+			bar[i].fg:SetAlpha(1)
+			bar[i].bar.FX:SetAlpha(1)
+			bar[i].bar:SetStatusBarTexture(SV.media.statusbar.default)
+			bar[i].bar.Change = RuneChange;
+		end
+	end
+
+	if bar.UpdateAllRuneTypes then
+		bar.UpdateAllRuneTypes(self)
+	end
+end
+--[[
+##########################################################
+DEATHKNIGHT
+##########################################################
+]]--
+function MOD:CreateClassBar(playerFrame)
+	local max = 6
+	local bar = CreateFrame("Frame", nil, playerFrame)
+	bar:SetFrameLevel(playerFrame.TextGrip:GetFrameLevel() + 30)
+	for i=1, max do
+		local rune = CreateFrame("Frame", nil, bar)
+		rune:SetFrameStrata("BACKGROUND")
+		rune:SetFrameLevel(0)
+
+		local bgFrame = CreateFrame("Frame", nil, rune)
+		bgFrame:InsetPoints(rune)
+		rune.holder = bgFrame;
+
+		local bgTexture = bgFrame:CreateTexture(nil, "BORDER")
+		bgTexture:SetAllPoints(bgFrame)
+		bgTexture:SetTexture(RUNE_BG)
+		bgTexture:SetGradientAlpha("VERTICAL",0,0,0,0.5,0,0,0,0.85)
+
+	    rune.bar = CreateFrame("StatusBar", nil, bgFrame)
+		rune.bar.noupdate = true;
+		rune.bar:InsetPoints(bgFrame,4,4)
+		rune.bar:SetOrientation("HORIZONTAL")
+		rune.bar:SetStatusBarTexture(SV.media.statusbar.default)
+		rune.bar.bg = bgTexture;
+
+		local fgFrame = CreateFrame("Frame", nil, rune.bar)
+		fgFrame:SetAllPoints(bgFrame)
+
+		local fgTexture = fgFrame:CreateTexture(nil, "OVERLAY")
+		fgTexture:SetAllPoints(fgFrame)
+		fgTexture:SetTexture(RUNE_FG)
+		fgTexture:SetVertexColor(0.25,0.25,0.25)
+		rune.fg = fgTexture;
+
+		local effectName = specEffects[i]
+		SV.SpecialFX:SetFXFrame(rune.bar, effectName)
+
+		bar[i] = rune;
+		bar[i].bar.effectIndex = i;
+		bar[i].bar.Change = RuneChange;
+		bar[i].bar:SetOrientation("VERTICAL");
+	end
+
+	local classBarHolder = CreateFrame("Frame", "Player_ClassBar", bar)
+	classBarHolder:SetPoint("TOPLEFT", playerFrame, "BOTTOMLEFT", 0, -2)
+	bar:SetPoint("TOPLEFT", classBarHolder, "TOPLEFT", 0, 0)
+	bar.Holder = classBarHolder
+	SV:NewAnchor(bar.Holder, L["Classbar"], OnMove)
+
+	playerFrame.MaxClassPower = max;
+	playerFrame.RefreshClassBar = Reposition;
+	playerFrame.Necromancy = bar
+	return 'Necromancy'
+end
diff --git a/SVUI_UnitFrames/class_resources/demonhunter.lua b/SVUI_UnitFrames/class_resources/demonhunter.lua
new file mode 100644
index 0000000..f5d4daa
--- /dev/null
+++ b/SVUI_UnitFrames/class_resources/demonhunter.lua
@@ -0,0 +1,92 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack    = _G.unpack;
+local select    = _G.select;
+local pairs     = _G.pairs;
+local ipairs    = _G.ipairs;
+local type      = _G.type;
+local error     = _G.error;
+local pcall     = _G.pcall;
+local tostring  = _G.tostring;
+local tonumber  = _G.tonumber;
+local assert 	= _G.assert;
+local math 		= _G.math;
+--[[ MATH METHODS ]]--
+local random = math.random;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L;
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local MOD = SV.UnitFrames
+
+if(not MOD) then return end
+
+local oUF_SVUI = MOD.oUF
+assert(oUF_SVUI, "SVUI UnitFrames: unable to locate oUF.")
+if(SV.class ~= "DEMONHUNTER") then return end
+--[[
+##########################################################
+LOCALS
+##########################################################
+]]--
+
+--[[
+##########################################################
+POSITIONING
+##########################################################
+]]--
+
+local Reposition = function(self)
+	local db = SV.db.UnitFrames.player
+	local bar = self.Illidanian;
+	local max = self.MaxClassPower;
+	local size = db.classbar.height
+	local inset = size * 0.1
+	local width = size * max;
+
+	local spec = GetSpecialization()
+
+	bar.Holder:SetSize(width, size)
+    if(not db.classbar.detachFromFrame) then
+    	SV:ResetAnchors(L["Classbar"])
+    end
+    local holderUpdate = bar.Holder:GetScript('OnSizeChanged')
+    if holderUpdate then
+        holderUpdate(bar.Holder)
+    end
+
+    bar:ClearAllPoints()
+    bar:SetAllPoints(bar.Holder)
+end
+--[[
+##########################################################
+DEATHKNIGHT
+##########################################################
+]]--
+function MOD:CreateClassBar(playerFrame)
+	local max = 6
+	local bar = CreateFrame("Frame", nil, playerFrame)
+	bar:SetFrameLevel(playerFrame.TextGrip:GetFrameLevel() + 30)
+
+	local classBarHolder = CreateFrame("Frame", "Player_ClassBar", bar)
+	classBarHolder:SetPoint("TOPLEFT", playerFrame, "BOTTOMLEFT", 0, -2)
+	bar:SetPoint("TOPLEFT", classBarHolder, "TOPLEFT", 0, 0)
+	bar.Holder = classBarHolder
+	SV:NewAnchor(bar.Holder, L["Classbar"], OnMove)
+
+	playerFrame.MaxClassPower = max;
+	playerFrame.RefreshClassBar = Reposition;
+	playerFrame.Illidanian = bar
+	return 'Illidanian'
+end
diff --git a/SVUI_UnitFrames/class_resources/druid.lua b/SVUI_UnitFrames/class_resources/druid.lua
new file mode 100644
index 0000000..3ef3480
--- /dev/null
+++ b/SVUI_UnitFrames/class_resources/druid.lua
@@ -0,0 +1,372 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack    = _G.unpack;
+local select    = _G.select;
+local pairs     = _G.pairs;
+local ipairs    = _G.ipairs;
+local type      = _G.type;
+local error     = _G.error;
+local pcall     = _G.pcall;
+local tostring  = _G.tostring;
+local tonumber  = _G.tonumber;
+local assert 	= _G.assert;
+local math 		= _G.math;
+--[[ MATH METHODS ]]--
+local random,floor = math.random, math.floor;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L;
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local MOD = SV.UnitFrames
+
+if(not MOD) then return end
+
+local oUF_SVUI = MOD.oUF
+assert(oUF_SVUI, "SVUI UnitFrames: unable to locate oUF.")
+if(SV.class ~= "DRUID") then return end
+--[[
+##########################################################
+DRUID ALT MANA
+##########################################################
+]]--
+local TRACKER_FONT = [[Interface\AddOns\SVUI_!Core\assets\fonts\Combo.ttf]];
+local cpointColor = {
+	[1]={0.69,0.31,0.31},
+	[2]={0.69,0.31,0.31},
+	[3]={0.65,0.63,0.35},
+	[4]={0.65,0.63,0.35},
+	[5]={0.33,0.59,0.33}
+};
+
+local comboTextures = {
+	[1]=[[Interface\Addons\SVUI_UnitFrames\assets\Class\DRUID-CLAW-UP]],
+	[2]=[[Interface\Addons\SVUI_UnitFrames\assets\Class\DRUID-CLAW-DOWN]],
+	[3]=[[Interface\Addons\SVUI_UnitFrames\assets\Class\DRUID-BITE]],
+};
+
+local ShowPoint = function(self)
+	self:SetAlpha(1)
+end
+
+local HidePoint = function(self)
+	self.Icon:SetTexture(comboTextures[random(1,3)])
+	self:SetAlpha(0)
+end
+
+local UpdateAltPower = function(self, unit, arg1, arg2)
+	local value = self:GetParent().TextGrip.Power;
+	if(arg1 ~= arg2) then
+		local color = oUF_SVUI.colors.power.MANA
+		color = SV:HexColor(color[1],color[2],color[3])
+		local altValue = floor(arg1 / arg2 * 100)
+		local altStr = ""
+		if(value:GetText()) then
+			if(select(4, value:GetPoint()) < 0) then
+				altStr = ("|cff%s%d%%|r |cffD7BEA5- |r"):format(color, altValue)
+			else
+				altStr = ("|cffD7BEA5-|r|cff%s%d%%|r"):format(color, altValue)
+			end
+		else
+			altStr = ("|cff%s%d%%|r"):format(color, altValue)
+		end
+		self.Text:SetText(altStr)
+	else
+		self.Text:SetText()
+	end
+end
+--[[
+##########################################################
+POSITIONING
+##########################################################
+]]--
+local OnMove = function()
+	SV.db.UnitFrames.player.classbar.detachFromFrame = true
+end
+
+local Reposition = function(self)
+	local db = SV.db.UnitFrames.player
+	local bar = self.Druidness;
+	if not bar or not db then print("Error") return end
+	--self.Druidness.Chicken.isEnabled = db.classbar.enableChicken;
+	self.Druidness.Mana.isEnabled = db.classbar.enableAltMana;
+	self.Druidness.Cat.isEnabled = db.classbar.enableCat;
+	--local chicken = bar.Chicken;
+	local height = db.classbar.height
+	local offset = (height - 10)
+	local adjustedBar = (height * 1.5)
+	local adjustedAnim = (height * 1.25)
+	local scaled = (height * 0.8)
+	local width = db.width * 0.4;
+
+	bar.Holder:SetSize(width, height)
+    if(not db.classbar.detachFromFrame) then
+    	SV:ResetAnchors(L["Classbar"])
+    end
+    local holderUpdate = bar.Holder:GetScript('OnSizeChanged')
+    if holderUpdate then
+        holderUpdate(bar.Holder)
+    end
+
+    bar:ClearAllPoints()
+    bar:SetAllPoints(bar.Holder)
+
+ --    chicken:ClearAllPoints()
+ --    chicken:SetAllPoints()
+
+	-- chicken.LunarBar:SetSize(width, adjustedBar)
+	-- chicken.LunarBar:SetStatusBarColor(.13,.32,1)
+
+	-- chicken.Moon:SetSize(height, height)
+	-- chicken.Moon[1]:SetSize(adjustedAnim, adjustedAnim)
+	-- chicken.Moon[2]:SetSize(scaled, scaled)
+
+	-- chicken.SolarBar:SetSize(width, adjustedBar)
+	-- chicken.SolarBar:SetStatusBarColor(1,1,0.21)
+
+	-- chicken.Sun:SetSize(height, height)
+	-- chicken.Sun[1]:SetSize(adjustedAnim, adjustedAnim)
+	-- chicken.Sun[2]:SetSize(scaled, scaled)
+
+	-- chicken.Text:SetPoint("TOPLEFT", chicken, "TOPLEFT", 10, 0)
+	-- chicken.Text:SetPoint("BOTTOMRIGHT", chicken, "BOTTOMRIGHT", -10, 0)
+	-- chicken.Text:SetFont(TRACKER_FONT, scaled, 'OUTLINE')
+
+	local max = MAX_COMBO_POINTS;
+	local cat = bar.Cat;
+	local size = (height - 4)
+	for i = 1, max do
+		cat[i]:ClearAllPoints()
+		cat[i]:SetSize(size, size)
+		cat[i].Icon:ClearAllPoints()
+		cat[i].Icon:SetAllPoints(cat[i])
+		if i==1 then
+			cat[i]:SetPoint("LEFT", cat)
+		else
+			cat[i]:SetPoint("LEFT", cat[i - 1], "RIGHT", -2, 0)
+		end
+	end
+end
+--[[
+##########################################################
+DRUID ECLIPSE BAR
+##########################################################
+]]--
+local EclipseDirection = function(self)
+	local status = GetEclipseDirection()
+
+	if(self.inEclipse) then
+		if(status == "sun") then
+			--self.Text:SetText("<")
+			--self.Text:SetTextColor(0.2, 1, 1, 0.5)
+			if(not self.Moon[1].anim:IsPlaying()) then
+				self.Sun[1]:Hide()
+				self.Sun[1].anim:Finish()
+				self.Sun.FX:Hide()
+				self.Moon[1]:Show()
+				self.Moon[1].anim:Play()
+				self.Moon.FX:Show()
+				self.Moon.FX:UpdateEffect()
+			end
+		elseif(status == "moon") then
+			--self.Text:SetText(">")
+			--self.Text:SetTextColor(1, 0.5, 0, 0.5)
+			if(not self.Sun[1].anim:IsPlaying()) then
+				self.Moon[1]:Hide()
+				self.Moon[1].anim:Finish()
+				self.Moon.FX:Hide()
+				self.Sun[1]:Show()
+				self.Sun[1].anim:Play()
+				self.Sun.FX:Show()
+				self.Sun.FX:UpdateEffect()
+			end
+		else
+			--self.Text:SetText("<")
+			--self.Text:SetTextColor(0.2, 1, 1, 0.5)
+			self.Sun[1]:Hide()
+			self.Sun[1].anim:Finish()
+			self.Sun.FX:Hide()
+			self.Moon[1]:Hide()
+			self.Moon[1].anim:Finish()
+			self.Moon.FX:Hide()
+		end
+	else
+		if(status == "sun") then
+			--self.Text:SetText("<")
+			--self.Text:SetTextColor(0.2, 1, 1, 0.5)
+			if(not self.Moon[1].anim:IsPlaying()) then
+				self.Sun[1]:Hide()
+				self.Sun[1].anim:Finish()
+				self.Sun.FX:Hide()
+				self.Moon[1]:Show()
+				self.Moon[1].anim:Play()
+				self.Moon.FX:Show()
+				self.Moon.FX:UpdateEffect()
+			end
+		elseif(status == "moon") then
+			--self.Text:SetText(">")
+			--self.Text:SetTextColor(1, 0.5, 0, 0.5)
+			if(not self.Sun[1].anim:IsPlaying()) then
+				self.Moon[1]:Hide()
+				self.Moon[1].anim:Finish()
+				self.Moon.FX:Hide()
+				self.Sun[1]:Show()
+				self.Sun[1].anim:Play()
+				self.Sun.FX:Show()
+				self.Sun.FX:UpdateEffect()
+			end
+		else
+			--self.Text:SetText("<")
+			--self.Text:SetTextColor(0.2, 1, 1, 0.5)
+			self.Sun[1]:Hide()
+			self.Sun[1].anim:Finish()
+			self.Sun.FX:Hide()
+			self.Moon[1]:Hide()
+			self.Moon[1].anim:Finish()
+			self.Moon.FX:Hide()
+		end
+	end
+end
+
+function MOD:CreateClassBar(playerFrame)
+	local bar = CreateFrame('Frame', nil, playerFrame)
+	bar:SetFrameLevel(playerFrame.TextGrip:GetFrameLevel() + 30)
+	bar:SetSize(100,40)
+--[[
+	local chicken = CreateFrame('Frame', nil, bar)
+	chicken:SetAllPoints(bar)
+
+	local moon = CreateFrame('Frame', nil, chicken)
+	moon:SetFrameLevel(chicken:GetFrameLevel() + 2)
+	moon:SetSize(40, 40)
+	moon:SetPoint("TOPLEFT", chicken, "TOPLEFT", -4, 0)
+	SV.SpecialFX:SetFXFrame(moon, "shadow")
+	moon.FX:SetFrameLevel(chicken:GetFrameLevel() - 2)
+
+	moon[1] = moon:CreateTexture(nil, "BACKGROUND", nil, 1)
+	moon[1]:SetSize(50, 50)
+	moon[1]:SetPoint("CENTER")
+	moon[1]:SetTexture("Interface\\AddOns\\SVUI_UnitFrames\\assets\\Class\\VORTEX")
+	moon[1]:SetBlendMode("ADD")
+	moon[1]:SetVertexColor(0, 0.5, 1, 0.15)
+	SV.Animate:Orbit(moon[1], 10, false)
+
+	moon[2] = moon:CreateTexture(nil, "OVERLAY", nil, 2)
+	moon[2]:SetSize(40, 40)
+	moon[2]:SetPoint("CENTER")
+	moon[2]:SetTexture("Interface\\AddOns\\SVUI_UnitFrames\\assets\\Class\\DRUID-MOON")
+	moon[1]:Hide()
+	chicken.Moon = moon;
+
+	local lunar = CreateFrame('StatusBar', nil, chicken)
+	lunar:SetPoint("LEFT", moon, "RIGHT", -6, 0)
+	lunar:SetSize(100,40)
+	lunar:SetStatusBarTexture(SV.media.statusbar.lazer)
+	lunar.noupdate = true;
+	lunar:SetMinMaxValues(-1, 1)
+	lunar:SetValue(0)
+	chicken.LunarBar = lunar;
+
+	local solar = CreateFrame('StatusBar', nil, chicken)
+	solar:SetPoint('LEFT', lunar:GetStatusBarTexture(), 'RIGHT')
+	solar:SetSize(100,40)
+	solar:SetStatusBarTexture(SV.media.statusbar.lazer)
+	solar.noupdate = true;
+	solar:SetMinMaxValues(-1, 1)
+	solar:SetValue(0)
+	chicken.SolarBar = solar;
+
+	local sun = CreateFrame('Frame', nil, chicken)
+	sun:SetFrameLevel(chicken:GetFrameLevel() + 2)
+	sun:SetSize(40, 40)
+	sun:SetPoint("LEFT", lunar, "RIGHT", -6, 0)
+	SV.SpecialFX:SetFXFrame(sun, "holy")
+	sun.FX:SetFrameLevel(chicken:GetFrameLevel() - 2)
+
+	sun[1] = sun:CreateTexture(nil, "BACKGROUND", nil, 1)
+	sun[1]:SetSize(50, 50)
+	sun[1]:SetPoint("CENTER")
+	sun[1]:SetTexture("Interface\\AddOns\\SVUI_UnitFrames\\assets\\Class\\VORTEX")
+	sun[1]:SetBlendMode("ADD")
+	sun[1]:SetVertexColor(1, 0.5, 0, 0.15)
+	SV.Animate:Orbit(sun[1], 10, false)
+
+	sun[2] = sun:CreateTexture(nil, "OVERLAY", nil, 2)
+	sun[2]:SetSize(40, 40)
+	sun[2]:SetPoint("CENTER")
+	sun[2]:SetTexture("Interface\\AddOns\\SVUI_UnitFrames\\assets\\Class\\DRUID-SUN")
+	sun[1]:Hide()
+	chicken.Sun = sun;
+
+	chicken.Text = lunar:CreateFontString(nil, 'OVERLAY')
+	chicken.Text:SetPoint("CENTER", chicken, "CENTER", 0, 0)
+	chicken.Text:SetFont(SV.media.font.default, 16, "NONE")
+	chicken.Text:SetShadowOffset(0,0)
+	chicken.Text:SetJustifyH("CENTER")
+
+	chicken.PostUpdatePower = EclipseDirection;
+	chicken.PostUpdateAura = EclipseDirection;
+]]--
+	local cat = CreateFrame('Frame',nil,bar)
+	cat:SetAllPoints(bar)
+	local max = MAX_COMBO_POINTS;
+	local size = 20
+	for i = 1, max do
+		local cpoint = CreateFrame('Frame',nil,cat)
+		cpoint:SetSize(size,size)
+
+		local icon = cpoint:CreateTexture(nil,"OVERLAY",nil,1)
+		icon:SetSize(size,size)
+		icon:SetPoint("CENTER")
+		icon:SetBlendMode("BLEND")
+		icon:SetTexture(comboTextures[random(1,3)])
+		cpoint.Icon = icon
+
+		cat[i] = cpoint
+	end
+	cat.PointShow = ShowPoint;
+	cat.PointHide = HidePoint;
+
+	local mana = CreateFrame("Frame", nil, playerFrame)
+	mana:SetFrameStrata("LOW")
+	mana:InsetPoints(bar, 2, 4)
+	mana:SetStyle("!_Frame", "Default")
+	mana:SetFrameLevel(mana:GetFrameLevel() + 1)
+	mana.colorPower = true;
+	mana.PostUpdatePower = UpdateAltPower;
+	mana.ManaBar = CreateFrame("StatusBar", nil, mana)
+	mana.ManaBar.noupdate = true;
+	mana.ManaBar:SetStatusBarTexture(SV.media.statusbar.glow)
+	mana.ManaBar:InsetPoints(mana)
+	mana.bg = mana:CreateTexture(nil, "BORDER")
+	mana.bg:SetAllPoints(mana.ManaBar)
+	mana.bg:SetTexture([[Interface\BUTTONS\WHITE8X8]])
+	mana.bg.multiplier = 0.3;
+	mana.Text = mana.ManaBar:CreateFontString(nil, "OVERLAY")
+	mana.Text:SetAllPoints(mana.ManaBar)
+	mana.Text:SetFontObject(SVUI_Font_Unit)
+
+	bar.Cat = cat;
+	--bar.Chicken = chicken;
+	bar.Mana = mana;
+
+	local classBarHolder = CreateFrame("Frame", "Player_ClassBar", bar)
+	classBarHolder:SetPoint("TOPLEFT", playerFrame, "BOTTOMLEFT", 0, -2)
+	bar:SetPoint("TOPLEFT", classBarHolder, "TOPLEFT", 0, 0)
+	bar.Holder = classBarHolder
+	SV:NewAnchor(bar.Holder, L["Classbar"], OnMove)
+
+	playerFrame.RefreshClassBar = Reposition;
+	playerFrame.Druidness = bar
+	return 'Druidness'
+end
diff --git a/SVUI_UnitFrames/class_resources/hunter.lua b/SVUI_UnitFrames/class_resources/hunter.lua
new file mode 100644
index 0000000..fb22a0f
--- /dev/null
+++ b/SVUI_UnitFrames/class_resources/hunter.lua
@@ -0,0 +1,149 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack    = _G.unpack;
+local select    = _G.select;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L;
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local MOD = SV.UnitFrames
+
+if(not MOD) then return end
+
+local oUF_SVUI = MOD.oUF
+assert(oUF_SVUI, "SVUI UnitFrames: unable to locate oUF.")
+if(SV.class ~= "HUNTER") then return end
+
+SV.SpecialFX:Register("trap_fire", [[Spells\Fireshot_missile.m2]], -12, 12, 12, -12, 0.6, 0, 0.2)
+SV.SpecialFX:Register("trap_ice", [[Spells\Frostshot_missile.m2]], -12, 12, 12, -12, 0.6, 0, 0.18)
+SV.SpecialFX:Register("trap_frost", [[Spells\Blindingshot_missile.m2]], -12, 12, 12, -12, 0.6, -0.1, 0.22)
+SV.SpecialFX:Register("trap_snake", [[Spells\Poisonshot_missile.m2]], -12, 12, 12, -12, 0.4, 0, -0.21)
+local specEffects = {
+	[1] = "trap_fire",
+	[2] = "trap_ice",
+	[3] = "trap_frost"
+};
+local HAS_SNAKE_TRAP = false;
+--[[
+##########################################################
+POSITIONING
+##########################################################
+]]--
+local OnMove = function()
+	SV.db.UnitFrames.player.classbar.detachFromFrame = true
+end
+
+local Reposition = function(self)
+	local db = SV.db.UnitFrames.player
+	local bar = self.HunterTraps;
+	local max = self.MaxClassPower;
+	local size = db.classbar.height + 10
+	local width = size * max;
+	bar.Holder:SetSize(width, size)
+    if(not db.classbar.detachFromFrame) then
+    	SV:ResetAnchors(L["Classbar"])
+    end
+    local holderUpdate = bar.Holder:GetScript('OnSizeChanged')
+    if holderUpdate then
+        holderUpdate(bar.Holder)
+    end
+
+    bar:ClearAllPoints()
+    bar:SetAllPoints(bar.Holder)
+	for i = 1, max do
+		bar[i]:ClearAllPoints()
+		bar[i]:SetHeight(size)
+		bar[i]:SetWidth(size)
+		if i==1 then
+			bar[i]:SetPoint("TOPLEFT", bar, "TOPLEFT", 0, 0)
+		else
+			bar[i]:SetPoint("LEFT", bar[i - 1], "RIGHT", -1, 0)
+		end
+	end
+end
+--[[
+##########################################################
+MAGE CHARGES
+##########################################################
+]]--
+local TrapUpdate = function(self, isReady)
+	if(isReady) then
+		if(not self.FX:IsShown()) then
+			self.FX:Show()
+		end
+		self.FX:UpdateEffect()
+	else
+		self.FX:Hide()
+	end
+end
+
+local SnakeTrapUpdate = function(self, isReady, isSnake, bypass)
+	if((isSnake ~= nil) and (isSnake ~= HAS_SNAKE_TRAP)) then
+		if(isSnake == true) then
+			specEffects[3] = "trap_snake"
+		else
+			specEffects[3] = "trap_frost"
+		end
+		HAS_SNAKE_TRAP = isSnake
+
+		self.FX:SetEffect(specEffects[3])
+	end
+
+	if(not bypass) then
+		if(isReady) then
+			if(not self.FX:IsShown()) then
+				self.FX:Show()
+			end
+			self.FX:UpdateEffect()
+		else
+			self.FX:Hide()
+		end
+	end
+end
+
+function MOD:CreateClassBar(playerFrame)
+	local max = 3
+	local bar = CreateFrame("Frame",nil,playerFrame)
+	bar:SetFrameLevel(playerFrame.TextGrip:GetFrameLevel() + 30)
+
+	for i = 1, max do
+		bar[i] = CreateFrame("StatusBar", nil, bar)
+		bar[i]:SetStatusBarTexture("Interface\\AddOns\\SVUI_UnitFrames\\assets\\Class\\HUNTER-TRAP")
+		bar[i]:GetStatusBarTexture():SetHorizTile(false)
+		bar[i]:SetOrientation("VERTICAL")
+		bar[i].noupdate = true;
+
+		bar[i].bg = bar[i]:CreateTexture(nil, "BACKGROUND")
+		bar[i].bg:SetAllPoints(bar[i])
+		bar[i].bg:SetTexture("Interface\\AddOns\\SVUI_UnitFrames\\assets\\Class\\HUNTER-TRAP-BG");
+
+		local effectName = specEffects[i]
+		SV.SpecialFX:SetFXFrame(bar[i], effectName)
+	end
+
+	bar[1].Update = TrapUpdate
+	bar[2].Update = TrapUpdate
+	bar[3].Update = SnakeTrapUpdate
+
+	local classBarHolder = CreateFrame("Frame", "Player_ClassBar", bar)
+	classBarHolder:SetPoint("TOPLEFT", playerFrame, "BOTTOMLEFT", 0, -2)
+	bar:SetPoint("TOPLEFT", classBarHolder, "TOPLEFT", 0, 0)
+	bar.Holder = classBarHolder
+	SV:NewAnchor(bar.Holder, L["Classbar"], OnMove)
+
+	playerFrame.MaxClassPower = max;
+	playerFrame.RefreshClassBar = Reposition;
+	playerFrame.HunterTraps = bar
+	return 'HunterTraps'
+end
diff --git a/SVUI_UnitFrames/class_resources/mage.lua b/SVUI_UnitFrames/class_resources/mage.lua
new file mode 100644
index 0000000..f6fe064
--- /dev/null
+++ b/SVUI_UnitFrames/class_resources/mage.lua
@@ -0,0 +1,204 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack    = _G.unpack;
+local select    = _G.select;
+local pairs     = _G.pairs;
+local ipairs    = _G.ipairs;
+local type      = _G.type;
+local error     = _G.error;
+local pcall     = _G.pcall;
+local tostring  = _G.tostring;
+local tonumber  = _G.tonumber;
+local assert 	= _G.assert;
+local math 		= _G.math;
+--[[ MATH METHODS ]]--
+local random = math.random;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L;
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local MOD = SV.UnitFrames
+
+if(not MOD) then return end
+
+local oUF_SVUI = MOD.oUF
+assert(oUF_SVUI, "SVUI UnitFrames: unable to locate oUF.")
+if(SV.class ~= "MAGE") then return end
+
+local ORB_ICON = [[Interface\AddOns\SVUI_UnitFrames\assets\Class\ORB]];
+local ORB_BG = [[Interface\AddOns\SVUI_UnitFrames\assets\Class\ORB-BG]];
+local CHARGE_ICON = [[Interface\AddOns\SVUI_UnitFrames\assets\Class\MAGE-CHARGE]];
+local ICICLE_ICON = [[Interface\AddOns\SVUI_UnitFrames\assets\Class\MAGE-ICICLE]];
+local NO_ART = SV.NoTexture;
+SV.SpecialFX:Register("mage_fire", [[Spells\Fill_fire_cast_01.m2]], 2, -2, -2, 2, 0.85, -0.45, 1)
+local specEffects = { [1] = "arcane", [2] = "mage_fire", [3] = "frost" };
+local specColors = {
+	[1] = {0.8, 1, 1, 1},
+	[2] = {1, 0.2, 0, 0.75},
+	[3] = {0.95, 1, 1, 0.75}
+};
+--[[
+##########################################################
+POSITIONING
+##########################################################
+]]--
+local OnMove = function()
+	SV.db.UnitFrames.player.classbar.detachFromFrame = true
+end
+
+local Reposition = function(self)
+	local db = SV.db.UnitFrames.player
+	local bar = self.MageMagic;
+	local max = self.MaxClassPower;
+	local size = db.classbar.height
+	local width = size * max;
+	bar.Holder:SetSize(width, size)
+    if(not db.classbar.detachFromFrame) then
+    	SV:ResetAnchors(L["Classbar"])
+    end
+    local holderUpdate = bar.Holder:GetScript('OnSizeChanged')
+    if holderUpdate then
+        holderUpdate(bar.Holder)
+    end
+
+    bar:ClearAllPoints()
+    bar:SetAllPoints(bar.Holder)
+	for i = 1, max do
+		bar[i]:ClearAllPoints()
+		bar[i]:SetHeight(size-4)
+		bar[i]:SetWidth(size-4)
+		if i==1 then
+			bar[i]:SetPoint("TOPLEFT", bar, "TOPLEFT", 0, 0)
+		else
+			bar[i]:SetPoint("LEFT", bar[i - 1], "RIGHT", -3, 0)
+		end
+	end
+end
+--[[
+##########################################################
+MAGE CHARGES
+##########################################################
+]]--
+local PostTalentUpdate = function(self, spec)
+	if(not self:IsShown()) then
+		self:Show()
+	end
+	local color = specColors[spec]
+	if(spec == 1) then
+		for i = 1, 5 do
+			self[i]:SetStatusBarTexture(CHARGE_ICON)
+			self[i].bg:SetTexture(ORB_BG)
+			self[i]:SetStatusBarColor(unpack(color))
+			self[i].FX:SetEffect(specEffects[spec])
+		end
+	elseif(spec == 3) then
+		for i = 1, 5 do
+			self[i]:SetStatusBarTexture(ICICLE_ICON.."-"..i)
+			self[i].bg:SetTexture(ICICLE_ICON.."-"..i)
+			self[i]:SetStatusBarColor(unpack(color))
+			self[i].FX:SetEffect(specEffects[spec])
+		end
+	else
+		self.Ignite.FX:SetEffect(specEffects[spec])
+	end
+end
+
+function MOD:CreateClassBar(playerFrame)
+	local max = 5
+	local bar = CreateFrame("Frame",nil,playerFrame)
+	bar:SetFrameLevel(playerFrame.TextGrip:GetFrameLevel() + 30)
+
+	for i = 1, max do
+		bar[i] = CreateFrame("StatusBar", nil, bar)
+		bar[i]:SetStatusBarTexture(CHARGE_ICON)
+		bar[i]:GetStatusBarTexture():SetHorizTile(false)
+		bar[i]:SetOrientation("VERTICAL")
+		bar[i]:SetStatusBarColor(0.95, 1, 1, 0.75)
+		bar[i].noupdate = true;
+
+		bar[i].bg = bar[i]:CreateTexture(nil, "BACKGROUND")
+		bar[i].bg:SetAllPoints(bar[i])
+		bar[i].bg:SetTexture(ORB_BG);
+		bar[i].bg:SetVertexColor(0.25,0.5,0.5)
+
+		SV.SpecialFX:SetFXFrame(bar[i], "arcane")
+		--bar[i].FX:SetFrameLevel(0)
+		bar[i].FX:SetAlpha(0.5)
+	end
+
+	local bgFrame = CreateFrame("Frame", nil, bar)
+	bgFrame:InsetPoints(bar)
+	SV.SpecialFX:SetFXFrame(bgFrame, "arcane")
+
+	local bgTexture = bgFrame:CreateTexture(nil, "BACKGROUND")
+	bgTexture:SetAllPoints(bgFrame)
+	bgTexture:SetColorTexture(0.09,0.01,0,0.5)
+
+	local borderB = bgFrame:CreateTexture(nil,"OVERLAY")
+	borderB:SetColorTexture(0,0,0)
+	borderB:SetPoint("BOTTOMLEFT")
+	borderB:SetPoint("BOTTOMRIGHT")
+	borderB:SetHeight(2)
+
+	local borderT = bgFrame:CreateTexture(nil,"OVERLAY")
+	borderT:SetColorTexture(0,0,0)
+	borderT:SetPoint("TOPLEFT")
+	borderT:SetPoint("TOPRIGHT")
+	borderT:SetHeight(2)
+
+	local borderL = bgFrame:CreateTexture(nil,"OVERLAY")
+	borderL:SetColorTexture(0,0,0)
+	borderL:SetPoint("TOPLEFT")
+	borderL:SetPoint("BOTTOMLEFT")
+	borderL:SetWidth(2)
+
+	local borderR = bgFrame:CreateTexture(nil,"OVERLAY")
+	borderR:SetColorTexture(0,0,0)
+	borderR:SetPoint("TOPRIGHT")
+	borderR:SetPoint("BOTTOMRIGHT")
+	borderR:SetWidth(2)
+
+	bar.bg = bgTexture;
+
+
+	local ignite = CreateFrame("StatusBar", nil, bgFrame)
+	ignite.noupdate = true;
+	ignite:InsetPoints(bgFrame)
+	ignite:SetOrientation("HORIZONTAL")
+	ignite:SetStatusBarTexture(SV.media.statusbar.glow)
+	ignite:SetStatusBarColor(1, 0.2, 0, 0.75)
+	ignite.text = ignite:CreateFontString(nil, "OVERLAY")
+	ignite.text:SetPoint("LEFT")
+	ignite.text:SetFontObject(SVUI_Font_Unit_Small)
+	ignite.text:SetJustifyH('LEFT')
+	ignite.text:SetTextColor(1,1,0)
+	ignite.text:SetText("0")
+	bgFrame.Bar = ignite;
+    --SV.SpecialFX:SetFXFrame(ignite, "conqueror", true)
+	--ignite.FX:SetScript("OnShow", EffectModel_OnShow)
+	bar.Ignite = bgFrame;
+	bar.Ignite:Hide();
+
+	bar.PostTalentUpdate = PostTalentUpdate;
+	local classBarHolder = CreateFrame("Frame", "Player_ClassBar", bar)
+	classBarHolder:SetPoint("TOPLEFT", playerFrame, "BOTTOMLEFT", 0, -2)
+	bar:SetPoint("TOPLEFT", classBarHolder, "TOPLEFT", 0, 0)
+	bar.Holder = classBarHolder
+	SV:NewAnchor(bar.Holder, L["Classbar"], OnMove)
+
+	playerFrame.MaxClassPower = max;
+	playerFrame.RefreshClassBar = Reposition;
+	playerFrame.MageMagic = bar
+	return 'MageMagic'
+end
diff --git a/SVUI_UnitFrames/class_resources/monk.lua b/SVUI_UnitFrames/class_resources/monk.lua
new file mode 100644
index 0000000..fcb9f5b
--- /dev/null
+++ b/SVUI_UnitFrames/class_resources/monk.lua
@@ -0,0 +1,175 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack    = _G.unpack;
+local select    = _G.select;
+local pairs     = _G.pairs;
+local ipairs    = _G.ipairs;
+local type      = _G.type;
+local error     = _G.error;
+local pcall     = _G.pcall;
+local tostring  = _G.tostring;
+local tonumber  = _G.tonumber;
+local assert 	= _G.assert;
+local math 		= _G.math;
+--[[ MATH METHODS ]]--
+local random = math.random;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L;
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local MOD = SV.UnitFrames
+
+if(not MOD) then return end
+
+local oUF_SVUI = MOD.oUF
+assert(oUF_SVUI, "SVUI UnitFrames: unable to locate oUF.")
+if(SV.class ~= "MONK") then return end
+
+local ORB_ICON = [[Interface\AddOns\SVUI_UnitFrames\assets\Class\ORB]];
+local ORB_BG = [[Interface\AddOns\SVUI_UnitFrames\assets\Class\ORB-BG]];
+
+local STAGGER_BAR = [[Interface\AddOns\SVUI_UnitFrames\assets\Class\MONK-STAGGER-BAR]];
+local STAGGER_BG = [[Interface\AddOns\SVUI_UnitFrames\assets\Class\MONK-STAGGER-BG]];
+local STAGGER_FG = [[Interface\AddOns\SVUI_UnitFrames\assets\Class\MONK-STAGGER-FG]];
+local STAGGER_ICON = [[Interface\AddOns\SVUI_UnitFrames\assets\Class\MONK-STAGGER-ICON]];
+
+local CHI_FILE = [[Interface\Addons\SVUI_UnitFrames\assets\Class\MONK]];
+local CHI_COORDS = {
+	[1] = {0,0.5,0,0.5},
+	[2] = {0.5,1,0,0.5},
+	[3] = {0,0.5,0.5,1},
+	[4] = {0.5,1,0.5,1},
+	[5] = {0.5,1,0,0.5},
+	[6] = {0,0.5,0.5,1},
+};
+--[[
+##########################################################
+POSITIONING
+##########################################################
+]]--
+local OnMove = function()
+	SV.db.UnitFrames.player.classbar.detachFromFrame = true
+end
+
+local Reposition = function(self)
+	local db = SV.db.UnitFrames.player
+	self.KungFu.DrunkenMaster.isEnabled = db.classbar.enableStagger;
+	local bar = self.KungFu;
+	local max = self.MaxClassPower;
+	local size = db.classbar.height
+	local width = size * max;
+	bar.Holder:SetSize(width, size)
+    if(not db.classbar.detachFromFrame) then
+    	SV:ResetAnchors(L["Classbar"])
+    end
+    local holderUpdate = bar.Holder:GetScript('OnSizeChanged')
+    if holderUpdate then
+        holderUpdate(bar.Holder)
+    end
+
+    bar:ClearAllPoints()
+    bar:SetAllPoints(bar.Holder)
+	local tmp = 0.67
+	for i = 1, max do
+		local chi = tmp - (i * 0.1)
+		bar[i]:ClearAllPoints()
+		bar[i]:SetHeight(size)
+		bar[i]:SetWidth(size)
+		bar[i]:SetStatusBarColor(chi, 0.87, 0.35)
+		if i==1 then
+			bar[i]:SetPoint("TOPLEFT", bar, "TOPLEFT", 0, 0)
+		else
+			bar[i]:SetPoint("LEFT", bar[i - 1], "RIGHT", -2, 0)
+		end
+	end
+end
+
+local StartFlash = function(self) SV.Animate:Flash(self.overlay,1,true) end
+local StopFlash = function(self) SV.Animate:StopFlash(self.overlay) end
+--[[
+##########################################################
+MONK HARMONY
+##########################################################
+]]--
+function MOD:CreateClassBar(playerFrame)
+	local max = 6
+	local bar = CreateFrame("Frame", nil, playerFrame)
+	bar:SetFrameLevel(playerFrame.TextGrip:GetFrameLevel() + 30)
+	for i=1, max do
+		local coords = CHI_COORDS[i]
+		bar[i] = CreateFrame("StatusBar", nil, bar)
+		bar[i]:SetStatusBarTexture(ORB_ICON)
+		bar[i]:GetStatusBarTexture():SetHorizTile(false)
+		bar[i].noupdate = true;
+
+		bar[i].bg = bar[i]:CreateTexture(nil, "BACKGROUND")
+		bar[i].bg:SetAllPoints(bar[i])
+		bar[i].bg:SetTexture(ORB_BG)
+
+		bar[i].glow = bar[i]:CreateTexture(nil, "OVERLAY")
+		bar[i].glow:SetAllPoints(bar[i])
+		bar[i].glow:SetTexture(CHI_FILE)
+		bar[i].glow:SetTexCoord(coords[1],coords[2],coords[3],coords[4])
+
+		bar[i].overlay = bar[i]:CreateTexture(nil, "OVERLAY", nil, 7)
+		bar[i].overlay:SetAllPoints(bar[i])
+		bar[i].overlay:SetTexture(CHI_FILE)
+		bar[i].overlay:SetTexCoord(coords[1],coords[2],coords[3],coords[4])
+		bar[i].overlay:SetVertexColor(0, 0, 0)
+
+		bar[i]:SetScript("OnShow", StartFlash)
+		bar[i]:SetScript("OnHide", StopFlash)
+
+		SV.SpecialFX:SetFXFrame(bar[i], "chi")
+		bar[i].FX:SetFrameLevel(bar[i]:GetFrameLevel())
+	end
+
+	local stagger = CreateFrame("Statusbar",nil,playerFrame)
+	stagger:SetPoint('TOPLEFT', playerFrame, 'TOPRIGHT', 3, 0)
+	stagger:SetPoint('BOTTOMLEFT', playerFrame, 'BOTTOMRIGHT', 3, 0)
+	stagger:SetWidth(10)
+	stagger:SetStyle("Frame", "Bar")
+	stagger:SetOrientation("VERTICAL")
+	stagger:SetStatusBarTexture(SV.media.statusbar.default)
+	--stagger:GetStatusBarTexture():SetHorizTile(false)
+
+	stagger.bg = stagger:CreateTexture(nil,'BORDER',nil,1)
+	stagger.bg:SetAllPoints(stagger)
+	stagger.bg:SetTexture(SV.media.statusbar.default)
+	stagger.bg:SetVertexColor(0,0,0,0.33)
+
+	-- stagger.overlay = stagger:CreateTexture(nil,'OVERLAY')
+	-- stagger.overlay:SetAllPoints(stagger)
+	-- stagger.overlay:SetTexture(STAGGER_FG)
+	-- stagger.overlay:SetVertexColor(1,1,1)
+
+	-- stagger.icon = stagger:CreateTexture(nil,'OVERLAY')
+	-- stagger.icon:SetAllPoints(stagger)
+	-- stagger.icon:SetTexture(STAGGER_ICON)
+	stagger.isEnabled = true;
+
+	bar.DrunkenMaster = stagger
+
+	local classBarHolder = CreateFrame("Frame", "Player_ClassBar", bar)
+	classBarHolder:SetPoint("TOPLEFT", playerFrame, "BOTTOMLEFT", 0, -2)
+	bar:SetPoint("TOPLEFT", classBarHolder, "TOPLEFT", 0, 0)
+	bar.Holder = classBarHolder
+	SV:NewAnchor(bar.Holder, L["Classbar"], OnMove)
+
+	playerFrame.MaxClassPower = max
+	playerFrame.RefreshClassBar = Reposition
+
+	playerFrame.KungFu = bar
+	return 'KungFu'
+end
diff --git a/SVUI_UnitFrames/class_resources/paladin.lua b/SVUI_UnitFrames/class_resources/paladin.lua
new file mode 100644
index 0000000..29ac2ec
--- /dev/null
+++ b/SVUI_UnitFrames/class_resources/paladin.lua
@@ -0,0 +1,157 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack    = _G.unpack;
+local select    = _G.select;
+local pairs     = _G.pairs;
+local ipairs    = _G.ipairs;
+local type      = _G.type;
+local error     = _G.error;
+local pcall     = _G.pcall;
+local tostring  = _G.tostring;
+local tonumber  = _G.tonumber;
+local assert 	= _G.assert;
+local math 		= _G.math;
+--[[ MATH METHODS ]]--
+local random = math.random;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L;
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local MOD = SV.UnitFrames
+
+if(not MOD) then return end
+
+local oUF_SVUI = MOD.oUF
+assert(oUF_SVUI, "SVUI UnitFrames: unable to locate oUF.")
+if(SV.class ~= "PALADIN") then return end
+
+--SV.SpecialFX:Register("holypower", [[Spells\Holy_missile_low.m2]], -12, 12, 12, -12, 1.5, 0, 0)
+SV.SpecialFX:Register("holypower", [[Spells\Holylight_impact_head.m2]], -12, 12, 12, -12, 1.5, 0, -0.4)
+--SV.SpecialFX:Register("holypower", [[Spells\Paladin_healinghands_state_01.m2]], -12, 12, 12, -12, 1.2, 0, 0)
+--[[
+##########################################################
+LOCAL FUNCTIONS
+##########################################################
+]]--
+
+--[[
+##########################################################
+POSITIONING
+##########################################################
+]]--
+local OnMove = function()
+	SV.db.UnitFrames.player.classbar.detachFromFrame = true
+end
+
+local Reposition = function(self)
+	local db = SV.db.UnitFrames.player
+	local bar = self.HolyPower;
+	local max = self.MaxClassPower;
+	local size = db.classbar.height + 4;
+	local width = size * max;
+	bar.Holder:SetSize(width, size)
+    if(not db.classbar.detachFromFrame) then
+    	SV:ResetAnchors(L["Classbar"])
+    end
+    local holderUpdate = bar.Holder:GetScript('OnSizeChanged')
+    if holderUpdate then
+        holderUpdate(bar.Holder)
+    end
+
+    bar:ClearAllPoints()
+    bar:SetAllPoints(bar.Holder)
+	for i = 1, max do
+		bar[i].holder:ClearAllPoints()
+		bar[i].holder:SetHeight(size)
+		bar[i].holder:SetWidth(size)
+		bar[i]:GetStatusBarTexture():SetHorizTile(false)
+		if i==1 then
+			bar[i].holder:SetPoint("TOPLEFT", bar, "TOPLEFT", 0, 0)
+		else
+			bar[i].holder:SetPoint("LEFT", bar[i - 1].holder, "RIGHT", -4, 0)
+		end
+	end
+end
+
+local Update = function(self, event, unit, powerType)
+	if self.unit ~= unit or (powerType and powerType ~= 'HOLY_POWER') then return end
+	local bar = self.HolyPower;
+	local baseCount = UnitPower('player',SPELL_POWER_HOLY_POWER)
+	local maxCount = UnitPowerMax('player',SPELL_POWER_HOLY_POWER)
+	for i=1,maxCount do
+		if i <= baseCount then
+			bar[i]:SetAlpha(1)
+			if(not bar[i].holder.FX:IsShown()) then
+				bar[i].holder.FX:Show()
+				bar[i].holder.FX:UpdateEffect()
+			end
+		else
+			bar[i]:SetAlpha(0)
+			bar[i].holder.FX:Hide()
+		end
+		if i > maxCount then
+			bar[i]:Hide()
+		else
+			bar[i]:Show()
+		end
+	end
+	self.MaxClassPower = maxCount
+end
+--[[
+##########################################################
+PALADIN
+##########################################################
+]]--
+local ShowLink = function(self) self.holder:Show() end
+local HideLink = function(self) self.holder:Hide() end
+
+function MOD:CreateClassBar(playerFrame)
+	local max = 5
+	local bar = CreateFrame("Frame", nil, playerFrame)
+	bar:SetFrameLevel(playerFrame.TextGrip:GetFrameLevel() + 30)
+
+	for i = 1, max do
+		local underlay = CreateFrame("Frame", nil, bar);
+		SV.SpecialFX:SetFXFrame(underlay, "holypower", true)
+		underlay.FX:SetFrameStrata("BACKGROUND")
+		underlay.FX:SetFrameLevel(0)
+
+		bar[i] = CreateFrame("StatusBar", nil, underlay)
+		bar[i]:SetAllPoints(underlay)
+		bar[i]:SetStatusBarTexture("Interface\\AddOns\\SVUI_UnitFrames\\assets\\Class\\PALADIN-HAMMER-FG")
+		bar[i]:GetStatusBarTexture():SetHorizTile(false)
+		bar[i]:SetStatusBarColor(0.9,0.9,0.8)
+
+		-- bar[i].bg = underlay:CreateTexture(nil,"BORDER")
+		-- bar[i].bg:SetAllPoints(underlay)
+		-- bar[i].bg:SetTexture("Interface\\AddOns\\SVUI_UnitFrames\\assets\\Class\\PALADIN-HAMMER-BG")
+		-- bar[i].bg:SetVertexColor(0,0,0)
+
+		bar[i].holder = underlay
+		--bar[i]:SetScript("OnShow", ShowLink)
+		--bar[i]:SetScript("OnHide", HideLink)
+	end
+	bar.Override = Update;
+
+	local classBarHolder = CreateFrame("Frame", "Player_ClassBar", bar)
+	classBarHolder:SetPoint("TOPLEFT", playerFrame, "BOTTOMLEFT", 0, -2)
+	bar:SetPoint("TOPLEFT", classBarHolder, "TOPLEFT", 0, 0)
+	bar.Holder = classBarHolder
+	SV:NewAnchor(bar.Holder, L["Classbar"], OnMove)
+
+	playerFrame.MaxClassPower = max;
+	playerFrame.RefreshClassBar = Reposition;
+	playerFrame.HolyPower = bar
+	return 'HolyPower'
+end
diff --git a/SVUI_UnitFrames/class_resources/priest.lua b/SVUI_UnitFrames/class_resources/priest.lua
new file mode 100644
index 0000000..e063c84
--- /dev/null
+++ b/SVUI_UnitFrames/class_resources/priest.lua
@@ -0,0 +1,130 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack    = _G.unpack;
+local select    = _G.select;
+local pairs     = _G.pairs;
+local ipairs    = _G.ipairs;
+local type      = _G.type;
+local error     = _G.error;
+local pcall     = _G.pcall;
+local tostring  = _G.tostring;
+local tonumber  = _G.tonumber;
+local assert 	= _G.assert;
+local math 		= _G.math;
+--[[ MATH METHODS ]]--
+local random = math.random;
+local CreateFrame = _G.CreateFrame;
+local GetSpecialization = _G.GetSpecialization;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L;
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local MOD = SV.UnitFrames
+
+if(not MOD) then return end
+
+local oUF_SVUI = MOD.oUF
+assert(oUF_SVUI, "SVUI UnitFrames: unable to locate oUF.")
+if(SV.class ~= "PRIEST") then return end
+
+local ORB_ICON = [[Interface\AddOns\SVUI_UnitFrames\assets\Class\ORB]]
+local ORB_BG = [[Interface\AddOns\SVUI_UnitFrames\assets\Class\ORB-BG]]
+local specEffects = { [1] = "holy", [2] = "holy", [3] = "shadow" };
+--[[
+##########################################################
+POSITIONING
+##########################################################
+]]--
+local OnMove = function()
+	SV.db.UnitFrames.player.classbar.detachFromFrame = true
+end
+
+local Reposition = function(self)
+	local db = SV.db.UnitFrames.player
+	local bar = self.PriestOrbs;
+	local max = self.MaxClassPower;
+	local size = db.classbar.height
+	local width = size * max;
+
+	bar.Holder:SetSize(width, size)
+    if(not db.classbar.detachFromFrame) then
+    	SV:ResetAnchors(L["Classbar"])
+    end
+    local holderUpdate = bar.Holder:GetScript('OnSizeChanged')
+    if holderUpdate then
+        holderUpdate(bar.Holder)
+    end
+
+    bar:ClearAllPoints()
+    bar:SetAllPoints(bar.Holder)
+
+	for i = 1, max do
+		bar[i]:ClearAllPoints()
+		bar[i]:SetHeight(size)
+		bar[i]:SetWidth(size)
+		if i==1 then
+			bar[i]:SetPoint("TOPLEFT", bar, "TOPLEFT", 0, 0)
+		else
+			bar[i]:SetPoint("LEFT", bar[i - 1], "RIGHT", -1, 0)
+		end
+	end
+	--print(UnitPowerType('player'))
+end
+--[[
+##########################################################
+PRIEST
+##########################################################
+]]--
+local PreUpdate = function(self, spec)
+	if(self.CurrentSpec and (self.CurrentSpec == spec)) then return end
+	local effectName = specEffects[spec]
+	for i = 1, 5 do
+		self[i].FX:SetEffect(effectName)
+	end
+	self.CurrentSpec = spec
+end
+
+function MOD:CreateClassBar(playerFrame)
+	local max = 5
+	local bar = CreateFrame("Frame", nil, playerFrame)
+	bar:SetFrameLevel(playerFrame.TextGrip:GetFrameLevel() + 30)
+
+	for i=1, max do
+		bar[i] = CreateFrame("StatusBar", nil, bar)
+		bar[i]:SetStatusBarTexture(ORB_ICON)
+		bar[i]:GetStatusBarTexture():SetHorizTile(false)
+		bar[i].noupdate = true;
+
+		bar[i].bg = bar[i]:CreateTexture(nil, "BACKGROUND")
+		bar[i].bg:SetAllPoints(bar[i])
+		bar[i].bg:SetTexture(ORB_BG)
+
+		local spec = GetSpecialization()
+		local effectName = specEffects[spec]
+		SV.SpecialFX:SetFXFrame(bar[i], effectName)
+	end
+	bar.PreUpdate = PreUpdate
+
+	local classBarHolder = CreateFrame("Frame", "Player_ClassBar", bar)
+	classBarHolder:SetPoint("TOPLEFT", playerFrame, "BOTTOMLEFT", 0, -2)
+	bar:SetPoint("TOPLEFT", classBarHolder, "TOPLEFT", 0, 0)
+	bar.Holder = classBarHolder
+	SV:NewAnchor(bar.Holder, L["Classbar"], OnMove)
+
+	playerFrame.MaxClassPower = max;
+	playerFrame.RefreshClassBar = Reposition;
+
+	playerFrame.PriestOrbs = bar
+	return 'PriestOrbs'
+end
\ No newline at end of file
diff --git a/SVUI_UnitFrames/class_resources/rogue.lua b/SVUI_UnitFrames/class_resources/rogue.lua
new file mode 100644
index 0000000..0a81bec
--- /dev/null
+++ b/SVUI_UnitFrames/class_resources/rogue.lua
@@ -0,0 +1,193 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack    = _G.unpack;
+local select    = _G.select;
+local pairs     = _G.pairs;
+local ipairs    = _G.ipairs;
+local type      = _G.type;
+local error     = _G.error;
+local pcall     = _G.pcall;
+local tostring  = _G.tostring;
+local tonumber  = _G.tonumber;
+local assert 	= _G.assert;
+local math 		= _G.math;
+--[[ MATH METHODS ]]--
+local random = math.random;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L;
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local MOD = SV.UnitFrames
+
+if(not MOD) then return end
+
+local oUF_SVUI = MOD.oUF
+assert(oUF_SVUI, "SVUI UnitFrames: unable to locate oUF.")
+if(SV.class ~= "ROGUE") then return end
+--[[
+##########################################################
+LOCALS
+##########################################################
+]]--
+local TRACKER_FONT = [[Interface\AddOns\SVUI_!Core\assets\fonts\Combo.ttf]];
+local EMPTY_TEXTURE = [[Interface\AddOns\SVUI_!Core\assets\textures\EMPTY]];
+local BLOOD_TEXTURE = [[Interface\Addons\SVUI_UnitFrames\assets\Class\COMBO-ANIMATION]];
+local ICON_BG = [[Interface\Addons\SVUI_UnitFrames\assets\Class\ROGUE-SMOKE]];
+local ICON_ANTI = [[Interface\Addons\SVUI_UnitFrames\assets\Class\ROGUE-ANTICIPATION]];
+local ICON_FILE = [[Interface\Addons\SVUI_UnitFrames\assets\Class\ROGUE]];
+local ICON_COORDS = {
+	{0,0.5,0,0.5},
+	{0.5,1,0,0.5},
+	{0,0.5,0.5,1},
+	{0.5,1,0.5,1},
+};
+local cpointColor = {
+	{0.69,0.31,0.31},
+	{0.69,0.31,0.31},
+	{0.65,0.63,0.35},
+	{0.65,0.63,0.35},
+	{0.33,0.59,0.33}
+};
+--[[
+##########################################################
+POSITIONING
+##########################################################
+]]--
+local OnMove = function()
+	SV.db.UnitFrames.player.classbar.detachFromFrame = true
+end
+
+local ShowPoint = function(self)
+	self.FX:SetEffect("default")
+end
+
+local HidePoint = function(self)
+	local coords = ICON_COORDS[random(2,4)];
+	self.Icon:SetTexCoord(coords[1],coords[2],coords[3],coords[4])
+	self.Blood:SetTexture(BLOOD_TEXTURE)
+end
+
+local Reposition = function(self)
+	local db = SV.db.UnitFrames.player
+	local bar = self.HyperCombo;
+	if not db then return end
+	local height = db.classbar.height
+	local width = height * 3;
+	local textwidth = height * 1.25;
+
+	bar.Holder:SetSize(width, height)
+
+	if(not db.classbar.detachFromFrame) then
+		SV:ResetAnchors(L["Classbar"])
+	end
+
+	local holderUpdate = bar.Holder:GetScript('OnSizeChanged')
+	if holderUpdate then
+	  holderUpdate(bar.Holder)
+	end
+
+	bar:ClearAllPoints()
+	bar:SetAllPoints(bar.Holder)
+
+	local points = bar.Combo;
+	local max = UnitPowerMax('player', SPELL_POWER_COMBO_POINTS);
+
+	points:ClearAllPoints()
+	points:SetAllPoints(bar)
+	if(db.classbar.altComboPoints) then
+		for i = 1, max do
+			points[i].FX:SetAlpha(0)
+			points[i]:ClearAllPoints()
+			points[i]:SetSize(height, height)
+			points[i].Icon:SetTexture(ICON_FILE)
+			if i==1 then
+				points[i]:SetPoint("LEFT", points)
+			else
+				points[i]:SetPoint("LEFT", points[i - 1], "RIGHT", -8, 0)
+			end
+		end
+		bar.PointShow = nil;
+		bar.PointHide = HidePoint;
+	else
+		for i = 1, max do
+			points[i].FX:SetAlpha(1)
+			points[i]:ClearAllPoints()
+			points[i]:SetSize(height, height)
+			points[i].Icon:SetTexture(EMPTY_TEXTURE)
+			if(points[i].Blood) then
+				points[i].Blood:SetTexture(EMPTY_TEXTURE)
+			end
+			if i==1 then
+				points[i]:SetPoint("LEFT", points)
+			else
+				points[i]:SetPoint("LEFT", points[i - 1], "RIGHT", -8, 0)
+			end
+		end
+		bar.PointShow = ShowPoint;
+		bar.PointHide = nil;
+	end
+end
+--[[
+##########################################################
+ROGUE COMBO TRACKER
+##########################################################
+]]--
+function MOD:CreateClassBar(playerFrame)
+	local max = 6
+	local size = 20
+	local coords
+
+	local bar = CreateFrame("Frame", nil, playerFrame)
+	bar:SetFrameLevel(playerFrame.TextGrip:GetFrameLevel() + 30)
+
+	bar.Combo = CreateFrame("Frame",nil,bar)
+	for i = 1, max do
+		local coords = ICON_COORDS[random(2,4)]
+		local cpoint = CreateFrame('Frame', nil, bar.Combo)
+		cpoint:SetSize(size,size)
+
+		SV.SpecialFX:SetFXFrame(cpoint, "default")
+
+		local icon = cpoint:CreateTexture(nil,"OVERLAY",nil,1)
+		icon:SetAllPoints(cpoint)
+		icon:SetTexture(ICON_FILE)
+		icon:SetBlendMode("BLEND")
+		icon:SetTexCoord(coords[1],coords[2],coords[3],coords[4])
+		cpoint.Icon = icon
+
+		local blood = cpoint:CreateTexture(nil,"OVERLAY",nil,2)
+		blood:SetAllPoints(cpoint)
+		blood:SetTexture(EMPTY_TEXTURE)
+		blood:SetBlendMode("ADD")
+
+		SV.Animate:Sprite4(blood,0.08,2,true)
+		cpoint.Blood = blood
+
+		bar.Combo[i] = cpoint
+	end
+
+	bar.PointShow = ShowPoint;
+	bar.PointHide = HidePoint;
+
+	local classBarHolder = CreateFrame("Frame", "Player_ClassBar", bar)
+	classBarHolder:SetPoint("TOPLEFT", playerFrame, "BOTTOMLEFT", 0, -2)
+	bar:SetPoint("TOPLEFT", classBarHolder, "TOPLEFT", 0, 0)
+	bar.Holder = classBarHolder
+	SV:NewAnchor(bar.Holder, L["Classbar"], OnMove)
+
+	playerFrame.MaxClassPower = 5;
+	playerFrame.RefreshClassBar = Reposition;
+	playerFrame.HyperCombo = bar
+	return 'HyperCombo'
+end
diff --git a/SVUI_UnitFrames/class_resources/shaman.lua b/SVUI_UnitFrames/class_resources/shaman.lua
new file mode 100644
index 0000000..4cd21c8
--- /dev/null
+++ b/SVUI_UnitFrames/class_resources/shaman.lua
@@ -0,0 +1,159 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack    = _G.unpack;
+local select    = _G.select;
+local pairs     = _G.pairs;
+local ipairs    = _G.ipairs;
+local type      = _G.type;
+local error     = _G.error;
+local pcall     = _G.pcall;
+local tostring  = _G.tostring;
+local tonumber  = _G.tonumber;
+local assert 	= _G.assert;
+local math 		= _G.math;
+--[[ MATH METHODS ]]--
+local random = math.random;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L;
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local MOD = SV.UnitFrames
+
+if(not MOD) then return end
+
+local oUF_SVUI = MOD.oUF
+assert(oUF_SVUI, "SVUI UnitFrames: unable to locate oUF.")
+if(SV.class ~= "SHAMAN") then return end
+--[[
+##########################################################
+LOCALS
+##########################################################
+]]--
+SV.SpecialFX:Register("maelstrom", [[Spells\Fill_lightning_cast_01.m2]], 0, 0, 0, 0, 1.18, 0, 0)
+SV.SpecialFX:Register("maelstrom_air", [[Spells\Monk_rushingjadewind_grey.m2]], 2, -2, -2, 2, 0.5, 0, 2)
+SV.SpecialFX:Register("maelstrom_water", [[Spells\Flowingwater_high.m2]], 2, -2, -2, 2, 0.008, -0.02, -0.22)
+--[[
+##########################################################
+POSITIONING
+##########################################################
+]]--
+local OnMove = function()
+	SV.db.UnitFrames.player.classbar.detachFromFrame = true
+end
+
+local Reposition = function(self)
+	local db = SV.db.UnitFrames.player
+	local bar = self.Maelstrom;
+	local max = self.MaxClassPower;
+	local size = db.classbar.height
+	local width = size * max;
+	bar.Holder:SetSize(width, size*0.8)
+    if(not db.classbar.detachFromFrame) then
+    	SV:ResetAnchors(L["Classbar"])
+    end
+    local holderUpdate = bar.Holder:GetScript('OnSizeChanged')
+    if holderUpdate then
+        holderUpdate(bar.Holder)
+    end
+
+    bar:ClearAllPoints()
+    bar:SetAllPoints(bar.Holder)
+end
+--[[
+##########################################################
+SHAMAN
+##########################################################
+]]--
+local PostUpdate = function(self, ...)
+	local value = ...;
+	if(not value) then return end
+	if(value > 0) then
+		self:FadeIn()
+		if(not self.Bar.FX:IsShown()) then
+			self.Bar.FX:Show()
+			self.Bar.FX:UpdateEffect()
+		end
+	else
+		self:FadeOut()
+	end
+end
+
+function MOD:CreateClassBar(playerFrame)
+	local max = 6
+	local bar = CreateFrame("Frame",nil,playerFrame)
+	bar:SetFrameLevel(playerFrame.TextGrip:GetFrameLevel() + 30)
+
+	local bgTexture = bar:CreateTexture(nil, "BACKGROUND")
+	bgTexture:SetAllPoints(bar)
+	bgTexture:SetColorTexture(0,0.05,0.1,0.5)
+
+	local borderB = bar:CreateTexture(nil,"OVERLAY")
+	borderB:SetColorTexture(0,0,0)
+	borderB:SetPoint("BOTTOMLEFT")
+	borderB:SetPoint("BOTTOMRIGHT")
+	borderB:SetHeight(2)
+
+	local borderT = bar:CreateTexture(nil,"OVERLAY")
+	borderT:SetColorTexture(0,0,0)
+	borderT:SetPoint("TOPLEFT")
+	borderT:SetPoint("TOPRIGHT")
+	borderT:SetHeight(2)
+
+	local borderL = bar:CreateTexture(nil,"OVERLAY")
+	borderL:SetColorTexture(0,0,0)
+	borderL:SetPoint("TOPLEFT")
+	borderL:SetPoint("BOTTOMLEFT")
+	borderL:SetWidth(2)
+
+	local borderR = bar:CreateTexture(nil,"OVERLAY")
+	borderR:SetColorTexture(0,0,0)
+	borderR:SetPoint("TOPRIGHT")
+	borderR:SetPoint("BOTTOMRIGHT")
+	borderR:SetWidth(2)
+
+	bar.bg = bgTexture;
+
+	local maelBar = CreateFrame("StatusBar", nil, bar)
+	maelBar.noupdate = true;
+	maelBar:InsetPoints(bar)
+	maelBar:SetOrientation("HORIZONTAL")
+	maelBar:SetStatusBarTexture(SV.media.statusbar.gradient)
+	maelBar:SetStatusBarColor(0.2, 0.9, 1, 0.75)
+	maelBar.text = maelBar:CreateFontString(nil, "OVERLAY")
+	maelBar.text:SetPoint("LEFT")
+	maelBar.text:SetFontObject(SVUI_Font_Unit_Small)
+	maelBar.text:SetJustifyH('LEFT')
+	maelBar.text:SetTextColor(1,1,1)
+	maelBar.text:SetText("0")
+
+	SV.SpecialFX:SetFXFrame(bar, "maelstrom_air", true)
+	SV.SpecialFX:SetFXFrame(maelBar, "maelstrom", true)
+	bar.FX:SetFrameLevel(0)
+	bar.FX:SetAlpha(0.5)
+
+	bar.Bar = maelBar;
+	bar.PostUpdate = PostUpdate;
+
+	local classBarHolder = CreateFrame("Frame", "Player_ClassBar", bar)
+	classBarHolder:SetPoint("TOPLEFT", playerFrame, "BOTTOMLEFT", 0, -2)
+	bar:SetPoint("TOPLEFT", classBarHolder, "TOPLEFT", 0, 0)
+	bar.Holder = classBarHolder
+	SV:NewAnchor(bar.Holder, L["Classbar"], OnMove)
+
+	playerFrame.MaxClassPower = max
+	playerFrame.PostTalentUpdate = PostUpdate;
+	playerFrame.RefreshClassBar = Reposition;
+	playerFrame.Maelstrom = bar
+	return 'Maelstrom'
+end
diff --git a/SVUI_UnitFrames/class_resources/warlock.lua b/SVUI_UnitFrames/class_resources/warlock.lua
new file mode 100644
index 0000000..5f7f5c0
--- /dev/null
+++ b/SVUI_UnitFrames/class_resources/warlock.lua
@@ -0,0 +1,203 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack    = _G.unpack;
+local select    = _G.select;
+local pairs     = _G.pairs;
+local ipairs    = _G.ipairs;
+local type      = _G.type;
+local error     = _G.error;
+local pcall     = _G.pcall;
+local tostring  = _G.tostring;
+local tonumber  = _G.tonumber;
+local assert 	= _G.assert;
+local math 		= _G.math;
+--[[ MATH METHODS ]]--
+local random, floor = math.random, math.floor;
+local CreateFrame = _G.CreateFrame;
+local GetSpecialization = _G.GetSpecialization;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L;
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local MOD = SV.UnitFrames
+
+if(not MOD) then return end
+
+local oUF_SVUI = MOD.oUF
+assert(oUF_SVUI, "SVUI UnitFrames: unable to locate oUF.")
+if(SV.class ~= "WARLOCK") then return end
+
+--SV.SpecialFX:Register("affliction", [[Spells\Fel_fire_precast_high_hand.m2]], -12, 12, 12, -12, 0.35, 0, 0);
+SV.SpecialFX:Register("demonology", [[Spells\Warlock_bodyofflames_medium_state_shoulder_right_purple.m2]], -12, 12, 12, -12, 0.4, 0, 0.45)
+SV.SpecialFX:Register("destruction", [[Spells\Fill_fire_cast_01.m2]], -12, 12, 12, -12, 1.5, -0.25, 0.5);
+--[[
+##########################################################
+LOCAL FUNCTIONS
+##########################################################
+]]--
+local FURY_FONT = [[Interface\AddOns\SVUI_!Core\assets\fonts\Numbers.ttf]]
+local shardColors = {
+	[1] = {{0.5,1,0,1}, {0,0,0,0.9}},
+	[2] = {{0.67,0.42,0.93,1}, {0,0,0,0.9}},
+	[3] = {{1,1,0,1}, {0,0,0,0.9}},
+	[4] = {{0.5,1,0,1}, {0,0,0,0.9}}
+}
+local shardTextures = {
+	[1] = {
+		[[Interface\Addons\SVUI_UnitFrames\assets\Class\WARLOCK-SHARD]],
+		[[Interface\Addons\SVUI_UnitFrames\assets\Class\WARLOCK-SHARD-BG]],
+		[[Interface\Addons\SVUI_UnitFrames\assets\Class\WARLOCK-SHARD-FG]]
+	},
+	[2] = {
+		[[Interface\Addons\SVUI_UnitFrames\assets\Class\WARLOCK-SHARD]],
+		[[Interface\Addons\SVUI_UnitFrames\assets\Class\WARLOCK-SHARD-BG]],
+		[[Interface\Addons\SVUI_UnitFrames\assets\Class\WARLOCK-SHARD-FG]]
+	},
+	[3] = {
+		[[Interface\Addons\SVUI_UnitFrames\assets\Class\WARLOCK-EMBER]],
+		[[Interface\Addons\SVUI_UnitFrames\assets\Class\WARLOCK-EMBER]],
+		[[Interface\Addons\SVUI_UnitFrames\assets\Class\WARLOCK-EMBER-FG]]
+	},
+}
+local specFX = {"demonology","demonology","destruction"};
+--[[
+##########################################################
+POSITIONING
+##########################################################
+]]--
+local OnMove = function()
+	SV.db.UnitFrames.player.classbar.detachFromFrame = true
+end
+
+local Reposition = function(self)
+	local db = SV.db.UnitFrames.player
+	local bar = self.WarlockShards;
+	local max = self.MaxClassPower;
+	local size = db.classbar.height
+	local width = size * max;
+	local dbOffset = (size * 0.15)
+	bar.Holder:SetSize(width, size)
+    if(not db.classbar.detachFromFrame) then
+    	SV:ResetAnchors(L["Classbar"], true)
+    end
+    local holderUpdate = bar.Holder:GetScript('OnSizeChanged')
+    if holderUpdate then
+        holderUpdate(bar.Holder)
+    end
+
+    bar:ClearAllPoints()
+    bar:SetAllPoints(bar.Holder)
+
+	for i = 1, max do
+		bar[i]:ClearAllPoints()
+		bar[i]:SetHeight(size)
+		bar[i]:SetWidth(size)
+		if(i == 1) then
+			bar[i]:SetPoint("LEFT", bar)
+		else
+			bar[i]:SetPoint("LEFT", bar[i - 1], "RIGHT", -2, 0)
+		end
+	end
+end
+--[[
+##########################################################
+CUSTOM HANDLERS
+##########################################################
+]]--
+local UpdateTextures = function(self, spec)
+	local max = self.MaxCount;
+	local colors = shardColors[spec];
+	local textures = shardTextures[spec];
+	for i = 1, max do
+		self[i]:SetStatusBarTexture(textures[1])
+		self[i]:GetStatusBarTexture():SetHorizTile(false)
+		self[i].overlay:SetTexture(textures[3])
+		self[i].overlay:SetVertexColor(unpack(colors[1]))
+		self[i].bg:SetTexture(textures[2])
+		self[i].bg:SetVertexColor(unpack(colors[2]))
+		self[i].FX:SetEffect(specFX[spec])
+	end
+	self.CurrentSpec = spec
+end
+
+local ShardUpdate = function(self, value)
+	if (value and value == 1) then
+		if(self.overlay) then
+			self.overlay:Show()
+			SV.Animate:Flash(self.overlay,1,true)
+		end
+		if(not self.FX:IsShown()) then
+			self.FX:Show()
+		end
+		self.FX:UpdateEffect()
+	else
+		if(self.overlay) then
+			SV.Animate:StopFlash(self.overlay)
+			self.overlay:Hide()
+		end
+		self.FX:Hide()
+	end
+end
+--[[
+##########################################################
+WARLOCK
+##########################################################
+]]--
+local EffectModel_OnShow = function(self)
+	self:SetEffect("overlay_demonbar");
+end
+
+function MOD:CreateClassBar(playerFrame)
+	local max = 5;
+	local textures = shardTextures[1];
+	local colors = shardColors[1];
+	local bar = CreateFrame("Frame",nil,playerFrame)
+	bar:SetFrameLevel(playerFrame.TextGrip:GetFrameLevel() + 30)
+	for i = 1, max do
+		bar[i] = CreateFrame("StatusBar", nil, bar)
+		bar[i].noupdate = true;
+		bar[i]:SetOrientation("VERTICAL")
+		bar[i]:SetStatusBarTexture(textures[1])
+		bar[i]:GetStatusBarTexture():SetHorizTile(false)
+
+		bar[i].bg = bar[i]:CreateTexture(nil,'BORDER',nil,1)
+		bar[i].bg:SetAllPoints(bar[i])
+		bar[i].bg:SetTexture(textures[2])
+		bar[i].bg:SetVertexColor(unpack(colors[2]))
+
+		bar[i].overlay = bar[i]:CreateTexture(nil,'OVERLAY')
+		bar[i].overlay:SetAllPoints(bar[i])
+		bar[i].overlay:SetTexture(textures[3])
+		bar[i].overlay:SetBlendMode("BLEND")
+		bar[i].overlay:Hide()
+		bar[i].overlay:SetVertexColor(unpack(colors[1]))
+
+		SV.SpecialFX:SetFXFrame(bar[i], specFX[1], true)
+		bar[i].Update = ShardUpdate
+	end
+
+	bar.UpdateTextures = UpdateTextures;
+	bar.MaxCount = max;
+
+	local classBarHolder = CreateFrame("Frame", "Player_ClassBar", bar)
+	classBarHolder:SetPoint("TOPLEFT", playerFrame, "BOTTOMLEFT", 0, -2)
+	bar:SetPoint("TOPLEFT", classBarHolder, "TOPLEFT", 0, 0)
+	bar.Holder = classBarHolder
+	SV:NewAnchor(bar.Holder, L["Classbar"], OnMove)
+
+	playerFrame.MaxClassPower = max;
+	playerFrame.RefreshClassBar = Reposition;
+	playerFrame.WarlockShards = bar
+	return 'WarlockShards'
+end
diff --git a/SVUI_UnitFrames/class_resources/warrior.lua b/SVUI_UnitFrames/class_resources/warrior.lua
new file mode 100644
index 0000000..104557c
--- /dev/null
+++ b/SVUI_UnitFrames/class_resources/warrior.lua
@@ -0,0 +1,131 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+local unpack    = _G.unpack;
+local select    = _G.select;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L;
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local MOD = SV.UnitFrames
+
+if(not MOD) then return end
+
+local oUF_SVUI = MOD.oUF
+assert(oUF_SVUI, "SVUI UnitFrames: unable to locate oUF.")
+if(SV.class ~= "WARRIOR") then return end
+
+local ORB_ICON = [[Interface\AddOns\SVUI_UnitFrames\assets\Class\ORB]];
+local ORB_BG = [[Interface\AddOns\SVUI_UnitFrames\assets\Class\ORB-BG]];
+SV.SpecialFX:Register("conqueror", [[Spells\Warlock_destructioncharge_impact_chest.m2]], 2, -2, -2, 2, 0.9, 0, 0.8)
+--[[
+##########################################################
+POSITIONING
+##########################################################
+]]--
+local OnMove = function()
+  SV.db.UnitFrames.player.classbar.detachFromFrame = true
+end
+
+local Reposition = function(self)
+	local db = SV.db.UnitFrames.player
+	local bar = self.Conqueror;
+	local max = self.MaxClassPower;
+	local size = db.classbar.height
+	local width = size * max;
+
+	bar.Holder:SetSize(width, size)
+  if(not db.classbar.detachFromFrame) then
+  	SV:ResetAnchors(L["Classbar"])
+  end
+  local holderUpdate = bar.Holder:GetScript('OnSizeChanged')
+  if holderUpdate then
+      holderUpdate(bar.Holder)
+  end
+
+  bar:ClearAllPoints()
+  bar:SetAllPoints(bar.Holder)
+end
+
+local EffectModel_OnShow = function(self)
+	self:SetEffect("conqueror");
+end
+
+function MOD:CreateClassBar(playerFrame)
+	local max = 6
+	local bar = CreateFrame("Frame",nil,playerFrame)
+
+	bar:SetFrameLevel(playerFrame.TextGrip:GetFrameLevel() + 30)
+	--SV.SpecialFX:SetFXFrame(bar, "conqueror")
+	--bar.FX:SetFrameStrata("BACKGROUND")
+	--bar.FX:SetFrameLevel(playerFrame.TextGrip:GetFrameLevel() + 1)
+
+	local bgFrame = CreateFrame("Frame", nil, bar)
+	bgFrame:InsetPoints(bar, 1, 4)
+	SV.SpecialFX:SetFXFrame(bgFrame, "conqueror")
+
+	local bgTexture = bgFrame:CreateTexture(nil, "BACKGROUND")
+	bgTexture:SetAllPoints(bgFrame)
+	bgTexture:SetColorTexture(0.2,0,0,0.5)
+
+	local borderB = bgFrame:CreateTexture(nil,"OVERLAY")
+	borderB:SetColorTexture(0,0,0)
+	borderB:SetPoint("BOTTOMLEFT")
+	borderB:SetPoint("BOTTOMRIGHT")
+	borderB:SetHeight(2)
+
+	local borderT = bgFrame:CreateTexture(nil,"OVERLAY")
+	borderT:SetColorTexture(0,0,0)
+	borderT:SetPoint("TOPLEFT")
+	borderT:SetPoint("TOPRIGHT")
+	borderT:SetHeight(2)
+
+	local borderL = bgFrame:CreateTexture(nil,"OVERLAY")
+	borderL:SetColorTexture(0,0,0)
+	borderL:SetPoint("TOPLEFT")
+	borderL:SetPoint("BOTTOMLEFT")
+	borderL:SetWidth(2)
+
+	local borderR = bgFrame:CreateTexture(nil,"OVERLAY")
+	borderR:SetColorTexture(0,0,0)
+	borderR:SetPoint("TOPRIGHT")
+	borderR:SetPoint("BOTTOMRIGHT")
+	borderR:SetWidth(2)
+
+	bar.bg = bgTexture;
+
+	local enrage = CreateFrame("StatusBar", nil, bgFrame)
+	enrage.noupdate = true;
+	enrage:InsetPoints(bgFrame)
+	enrage:SetOrientation("HORIZONTAL")
+	enrage:SetStatusBarTexture(SV.media.statusbar.glow)
+	enrage:SetStatusBarColor(1, 0, 0, 0.75)
+
+	bgFrame.bar = enrage;
+	--SV.SpecialFX:SetFXFrame(enrage, "conqueror", true)
+	--enrage.FX:SetScript("OnShow", EffectModel_OnShow)
+	bar.Enrage = bgFrame;
+
+
+	local classBarHolder = CreateFrame("Frame", "Player_ClassBar", bar)
+	classBarHolder:SetPoint("TOPLEFT", playerFrame, "BOTTOMLEFT", 0, -2)
+	bar:SetPoint("TOPLEFT", classBarHolder, "TOPLEFT", 0, 0)
+	bar.Holder = classBarHolder
+	SV:NewAnchor(bar.Holder, L["Classbar"], OnMove)
+
+	playerFrame.MaxClassPower = max
+	playerFrame.RefreshClassBar = Reposition
+
+	playerFrame.Conqueror = bar
+	return 'Conqueror'
+end
\ No newline at end of file
diff --git a/SVUI_UnitFrames/elements/auras.lua b/SVUI_UnitFrames/elements/auras.lua
new file mode 100644
index 0000000..23050f4
--- /dev/null
+++ b/SVUI_UnitFrames/elements/auras.lua
@@ -0,0 +1,440 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--LUA
+local unpack        = unpack;
+local select        = select;
+local pairs         = pairs;
+local type          = type;
+local rawset        = rawset;
+local rawget        = rawget;
+local tostring      = tostring;
+local error         = error;
+local next          = next;
+local pcall         = pcall;
+local getmetatable  = getmetatable;
+local setmetatable  = setmetatable;
+local assert        = assert;
+--BLIZZARD
+local _G            = _G;
+local tinsert       = _G.tinsert;
+local tremove       = _G.tremove;
+local twipe         = _G.wipe;
+--STRING
+local string        = string;
+local upper         = string.upper;
+local format        = string.format;
+local find          = string.find;
+local match         = string.match;
+local gsub          = string.gsub;
+--MATH
+local math          = math;
+local floor         = math.floor
+local ceil         	= math.ceil
+--TABLE
+local table         = table;
+local tsort         = table.sort;
+local tremove       = table.remove;
+
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+local GameTooltip           = _G.GameTooltip;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L;
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local MOD = SV.UnitFrames
+
+if(not MOD) then return end
+
+local oUF_SVUI = MOD.oUF
+assert(oUF_SVUI, "SVUI UnitFrames: unable to locate oUF.")
+
+local DEFAULT_BUFFS_COLOR = {0.04, 0.52, 0.95};
+local BUFFS_COLOR = DEFAULT_BUFFS_COLOR;
+local DEFAULT_DEBUFFS_COLOR = {.9, 0, 0};
+local DEBUFFS_COLOR = DEFAULT_DEBUFFS_COLOR;
+local AURA_STATUSBAR = SV.media.statusbar.default;
+local BASIC_TEXTURE = SV.media.statusbar.default;
+local CanSteal = (SV.class == "MAGE");
+
+local CreateFrame 		= _G.CreateFrame;
+local UnitIsEnemy 		= _G.UnitIsEnemy;
+local IsShiftKeyDown 	= _G.IsShiftKeyDown;
+local DebuffTypeColor 	= _G.DebuffTypeColor;
+
+local SVUI_Font_UnitAura 		= _G.SVUI_Font_UnitAura;
+local SVUI_Font_UnitAura_Bar 	= _G.SVUI_Font_UnitAura_Bar;
+--[[
+##########################################################
+LOCAL FUNCTIONS
+##########################################################
+]]--
+local FilterAura_OnClick = function(self)
+	if not IsShiftKeyDown() then return end
+	local name = self.name;
+	local spellID = self.spellID;
+	local filterKey = tostring(spellID)
+	if name and filterKey then
+		SV:AddonMessage((L["The spell '%s' has been added to the BlackList unitframe aura filter."]):format(name))
+		SV.db.Filters["BlackList"][filterKey] = {['enable'] = true, ['id'] = spellID}
+		MOD:RefreshUnitFrames()
+	end
+end
+
+local Aura_OnEnter = function(self)
+	if(not self:IsVisible()) then return end
+	GameTooltip:SetOwner(self, "ANCHOR_BOTTOMRIGHT")
+	GameTooltip:SetUnitAura(self.unit, self.index, self.filter)
+end
+
+local Aura_OnLeave = function()
+	GameTooltip:Hide()
+end
+
+local _hook_AuraBGBorderColor = function(self, ...) self.bg:SetBackdropBorderColor(...) end
+
+local CreateAuraIcon = function(icons, index)
+	local baseSize = icons.auraSize or 16
+	local aura = CreateFrame("Button", nil, icons)
+	aura:RemoveTextures()
+	aura:EnableMouse(true)
+	aura:RegisterForClicks('RightButtonUp')
+
+	aura:SetWidth(baseSize)
+	aura:SetHeight(baseSize)
+
+	aura:SetBackdrop({
+    bgFile = [[Interface\BUTTONS\WHITE8X8]],
+		tile = false,
+		tileSize = 0,
+		edgeFile = [[Interface\BUTTONS\WHITE8X8]],
+      edgeSize = 1,
+      insets = {
+          left = 0,
+          right = 0,
+          top = 0,
+          bottom = 0
+      }
+  });
+  aura:SetBackdropColor(0, 0, 0, 0)
+  aura:SetBackdropBorderColor(0, 0, 0)
+
+  local bg = CreateFrame("Frame", nil, aura)
+  bg:SetFrameStrata("BACKGROUND")
+  bg:SetFrameLevel(0)
+  bg:WrapPoints(aura, 2, 2)
+  bg:SetBackdrop(SV.media.backdrop.aura)
+  bg:SetBackdropColor(0, 0, 0, 0)
+  bg:SetBackdropBorderColor(0, 0, 0, 0)
+  aura.bg = bg;
+
+  --hooksecurefunc(aura, "SetBackdropBorderColor", _hook_AuraBGBorderColor)
+
+  local fontgroup = "SVUI_Font_UnitAura";
+  if(baseSize < 18) then
+  	fontgroup = "SVUI_Font_UnitAura_Small";
+  end
+  --print(baseSize)
+  --print(fontgroup)
+
+	local cd = CreateFrame("Cooldown", nil, aura, "CooldownFrameTemplate");
+	cd:InsetPoints(aura, 1, 1);
+	cd.noOCC = true;
+	cd.noCooldownCount = true;
+	cd:SetReverse(true);
+	cd:SetHideCountdownNumbers(true);
+
+	local fg = CreateFrame("Frame", nil, aura)
+  fg:WrapPoints(aura, 2, 2)
+
+	local text = fg:CreateFontString(nil, 'OVERLAY');
+	text:SetFontObject(_G[fontgroup]);
+	text:SetPoint('CENTER', aura, 'CENTER', 1, 1);
+	text:SetJustifyH('CENTER');
+
+	local count = fg:CreateFontString(nil, "OVERLAY");
+	count:SetFontObject(_G[fontgroup]);
+	count:SetPoint("CENTER", aura, "BOTTOMRIGHT", -3, 3);
+
+	local icon = aura:CreateTexture(nil, "BACKGROUND");
+	icon:SetAllPoints(aura);
+	icon:InsetPoints(aura, 1, 1);
+  icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS));
+
+	local overlay = aura:CreateTexture(nil, "OVERLAY");
+	overlay:InsetPoints(aura, 1, 1);
+	overlay:SetTexture(BASIC_TEXTURE);
+	overlay:SetVertexColor(0, 0, 0);
+	overlay:Hide();
+
+	-- local stealable = aura:CreateTexture(nil, 'OVERLAY')
+	-- stealable:SetTexture("")
+	-- stealable:SetPoint('TOPLEFT', -3, 3)
+	-- stealable:SetPoint('BOTTOMRIGHT', 3, -3)
+	-- aura.stealable = stealable
+
+	aura:SetScript("OnClick", FilterAura_OnClick);
+	aura:SetScript("OnEnter", Aura_OnEnter);
+	aura:SetScript("OnLeave", Aura_OnLeave);
+
+	aura.parent = icons;
+	aura.cooldown = cd;
+	aura.text = text;
+	aura.icon = icon;
+	aura.count = count;
+	aura.overlay = overlay;
+
+	return aura
+end
+
+local PostCreateAuraBars = function(self)
+	local bar = self.statusBar
+	local barTexture = LSM:Fetch("statusbar", SV.db.UnitFrames.auraBarStatusbar)
+	bar:SetStatusBarTexture(barTexture)
+	bar.spelltime:SetFontObject(SVUI_Font_UnitAura_Bar);
+	bar.spelltime:SetTextColor(1 ,1, 1)
+	bar.spelltime:SetShadowOffset(1, -1)
+  	bar.spelltime:SetShadowColor(0, 0, 0)
+	bar.spelltime:SetJustifyH'RIGHT'
+	bar.spelltime:SetJustifyV'CENTER'
+	bar.spelltime:SetPoint'RIGHT'
+
+	bar.spellname:SetFontObject(SVUI_Font_UnitAura_Bar);
+	bar.spellname:SetTextColor(1, 1, 1)
+	bar.spellname:SetShadowOffset(1, -1)
+  	bar.spellname:SetShadowColor(0, 0, 0)
+	bar.spellname:SetJustifyH'LEFT'
+	bar.spellname:SetJustifyV'CENTER'
+	bar.spellname:SetPoint'LEFT'
+	bar.spellname:SetPoint('RIGHT', bar.spelltime, 'LEFT')
+
+	self:RegisterForClicks("RightButtonUp")
+	self:SetScript("OnClick", FilterAura_OnClick)
+end
+
+local PostBarUpdate = function(self, bar, spellID, isDebuff, debuffType)
+	if((not bar) or (not bar:IsVisible())) then return end
+
+	local color;
+	if(SV.db.UnitFrames.auraBarByType) then
+		local filterKey = tostring(spellID)
+		if(SV.db.Filters.AuraBars[filterKey]) then
+			color = SV.db.Filters.AuraBars[filterKey]
+		elseif isDebuff then
+			if(debuffType and DebuffTypeColor[debuffType]) then
+				color = {DebuffTypeColor[debuffType].r, DebuffTypeColor[debuffType].g, DebuffTypeColor[debuffType].b}
+			else
+				color = DEBUFFS_COLOR;
+			end
+		else
+			color = BUFFS_COLOR;
+		end
+	else
+		color = BUFFS_COLOR;
+	end
+
+	bar:SetStatusBarTexture(AURA_STATUSBAR)
+
+	bar:SetStatusBarColor(unpack(color))
+end
+
+--[[ AURA FILTERING ]]--
+
+local CommonAuraFilter = function(self, isEnemy, isPlayer, auraName, spellID, debuffType, duration, shouldConsolidate)
+	local db = SV.db.UnitFrames[self.___unitkey]
+	if((not db) or (db and not db[self.___aurakey])) then
+		return false;
+	end
+
+	local auraDB = db[self.___aurakey];
+	local filterKey = tostring(spellID)
+
+	if(auraDB.filterWhiteList and (not SV.db.Filters.WhiteList[filterKey])) then
+		return false;
+	elseif(SV.db.Filters.BlackList[filterKey] and SV.db.Filters.BlackList[filterKey].enable) then
+		return false;
+	else
+		if(auraDB.filterPlayer and (not isPlayer)) then
+			return false
+		end
+
+		if(auraDB.filterDispellable and (debuffType and not MOD.Dispellable[debuffType])) then
+			return false
+		end
+
+		if(auraDB.filterRaid and shouldConsolidate) then
+			return false
+		end
+
+		if(auraDB.filterInfinite and ((not duration) or (duration and duration == 0))) then
+			return false
+		end
+
+		local active = auraDB.useFilter
+		if(active and SV.db.Filters[active]) then
+			local spellDB = SV.db.Filters[active];
+			if(spellDB[filterKey] and spellDB[filterKey].enable) then
+				return false
+			end
+		end
+	end
+  	return true
+end
+
+--[[ DETAILED AURA FILTERING ]]--
+
+local function filter_test(setting, isEnemy)
+	if((not setting) or (setting and type(setting) ~= "table")) then
+		return false;
+	end
+	if((setting.enemy and isEnemy) or (setting.friendly and (not isEnemy))) then
+	  return true;
+	end
+  	return false
+end
+
+local DetailedAuraFilter = function(self, isEnemy, isPlayer, auraName, spellID, debuffType, duration, shouldConsolidate)
+	local db = SV.db.UnitFrames[self.___unitkey]
+	local auraType = self.___aurakey
+	if((not db) or (not auraType) or (db and (not db[auraType]))) then
+		return false;
+	end
+
+	local auraDB = db[self.___aurakey];
+	local filterKey = tostring(spellID)
+
+	if(filter_test(auraDB.filterAll, isEnemy)) then
+		return false
+	elseif(filter_test(auraDB.filterWhiteList, isEnemy) and (not SV.db.Filters.WhiteList[filterKey])) then
+		return false;
+	elseif(SV.db.Filters.BlackList[filterKey] and SV.db.Filters.BlackList[filterKey].enable) then
+		return false
+	else
+		if(filter_test(auraDB.filterPlayer, isEnemy) and (not isPlayer)) then
+			return false
+		end
+		if(filter_test(auraDB.filterDispellable, isEnemy)) then
+			if((CanSteal and (auraType == 'buffs' and isStealable)) or (debuffType and (not MOD.Dispellable[debuffType])) or (not debuffType)) then
+				return false
+			end
+		end
+		if(filter_test(auraDB.filterRaid, isEnemy) and shouldConsolidate) then
+			return false
+		end
+		if(filter_test(auraDB.filterInfinite, isEnemy) and ((not duration) or (duration and duration == 0))) then
+			return false
+		end
+		local active = auraDB.useFilter
+		if(active and SV.db.Filters[active]) then
+			local spellDB = SV.db.Filters[active];
+			if(spellDB[filterKey] and spellDB[filterKey].enable) then
+				return false
+			end
+		end
+	end
+  	return true
+end
+--[[
+##########################################################
+BUILD FUNCTION
+##########################################################
+]]--
+local BoolFilters = {
+	['player'] = true,
+	['pet'] = true,
+	['boss'] = true,
+	['arena'] = true,
+	['party'] = true,
+	['raid'] = true,
+	['raidpet'] = true,
+};
+
+function MOD:CreateAuraFrames(frame, unit, barsAvailable)
+	local buffs = CreateFrame("Frame", frame:GetName().."Buffs", frame)
+	buffs.___unitkey = unit;
+	buffs.___aurakey = "buffs";
+	buffs.CreateAuraIcon = CreateAuraIcon;
+	if(BoolFilters[unit]) then
+		buffs.CustomFilter = CommonAuraFilter;
+	else
+		buffs.CustomFilter = DetailedAuraFilter;
+	end
+	buffs:SetFrameLevel(10)
+	frame.Buffs = buffs
+
+	local debuffs = CreateFrame("Frame", frame:GetName().."Debuffs", frame)
+	debuffs.___unitkey = unit;
+	debuffs.___aurakey = "debuffs";
+	debuffs.CreateAuraIcon = CreateAuraIcon;
+	if(BoolFilters[unit]) then
+		debuffs.CustomFilter = CommonAuraFilter;
+	else
+		debuffs.CustomFilter = DetailedAuraFilter;
+	end
+	debuffs:SetFrameLevel(10)
+	frame.Debuffs = debuffs
+
+	if(barsAvailable) then
+		frame.AuraBarsAvailable = true;
+		buffs.PostCreateBar = PostCreateAuraBars;
+		buffs.PostBarUpdate = PostBarUpdate;
+		debuffs.PostCreateBar = PostCreateAuraBars;
+		debuffs.PostBarUpdate = PostBarUpdate;
+	end
+end
+--[[
+##########################################################
+AURA WATCH
+##########################################################
+]]--
+local PreForcedUpdate = function(self)
+	local unit = self.___key;
+	if not SV.db.UnitFrames[unit] then return end
+	local db = SV.db.UnitFrames[unit].auraWatch;
+	if not db then return end;
+	if(unit == "pet" or unit == "raidpet") then
+		self.watchFilter = SV.db.Filters.PetBuffWatch
+	else
+		self.watchFilter = SV.db.Filters.BuffWatch
+	end
+	self.watchEnabled = db.enable;
+	self.watchSize = db.size;
+end
+
+function MOD:CreateAuraWatch(frame, unit)
+	local watch = CreateFrame("Frame", nil, frame)
+	watch:SetFrameLevel(frame:GetFrameLevel() + 25)
+	watch:SetAllPoints(frame);
+	watch.___key = unit;
+	watch.watchEnabled = true;
+	watch.presentAlpha = 1;
+	watch.missingAlpha = 0;
+	if(unit == "pet" or unit == "raidpet") then
+		watch.watchFilter = SV.db.Filters.PetBuffWatch
+	else
+		watch.watchFilter = SV.db.Filters.BuffWatch
+	end
+
+	watch.PreForcedUpdate = PreForcedUpdate
+	return watch
+end
+--[[
+##########################################################
+CUSTOM EVENT UPDATES
+##########################################################
+]]--
+local function UpdateAuraMediaLocals()
+	BUFFS_COLOR = oUF_SVUI.colors.buff_bars or DEFAULT_BUFFS_COLOR;
+	DEBUFFS_COLOR = oUF_SVUI.colors.debuff_bars or DEFAULT_DEBUFFS_COLOR;
+	AURA_STATUSBAR = LSM:Fetch("statusbar", SV.db.UnitFrames.auraBarStatusbar);
+end
+SV.Events:On("UNITFRAME_COLORS_UPDATED", UpdateAuraMediaLocals, true);
diff --git a/SVUI_UnitFrames/elements/castbar.lua b/SVUI_UnitFrames/elements/castbar.lua
new file mode 100644
index 0000000..c08fab0
--- /dev/null
+++ b/SVUI_UnitFrames/elements/castbar.lua
@@ -0,0 +1,781 @@
+--[[
+##############################################################################
+S V U I  By: Failcoder               #
+##############################################################################
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+local _G            = _G;
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pcall         = _G.pcall;
+local print         = _G.print;
+local ipairs        = _G.ipairs;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local rawset        = _G.rawset;
+local rawget        = _G.rawget;
+local tostring      = _G.tostring;
+local tonumber      = _G.tonumber;
+local tinsert       = _G.tinsert;
+local tremove       = _G.tremove;
+local twipe         = _G.wipe;
+--STRING
+local string        = string;
+local format        = string.format;
+local sub           = string.sub;
+--MATH
+local math          = math;
+--TABLE
+local table         = table;
+local tsort         = table.sort;
+local tremove       = table.remove;
+--[[ MATH METHODS ]]--
+local abs, ceil, floor = math.abs, math.ceil, math.floor; -- Basic
+local parsefloat = math.parsefloat; -- Uncommon
+
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+local GameTooltip           = _G.GameTooltip;
+local UnitClass             = _G.UnitClass;
+local UnitIsPlayer          = _G.UnitIsPlayer;
+local UnitReaction          = _G.UnitReaction;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L;
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local MOD = SV.UnitFrames
+
+if(not MOD) then return end
+
+local oUF_SVUI = MOD.oUF
+assert(oUF_SVUI, "SVUI UnitFrames: unable to locate oUF.")
+
+SV.SpecialFX:Register("overlay_castbar", [[Spells\Eastern_plaguelands_beam_effect.m2]], 2, -2, -2, 2, 0.95, -1, 0)
+SV.SpecialFX:Register("underlay_castbar", [[Spells\Xplosion_twilight_impact_noflash.m2]], 1, -1, -1, 1, 0.9, 0, 0)
+--[[
+##########################################################
+LOCAL VARIABLES
+##########################################################
+]]--
+local ticks = {}
+local function SpellName(id)
+	local name, _, _, _, _, _, _, _, _ = GetSpellInfo(id)
+	if not name then
+		name = "Voodoo Doll";
+	end
+	return name
+end
+local CustomTickData = {
+	["ChannelTicks"] = {
+		--Warlock
+		[SpellName(1120)] = 6, --"Drain Soul"
+		[SpellName(689)] = 6, -- "Drain Life"
+		[SpellName(108371)] = 6, -- "Harvest Life"
+		[SpellName(5740)] = 4, -- "Rain of Fire"
+		[SpellName(755)] = 6, -- Health Funnel
+		[SpellName(103103)] = 4, --Malefic Grasp
+		--Druid
+		[SpellName(44203)] = 4, -- "Tranquility"
+		[SpellName(16914)] = 10, -- "Hurricane"
+		--Priest
+		[SpellName(15407)] = 3, -- "Mind Flay"
+		[SpellName(129197)] = 3, -- "Mind Flay (Insanity)"
+		[SpellName(48045)] = 5, -- "Mind Sear"
+		[SpellName(47540)] = 2, -- "Penance"
+		[SpellName(64901)] = 4, -- Hymn of Hope
+		[SpellName(64843)] = 4, -- Divine Hymn
+		--Mage
+		[SpellName(5143)] = 5, -- "Arcane Missiles"
+		[SpellName(10)] = 8, -- "Blizzard"
+		[SpellName(12051)] = 4, -- "Evocation"
+
+		--Monk
+		[SpellName(115175)] = 9, -- "Smoothing Mist"
+	},
+	["ChannelTicksSize"] = {
+	  --Warlock
+	  	[SpellName(1120)] = 2, --"Drain Soul"
+	  	[SpellName(689)] = 1, -- "Drain Life"
+		[SpellName(108371)] = 1, -- "Harvest Life"
+		[SpellName(103103)] = 1, -- "Malefic Grasp"
+	},
+	["HastedChannelTicks"] = {
+		[SpellName(64901)] = true, -- Hymn of Hope
+		[SpellName(64843)] = true, -- Divine Hymn
+	},
+}
+--[[
+##########################################################
+LOCAL FUNCTIONS
+##########################################################
+]]--
+local function HideTicks()
+	for i=1,#ticks do
+		ticks[i]:Hide()
+	end
+end
+
+local function SetCastTicks(bar,count,mod)
+	mod = mod or 0;
+	HideTicks()
+	if count and count <= 0 then return end
+	local barWidth = bar:GetWidth()
+	local offset = barWidth / count + mod;
+	for i=1,count do
+		if not ticks[i] then
+			ticks[i] = bar:CreateTexture(nil,'OVERLAY')
+			ticks[i]:SetTexture(SV.media.statusbar.lazer)
+			ticks[i]:SetVertexColor(0,0,0,0.8)
+			ticks[i]:SetWidth(1)
+			ticks[i]:SetHeight(bar:GetHeight())
+		end
+		ticks[i]:ClearAllPoints()
+		ticks[i]:SetPoint("RIGHT", bar, "LEFT", offset * i, 0)
+		ticks[i]:Show()
+	end
+end
+
+local Fader_OnEvent = function(self, event, arg)
+	if arg ~= "player" then return end
+	local isTradeskill = self:GetParent().recipecount
+	if(isTradeskill and isTradeskill > 0) then return end;
+	if event == "UNIT_SPELLCAST_START" then
+		self.fails = nil;
+		self.isokey = nil;
+		self.ischanneling = nil;
+		self:SetAlpha(0)
+		self.mask:SetAlpha(1)
+		if self.anim:IsPlaying() then
+			self.anim:Stop()
+		end
+	elseif event == "UNIT_SPELLCAST_CHANNEL_START" then
+		self:SetAlpha(0)
+		self.mask:SetAlpha(1)
+		if self.anim:IsPlaying() then
+			self.anim:Stop()
+		end
+		self.iscasting = nil;
+		self.fails = nil;
+		self.isokey = nil
+	elseif event == "UNIT_SPELLCAST_SUCCEEDED" then
+		self.fails = nil;
+		self.isokey = true;
+		self.fails_a = nil
+	elseif event == "UNIT_SPELLCAST_FAILED" or event == "UNIT_SPELLCAST_FAILED_QUIET" then
+		self.fails = true;
+		self.isokey = nil;
+		self.fails_a = nil
+	elseif event == "UNIT_SPELLCAST_INTERRUPTED" then
+		self.fails = nil;
+		self.isokey = nil;
+		self.fails_a = true
+	elseif event == "UNIT_SPELLCAST_STOP" then
+		if self.fails or self.fails_a then
+			self:SetBackdropColor(1, 0.2, 0.2, 0.5)
+			self.txt:SetText(SPELL_FAILED_FIZZLE)
+			self.txt:SetTextColor(1, 0.8, 0, 0.5)
+		elseif self.isokey then
+			self:SetBackdropColor(0.2, 1, 0.2, 0.5)
+			self.txt:SetText(SUCCESS)
+			self.txt:SetTextColor(0.5, 1, 0.4, 0.5)
+		end
+		self.mask:SetAlpha(0)
+		self:SetAlpha(0)
+		if not self.anim:IsPlaying() then
+			self.anim:Play()
+		end
+	elseif event == "UNIT_SPELLCAST_CHANNEL_STOP" then
+		self.mask:SetAlpha(0)
+		self:SetAlpha(0)
+		if self.fails_a then
+			self:SetBackdropColor(1, 0.2, 0.2, 0.5)
+			self.txt:SetText(SPELL_FAILED_FIZZLE)
+			self.txt:SetTextColor(0.5, 1, 0.4, 0.5)
+			if not self.anim:IsPlaying() then
+				self.anim:Play()
+			end
+		end
+	end
+end
+
+local function SetCastbarFading(castbar, texture)
+	local fader = CreateFrame("Frame", nil, castbar)
+	fader:SetFrameLevel(2)
+	fader:InsetPoints(castbar)
+	fader:SetBackdrop({bgFile = texture})
+	fader:SetBackdropColor(0, 0, 0, 0)
+	fader:SetAlpha(0)
+	fader:RegisterEvent("UNIT_SPELLCAST_INTERRUPTED")
+	fader:RegisterEvent("UNIT_SPELLCAST_START")
+	fader:RegisterEvent("UNIT_SPELLCAST_STOP")
+	fader:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED")
+	fader:RegisterEvent("UNIT_SPELLCAST_CHANNEL_START")
+	fader:RegisterEvent("UNIT_SPELLCAST_CHANNEL_STOP")
+	fader:RegisterEvent("UNIT_SPELLCAST_FAILED")
+	fader:RegisterEvent("UNIT_SPELLCAST_FAILED_QUIET")
+	fader.mask = CreateFrame("Frame", nil, castbar)
+	fader.mask:SetBackdrop({bgFile = texture})
+	fader.mask:InsetPoints(castbar)
+	fader.mask:SetFrameLevel(2)
+	fader.mask:SetBackdropColor(0, 0, 0, 0)
+	fader.mask:SetAlpha(0)
+	fader.txt = fader:CreateFontString(nil, "OVERLAY")
+	fader.txt:SetFont(SV.media.font.alert, 16)
+	fader.txt:SetAllPoints(fader)
+	fader.txt:SetJustifyH("CENTER")
+	fader.txt:SetJustifyV("CENTER")
+	fader.txt:SetText("")
+	fader.anim = fader:CreateAnimationGroup("Flash")
+	fader.anim.fadein = fader.anim:CreateAnimation("ALPHA", "FadeIn")
+	fader.anim.fadein:SetFromAlpha(0)
+    fader.anim.fadein:SetToAlpha(1)
+	fader.anim.fadein:SetOrder(1)
+	fader.anim.fadeout1 = fader.anim:CreateAnimation("ALPHA", "FadeOut")
+	fader.anim.fadeout1:SetFromAlpha(1)
+    fader.anim.fadeout1:SetToAlpha(0.75)
+	fader.anim.fadeout1:SetOrder(2)
+	fader.anim.fadeout2 = fader.anim:CreateAnimation("ALPHA", "FadeOut")
+	fader.anim.fadeout1:SetFromAlpha(0.75)
+    fader.anim.fadeout1:SetToAlpha(0.25)
+	fader.anim.fadeout2:SetOrder(3)
+	fader.anim.fadein:SetDuration(0)
+	fader.anim.fadeout1:SetDuration(.8)
+	fader.anim.fadeout2:SetDuration(.4)
+	fader:SetScript("OnEvent", Fader_OnEvent)
+end
+
+local CustomCastDelayText = function(self, value)
+	if not self.TimeFormat then return end
+	if self.channeling then
+		if self.TimeFormat == "CURRENT" then
+			self.Time:SetText(("%.1f |cffaf5050%.1f|r"):format(abs(value - self.max), self.delay))
+		elseif self.TimeFormat == "CURRENTMAX" then
+			self.Time:SetText(("%.1f / %.1f |cffaf5050%.1f|r"):format(value, self.max, self.delay))
+		elseif self.TimeFormat == "REMAINING" then
+			self.Time:SetText(("%.1f |cffaf5050%.1f|r"):format(value, self.delay))
+		end
+	else
+		if self.TimeFormat == "CURRENT" then
+			self.Time:SetText(("%.1f |cffaf5050%s %.1f|r"):format(value, "+", self.delay))
+		elseif self.TimeFormat == "CURRENTMAX" then
+			self.Time:SetText(("%.1f / %.1f |cffaf5050%s %.1f|r"):format(value, self.max, "+", self.delay))
+		elseif self.TimeFormat == "REMAINING"then
+			self.Time:SetText(("%.1f |cffaf5050%s %.1f|r"):format(abs(value - self.max), "+", self.delay))
+		end
+	end
+end
+
+local CustomTimeText = function(self, value)
+	if not self.TimeFormat then return end
+	if self.channeling then
+		if self.TimeFormat == "CURRENT" then
+			self.Time:SetText(("%.1f"):format(abs(value - self.max)))
+		elseif self.TimeFormat == "CURRENTMAX" then
+			self.Time:SetText(("%.1f / %.1f"):format(value, self.max))
+			self.Time:SetText(("%.1f / %.1f"):format(abs(value - self.max), self.max))
+		elseif self.TimeFormat == "REMAINING" then
+			self.Time:SetText(("%.1f"):format(value))
+		end
+	else
+		if self.TimeFormat == "CURRENT" then
+			self.Time:SetText(("%.1f"):format(value))
+		elseif self.TimeFormat == "CURRENTMAX" then
+			self.Time:SetText(("%.1f / %.1f"):format(value, self.max))
+		elseif self.TimeFormat == "REMAINING" then
+			self.Time:SetText(("%.1f"):format(abs(value - self.max)))
+		end
+	end
+end
+
+local CustomCastTimeUpdate = function(self, duration)
+	if(self.recipecount and self.recipecount > 0 and self.maxrecipe and self.maxrecipe > 1) then
+		self.Text:SetText(self.recipecount .. "/" .. self.maxrecipe .. ": " .. self.previous)
+	end
+	if(self.Time) then
+		if(self.delay ~= 0) then
+			if(self.CustomDelayText) then
+				self:CustomDelayText(duration)
+			else
+				self.Time:SetFormattedText("%.1f|cffff0000-%.1f|r", duration, self.delay)
+			end
+		else
+			if(self.CustomTimeText) then
+				self:CustomTimeText(duration)
+			else
+				self.Time:SetFormattedText("%.1f", duration)
+			end
+		end
+	end
+	if(self.Spark) then
+		local xOffset = 0
+		local yOffset = 0
+		if self.Spark.xOffset then
+			xOffset = self.Spark.xOffset
+			yOffset = self.Spark.yOffset
+		end
+		if(self:GetReverseFill()) then
+			self.Spark:SetPoint("CENTER", self, "RIGHT", -((duration / self.max) * self:GetWidth() + xOffset), yOffset)
+		else
+			self.Spark:SetPoint("CENTER", self, "LEFT", ((duration / self.max) * self:GetWidth() + xOffset), yOffset)
+		end
+	end
+end
+
+local CustomCastBarUpdate = function(self, elapsed)
+	self.lastUpdate = (self.lastUpdate or 0) + elapsed
+
+	if not (self.casting or self.channeling) then
+		self.unitName = nil
+		self.previous = nil
+		self.casting = nil
+		self.castid = nil
+		self.channeling = nil
+		self.tradeskill = nil
+		self.recipecount = nil
+		self.maxrecipe = 1
+		self:SetValue(1)
+		self:Hide()
+		return
+	end
+
+	if(self.Spark and self.Spark[1]) then self.Spark[1]:Hide(); self.Spark[1].overlay:Hide() end
+	if(self.Spark and self.Spark[2]) then self.Spark[2]:Hide(); self.Spark[2].overlay:Hide() end
+
+	if(self.casting) then
+		if self.Spark then
+			if self.Spark.iscustom then
+				self.Spark.xOffset = -12
+				self.Spark.yOffset = 0
+			end
+			if(self.Spark[1]) then
+				self.Spark[1]:Show()
+				self.Spark[1].overlay:Show()
+				if not self.Spark[1].anim:IsPlaying() then self.Spark[1].anim:Play() end
+			end
+		end
+
+		local duration = self.duration + self.lastUpdate
+
+		if(duration >= self.max) then
+			self.previous = nil
+			self.casting = nil
+			self.tradeskill = nil
+			self.recipecount = nil
+			self.maxrecipe = 1
+			self:Hide()
+
+			if(self.PostCastStop) then self:PostCastStop(self.__owner.unit) end
+			return
+		end
+
+		CustomCastTimeUpdate(self, duration)
+
+		self.duration = duration
+		self:SetValue(duration)
+	elseif(self.channeling) then
+		if self.Spark then
+			if self.Spark.iscustom then
+				self.Spark.xOffset = 12
+				self.Spark.yOffset = 4
+			end
+			if(self.Spark[2]) then
+				self.Spark[2]:Show()
+				self.Spark[2].overlay:Show()
+				if not self.Spark[2].anim:IsPlaying() then self.Spark[2].anim:Play() end
+			end
+		end
+		local duration = self.duration - self.lastUpdate
+
+		if(duration <= 0) then
+			self.channeling = nil
+			self.previous = nil
+			self.casting = nil
+			self.tradeskill = nil
+			self.recipecount = nil
+			self.maxrecipe = 1
+			self:Hide()
+
+			if(self.PostChannelStop) then self:PostChannelStop(self.__owner.unit) end
+			return
+		end
+
+		CustomCastTimeUpdate(self, duration)
+
+		self.duration = duration
+		self:SetValue(duration)
+	end
+
+	self.lastUpdate = 0
+end
+
+local CustomChannelUpdate = function(self, unit, index, hasTicks)
+	if not(unit == "player" or unit == "vehicle") then return end
+	if hasTicks then
+		local activeTicks = CustomTickData.ChannelTicks[index]
+		if activeTicks and CustomTickData.ChannelTicksSize[index] and CustomTickData.HastedChannelTicks[index] then
+			local mod1 = 1 / activeTicks;
+			local haste = UnitSpellHaste("player") * 0.01;
+			local mod2 = mod1 / 2;
+			local total = 0;
+			if haste >= mod2 then total = total + 1 end
+			local calc1 = tonumber(parsefloat(mod2 + mod1, 2))
+			while haste >= calc1 do
+				calc1 = tonumber(parsefloat(mod2 + mod1 * total, 2))
+				if haste >= calc1 then
+					total = total + 1
+				end
+			end
+			local activeSize = CustomTickData.ChannelTicksSize[index]
+			local sizeMod = activeSize / 1 + haste;
+			local calc2 = self.max - sizeMod * activeTicks + total;
+			if self.chainChannel then
+				self.extraTickRatio = calc2 / sizeMod;
+				self.chainChannel = nil
+			end
+			SetCastTicks(self, activeTicks + total, self.extraTickRatio)
+		elseif activeTicks and CustomTickData.ChannelTicksSize[index] then
+			local haste = UnitSpellHaste("player") * 0.01;
+			local activeSize = CustomTickData.ChannelTicksSize[index]
+			local sizeMod = activeSize / 1 + haste;
+			local calc2 = self.max - sizeMod * activeTicks;
+			if self.chainChannel then
+				self.extraTickRatio = calc2 / sizeMod;
+				self.chainChannel = nil
+			end
+			SetCastTicks(self, activeTicks, self.extraTickRatio)
+		elseif activeTicks then
+			SetCastTicks(self, activeTicks)
+		else
+			HideTicks()
+		end
+	else
+		HideTicks()
+	end
+end
+
+local CustomInterruptible = function(self, unit, useClass)
+	local colors = oUF_SVUI.colors
+	local r, g, b = self.CastColor[1], self.CastColor[2], self.CastColor[3]
+	if useClass then
+		local colorOverride;
+		if UnitIsPlayer(unit) then
+			local _, class = UnitClass(unit)
+			colorOverride = colors.class[class]
+		elseif UnitReaction(unit, "player") then
+			colorOverride = colors.reaction[UnitReaction(unit, "player")]
+		end
+		if colorOverride then
+			r, g, b = colorOverride[1], colorOverride[2], colorOverride[3]
+		end
+	end
+	if self.interrupt and unit ~= "player" and UnitCanAttack("player", unit) then
+		r, g, b = colors.interrupt[1], colors.interrupt[2], colors.interrupt[3]
+	end
+	self:SetStatusBarColor(r, g, b)
+	if self.bg:IsShown() then
+		self.bg:SetVertexColor(r * 0.2, g * 0.2, b * 0.2)
+	end
+
+	if(self.Spark and self.Spark[1]) then
+		r, g, b = self.SparkColor[1], self.SparkColor[2], self.SparkColor[3]
+		self.Spark[1]:SetVertexColor(r, g, b)
+		self.Spark[2]:SetVertexColor(r, g, b)
+	end
+end
+--[[
+##########################################################
+BUILD FUNCTION
+##########################################################
+]]--
+function MOD:CreateCastbar(frame, reversed, moverName, ryu, useFader, isBoss, hasModel)
+	local colors = oUF_SVUI.colors;
+	local castbar = CreateFrame("StatusBar", nil, frame)
+	castbar.OnUpdate = CustomCastBarUpdate;
+	castbar.CustomDelayText = CustomCastDelayText;
+	castbar.CustomTimeText = CustomTimeText;
+	castbar.PostCastStart = MOD.PostCastStart;
+	castbar.PostChannelStart = MOD.PostCastStart;
+	castbar.PostCastStop = MOD.PostCastStop;
+	castbar.PostChannelStop = MOD.PostCastStop;
+	castbar.PostChannelUpdate = MOD.PostChannelUpdate;
+	castbar.PostCastInterruptible = MOD.PostCastInterruptible;
+	castbar.PostCastNotInterruptible = MOD.PostCastNotInterruptible;
+	castbar:SetClampedToScreen(true)
+	castbar:SetFrameLevel(2)
+
+	castbar.LatencyTexture = castbar:CreateTexture(nil, "OVERLAY")
+
+	local cbName = frame:GetName().."Castbar"
+	local castbarHolder = CreateFrame("Frame", cbName, castbar)
+
+	local organizer = CreateFrame("Frame", nil, castbar)
+	organizer:SetFrameStrata("HIGH")
+
+	local iconHolder = CreateFrame("Frame", nil, organizer)
+	iconHolder:SetStyle("!_Frame", "Inset", false)
+	organizer.Icon = iconHolder
+
+	local buttonIcon = iconHolder:CreateTexture(nil, "BORDER")
+	buttonIcon:InsetPoints()
+	buttonIcon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+	castbar.Icon = buttonIcon;
+
+	local shieldIcon = iconHolder:CreateTexture(nil, "ARTWORK")
+	shieldIcon:SetPoint("TOPLEFT", buttonIcon, "TOPLEFT", -7, 7)
+	shieldIcon:SetPoint("BOTTOMRIGHT", buttonIcon, "BOTTOMRIGHT", 7, -8)
+	shieldIcon:SetTexture("Interface\\Addons\\SVUI_UnitFrames\\assets\\Castbar\\SHIELD")
+	castbar.Shield = shieldIcon;
+
+	castbar.Time = organizer:CreateFontString(nil, "OVERLAY")
+	castbar.Time:SetDrawLayer("OVERLAY", 7)
+
+	castbar.Text = organizer:CreateFontString(nil, "OVERLAY")
+	castbar.Text:SetDrawLayer("OVERLAY", 7)
+
+	castbar.Organizer = organizer
+
+	local bgFrame = CreateFrame("Frame", nil, castbar)
+	local hadouken = CreateFrame("Frame", nil, castbar)
+
+	if ryu then
+		castbar.Time:SetFontObject(SVUI_Font_Aura)
+		castbar.Time:SetTextColor(1, 1, 1)
+		castbar.Text:SetFontObject(SVUI_Font_Caps)
+		castbar.Text:SetTextColor(1, 1, 1, 0.75)
+		castbar.Text:SetWordWrap(false)
+
+		castbar:SetStatusBarTexture(SV.media.statusbar.lazer)
+
+		bgFrame:InsetPoints(castbar, -2, 10)
+		bgFrame:SetFrameLevel(bgFrame:GetFrameLevel() - 1)
+
+	  	castbar.LatencyTexture:SetTexture(SV.media.statusbar.lazer)
+		castbar.noupdate = true;
+		castbar.pewpew = true
+		hadouken.iscustom = true;
+		hadouken:SetHeight(50)
+		hadouken:SetWidth(50)
+		hadouken:SetAlpha(0.9)
+
+		castbarHolder:SetPoint("TOP", frame, "BOTTOM", 0, isBoss and -4 or -35)
+
+		if reversed then
+			castbar:SetReverseFill(true)
+			hadouken[1] = hadouken:CreateTexture(nil, "ARTWORK")
+			hadouken[1]:SetAllPoints(hadouken)
+			hadouken[1]:SetBlendMode("ADD")
+			hadouken[1]:SetTexture("Interface\\Addons\\SVUI_UnitFrames\\assets\\Castbar\\HADOUKEN-REVERSED")
+			hadouken[1]:SetVertexColor(colors.spark[1],colors.spark[2],colors.spark[3])
+			hadouken[1].overlay = hadouken:CreateTexture(nil, "OVERLAY")
+			hadouken[1].overlay:SetHeight(50)
+			hadouken[1].overlay:SetWidth(50)
+			hadouken[1].overlay:SetPoint("CENTER", hadouken)
+			hadouken[1].overlay:SetBlendMode("ADD")
+			hadouken[1].overlay:SetTexture("Interface\\Addons\\SVUI_UnitFrames\\assets\\Castbar\\SKULLS-REVERSED")
+			hadouken[1].overlay:SetVertexColor(1, 1, 1)
+
+			SV.Animate:Sprite4(hadouken[1],false,false,true)
+
+			hadouken[2] = hadouken:CreateTexture(nil, "ARTWORK")
+			hadouken[2]:InsetPoints(hadouken, 4, 4)
+			hadouken[2]:SetBlendMode("ADD")
+			hadouken[2]:SetTexture("Interface\\Addons\\SVUI_UnitFrames\\assets\\Castbar\\CHANNEL-REVERSED")
+			hadouken[2]:SetVertexColor(colors.spark[1],colors.spark[2],colors.spark[3])
+			hadouken[2].overlay = hadouken:CreateTexture(nil, "OVERLAY")
+			hadouken[2].overlay:SetHeight(50)
+			hadouken[2].overlay:SetWidth(50)
+			hadouken[2].overlay:SetPoint("CENTER", hadouken)
+			hadouken[2].overlay:SetBlendMode("ADD")
+			hadouken[2].overlay:SetTexture("Interface\\Addons\\SVUI_UnitFrames\\assets\\Castbar\\CHANNEL-REVERSED")
+			hadouken[2].overlay:SetVertexColor(1, 1, 1)
+
+			SV.Animate:Sprite4(hadouken[2],false,false,true)
+
+			castbar:SetPoint("BOTTOMLEFT", castbarHolder, "BOTTOMLEFT", 1, 1)
+			organizer:SetPoint("LEFT", castbar, "RIGHT", 4, 0)
+
+			castbar.Time:SetPoint("RIGHT", castbar, "LEFT", -4, 0)
+		else
+			hadouken[1] = hadouken:CreateTexture(nil, "ARTWORK")
+			hadouken[1]:SetAllPoints(hadouken)
+			hadouken[1]:SetBlendMode("ADD")
+			hadouken[1]:SetTexture("Interface\\Addons\\SVUI_UnitFrames\\assets\\Castbar\\HADOUKEN")
+			hadouken[1]:SetVertexColor(colors.spark[1],colors.spark[2],colors.spark[3])
+			hadouken[1].overlay = hadouken:CreateTexture(nil, "OVERLAY")
+			hadouken[1].overlay:SetHeight(50)
+			hadouken[1].overlay:SetWidth(50)
+			hadouken[1].overlay:SetPoint("CENTER", hadouken)
+			hadouken[1].overlay:SetBlendMode("ADD")
+			hadouken[1].overlay:SetTexture("Interface\\Addons\\SVUI_UnitFrames\\assets\\Castbar\\HADOUKEN")
+			hadouken[1].overlay:SetVertexColor(1, 1, 1)
+
+			SV.Animate:Sprite4(hadouken[1],false,false,true)
+
+			hadouken[2] = hadouken:CreateTexture(nil, "ARTWORK")
+			hadouken[2]:InsetPoints(hadouken, 4, 4)
+			hadouken[2]:SetBlendMode("ADD")
+			hadouken[2]:SetTexture("Interface\\Addons\\SVUI_UnitFrames\\assets\\Castbar\\CHANNEL")
+			hadouken[2]:SetVertexColor(colors.spark[1],colors.spark[2],colors.spark[3])
+			hadouken[2].overlay = hadouken:CreateTexture(nil, "OVERLAY")
+			hadouken[2].overlay:SetHeight(50)
+			hadouken[2].overlay:SetWidth(50)
+			hadouken[2].overlay:SetPoint("CENTER", hadouken)
+			hadouken[2].overlay:SetBlendMode("ADD")
+			hadouken[2].overlay:SetTexture("Interface\\Addons\\SVUI_UnitFrames\\assets\\Castbar\\CHANNEL")
+			hadouken[2].overlay:SetVertexColor(1, 1, 1)
+
+			SV.Animate:Sprite4(hadouken[2],false,false,true)
+
+			castbar:SetPoint("BOTTOMRIGHT", castbarHolder, "BOTTOMRIGHT", -1, 1)
+			organizer:SetPoint("RIGHT", castbar, "LEFT", -4, 0)
+
+			castbar.Time:SetPoint("LEFT", castbar, "RIGHT", 4, 0)
+		end
+
+		-- castbar.Time:SetPoint("CENTER", organizer, "CENTER", 0, 0)
+		-- castbar.Time:SetJustifyH("CENTER")
+
+		castbar.Text:SetAllPoints(castbar)
+	else
+		castbar.Time:SetFontObject(SVUI_Font_Aura)
+		castbar.Time:SetTextColor(1, 1, 1, 0.9)
+		castbar.Time:SetPoint("RIGHT", castbar, "LEFT", -1, 0)
+
+		castbar.Text:SetFontObject(SVUI_Font_Caps)
+		castbar.Text:SetTextColor(1, 1, 1, 0.9)
+		castbar.Text:SetAllPoints(castbar)
+		castbar.Text:SetWordWrap(false)
+
+		castbar.pewpew = false
+
+		castbar:SetStatusBarTexture(SV.media.statusbar.glow)
+		castbarHolder:SetPoint("TOP", frame, "BOTTOM", 0, -4)
+		castbar:InsetPoints(castbarHolder, 2, 2)
+
+		bgFrame:SetAllPoints(castbarHolder)
+		bgFrame:SetFrameLevel(bgFrame:GetFrameLevel() - 1)
+
+
+		castbar.LatencyTexture:SetTexture(SV.media.statusbar.default)
+
+		if reversed then
+			castbar:SetReverseFill(true)
+			organizer:SetPoint("LEFT", castbar, "RIGHT", 6, 0)
+		else
+			organizer:SetPoint("RIGHT", castbar, "LEFT", -6, 0)
+		end
+	end
+
+	if(hasModel) then
+		SV.SpecialFX:SetFXFrame(bgFrame, "underlay_castbar")
+		bgFrame.FX:SetFrameLevel(0)
+  		SV.SpecialFX:SetFXFrame(castbar, "overlay_castbar", nil, bgFrame)
+  	end
+
+	castbar.bg = bgFrame:CreateTexture(nil, "BACKGROUND", nil, -2)
+	castbar.bg:SetAllPoints(bgFrame)
+	castbar.bg:SetTexture(SV.media.statusbar.default)
+  	castbar.bg:SetVertexColor(0,0,0,0.5)
+
+	local borderB = bgFrame:CreateTexture(nil,"OVERLAY")
+	borderB:SetColorTexture(0,0,0)
+	borderB:SetPoint("BOTTOMLEFT")
+	borderB:SetPoint("BOTTOMRIGHT")
+	borderB:SetHeight(2)
+
+	local borderT = bgFrame:CreateTexture(nil,"OVERLAY")
+	borderT:SetColorTexture(0,0,0)
+	borderT:SetPoint("TOPLEFT")
+	borderT:SetPoint("TOPRIGHT")
+	borderT:SetHeight(2)
+
+	local borderL = bgFrame:CreateTexture(nil,"OVERLAY")
+	borderL:SetColorTexture(0,0,0)
+	borderL:SetPoint("TOPLEFT")
+	borderL:SetPoint("BOTTOMLEFT")
+	borderL:SetWidth(2)
+
+	local borderR = bgFrame:CreateTexture(nil,"OVERLAY")
+	borderR:SetColorTexture(0,0,0)
+	borderR:SetPoint("TOPRIGHT")
+	borderR:SetPoint("BOTTOMRIGHT")
+	borderR:SetWidth(2)
+
+	castbar:SetStatusBarColor(colors.casting[1],colors.casting[2],colors.casting[3])
+	castbar.LatencyTexture:SetVertexColor(0.1, 1, 0.2, 0.5)
+
+	castbar.Spark = hadouken;
+	castbar.Holder = castbarHolder;
+
+	castbar.CastColor = oUF_SVUI.colors.casting
+	castbar.SparkColor = oUF_SVUI.colors.spark
+
+	if moverName then
+		castbar.Holder.snapOffset = -6
+		SV:NewAnchor(castbar.Holder, moverName)
+	end
+
+	if useFader then
+		SetCastbarFading(castbar, SV.media.statusbar.lazer)
+	end
+
+	castbar.TimeFormat = "REMAINING"
+	return castbar
+end
+--[[
+##########################################################
+UPDATE
+##########################################################
+]]--
+function MOD:PostCastStart(unit, index, ...)
+	if unit == "vehicle" then unit = "player" end
+	local db = SV.db.UnitFrames
+	if(not db or not(db and db[unit] and db[unit].castbar)) then return end
+	local unitDB = db[unit].castbar
+	if unitDB.displayTarget and self.curTarget then
+		self.Text:SetText(sub(index.." --> "..self.curTarget, 0, floor(32 / 245 * self:GetWidth() / db.fontSize * 12)))
+	else
+		self.Text:SetText(sub(index, 0, floor(32 / 245 * self:GetWidth() / db.fontSize * 12)))
+	end
+	self.unit = unit;
+	if unit == "player" or unit == "target" then
+		CustomChannelUpdate(self, unit, index, unitDB.ticks)
+		CustomInterruptible(self, unit, db.castClassColor)
+	end
+end
+
+function MOD:PostCastStop(unit, ...)
+	self.chainChannel = nil;
+	self.prevSpellCast = nil
+end
+
+function MOD:PostChannelUpdate(unit, index)
+	if unit == "vehicle" then unit = "player" end
+	local db = SV.db.UnitFrames[unit];
+	if(not db or not db.castbar or not(unit == "player")) then return end
+	CustomChannelUpdate(self, unit, index, db.castbar.ticks)
+end
+
+function MOD:PostCastInterruptible(unit)
+	if unit == "vehicle" or unit == "player" then return end
+	CustomInterruptible(self, unit, SV.db.UnitFrames.castClassColor)
+end
+
+function MOD:PostCastNotInterruptible(unit)
+	local castColor = self.CastColor;
+	self:SetStatusBarColor(castColor[1], castColor[2], castColor[3])
+	if(self.Spark and self.Spark[1]) then
+		local sparkColor = self.SparkColor;
+		self.Spark[1]:SetVertexColor(sparkColor[1], sparkColor[2], sparkColor[3])
+		self.Spark[2]:SetVertexColor(sparkColor[1], sparkColor[2], sparkColor[3])
+	end
+end
\ No newline at end of file
diff --git a/SVUI_UnitFrames/elements/essentials.lua b/SVUI_UnitFrames/elements/essentials.lua
new file mode 100644
index 0000000..e1ea157
--- /dev/null
+++ b/SVUI_UnitFrames/elements/essentials.lua
@@ -0,0 +1,797 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pcall         = _G.pcall;
+local print         = _G.print;
+local ipairs        = _G.ipairs;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local rawset        = _G.rawset;
+local rawget        = _G.rawget;
+local tostring      = _G.tostring;
+local tonumber      = _G.tonumber;
+local getmetatable  = _G.getmetatable;
+local setmetatable  = _G.setmetatable;
+--STRING
+local string        = _G.string;
+local upper         = string.upper;
+local format        = string.format;
+local find          = string.find;
+local match         = string.match;
+local gsub          = string.gsub;
+--MATH
+local math          = _G.math;
+local random        = math.random;
+local floor         = math.floor;
+local ceil         	= math.ceil;
+local min 			= math.min;
+
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+local IsLoggedIn            = _G.IsLoggedIn;
+local GameTooltip           = _G.GameTooltip;
+local UnitClass             = _G.UnitClass;
+local UnitIsPlayer          = _G.UnitIsPlayer;
+local UnitReaction          = _G.UnitReaction;
+local UnitIsConnected  		= _G.UnitIsConnected;
+local UnitIsDeadOrGhost  	= _G.UnitIsDeadOrGhost;
+local UnitClassBase  		= _G.UnitClassBase;
+local UnitPowerType  		= _G.UnitPowerType;
+local UnitPlayerControlled  = _G.UnitPlayerControlled;
+local UnitThreatSituation   = _G.UnitThreatSituation;
+local UnitAffectingCombat   = _G.UnitAffectingCombat;
+local GetThreatStatusColor   = _G.GetThreatStatusColor;
+local UnitAlternatePowerInfo  = _G.UnitAlternatePowerInfo;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L;
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local MOD = SV.UnitFrames
+
+if(not MOD) then return end
+
+local oUF_SVUI = MOD.oUF
+assert(oUF_SVUI, "SVUI UnitFrames: unable to locate oUF.")
+--[[
+##########################################################
+LOCALS
+##########################################################
+]]--
+local FontMapping = {
+	["player"] = "SVUI_Font_Unit",
+	["target"] = "SVUI_Font_Unit",
+	["targettarget"] = "SVUI_Font_Unit_Small",
+	["pet"] = "SVUI_Font_Unit",
+	["pettarget"] = "SVUI_Font_Unit_Small",
+	["focus"] = "SVUI_Font_Unit",
+	["focustarget"] = "SVUI_Font_Unit_Small",
+	["boss"] = "SVUI_Font_Unit",
+	["arena"] = "SVUI_Font_Unit",
+	["party"] = "SVUI_Font_Unit_Small",
+	["raid"] = "SVUI_Font_Unit_Small",
+	["raidpet"] = "SVUI_Font_Unit_Small",
+	["tank"] = "SVUI_Font_Unit_Small",
+	["assist"] = "SVUI_Font_Unit_Small",
+};
+local ThreatMapping = {
+	["player"] = true,
+	["pet"] = true,
+	["focus"] = true,
+	["party"] = true,
+	["raid"] = true,
+	["raidpet"] = true,
+	["tank"] = true,
+	["assist"] = true,
+};
+
+local _hook_ActionPanel_OnSizeChanged = function(self)
+	local width,height = self:GetSize()
+	local widthScale = min(128, width)
+	local heightScale = widthScale * 0.25
+
+	self.special[1]:SetSize(widthScale, heightScale)
+	self.special[2]:SetSize(widthScale, heightScale)
+	--self.special[3]:SetSize(height * 0.5, height)
+end
+-- local MISSING_MODEL_FILE = [[Spells\Blackmagic_precast_base.m2]];
+-- local MISSING_MODEL_FILE = [[Spells\Crow_baked.m2]];
+-- local MISSING_MODEL_FILE = [[Spells\monsterlure01.m2]];
+-- local MISSING_MODEL_FILE = [[interface\buttons\talktome_gears.m2]];
+-- local MISSING_MODEL_FILE = [[creature\Ghostlyskullpet\ghostlyskullpet.m2]];
+-- local MISSING_MODEL_FILE = [[creature\ghost\ghost.m2]];
+-- local MISSING_MODEL_FILE = [[Spells\Monk_travelingmist_missile.m2]];
+local ELITE_TOP = [[Interface\Addons\SVUI_UnitFrames\assets\Border\ELITE-TOP]];
+local ELITE_BOTTOM = [[Interface\Addons\SVUI_UnitFrames\assets\Border\ELITE-BOTTOM]];
+local ELITE_RIGHT = [[Interface\Addons\SVUI_UnitFrames\assets\Border\ELITE-RIGHT]];
+local STUNNED_ANIM = [[Interface\Addons\SVUI_UnitFrames\assets\UNIT-STUNNED]];
+local AGGRO_TEXTURE = [[Interface\AddOns\SVUI_UnitFrames\assets\UNIT-AGGRO]];
+local token = {[0] = "MANA", [1] = "RAGE", [2] = "FOCUS", [3] = "ENERGY", [6] = "RUNIC_POWER"}
+--[[
+##########################################################
+ACTIONPANEL
+##########################################################
+]]--
+local UpdateThreat = function(self, event, unit)
+	if(not unit or (self.unit ~= unit) or not IsLoggedIn()) then return end
+	local threat = self.Threat
+	local status = UnitThreatSituation(unit)
+	local r, g, b
+	if(status and status > 0) then
+		r, g, b = GetThreatStatusColor(status)
+		threat:SetBackdropBorderColor(r, g, b)
+		threat:Show()
+	else
+		threat:SetBackdropBorderColor(0, 0, 0, 0.5)
+		threat:Hide()
+	end
+end
+
+local UpdatePlayerThreat = function(self, event, unit)
+	if(unit ~= "player" or not IsLoggedIn()) then return end
+	local threat = self.Threat;
+	local aggro = self.Aggro;
+	local useAggro = aggro.isEnabled;
+	local status = UnitThreatSituation(unit)
+	local r, g, b
+	if(status and status > 0) then
+		r, g, b = GetThreatStatusColor(status)
+		threat:SetBackdropBorderColor(r, g, b)
+		if(useAggro and (status > 1) and (not aggro:IsShown())) then
+			self.Combat:Hide()
+			aggro:Show()
+		end
+		threat:Show()
+	else
+		threat:SetBackdropBorderColor(0, 0, 0, 0.5)
+		if(useAggro and aggro:IsShown()) then
+			aggro:Hide()
+			if(UnitAffectingCombat('player')) then
+				self.Combat:Show()
+			end
+		end
+		threat:Hide()
+	end
+end
+
+local function CreateThreat(frame, unit)
+	if(not frame.ActionPanel) then return; end
+	local threat = CreateFrame("Frame", nil, frame.ActionPanel)
+    threat:SetPoint("TOPLEFT", frame.ActionPanel, "TOPLEFT", -3, 3)
+    threat:SetPoint("BOTTOMRIGHT", frame.ActionPanel, "BOTTOMRIGHT", 3, -3)
+    threat:SetBackdrop({
+        edgeFile = SV.media.border.shadow,
+        edgeSize = 3,
+        insets =
+        {
+            left = 2,
+            right = 2,
+            top = 2,
+            bottom = 2,
+        },
+    });
+    threat:SetBackdropBorderColor(0,0,0,0.5)
+
+	if(unit == "player") then
+		local aggro = CreateFrame("Frame", "SVUI_PlayerThreatAlert", frame)
+		aggro:SetFrameStrata("HIGH")
+		aggro:SetFrameLevel(30)
+		aggro:SetSize(40,40)
+		aggro:SetPoint("BOTTOMLEFT", frame, "TOPRIGHT", -6, -6)
+		aggro.texture = aggro:CreateTexture(nil, "OVERLAY")
+		aggro.texture:SetAllPoints(aggro)
+		aggro.texture:SetTexture(AGGRO_TEXTURE)
+		SV.Animate:Pulse(aggro)
+		aggro:SetScript("OnShow", function(this)
+			this.anim:Play()
+		end);
+		aggro:Hide();
+		aggro.isEnabled = true;
+		frame.Aggro = aggro
+
+		threat.Override = UpdatePlayerThreat
+	else
+		threat.Override = UpdateThreat
+	end
+
+	return threat
+end
+
+local function CreateNameText(frame, unitName)
+	local db = SV.db.UnitFrames
+	if(SV.db.UnitFrames[unitName] and SV.db.UnitFrames[unitName].name) then
+		db = SV.db.UnitFrames[unitName].name
+	end
+	local name = frame:CreateFontString(nil, "OVERLAY")
+	name:SetFont(LSM:Fetch("font", db.font), db.fontSize, db.fontOutline)
+	name:SetShadowOffset(1.5, -1.5)
+	name:SetShadowColor(0, 0, 0, 0.5)
+	if unitName == "target" then
+		name:SetPoint("RIGHT", frame)
+		name:SetJustifyH("RIGHT")
+    	name:SetJustifyV("MIDDLE")
+	else
+		name:SetPoint("CENTER", frame)
+		name:SetJustifyH("CENTER")
+    	name:SetJustifyV("MIDDLE")
+	end
+	return name;
+end
+
+local function ADDInfoBG(frame)
+	local bg = frame.InfoPanel:CreateTexture(nil, "BACKGROUND")
+	bg:SetPoint("TOPLEFT", frame.InfoPanel, "TOPLEFT", 0, 1)
+	bg:SetPoint("BOTTOMRIGHT", frame.InfoPanel, "BOTTOMRIGHT", 0, 1)
+	bg:SetColorTexture(1, 1, 1, 1)
+	bg:SetGradientAlpha("VERTICAL", 0, 0, 0, 0, 0, 0, 0, 0.7)
+	frame.InfoPanelBG = bg
+
+	local left = frame.InfoPanel:CreateTexture(nil, "BACKGROUND")
+	left:SetPoint("TOPLEFT", frame.InfoPanel, "TOPLEFT", 0, -1)
+	left:SetPoint("BOTTOMLEFT", frame.InfoPanel, "BOTTOMLEFT", 0, -2)
+	left:SetWidth(2)
+	left:SetColorTexture(1, 1, 1, 1)
+	left:SetGradientAlpha("VERTICAL", 0, 0, 0, 0, 0, 0, 0, 1)
+	frame.InfoPanelLeft = left
+
+	local right = frame.InfoPanel:CreateTexture(nil, "BACKGROUND")
+	right:SetPoint("TOPRIGHT", frame.InfoPanel, "TOPRIGHT", 0, -1)
+	right:SetPoint("BOTTOMRIGHT", frame.InfoPanel, "BOTTOMRIGHT", 0, -2)
+	right:SetWidth(2)
+	right:SetColorTexture(1, 1, 1, 1)
+	right:SetGradientAlpha("VERTICAL", 0, 0, 0, 0, 0, 0, 0, 1)
+	frame.InfoPanelRight = right
+end
+
+function MOD:SetActionPanel(frame, unit, noHealthText, noPowerText, noMiscText)
+	if(frame.ActionPanel) then return; end
+	frame:SetStyle("Frame", "ActionPanel")
+	frame.ActionPanel = frame.Panel
+	local baseSize = SV.media.shared.font.unitprimary.size / 0.48;
+	if(unit and (unit == "target" or unit == "player")) then
+		local info = CreateFrame("Frame", nil, frame)
+		info:SetFrameStrata("BACKGROUND")
+		info:SetFrameLevel(0)
+		info:SetPoint("TOPLEFT", frame, "BOTTOMLEFT", 0, 1)
+		info:SetPoint("TOPRIGHT", frame, "BOTTOMRIGHT", 0, 1)
+		info:SetHeight(baseSize)
+
+		frame.TextGrip = CreateFrame("Frame", nil, info)
+		frame.TextGrip:SetFrameStrata("LOW")
+		frame.TextGrip:SetFrameLevel(20)
+		frame.TextGrip:SetAllPoints(info)
+
+		frame.InfoPanel = info;
+		ADDInfoBG(frame)
+
+		if(unit == "target") then
+			frame.ActionPanel:SetFrameLevel(1)
+			if(SV.db.UnitFrames.themed) then
+				frame.ActionPanel.special = CreateFrame("Frame", nil, frame.ActionPanel)
+				frame.ActionPanel.special:SetAllPoints(frame)
+				frame.ActionPanel.special:SetFrameStrata("BACKGROUND")
+				frame.ActionPanel.special:SetFrameLevel(0)
+				frame.ActionPanel.special[1] = frame.ActionPanel.special:CreateTexture(nil, "OVERLAY", nil, 1)
+				frame.ActionPanel.special[1]:SetPoint("BOTTOMRIGHT", frame.ActionPanel.special, "TOPRIGHT", 0, 0)
+				frame.ActionPanel.special[1]:SetWidth(frame.ActionPanel:GetWidth())
+				frame.ActionPanel.special[1]:SetHeight(frame.ActionPanel:GetWidth() * 0.25)
+				frame.ActionPanel.special[1]:SetTexture(ELITE_TOP)
+				frame.ActionPanel.special[1]:SetVertexColor(1, 0.75, 0)
+				frame.ActionPanel.special[1]:SetBlendMode("BLEND")
+				frame.ActionPanel.special[2] = frame.ActionPanel.special:CreateTexture(nil, "OVERLAY", nil, 1)
+				frame.ActionPanel.special[2]:SetPoint("TOPRIGHT", frame.ActionPanel.special, "BOTTOMRIGHT", 0, 0)
+				frame.ActionPanel.special[2]:SetWidth(frame.ActionPanel:GetWidth())
+				frame.ActionPanel.special[2]:SetHeight(frame.ActionPanel:GetWidth() * 0.25)
+				frame.ActionPanel.special[2]:SetTexture(ELITE_BOTTOM)
+				frame.ActionPanel.special[2]:SetVertexColor(1, 0.75, 0)
+				frame.ActionPanel.special[2]:SetBlendMode("BLEND")
+				-- frame.ActionPanel.special[3] = frame.ActionPanel.special:CreateTexture(nil, "OVERLAY", nil, 1)
+				-- frame.ActionPanel.special[3]:SetPoint("LEFT", frame.ActionPanel.special, "RIGHT", 0, 0)
+				-- frame.ActionPanel.special[3]:SetHeight(frame.ActionPanel:GetHeight())
+				-- frame.ActionPanel.special[3]:SetWidth(frame.ActionPanel:GetHeight() * 0.5)
+				-- frame.ActionPanel.special[3]:SetTexture(ELITE_RIGHT)
+				-- frame.ActionPanel.special[3]:SetVertexColor(1, 0.75, 0)
+				-- frame.ActionPanel.special[3]:SetBlendMode("BLEND")
+				frame.ActionPanel.special:SetAlpha(0.7)
+				frame.ActionPanel.special:Hide()
+
+				frame.ActionPanel:SetScript("OnSizeChanged", _hook_ActionPanel_OnSizeChanged)
+			end
+
+			frame.ActionPanel.class = CreateFrame("Frame", nil, frame.TextGrip)
+			frame.ActionPanel.class:SetSize(18, 18)
+			frame.ActionPanel.class:SetPoint("TOPLEFT", frame.ActionPanel, "TOPLEFT", 2, -2)
+			frame.ActionPanel.class:SetStyle("Frame", "Default", true, 2, 0, 0)
+
+			frame.ActionPanel.class.texture = frame.ActionPanel.class.Panel:CreateTexture(nil, "BORDER")
+			frame.ActionPanel.class.texture:SetAllPoints(frame.ActionPanel.class.Panel)
+			frame.ActionPanel.class.texture:SetTexture([[Interface\Glues\CharacterCreate\UI-CharacterCreate-Classes]])
+
+			local border1 = frame.ActionPanel.class:CreateTexture(nil, "OVERLAY")
+			border1:SetColorTexture(0, 0, 0)
+			border1:SetPoint("TOPLEFT")
+			border1:SetPoint("TOPRIGHT")
+			border1:SetHeight(2)
+
+			local border2 = frame.ActionPanel.class:CreateTexture(nil, "OVERLAY")
+			border2:SetColorTexture(0, 0, 0)
+			border2:SetPoint("BOTTOMLEFT")
+			border2:SetPoint("BOTTOMRIGHT")
+			border2:SetHeight(2)
+
+			local border3 = frame.ActionPanel.class:CreateTexture(nil, "OVERLAY")
+			border3:SetColorTexture(0, 0, 0)
+			border3:SetPoint("TOPRIGHT")
+			border3:SetPoint("BOTTOMRIGHT")
+			border3:SetWidth(2)
+
+			local border4 = frame.ActionPanel.class:CreateTexture(nil, "OVERLAY")
+			border4:SetColorTexture(0, 0, 0)
+			border4:SetPoint("TOPLEFT")
+			border4:SetPoint("BOTTOMLEFT")
+			border4:SetWidth(2)
+		else
+			frame.LossOfControl = CreateFrame("Frame", nil, frame.TextGrip)
+			frame.LossOfControl:SetAllPoints(frame)
+			frame.LossOfControl:SetFrameStrata("DIALOG")
+			frame.LossOfControl:SetFrameLevel(99)
+
+			local stunned = frame.LossOfControl:CreateTexture(nil, "OVERLAY", nil, 1)
+			stunned:SetPoint("CENTER", frame, "CENTER", 0, 0)
+			stunned:SetSize(96, 96)
+			stunned:SetTexture(STUNNED_ANIM)
+			stunned:SetBlendMode("ADD")
+			SV.Animate:Sprite4(stunned, 0.12, false, true)
+			frame.LossOfControl.stunned = stunned
+
+			frame.LossOfControl:SetParent(LossOfControlFrame)
+		end
+	elseif(unit and (unit == 'pet' or unit == 'targettarget')) then
+		local info = CreateFrame("Frame", nil, frame)
+		info:SetFrameStrata("BACKGROUND")
+		info:SetFrameLevel(0)
+		info:SetPoint("TOPLEFT", frame, "BOTTOMLEFT", 0, 1)
+		info:SetPoint("TOPRIGHT", frame, "BOTTOMRIGHT", 0, 1)
+		info:SetHeight(baseSize)
+
+		frame.InfoPanel = info;
+		ADDInfoBG(frame)
+
+		frame.TextGrip = CreateFrame("Frame", nil, info)
+		-- frame.TextGrip:SetFrameStrata("LOW")
+		frame.TextGrip:SetFrameLevel(20)
+		frame.TextGrip:SetAllPoints(info)
+	else
+		local info = CreateFrame("Frame", nil, frame)
+		info:SetFrameLevel(20)
+		info:SetAllPoints(frame)
+		frame.TextGrip = CreateFrame("Frame", nil, info)
+		--frame.TextGrip:SetFrameStrata("LOW")
+		frame.TextGrip:SetAllPoints(info)
+	end
+
+	frame.TextGrip.Name = CreateNameText(frame.TextGrip, unit)
+
+	local reverse = unit and (unit == "target" or unit == "focus" or unit == "boss" or unit == "arena") or false;
+	local offset, direction
+	local fontgroup = FontMapping[unit]
+	if(not noHealthText) then
+		frame.TextGrip.Health = frame.TextGrip:CreateFontString(nil, "OVERLAY")
+		frame.TextGrip.Health:SetFontObject(_G[fontgroup])
+		offset = reverse and 2 or -2;
+		direction = reverse and "LEFT" or "RIGHT";
+		frame.TextGrip.Health:SetPoint(direction, frame.TextGrip, direction, offset, 0)
+	end
+
+	if(not noPowerText) then
+		frame.TextGrip.Power = frame.TextGrip:CreateFontString(nil, "OVERLAY")
+		frame.TextGrip.Power:SetFontObject(_G[fontgroup])
+		offset = reverse and -2 or 2;
+		direction = reverse and "RIGHT" or "LEFT";
+		frame.TextGrip.Power:SetPoint(direction, frame.TextGrip, direction, offset, 0)
+	end
+
+	if(not noMiscText) then
+		frame.TextGrip.Misc = frame.TextGrip:CreateFontString(nil, "OVERLAY")
+		frame.TextGrip.Misc:SetFontObject(_G[fontgroup])
+		frame.TextGrip.Misc:SetPoint("CENTER", frame, "CENTER", 0, 0)
+	end
+
+	frame.StatusPanel = CreateFrame("Frame", nil, frame)
+	frame.StatusPanel:EnableMouse(false)
+
+	if(unit and (unit == "player" or unit == "pet" or unit == "target" or unit == "targettarget" or unit == "focus" or unit == "focustarget")) then
+		frame.StatusPanel:SetAllPoints(frame)
+		frame.StatusPanel.media = {
+			[[Interface\Addons\SVUI_UnitFrames\assets\TARGET-DC]],
+			[[Interface\Addons\SVUI_UnitFrames\assets\TARGET-DEAD]],
+			[[Interface\Addons\SVUI_UnitFrames\assets\TARGET-TAPPED]]
+		}
+	else
+		frame.StatusPanel:SetSize(50, 50)
+		frame.StatusPanel:SetPoint("CENTER", frame, "CENTER", 0, 0)
+		frame.StatusPanel.media = {
+			[[Interface\Addons\SVUI_UnitFrames\assets\UNIT-DC]],
+			[[Interface\Addons\SVUI_UnitFrames\assets\UNIT-DEAD]],
+			[[Interface\Addons\SVUI_UnitFrames\assets\UNIT-TAPPED]]
+		}
+	end
+
+	frame.StatusPanel:SetFrameStrata("LOW")
+	frame.StatusPanel:SetFrameLevel(32)
+	frame.StatusPanel.texture = frame.StatusPanel:CreateTexture(nil, "OVERLAY")
+	frame.StatusPanel.texture:SetAllPoints()
+	if(ThreatMapping[unit]) then
+		frame.Threat = CreateThreat(frame, unit)
+	end
+end
+
+function MOD:UpdateStatusMedia(frame)
+	if(not frame.StatusPanel) then return end
+	local width,height = frame.ActionPanel:GetSize()
+	frame.StatusPanel:ClearAllPoints()
+	if((height > (width * 0.5)) or (width < 75)) then
+		frame.StatusPanel:SetSize(height * 1.25, height * 1.25)
+		frame.StatusPanel:SetPoint("CENTER", frame.ActionPanel, "CENTER", 0, 0)
+		frame.StatusPanel.media = {
+			[[Interface\Addons\SVUI_UnitFrames\assets\UNIT-DC]],
+			[[Interface\Addons\SVUI_UnitFrames\assets\UNIT-DEAD]],
+			[[Interface\Addons\SVUI_UnitFrames\assets\UNIT-TAPPED]]
+		}
+	else
+		frame.StatusPanel:SetAllPoints(frame)
+		frame.StatusPanel.media = {
+			[[Interface\Addons\SVUI_UnitFrames\assets\TARGET-DC]],
+			[[Interface\Addons\SVUI_UnitFrames\assets\TARGET-DEAD]],
+			[[Interface\Addons\SVUI_UnitFrames\assets\TARGET-TAPPED]]
+		}
+	end
+	frame.StatusPanel.texture:ClearAllPoints()
+	frame.StatusPanel.texture:SetAllPoints()
+end
+--[[
+##########################################################
+HEALTH ANIMATIONS
+##########################################################
+]]--
+local Anim_OnUpdate = function(self)
+	local parent = self.parent
+	local coord = self._coords;
+	parent:SetTexCoord(coord[1],coord[2],coord[3],coord[4])
+end
+
+local Anim_OnPlay = function(self)
+	local parent = self.parent
+	parent:SetAlpha(1)
+	if not parent:IsShown() then
+		parent:Show()
+	end
+end
+
+local Anim_OnStop = function(self)
+	local parent = self.parent
+	parent:SetAlpha(0)
+	if parent:IsShown() then
+		parent:Hide()
+	end
+end
+
+local function SetNewAnimation(frame, animType, parent)
+	local anim = frame:CreateAnimation(animType)
+	anim.parent = parent
+	return anim
+end
+
+local function SetAnim(frame, parent)
+	local speed = 0.08
+	frame.anim = frame:CreateAnimationGroup("Sprite")
+	frame.anim.parent = parent;
+	frame.anim:SetScript("OnPlay", Anim_OnPlay)
+	frame.anim:SetScript("OnFinished", Anim_OnStop)
+	frame.anim:SetScript("OnStop", Anim_OnStop)
+
+	frame.anim[1] = SetNewAnimation(frame.anim, "Translation", frame)
+	frame.anim[1]:SetOrder(1)
+	frame.anim[1]:SetDuration(speed)
+	frame.anim[1]._coords = {0,0.5,0,0.25}
+	frame.anim[1]:SetScript("OnUpdate", Anim_OnUpdate)
+
+	frame.anim[2] = SetNewAnimation(frame.anim, "Translation", frame)
+	frame.anim[2]:SetOrder(2)
+	frame.anim[2]:SetDuration(speed)
+	frame.anim[2]._coords = {0.5,1,0,0.25}
+	frame.anim[2]:SetScript("OnUpdate", Anim_OnUpdate)
+
+	frame.anim[3] = SetNewAnimation(frame.anim, "Translation", frame)
+	frame.anim[3]:SetOrder(3)
+	frame.anim[3]:SetDuration(speed)
+	frame.anim[3]._coords = {0,0.5,0.25,0.5}
+	frame.anim[3]:SetScript("OnUpdate", Anim_OnUpdate)
+
+	frame.anim[4] = SetNewAnimation(frame.anim, "Translation", frame)
+	frame.anim[4]:SetOrder(4)
+	frame.anim[4]:SetDuration(speed)
+	frame.anim[4]._coords = {0.5,1,0.25,0.5}
+	frame.anim[4]:SetScript("OnUpdate", Anim_OnUpdate)
+
+	frame.anim[5] = SetNewAnimation(frame.anim, "Translation", frame)
+	frame.anim[5]:SetOrder(5)
+	frame.anim[5]:SetDuration(speed)
+	frame.anim[5]._coords = {0,0.5,0.5,0.75}
+	frame.anim[5]:SetScript("OnUpdate", Anim_OnUpdate)
+
+	frame.anim[6] = SetNewAnimation(frame.anim, "Translation", frame)
+	frame.anim[6]:SetOrder(6)
+	frame.anim[6]:SetDuration(speed)
+	frame.anim[6]._coords = {0.5,1,0.5,0.75}
+	frame.anim[6]:SetScript("OnUpdate", Anim_OnUpdate)
+
+	frame.anim[7] = SetNewAnimation(frame.anim, "Translation", frame)
+	frame.anim[7]:SetOrder(7)
+	frame.anim[7]:SetDuration(speed)
+	frame.anim[7]._coords = {0,0.5,0.75,1}
+	frame.anim[7]:SetScript("OnUpdate", Anim_OnUpdate)
+
+	frame.anim[8] = SetNewAnimation(frame.anim, "Translation", frame)
+	frame.anim[8]:SetOrder(8)
+	frame.anim[8]:SetDuration(speed)
+	frame.anim[8]._coords = {0.5,1,0.75,1}
+	frame.anim[8]:SetScript("OnUpdate", Anim_OnUpdate)
+
+	frame.anim:SetLooping("REPEAT")
+end
+--[[
+##########################################################
+HEALTH
+##########################################################
+]]--
+local OverlayHealthUpdate = function(health, unit, min, max)
+	local disconnected = not UnitIsConnected(unit)
+	health:SetMinMaxValues(-max, 0)
+	health:SetValue(disconnected and 0 or -min)
+	local invisible = ((min == max) or UnitIsDeadOrGhost(unit) or disconnected);
+	if invisible then health.lowAlerted = false end
+
+	if health.fillInverted then
+		health:SetReverseFill(true)
+	end
+	health.percent = invisible and 100 or ((min / max) * 100)
+	health.disconnected = disconnected
+
+	local bg = health.bg;
+	local mu = 0;
+	if(max ~= 0) then
+		mu = (min / max)
+	end
+
+	if(invisible or not health.overlayAnimation) then
+		health.animation[1].anim:Stop()
+		health.animation[1]:SetAlpha(0)
+	end
+
+	if(invisible) then
+		health:SetStatusBarColor(0.6,0.4,1,0.5)
+		health.animation[1]:SetVertexColor(0.8,0.3,1,0.4)
+	elseif(health.colorOverlay) then
+		local t = oUF_SVUI.colors.health
+		health:SetStatusBarColor(t[1], t[2], t[3], 0.9)
+	else
+		health:SetStatusBarColor(1-(0.65 * mu), 0.15 * mu, 0, 0.85)
+		health.animation[1]:SetVertexColor(1, 0.1 * mu, 0, 0.5)
+	end
+
+	if(health.overlayAnimation and not invisible) then
+		if(mu <= 0.25) then
+			health.animation[1]:SetAlpha(1)
+			health.animation[1].anim:Play()
+		else
+			health.animation[1].anim:Stop()
+			health.animation[1]:SetAlpha(0)
+		end
+	end
+end
+
+local RefreshHealthBar = function(self, overlay)
+	if(overlay) then
+		self.Health.bg:SetVertexColor(0, 0, 0, 0)
+		self.Health.PreUpdate = OverlayHealthUpdate;
+	else
+		self.Health.bg:SetVertexColor(0.4, 0.1, 0.1, 0.8)
+		self.Health.PreUpdate = nil;
+	end
+end
+
+function MOD:CreateHealthBar(frame, hasbg)
+	local healthBar = CreateFrame("StatusBar", nil, frame)
+	healthBar:SetFrameStrata("LOW")
+	healthBar:SetFrameLevel(4)
+	healthBar:SetStatusBarTexture(SV.media.statusbar.default);
+
+	if hasbg then
+		healthBar.bg = healthBar:CreateTexture(nil, "BORDER")
+		healthBar.bg:SetAllPoints()
+		healthBar.bg:SetTexture(SV.media.statusbar.gradient)
+		healthBar.bg:SetVertexColor(0.4, 0.1, 0.1)
+		healthBar.bg.multiplier = 0.25
+	end
+
+	local flasher = CreateFrame("Frame", nil, frame)
+	flasher:SetFrameLevel(3)
+	flasher:SetAllPoints(healthBar)
+
+	flasher[1] = flasher:CreateTexture(nil, "OVERLAY", nil, 1)
+	flasher[1]:SetTexture([[Interface\Addons\SVUI_UnitFrames\assets\UNIT-HEALTH-ANIMATION]])
+	flasher[1]:SetTexCoord(0, 0.5, 0, 0.25)
+	flasher[1]:SetVertexColor(1, 0.3, 0.1, 0.5)
+	flasher[1]:SetBlendMode("ADD")
+	flasher[1]:SetAllPoints(flasher)
+	SetAnim(flasher[1], flasher)
+	flasher:Hide()
+
+	healthBar.animation = flasher
+	healthBar.noupdate = false;
+	healthBar.fillInverted = false;
+	healthBar.gridMode = false;
+	healthBar.colorTapping = true;
+	healthBar.colorDisconnected = true;
+
+	frame.RefreshHealthBar = RefreshHealthBar
+
+	return healthBar
+end
+--[[
+##########################################################
+POWER
+##########################################################
+]]--
+local PostUpdateAltPower = function(self, min, current, max)
+	local remaining = floor(current  /  max  *  100)
+	local parent = self:GetParent()
+	if remaining < 35 then
+		self:SetStatusBarColor(0, 1, 0)
+	elseif remaining < 70 then
+		self:SetStatusBarColor(1, 1, 0)
+	else
+		self:SetStatusBarColor(1, 0, 0)
+	end
+	local unit = parent.unit;
+	if(unit == "player" and self.text) then
+		local apInfo = select(10, UnitAlternatePowerInfo(unit))
+		if remaining > 0 then
+			self.text:SetText(apInfo..": "..format("%d%%", remaining))
+		else
+			self.text:SetText(apInfo..": 0%")
+		end
+	elseif(unit and unit:find("boss%d") and self.text) then
+		self.text:SetTextColor(self:GetStatusBarColor())
+		if not parent.TextGrip.Power:GetText() or parent.TextGrip.Power:GetText() == "" then
+			self.text:SetPoint("BOTTOMRIGHT", parent.Health, "BOTTOMRIGHT")
+		else
+			self.text:SetPoint("RIGHT", parent.TextGrip.Power, "LEFT", 2, 0)
+		end
+		if remaining > 0 then
+			self.text:SetText("|cffD7BEA5[|r"..format("%d%%", remaining).."|cffD7BEA5]|r")
+		else
+			self.text:SetText(nil)
+		end
+	end
+end
+
+function MOD:CreatePowerBar(frame)
+	local power = CreateFrame("StatusBar", nil, frame)
+	power:SetStatusBarTexture(SV.media.statusbar.default)
+	power:SetFrameStrata("LOW")
+	power:SetFrameLevel(6)
+	power:SetStyle("Frame", "Bar")
+	power.bg = power:CreateTexture(nil, "BORDER")
+	power.bg:SetAllPoints()
+	power.bg:SetTexture(SV.media.statusbar.gradient)
+	power.bg:SetVertexColor(0.4, 0.1, 0.1)
+	power.bg.multiplier = 0.25
+
+	power.colorDisconnected = false;
+	power.colorTapping = false;
+	power.PostUpdate = MOD.PostUpdatePower;
+	return power
+end
+
+function MOD:CreateAltPowerBar(frame)
+	local altPower = CreateFrame("StatusBar", nil, frame)
+	altPower:SetStatusBarTexture(SV.media.statusbar.default)
+	altPower:SetStyle("Frame", "Bar")
+	altPower:GetStatusBarTexture():SetHorizTile(false)
+	altPower:SetFrameStrata("LOW")
+	altPower:SetFrameLevel(8)
+	altPower.text = altPower:CreateFontString(nil, "OVERLAY")
+	altPower.text:SetPoint("CENTER")
+	altPower.text:SetJustifyH("CENTER")
+	altPower.text:SetFontObject(SVUI_Font_Unit)
+	altPower.PostUpdate = PostUpdateAltPower;
+	return altPower
+end
+
+function MOD:PostUpdatePower(unit, value, max)
+	local db = SV.db.UnitFrames[unit]
+	local powerType, powerToken = UnitPowerType(unit)
+	local parent = self:GetParent()
+	if parent.isForced then
+		value = random(1, max)
+		powerType = random(0, 4)
+		self:SetValue(value)
+	end
+	local colors = oUF_SVUI.colors.power[powerToken]
+	local mult = self.bg.multiplier or 1;
+	local isPlayer = UnitPlayerControlled(unit)
+	if isPlayer and self.colorClass then
+		local _, class = UnitClassBase(unit);
+		colors = oUF_SVUI["colors"].class[class]
+	elseif(not isPlayer and (powerType and powerType == 1 and value == 0)) then
+		colors = nil
+	end
+	if(not colors) then
+		self:Hide()
+	else
+		if(not self:IsShown()) then self:Show() end
+		self:SetStatusBarColor(colors[1], colors[2], colors[3])
+		self.bg:SetVertexColor(colors[1] * mult, colors[2] * mult, colors[3] * mult)
+	end
+end
+--[[
+##########################################################
+PORTRAIT
+##########################################################
+]]--
+function MOD:CreatePortrait(frame,smallUnit,isPlayer)
+	-- 3D Portrait
+	local portrait3D = CreateFrame("PlayerModel",nil,frame)
+	portrait3D:SetFrameStrata("LOW")
+	portrait3D:SetFrameLevel(2)
+
+	if smallUnit then
+		portrait3D:SetStyle("Frame", "UnitSmall")
+	else
+		portrait3D:SetStyle("Frame", "UnitLarge")
+	end
+
+	portrait3D.Outline = CreateFrame("Frame", nil, portrait3D)
+	portrait3D.Outline:WrapPoints(portrait3D)
+	portrait3D.Outline:SetStyle("Frame", "ActionPanel")
+
+	portrait3D.UserRotation = 0;
+	portrait3D.UserCamDistance = 1.3;
+
+	-- 2D Portrait
+	local portrait2Danchor = CreateFrame('Frame', nil, frame)
+	portrait2Danchor:SetFrameStrata("LOW")
+	portrait2Danchor:SetFrameLevel(2)
+
+	portrait2Danchor:SetStyle("Frame")
+	portrait2Danchor:SetPanelColor("darkest")
+
+	portrait2Danchor.Outline = CreateFrame("Frame", nil, portrait2Danchor)
+	portrait2Danchor.Outline:WrapPoints(portrait2Danchor)
+	portrait2Danchor.Outline:SetStyle("Frame", "ActionPanel")
+
+	local portrait2D = portrait2Danchor:CreateTexture(nil,'OVERLAY')
+	portrait2D:SetAllPoints()
+	portrait2D:SetTexCoord(0.15,0.85,0.15,0.85)
+	portrait2D:SetBlendMode("ADD")
+
+	-- Assign To Frame
+	frame.PortraitModel = portrait3D;
+	frame.PortraitTexture = portrait2D;
+end
diff --git a/SVUI_UnitFrames/elements/misc.lua b/SVUI_UnitFrames/elements/misc.lua
new file mode 100644
index 0000000..97cfb87
--- /dev/null
+++ b/SVUI_UnitFrames/elements/misc.lua
@@ -0,0 +1,646 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pcall         = _G.pcall;
+local print         = _G.print;
+local ipairs        = _G.ipairs;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local rawset        = _G.rawset;
+local rawget        = _G.rawget;
+local tostring      = _G.tostring;
+local tonumber      = _G.tonumber;
+local getmetatable  = _G.getmetatable;
+local setmetatable  = _G.setmetatable;
+--STRING
+local string        = _G.string;
+local upper         = string.upper;
+local format        = string.format;
+local find          = string.find;
+local match         = string.match;
+local gsub          = string.gsub;
+--MATH
+local math          = _G.math;
+local random        = math.random;
+local floor         = math.floor
+local ceil         	= math.ceil
+local max         	= math.max
+
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+
+local SV = _G['SVUI']
+local L = SV.L;
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local MOD = SV.UnitFrames
+
+if(not MOD) then return end
+
+local oUF_SVUI = MOD.oUF
+assert(oUF_SVUI, "SVUI UnitFrames: unable to locate oUF.")
+--[[
+##########################################################
+LOCAL VARIABLES
+##########################################################
+]]--
+local AFFLICTED_SKIN = [[Interface\AddOns\SVUI_UnitFrames\assets\UNIT-AFFLICTED]];
+
+local ROLE_ICON_DATA = {
+	["TANK"] = {0,0.5,0,0.5, 0.5,0.75,0.51,0.75},
+	["HEALER"] = {0,0.5,0.5,1, 0.5,0.75,0.76,1},
+	["DAMAGER"] = {0.5,1,0,0.5, 0.76,1,0.51,0.75}
+}
+
+local function BasicBG(frame)
+	frame:SetBackdrop({
+    	bgFile = [[Interface\BUTTONS\WHITE8X8]],
+		tile = false,
+		tileSize = 0,
+		edgeFile = [[Interface\BUTTONS\WHITE8X8]],
+        edgeSize = 2,
+        insets = {
+            left = 0,
+            right = 0,
+            top = 0,
+            bottom = 0
+        }
+    })
+    frame:SetBackdropColor(0, 0, 0, 0)
+    frame:SetBackdropBorderColor(0, 0, 0)
+end
+--[[
+##########################################################
+RAID DEBUFFS / DEBUFF HIGHLIGHT
+##########################################################
+]]--
+function MOD:CreateRaidDebuffs(frame)
+	local raidDebuff = CreateFrame("Frame", nil, frame.TextGrip)
+	raidDebuff:SetFrameLevel(50)
+	raidDebuff:SetStyle("!_Frame", "Icon")
+	raidDebuff.icon = raidDebuff:CreateTexture(nil, "OVERLAY")
+	raidDebuff.icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+	raidDebuff.icon:InsetPoints(raidDebuff)
+	raidDebuff.count = raidDebuff:CreateFontString(nil, "OVERLAY")
+	raidDebuff.count:SetFontObject(SVUI_Font_UnitAura)
+	raidDebuff.count:SetPoint("BOTTOMRIGHT", 0, 2)
+	raidDebuff.count:SetTextColor(1, .9, 0)
+	raidDebuff.time = raidDebuff:CreateFontString(nil, "OVERLAY")
+	raidDebuff.time:SetFontObject(SVUI_Font_UnitAura)
+	raidDebuff.time:SetPoint("CENTER")
+	raidDebuff.time:SetTextColor(1, .9, 0)
+	if (frame.TextGrip.Name) then
+		raidDebuff.nameText = frame.TextGrip.Name
+	end
+	return raidDebuff
+end
+
+function MOD:CreateAfflicted(frame)
+	local afflicted = CreateFrame("Frame", nil, frame.TextGrip)
+	afflicted:SetFrameLevel(30)
+	afflicted:SetPoint("TOPLEFT", frame.Health, "TOPLEFT", -1, 1)
+	afflicted:SetPoint("BOTTOMRIGHT", frame.Health, "BOTTOMRIGHT", 1, -1)
+	afflicted:SetStyle("!_Frame", "Icon")
+	afflicted.Texture = afflicted:CreateTexture(nil, "OVERLAY", nil, 7)
+	afflicted.Texture:SetAllPoints(afflicted)
+	afflicted.Texture:SetTexture(AFFLICTED_SKIN)
+	afflicted.Texture:SetVertexColor(0, 0, 0, 0)
+	afflicted.Texture:SetBlendMode("ADD")
+	afflicted.ClassFilter = true
+	return afflicted
+end
+--[[
+##########################################################
+VARIOUS ICONS
+##########################################################
+]]--
+function MOD:CreateResurectionIcon(frame)
+	local rez = frame.TextGrip:CreateTexture(nil, "OVERLAY")
+	rez:SetPoint("CENTER", frame.TextGrip.Health, "CENTER")
+	rez:SetSize(30, 25)
+	rez:SetDrawLayer("OVERLAY", 7)
+	return rez
+end
+
+function MOD:CreateReadyCheckIcon(frame)
+	local rdyHolder = CreateFrame("Frame", nil, frame.TextGrip)
+	rdyHolder:SetAllPoints(frame)
+	local rdy = rdyHolder:CreateTexture(nil, "OVERLAY", nil, 7)
+	rdy:SetSize(18, 18)
+	rdy:SetPoint("RIGHT", rdyHolder, "RIGHT", 0, 0)
+	return rdy
+end
+
+function MOD:CreateGladiator(frame)
+	local pvp = CreateFrame("Frame", nil, frame)
+	pvp:SetFrameLevel(pvp:GetFrameLevel() + 1)
+
+	local trinket = CreateFrame("Frame", nil, pvp)
+	BasicBG(trinket)
+	trinket.Icon = trinket:CreateTexture(nil, "BORDER")
+	trinket.Icon:InsetPoints(trinket, 2, 2)
+	trinket.Icon:SetTexture([[Interface\Icons\INV_MISC_QUESTIONMARK]])
+	trinket.Icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+
+	trinket.Unavailable = trinket:CreateTexture(nil, "OVERLAY")
+	trinket.Unavailable:SetAllPoints(trinket)
+	trinket.Unavailable:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+	trinket.Unavailable:SetTexture([[Interface\BUTTONS\UI-GroupLoot-Pass-Up]])
+	trinket.Unavailable:Hide()
+
+	trinket.CD = CreateFrame("Cooldown", nil, trinket)
+	trinket.CD:SetAllPoints(trinket)
+
+	pvp.Trinket = trinket
+
+	local badge = CreateFrame("Frame", nil, pvp)
+	BasicBG(badge)
+	badge.Icon = badge:CreateTexture(nil, "OVERLAY")
+	badge.Icon:InsetPoints(badge, 2, 2)
+	badge.Icon:SetTexture([[Interface\Icons\INV_MISC_QUESTIONMARK]])
+	badge.Icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+
+	pvp.Badge = badge
+
+	return pvp
+end
+
+function MOD:CreateFriendshipBar(frame)
+	local buddy = CreateFrame("StatusBar", nil, frame.Power)
+    buddy:SetAllPoints(frame.Power)
+    buddy:SetStatusBarTexture(SV.media.statusbar.default)
+    buddy:SetStatusBarColor(1,0,0)
+    local bg = buddy:CreateTexture(nil, "BACKGROUND")
+	bg:SetAllPoints(buddy)
+	bg:SetColorTexture(0.2,0,0)
+	local icon = buddy:CreateTexture(nil, "OVERLAY")
+	icon:SetPoint("LEFT", buddy, "LEFT", -11, 0)
+	icon:SetSize(22,22)
+	icon:SetTexture(MOD.media.buddy)
+
+	return buddy
+end
+--[[
+##########################################################
+CONFIGURABLE ICONS
+##########################################################
+]]--
+function MOD:CreateRaidIcon(frame)
+	local rIcon = frame.TextGrip:CreateTexture(nil, "OVERLAY", nil, 2)
+	rIcon:SetTexture([[Interface\TargetingFrame\UI-RaidTargetingIcons]])
+	rIcon:SetSize(18, 18)
+	rIcon:SetPoint("CENTER", frame.TextGrip, "TOP", 0, 2)
+	return rIcon
+end
+
+local UpdateRoleIcon = function(self)
+	local key = self.___key
+	local db = SV.db.UnitFrames[key]
+	if(not db or not db.icons or (db.icons and not db.icons.roleIcon)) then return end
+	local lfd = self.LFDRole
+	if(not db.icons.roleIcon.enable) then lfd:Hide() return end
+	local unitRole = UnitGroupRolesAssigned(self.unit)
+	if(self.isForced and unitRole == "NONE") then
+		local rng = random(1, 3)
+		unitRole = rng == 1 and "TANK" or rng == 2 and "HEALER" or rng == 3 and "DAMAGER"
+	end
+	if(unitRole ~= "NONE" and (self.isForced or UnitIsConnected(self.unit))) then
+		local coords = ROLE_ICON_DATA[unitRole]
+		lfd:SetTexture(MOD.media.roles)
+		if(lfd:GetHeight() <= 13) then
+			lfd:SetTexCoord(coords[5], coords[6], coords[7], coords[8])
+		else
+			lfd:SetTexCoord(coords[1], coords[2], coords[3], coords[4])
+		end
+		lfd:Show()
+	else
+		lfd:Hide()
+	end
+end
+
+function MOD:CreateRoleIcon(frame)
+	local parent = frame.TextGrip or frame;
+	local rIconHolder = CreateFrame("Frame", nil, parent)
+	rIconHolder:SetAllPoints()
+	local rIcon = rIconHolder:CreateTexture(nil, "ARTWORK", nil, 2)
+	rIcon:SetSize(14, 14)
+	rIcon:SetPoint("BOTTOMRIGHT", rIconHolder, "BOTTOMRIGHT")
+	rIcon.Override = UpdateRoleIcon;
+	frame:RegisterEvent("UNIT_CONNECTION", UpdateRoleIcon)
+	return rIcon
+end
+
+function MOD:CreateRaidRoleFrames(frame)
+	local parent = frame.TextGrip or frame;
+	local raidRoles = CreateFrame("Frame", nil, frame)
+	raidRoles:SetSize(24, 12)
+	raidRoles:SetPoint("TOPLEFT", frame.ActionPanel, "TOPLEFT", -2, 4)
+	raidRoles:SetFrameLevel(parent:GetFrameLevel() + 50)
+
+	frame.Leader = raidRoles:CreateTexture(nil, "OVERLAY")
+	frame.Leader:SetSize(12, 12)
+	frame.Leader:SetTexture(MOD.media.lml)
+	frame.Leader:SetTexCoord(0, 0.5, 0, 0.5)
+	frame.Leader:SetVertexColor(1, 0.85, 0)
+	frame.Leader:SetPoint("LEFT")
+
+	frame.MasterLooter = raidRoles:CreateTexture(nil, "OVERLAY")
+	frame.MasterLooter:SetSize(12, 12)
+	frame.MasterLooter:SetTexture(MOD.media.lml)
+	frame.MasterLooter:SetTexCoord(0.5, 1, 0, 0.5)
+	frame.MasterLooter:SetVertexColor(1, 0.6, 0)
+	frame.MasterLooter:SetPoint("RIGHT")
+
+	frame.Leader.PostUpdate = MOD.RaidRoleUpdate;
+	frame.MasterLooter.PostUpdate = MOD.RaidRoleUpdate;
+	return raidRoles
+end
+
+function MOD:RaidRoleUpdate()
+	local frame = self:GetParent()
+	local leaderIcon = frame.Leader;
+	local looterIcon = frame.MasterLooter;
+	if not leaderIcon or not looterIcon then return end
+		local key = frame.___key;
+		local db = SV.db.UnitFrames[key];
+		local leaderShown = leaderIcon:IsShown()
+		local looterShown = looterIcon:IsShown()
+		leaderIcon:ClearAllPoints()
+		looterIcon:ClearAllPoints()
+		if db and db.icons and db.icons.raidRoleIcons then
+			local settings = db.icons.raidRoleIcons
+			if leaderShown and settings.position == "TOPLEFT"then
+				leaderIcon:SetPoint("LEFT", frame, "LEFT")
+				looterIcon:SetPoint("RIGHT", frame, "RIGHT")
+			elseif leaderShown and settings.position == "TOPRIGHT" then
+				leaderIcon:SetPoint("RIGHT", frame, "RIGHT")
+				looterIcon:SetPoint("LEFT", frame, "LEFT")
+			elseif looterShown and settings.position == "TOPLEFT" then
+				looterIcon:SetPoint("LEFT", frame, "LEFT")
+			else
+			looterIcon:SetPoint("RIGHT", frame, "RIGHT")
+		end
+	end
+end
+--[[
+##########################################################
+PLAYER ONLY COMPONENTS
+##########################################################
+]]--
+function MOD:CreatePlayerIndicators(frame)
+	local resting = CreateFrame("Frame",nil,frame)
+	resting:SetFrameStrata("MEDIUM")
+	resting:SetFrameLevel(20)
+	resting:SetSize(26,26)
+	resting:SetPoint("BOTTOMRIGHT", frame.Health, "BOTTOMRIGHT", 0, 0)
+	resting.bg = resting:CreateTexture(nil,"OVERLAY",nil,1)
+	resting.bg:SetAllPoints(resting)
+	resting.bg:SetTexture(MOD.media.playerstate)
+	resting.bg:SetTexCoord(0.5,1,0,0.5)
+
+	local combat = CreateFrame("Frame",nil,frame)
+	combat:SetFrameStrata("MEDIUM")
+	combat:SetFrameLevel(30)
+	combat:SetSize(26,26)
+	combat:SetPoint("BOTTOMLEFT", frame , "TOPRIGHT", 3, 3)
+	combat.bg = combat:CreateTexture(nil,"OVERLAY",nil,5)
+	combat.bg:SetAllPoints(combat)
+	combat.bg:SetTexture(MOD.media.playerstate)
+	combat.bg:SetTexCoord(0,0.5,0,0.5)
+	combat.linked = resting
+	SV.Animate:Pulse(combat)
+	--IsResting()
+	combat:SetScript("OnShow", function(this)
+		if not this.anim:IsPlaying() then this.anim:Play() end
+		if(resting:IsShown()) then
+			resting:SetAlpha(0)
+		end
+	end)
+	combat:Hide()
+	combat:SetScript("OnHide", function(this)
+		if(IsResting()) then
+			resting:SetAlpha(1)
+		end
+	end)
+
+	frame.Resting = resting
+	frame.Combat = combat
+end
+
+local ExRep_OnEnter = function(self)if self:IsShown() then UIFrameFadeIn(self,.1,0,1) end end
+local ExRep_OnLeave = function(self)if self:IsShown() then UIFrameFadeOut(self,.2,1,0) end end
+
+function MOD:CreateExperienceRepBar(frame)
+	local db = SV.db.UnitFrames.player;
+
+	if db.playerExpBar then
+		local xp = CreateFrame("StatusBar", "PlayerFrameExperienceBar", frame.Power)
+		xp:InsetPoints(frame.Power, 0, 0)
+		xp:SetStyle("Frame")
+		xp:SetStatusBarTexture(SV.media.statusbar.default)
+		xp:SetStatusBarColor(0, 0.1, 0.6)
+		--xp:SetBackdropColor(1, 1, 1, 0.8)
+		xp:SetFrameLevel(xp:GetFrameLevel() + 2)
+		xp.Tooltip = true;
+		xp.Rested = CreateFrame("StatusBar", nil, xp)
+		xp.Rested:SetAllPoints(xp)
+		xp.Rested:SetStatusBarTexture(SV.media.statusbar.default)
+		xp.Rested:SetStatusBarColor(1, 0, 1, 0.6)
+		xp.Value = xp:CreateFontString(nil, "TOOLTIP")
+		xp.Value:SetAllPoints(xp)
+		xp.Value:SetFontObject(SVUI_Font_Default)
+		xp.Value:SetTextColor(0.2, 0.75, 1)
+		xp.Value:SetShadowColor(0, 0, 0, 0)
+		xp.Value:SetShadowOffset(0, 0)
+		frame:Tag(xp.Value, "[curxp] / [maxxp]")
+		xp.Rested:SetBackdrop({bgFile = [[Interface\BUTTONS\WHITE8X8]]})
+		xp.Rested:SetBackdropColor(unpack(SV.media.color.default))
+		xp:SetScript("OnEnter", ExRep_OnEnter)
+		xp:SetScript("OnLeave", ExRep_OnLeave)
+		xp:SetAlpha(0)
+		frame.Experience = xp
+	end
+
+	if db.playerRepBar then
+		local rep = CreateFrame("StatusBar", "PlayerFrameReputationBar", frame.Power)
+		rep:InsetPoints(frame.Power, 0, 0)
+		rep:SetStyle("Frame")
+		rep:SetStatusBarTexture(SV.media.statusbar.default)
+		rep:SetStatusBarColor(0, 0.6, 0)
+		--rep:SetBackdropColor(1, 1, 1, 0.8)
+		rep:SetFrameLevel(rep:GetFrameLevel() + 2)
+		rep.Tooltip = true;
+		rep.Value = rep:CreateFontString(nil, "TOOLTIP")
+		rep.Value:SetAllPoints(rep)
+		rep.Value:SetFontObject(SVUI_Font_Default)
+		rep.Value:SetTextColor(0.1, 1, 0.2)
+		rep.Value:SetShadowColor(0, 0, 0, 0)
+		rep.Value:SetShadowOffset(0, 0)
+		frame:Tag(rep.Value, "[standing]: [currep] / [maxrep]")
+		rep:SetScript("OnEnter", ExRep_OnEnter)
+		rep:SetScript("OnLeave", ExRep_OnLeave)
+		rep:SetAlpha(0)
+		frame.Reputation = rep
+	end
+end
+--[[
+##########################################################
+HEAL PREDICTION
+##########################################################
+]]--
+local OverrideUpdate = function(self, event, unit)
+	if(self.unit ~= unit) or not unit then return end
+
+	local hp = self.HealPrediction
+	hp.parent = self
+	local hbar = self.Health;
+	local anchor, relative, relative2 = 'TOPLEFT', 'BOTTOMRIGHT', 'BOTTOMLEFT';
+	local reversed = true
+	hp.reversed = hbar.fillInverted or false
+	if(hp.reversed == true) then
+		anchor, relative, relative2 = 'TOPRIGHT', 'BOTTOMLEFT', 'BOTTOMRIGHT';
+		reversed = false
+	end
+
+	local myIncomingHeal = UnitGetIncomingHeals(unit, 'player') or 0
+	local allIncomingHeal = UnitGetIncomingHeals(unit) or 0
+	local totalAbsorb = UnitGetTotalAbsorbs(unit) or 0
+	local myCurrentHealAbsorb = UnitGetTotalHealAbsorbs(unit) or 0
+	local health, maxHealth = UnitHealth(unit), UnitHealthMax(unit)
+
+	local overHealAbsorb = false
+	if(health < myCurrentHealAbsorb) then
+		overHealAbsorb = true
+		myCurrentHealAbsorb = health
+	end
+
+	if(health - myCurrentHealAbsorb + allIncomingHeal > maxHealth * hp.maxOverflow) then
+		allIncomingHeal = maxHealth * hp.maxOverflow - health + myCurrentHealAbsorb
+	end
+
+	local otherIncomingHeal = 0
+	if(allIncomingHeal < myIncomingHeal) then
+		myIncomingHeal = allIncomingHeal
+	else
+		otherIncomingHeal = allIncomingHeal - myIncomingHeal
+	end
+
+	local overAbsorb = false
+	if(health - myCurrentHealAbsorb + allIncomingHeal + totalAbsorb >= maxHealth or health + totalAbsorb >= maxHealth) then
+		if(totalAbsorb > 0) then
+			overAbsorb = true
+		end
+
+		if(allIncomingHeal > myCurrentHealAbsorb) then
+			totalAbsorb = max(0, maxHealth - (health - myCurrentHealAbsorb + allIncomingHeal))
+		else
+			totalAbsorb = max(0, maxHealth - health)
+		end
+	end
+
+	if(myCurrentHealAbsorb > allIncomingHeal) then
+		myCurrentHealAbsorb = myCurrentHealAbsorb - allIncomingHeal
+	else
+		myCurrentHealAbsorb = 0
+	end
+
+	local barMin, barMax, barMod = 0, maxHealth, 1;
+
+	local previous = hbar:GetStatusBarTexture()
+	if(hp.myBar) then
+		hp.myBar:SetMinMaxValues(barMin, barMax)
+		if(not hp.otherBar) then
+			hp.myBar:SetValue(allIncomingHeal)
+		else
+			hp.myBar:SetValue(myIncomingHeal)
+		end
+		hp.myBar:SetPoint(anchor, hbar, anchor, 0, 0)
+		hp.myBar:SetPoint(relative, previous, relative, 0, 0)
+		hp.myBar:SetReverseFill(reversed)
+		previous = hp.myBar
+		hp.myBar:Show()
+	end
+
+	if(hp.absorbBar) then
+		hp.absorbBar:SetMinMaxValues(barMin, barMax)
+		hp.absorbBar:SetValue(totalAbsorb)
+		hp.absorbBar:SetAllPoints(hbar)
+		hp.absorbBar:SetReverseFill(not reversed)
+		hp.absorbBar:Show()
+	end
+
+	if(hp.healAbsorbBar) then
+		hp.healAbsorbBar:SetMinMaxValues(barMin, barMax)
+		hp.healAbsorbBar:SetValue(myCurrentHealAbsorb)
+		hp.healAbsorbBar:SetPoint(anchor, hbar, anchor, 0, 0)
+		hp.healAbsorbBar:SetPoint(relative, previous, relative, 0, 0)
+		hp.healAbsorbBar:SetReverseFill(reversed)
+		previous = hp.healAbsorbBar
+		hp.healAbsorbBar:Show()
+	end
+end
+
+function MOD:CreateHealPrediction(frame, fullSet)
+	local health = frame.Health;
+	local isReversed = false
+	if(health.fillInverted and health.fillInverted == true) then
+		isReversed = true
+	end
+	local hTex = health:GetStatusBarTexture()
+	local myBar = CreateFrame('StatusBar', nil, health)
+	myBar:SetFrameStrata("LOW")
+	myBar:SetFrameLevel(6)
+	myBar:SetStatusBarTexture([[Interface\BUTTONS\WHITE8X8]])
+	myBar:SetStatusBarColor(0.15, 0.7, 0.05, 0.9)
+
+	local absorbBar = CreateFrame('StatusBar', nil, health)
+	absorbBar:SetFrameStrata("LOW")
+	absorbBar:SetFrameLevel(7)
+	absorbBar:SetStatusBarTexture(SV.media.statusbar.gradient)
+	absorbBar:SetStatusBarColor(1, 1, 0, 0.5)
+
+	local healPrediction = {
+		myBar = myBar,
+		absorbBar = absorbBar,
+		maxOverflow = 1,
+		reversed = isReversed,
+		Override = OverrideUpdate
+	}
+
+	if(fullSet) then
+		local healAbsorbBar = CreateFrame('StatusBar', nil, health)
+		healAbsorbBar:SetFrameStrata("LOW")
+		healAbsorbBar:SetFrameLevel(9)
+		healAbsorbBar:SetStatusBarTexture(SV.media.statusbar.gradient)
+		healAbsorbBar:SetStatusBarColor(0.5, 0.2, 1, 0.9)
+		healPrediction["healAbsorbBar"] = healAbsorbBar;
+	end
+
+	return healPrediction
+end
+--[[
+##########################################################
+RESOLVE
+##########################################################
+]]--
+local cached_resolve;
+local RESOLVE_ID = 158300;
+
+local function Short(value)
+	local fmt
+	if value >= 10000 then
+		fmt = "%.0fk"
+		value = value / 1000
+	elseif value >= 1000 then
+		fmt = "%.1fk"
+		value = value / 1000
+	else
+		fmt = "%d"
+	end
+	return fmt:format(value)
+end
+
+local function IsTank()
+	local _, playerclass = UnitClass("player")
+	local masteryIndex
+	local tank = false
+	if playerclass == "DEATHKNIGHT" then
+		masteryIndex = GetSpecialization()
+		if masteryIndex and masteryIndex == 1 then
+			tank = true
+		end
+	elseif playerclass == "DRUID" then
+		masteryIndex = GetSpecialization()
+		if masteryIndex and masteryIndex == 3 then
+			tank = true
+		end
+	elseif playerclass == "MONK" then
+		masteryIndex = GetSpecialization()
+		if masteryIndex and masteryIndex == 1 then
+			tank = true
+		end
+	elseif playerclass == "PALADIN" then
+		masteryIndex = GetSpecialization()
+		if masteryIndex and masteryIndex == 2 then
+			tank = true
+		end
+	elseif playerclass == "WARRIOR" then
+		masteryIndex = GetSpecialization()
+		if masteryIndex and masteryIndex == 3 then
+			tank = true
+		end
+	end
+	return tank
+end
+
+local ResolveBar_OnEvent = function(self, event, unit)
+	if(SV.db.UnitFrames.resolveBar) then
+		if(event == 'UNIT_AURA') then
+			for index = 1, 30 do
+				local _, _, _, _, _, _, _, _, _, _, spellID, _, _, _, value, amount = UnitBuff('player', index)
+				if((spellID == RESOLVE_ID) and (amount and (cached_resolve ~= amount))) then
+					if(value) then
+						self.bar:SetValue(value)
+					end
+					self.bar.text:SetText(Short(amount))
+					self:FadeIn()
+					cached_resolve = amount
+				end
+			end
+		else
+			if IsTank() then
+				if(not self.bar:IsShown()) then
+					self:RegisterUnitEvent("UNIT_AURA", "player")
+					self.bar:Show()
+				end
+			else
+				if(self.bar:IsShown()) then
+					self:UnregisterEvent("UNIT_AURA")
+					self.bar:Hide()
+				end
+			end
+		end
+	end
+	if(self.bar:IsShown()) then
+		if(self.bar.text:GetText() == "0") then
+			self.bar.text:SetText("")
+			self:FadeOut()
+		end
+	end
+end
+
+function MOD:CreateResolveBar(frame)
+	local resolve = CreateFrame("Frame", nil, frame)
+	resolve:SetPoint("TOPLEFT", frame.Health, "TOPLEFT", 0, 0)
+	resolve:SetPoint("TOPRIGHT", frame.Health, "TOPRIGHT", 0, 0)
+	resolve:SetHeight(8)
+
+	local bar = CreateFrame('StatusBar', nil, resolve)
+	bar:InsetPoints(resolve)
+	bar:SetStyle("Frame", "Bar")
+	bar:SetStatusBarTexture([[Interface\BUTTONS\WHITE8X8]])
+	bar:SetStatusBarColor(0.15, 0.7, 0.05, 0.9)
+	bar:SetMinMaxValues(0, 100)
+	bar.text = bar:CreateFontString(nil, "OVERLAY")
+	bar.text:SetPoint("LEFT")
+	bar.text:SetFontObject(SVUI_Font_Pixel)
+	bar.text:SetJustifyH('LEFT')
+	bar.text:SetTextColor(0.8, 0.42, 0.09)
+	bar:Hide()
+	resolve.bar = bar;
+
+	resolve:RegisterEvent("PLAYER_TALENT_UPDATE")
+	resolve:RegisterEvent("PLAYER_ENTERING_WORLD")
+	resolve:SetScript('OnEvent', ResolveBar_OnEvent)
+
+	ResolveBar_OnEvent(resolve)
+	return resolve
+end
diff --git a/SVUI_UnitFrames/elements/tags.lua b/SVUI_UnitFrames/elements/tags.lua
new file mode 100644
index 0000000..846f879
--- /dev/null
+++ b/SVUI_UnitFrames/elements/tags.lua
@@ -0,0 +1,470 @@
+--[[
+##############################################################################
+S V U I  By: Failcoder               #
+##############################################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+--STRING
+local string        = _G.string;
+local upper         = string.upper;
+local format        = string.format;
+local find          = string.find;
+local match         = string.match;
+local sub         	= string.sub;
+local gsub          = string.gsub;
+local byte 			= string.byte;
+local upper 		= string.upper;
+local len         	= string.len;
+--MATH
+local math          = _G.math;
+local floor         = math.floor
+--TABLE
+local table         = _G.table;
+local tsort         = table.sort;
+local tconcat       = table.concat;
+local tinsert       = _G.tinsert;
+local tremove       = _G.tremove;
+local twipe         = _G.wipe;
+
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L;
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local MOD = SV.UnitFrames
+
+if(not MOD) then return end
+
+local oUF_SVUI = MOD.oUF
+assert(oUF_SVUI, "SVUI UnitFrames: unable to locate oUF.")
+--[[
+##########################################################
+LOCAL VARIABLES
+##########################################################
+]]--
+local Harmony = {
+	[0] = {1, 1, 1},
+	[1] = {.57, .63, .35, 1},
+	[2] = {.47, .63, .35, 1},
+	[3] = {.37, .63, .35, 1},
+	[4] = {.27, .63, .33, 1},
+	[5] = {.17, .63, .33, 1}
+}
+local SKULL_ICON = "|TInterface\\TARGETINGFRAME\\UI-TargetingFrame-Skull.blp:16:16|t";
+--[[
+##########################################################
+LOCAL FUNCTIONS
+##########################################################
+]]--
+local function Hex(r, g, b)
+	if(not r) then
+		r, g, b = 1, 1, 1;
+	elseif type(r) == "table" then
+		if r.r then r, g, b = r.r, r.g, r.b else r, g, b = unpack(r) end
+	end
+	return ("|cff%02x%02x%02x"):format(r*255, g*255, b*255)
+end
+
+local function TruncateString(value)
+	if value >= 1e9 then
+		return ("%.1fb"):format(value / 1e9):gsub("%.?0 + ([kmb])$", "%1")
+	elseif value >= 1e6 then
+		return ("%.1fm"):format(value / 1e6):gsub("%.?0 + ([kmb])$", "%1")
+	elseif value >= 1e3 or value <= -1e3 then
+		return ("%.1fk"):format(value / 1e3):gsub("%.?0 + ([kmb])$", "%1")
+	else
+		return value
+	end
+end
+
+local function SetTagStyle(style, min, max)
+	if max == 0 then max = 1 end
+	local result;
+	if style == "DEFICIT" then
+		local result = max - min;
+		if result <= 0 then
+			return ""
+		else
+			return ("-%s"):format(TruncateString(result))
+		end
+	elseif style == "PERCENT" then
+		local prct = min / max * 100
+		result = ("%.1f"):format(prct)
+		result = ("%s%%"):format(result)
+		result = result:gsub(".0%%", "%%")
+		return result
+	elseif style == "CURRENT" or ((style == "CURRENT_MAX" or style == "CURRENT_MAX_PERCENT" or style == "CURRENT_PERCENT") and min == max) then
+		return ("%s"):format(TruncateString(min))
+	elseif style == "CURRENT_MAX" then
+		return ("%s - %s"):format(TruncateString(min), TruncateString(max))
+	elseif style == "CURRENT_PERCENT" then
+		local prct = min / max * 100
+		result = ("%.1f"):format(prct)
+		result = ("%s - %s%%"):format(TruncateString(min), result)
+		result = result:gsub(".0%%", "%%")
+		return result
+	elseif style == "CURRENT_MAX_PERCENT" then
+		local prct = min / max * 100
+		result = ("%.1f"):format(prct)
+		result = ("%s - %s - %s%%"):format(TruncateString(min), TruncateString(max), result)
+		result = result:gsub(".0%%", "%%")
+		return result
+	end
+end
+
+local function TrimTagText(text, limit, ellipsis)
+	local length = text:len()
+	if length <= limit then
+		return text
+	else
+		local overall, charPos = 0, 1;
+		while charPos <= length do
+			overall = overall + 1;
+			local parse = text:byte(charPos)
+			if parse > 0 and parse <= 127 then
+				charPos = charPos + 1
+			elseif parse >= 192 and parse <= 223 then
+				charPos = charPos + 2
+			elseif parse >= 224 and parse <= 239 then
+				charPos = charPos + 3
+			elseif parse >= 240 and parse <= 247 then
+				charPos = charPos + 4
+			end
+			if overall == limit then break end
+		end
+		if overall == limit and charPos <= length then
+			return text:sub(1, charPos - 1)..(ellipsis and "..." or "")
+		else
+			return text
+		end
+	end
+end
+
+local function GetClassPower(class)
+	local currentPower, maxPower, r, g, b = 0, 0, 0, 0, 0;
+	local spec = GetSpecialization()
+	if class == "PALADIN"then
+		currentPower = UnitPower("player", SPELL_POWER_HOLY_POWER)
+		maxPower = UnitPowerMax("player", SPELL_POWER_HOLY_POWER)
+		r, g, b = 228 / 255, 225 / 255, 16 / 255
+	elseif class == "MONK"then
+		currentPower = UnitPower("player", SPELL_POWER_CHI)
+		maxPower = UnitPowerMax("player", SPELL_POWER_CHI)
+		r, g, b = unpack(Harmony[currentPower])
+	elseif class == "DRUID" and GetShapeshiftFormID() == MOONKIN_FORM then
+		currentPower = UnitPower("player", SPELL_POWER_ECLIPSE)
+		maxPower = UnitPowerMax("player", SPELL_POWER_ECLIPSE)
+		r, g, b = .30, .52, .90
+		--[[
+		if GetEclipseDirection() == "moon"then
+			r, g, b = .80, .82, .60
+		else
+			r, g, b = .30, .52, .90
+		end
+		]]--
+	elseif class == "PRIEST" and spec == SPEC_PRIEST_SHADOW and UnitLevel("player") > SHADOW_ORBS_SHOW_LEVEL then
+		currentPower = UnitPower("player", SPELL_POWER_SHADOW_ORBS)
+		maxPower = UnitPowerMax("player", SPELL_POWER_SHADOW_ORBS)
+		r, g, b = 1, 1, 1
+	elseif class == "WARLOCK"then
+		if spec == SPEC_WARLOCK_DESTRUCTION then
+			currentPower = UnitPower("player", SPELL_POWER_BURNING_EMBERS, true)
+			maxPower = UnitPowerMax("player", SPELL_POWER_BURNING_EMBERS, true)
+			currentPower = floor(currentPower / 10)
+			maxPower = floor(maxPower / 10)
+			r, g, b = 230 / 255, 95 / 255, 95 / 255
+		elseif spec == SPEC_WARLOCK_AFFLICTION then
+			currentPower = UnitPower("player", SPELL_POWER_SOUL_SHARDS)
+			maxPower = UnitPowerMax("player", SPELL_POWER_SOUL_SHARDS)
+			r, g, b = 148 / 255, 130 / 255, 201 / 255
+		elseif spec == SPEC_WARLOCK_DEMONOLOGY then
+			currentPower = UnitPower("player", SPELL_POWER_DEMONIC_FURY)
+			maxPower = UnitPowerMax("player", SPELL_POWER_DEMONIC_FURY)
+			r, g, b = 148 / 255, 130 / 255, 201 / 255
+		end
+	end
+	return currentPower, maxPower, r, g, b
+end
+
+local function GetStatusString(unit)
+	local afk, dnd, c = UnitIsAFK(unit), UnitIsDND(unit), UnitClassification(unit)
+	local preString, postString = "","";
+	if afk then
+		preString = ("|cffFFFFFF[|r|cffFF0000%s|r|cffFFFFFF] |r"):format(DEFAULT_AFK_MESSAGE)
+	elseif dnd then
+		preString = ("|cffFFFFFF[|r|cffFF0000%s|r|cffFFFFFF] |r"):format(L["DND"])
+	elseif(c == "rare" or c == "rareelite") then
+		preString = ("|cff00FFFF%s |r"):format("Rare")
+	end
+	if(c == "rareelite" or c == "elite") then
+		postString = "+"
+	end
+	return preString, postString
+end
+
+local function UnitName(unit)
+	local name = _G.UnitName(unit)
+	if name == UNKNOWN and SV.class == "MONK" and UnitIsUnit(unit, "pet") then
+		name = ("%s\'s Spirit"):format(_G.UnitName("player"))
+	else
+		return name
+	end
+end
+--[[
+##########################################################
+TAG EVENTS
+##########################################################
+]]--
+oUF_SVUI.Tags.Events["name:color"] = "UNIT_NAME_UPDATE";
+for i = 1, 30 do
+	oUF_SVUI.Tags.Events["name:"..i] = "UNIT_NAME_UPDATE";
+end
+oUF_SVUI.Tags.Events["name:level"] = "UNIT_LEVEL PLAYER_LEVEL_UP PLAYER_FLAGS_CHANGED";
+oUF_SVUI.Tags.Events["name:grid"] = "UNIT_NAME_UPDATE";
+
+oUF_SVUI.Tags.Events["health:color"] = "UNIT_HEALTH_FREQUENT UNIT_MAXHEALTH UNIT_CONNECTION PLAYER_FLAGS_CHANGED";
+oUF_SVUI.Tags.Events["health:deficit"] = "UNIT_HEALTH_FREQUENT UNIT_MAXHEALTH UNIT_CONNECTION PLAYER_FLAGS_CHANGED";
+oUF_SVUI.Tags.Events["health:current"] = "UNIT_HEALTH_FREQUENT UNIT_MAXHEALTH UNIT_CONNECTION PLAYER_FLAGS_CHANGED";
+oUF_SVUI.Tags.Events["health:curmax"] = "UNIT_HEALTH_FREQUENT UNIT_MAXHEALTH UNIT_CONNECTION PLAYER_FLAGS_CHANGED";
+oUF_SVUI.Tags.Events["health:curpercent"] = "UNIT_HEALTH_FREQUENT UNIT_MAXHEALTH UNIT_CONNECTION PLAYER_FLAGS_CHANGED";
+oUF_SVUI.Tags.Events["health:curmax-percent"] = "UNIT_HEALTH_FREQUENT UNIT_MAXHEALTH UNIT_CONNECTION PLAYER_FLAGS_CHANGED";
+oUF_SVUI.Tags.Events["health:percent"] = "UNIT_HEALTH_FREQUENT UNIT_MAXHEALTH UNIT_CONNECTION PLAYER_FLAGS_CHANGED";
+
+oUF_SVUI.Tags.Events["power:color"] = "UNIT_POWER_FREQUENT UNIT_MAXPOWER";
+oUF_SVUI.Tags.Events["power:deficit"] = "UNIT_POWER_FREQUENT UNIT_MAXPOWER";
+oUF_SVUI.Tags.Events["power:current"] = "UNIT_POWER_FREQUENT UNIT_MAXPOWER";
+oUF_SVUI.Tags.Events["power:curmax"] = "UNIT_POWER_FREQUENT UNIT_MAXPOWER";
+oUF_SVUI.Tags.Events["power:curpercent"] = "UNIT_POWER_FREQUENT UNIT_MAXPOWER";
+oUF_SVUI.Tags.Events["power:curmax-percent"] = "UNIT_POWER_FREQUENT UNIT_MAXPOWER";
+oUF_SVUI.Tags.Events["power:percent"] = "UNIT_POWER_FREQUENT UNIT_MAXPOWER";
+
+oUF_SVUI.Tags.Events["absorbs"] = "UNIT_ABSORB_AMOUNT_CHANGED";
+oUF_SVUI.Tags.Events["incoming"] = "UNIT_HEAL_PREDICTION";
+oUF_SVUI.Tags.Events["classpower"] = "UNIT_POWER PLAYER_TALENT_UPDATE UPDATE_SHAPESHIFT_FORM";
+oUF_SVUI.Tags.Events["altpower"] = "UNIT_POWER UNIT_MAXPOWER";
+oUF_SVUI.Tags.Events["threat"] = "UNIT_THREAT_LIST_UPDATE GROUP_ROSTER_UPDATE";
+--[[
+##########################################################
+NAME TAG METHODS
+##########################################################
+]]--
+oUF_SVUI.Tags.Methods["name:color"] = function(unit)
+	local unitReaction = UnitReaction(unit, "player")
+	local _, classToken = UnitClass(unit)
+	if UnitIsPlayer(unit) then
+		local class = RAID_CLASS_COLORS[classToken]
+		if not class then return "" end
+		return Hex(class.r, class.g, class.b)
+	elseif unitReaction then
+		local reaction = oUF_SVUI["colors"].reaction[unitReaction]
+		return Hex(reaction[1], reaction[2], reaction[3])
+	else
+		return "|cFFC2C2C2"
+	end
+end
+
+for i = 1, 30 do
+	oUF_SVUI.Tags.Methods["name:"..i] = function(unit)
+		local name = UnitName(unit)
+		local result = (name ~= nil) and (TrimTagText(name, i).."|r ") or ""
+		return result
+	end
+end
+
+oUF_SVUI.Tags.Methods["name:level"] = function(unit)
+	local afk, dnd, c = UnitIsAFK(unit), UnitIsDND(unit), UnitClassification(unit)
+	local r, g, b, color = 0.55, 0.57, 0.61;
+	local hexString = "";
+	local level = UnitLevel(unit)
+	if(c == "worldboss" or not (level > 0)) then
+		return SKULL_ICON
+	end
+	if(UnitIsWildBattlePet(unit) or UnitIsBattlePetCompanion(unit)) then
+		level = UnitBattlePetLevel(unit)
+		local pta = C_PetJournal.GetPetTeamAverageLevel()
+		if pta < level or pta > level then
+			color = GetRelativeDifficultyColor(pta, level)
+			r, g, b = color.r, color.g, color.b
+		else
+			color = QuestDifficultyColors["difficult"]
+			r, g, b = color.r, color.g, color.b
+		end
+	else
+		local diff = UnitLevel(unit) - UnitLevel("player")
+		if diff >= 5 then
+			r, g, b = 0.69, 0.31, 0.31
+		elseif diff >= 3 then
+			r, g, b = 0.71, 0.43, 0.27
+		elseif diff >= -2 then
+			r, g, b = 0.84, 0.75, 0.65
+		elseif -diff <= GetQuestGreenRange() then
+			r, g, b = 0.33, 0.59, 0.33
+		else
+			r, g, b = 0.55, 0.57, 0.61
+		end
+	end
+	local pre,status = GetStatusString(unit)
+	local levelString = " " .. pre .. level .. status
+	hexString = Hex(r, g, b)
+	return ("%s%s|r"):format(hexString, levelString)
+end
+
+oUF_SVUI.Tags.Methods["name:grid"] = function(unit)
+	local name = UnitName(unit)
+	if not name then return "" end
+	local unitReaction = UnitReaction(unit, "player")
+	local _, classToken = UnitClass(unit)
+	local result = "|cffC2C2C2"
+	if UnitIsPlayer(unit) then
+		local class = RAID_CLASS_COLORS[classToken]
+		if class then
+			result = Hex(class.r, class.g, class.b)
+		end
+	elseif unitReaction then
+		local reaction = oUF_SVUI["colors"].reaction[unitReaction]
+		result = Hex(reaction[1], reaction[2], reaction[3])
+	end
+	name = TrimTagText(name, 4)
+	name = upper(name)
+	result = ("%s%s|r"):format(result, name)
+	return result
+end
+--[[
+##########################################################
+HEALTH TAG METHODS
+##########################################################
+]]--
+oUF_SVUI.Tags.Methods["health:color"] = function(f)
+	if UnitIsDeadOrGhost(f) or not UnitIsConnected(f)then
+		return Hex(0.84, 0.75, 0.65)
+	else
+		local r, g, b = oUF_SVUI.ColorGradient(UnitHealth(f), UnitHealthMax(f), 0.89, 0.21, 0.21, 0.85, 0.53, 0.25, 0.23, 0.89, 0.33)
+		return Hex(r, g, b)
+	end
+end
+
+oUF_SVUI.Tags.Methods["health:current"] = function(f)local i = UnitIsDead(f)and DEAD or UnitIsGhost(f)and L["Ghost"]or not UnitIsConnected(f)and L["Offline"]if i then return i else return SetTagStyle("CURRENT", UnitHealth(f), UnitHealthMax(f))end end
+
+oUF_SVUI.Tags.Methods["health:curmax"] = function(f)local i = UnitIsDead(f)and DEAD or UnitIsGhost(f)and L["Ghost"]or not UnitIsConnected(f)and L["Offline"]if i then return i else return SetTagStyle("CURRENT_MAX", UnitHealth(f), UnitHealthMax(f))end end
+
+oUF_SVUI.Tags.Methods["health:curpercent"] = function(f)local i = UnitIsDead(f)and DEAD or UnitIsGhost(f)and L["Ghost"]or not UnitIsConnected(f)and L["Offline"]if i then return i else return SetTagStyle("CURRENT_PERCENT", UnitHealth(f), UnitHealthMax(f))end end
+
+oUF_SVUI.Tags.Methods["health:curmax-percent"] = function(f)local i = UnitIsDead(f)and DEAD or UnitIsGhost(f)and L["Ghost"]or not UnitIsConnected(f)and L["Offline"]if i then return i else return SetTagStyle("CURRENT_MAX_PERCENT", UnitHealth(f), UnitHealthMax(f))end end
+
+oUF_SVUI.Tags.Methods["health:percent"] = function(f)local i = UnitIsDead(f)and DEAD or UnitIsGhost(f)and L["Ghost"]or not UnitIsConnected(f)and L["Offline"]if i then return i else return SetTagStyle("PERCENT", UnitHealth(f), UnitHealthMax(f))end end
+
+oUF_SVUI.Tags.Methods["health:deficit"] = function(f)local i = UnitIsDead(f)and DEAD or UnitIsGhost(f)and L["Ghost"]or not UnitIsConnected(f)and L["Offline"]if i then return i else return SetTagStyle("DEFICIT", UnitHealth(f), UnitHealthMax(f))end end
+--[[
+##########################################################
+POWER TAG METHODS
+##########################################################
+]]--
+oUF_SVUI.Tags.Methods["power:color"] = function(f)
+	local j, k, l, m, n = UnitPowerType(f)
+	local o = oUF_SVUI["colors"].power[k]
+	if o then
+		return Hex(o[1], o[2], o[3])
+	else
+		return Hex(l, m, n)
+	end
+end
+
+oUF_SVUI.Tags.Methods["power:current"] = function(f)local j = UnitPowerType(f)local p = UnitPower(f, j)return p == 0 and" "or SetTagStyle("CURRENT", p, UnitPowerMax(f, j))end
+
+oUF_SVUI.Tags.Methods["power:curmax"] = function(f)local j = UnitPowerType(f)local p = UnitPower(f, j)return p == 0 and" "or SetTagStyle("CURRENT_MAX", p, UnitPowerMax(f, j))end
+
+oUF_SVUI.Tags.Methods["power:curpercent"] = function(f)local j = UnitPowerType(f)local p = UnitPower(f, j)return p == 0 and" "or SetTagStyle("CURRENT_PERCENT", p, UnitPowerMax(f, j))end
+
+oUF_SVUI.Tags.Methods["power:curmax-percent"] = function(f)local j = UnitPowerType(f)local p = UnitPower(f, j)return p == 0 and" "or SetTagStyle("CURRENT_PERCENT", p, UnitPowerMax(f, j))end
+
+oUF_SVUI.Tags.Methods["power:percent"] = function(f)local j = UnitPowerType(f)local p = UnitPower(f, j)return p == 0 and" "or SetTagStyle("PERCENT", p, UnitPowerMax(f, j))end
+
+oUF_SVUI.Tags.Methods["power:deficit"] = function(f)local j = UnitPowerType(f) return SetTagStyle("DEFICIT", UnitPower(f, j), UnitPowerMax(f, j))end
+--[[
+##########################################################
+MISC TAG METHODS
+##########################################################
+]]--
+oUF_SVUI.Tags.Methods["absorbs"] = function(unit)
+	local asrb = UnitGetTotalAbsorbs(unit) or 0;
+	if asrb == 0 then
+		return " "
+	else
+		local amt = TruncateString(asrb)
+		return ("|cffFFFFFF(%s) |r"):format(amt)
+	end
+end
+
+oUF_SVUI.Tags.Methods["incoming"] = function(unit)
+	local fromPlayer = UnitGetIncomingHeals(unit, "player") or 0;
+	local fromOthers = UnitGetIncomingHeals(unit) or 0;
+	local amt = fromPlayer + fromOthers;
+	if amt == 0 then
+		return " "
+	else
+		local incoming = TruncateString(amt)
+		return ("|cff2EFF2E+%s |r"):format(incoming)
+	end
+end
+
+oUF_SVUI.Tags.Methods["threat"] = function(unit)
+	if UnitCanAttack("player", unit)then
+		local status, threat = select(2, UnitDetailedThreatSituation("player", unit))
+		if status then
+			local color = Hex(GetThreatStatusColor(status))
+			return ("%s%.0f%% |r"):format(color, threat)
+		end
+	end
+	return " "
+end
+
+oUF_SVUI.Tags.Methods["classpower"] = function()
+	local currentPower, maxPower, r, g, b = GetClassPower(SV.class)
+	if currentPower == 0 then
+		return " "
+	else
+		local color = Hex(r, g, b)
+		local amt = SetTagStyle("CURRENT", currentPower, maxPower)
+		return ("%s%s "):format(color, amt)
+	end
+end
+
+oUF_SVUI.Tags.Methods["altpower"] = function(unit)
+	local power = UnitPower(unit, ALTERNATE_POWER_INDEX)
+	if(power > 0) then
+		local texture, r, g, b = UnitAlternatePowerTextureInfo(unit, 2)
+		if not r then
+			r, g, b = 1, 1, 1
+		end
+		local color = Hex(r, g, b)
+		return ("%s%s "):format(color, power)
+	else
+		return " "
+	end
+end
+
+oUF_SVUI.Tags.Methods["pvptimer"] = function(unit)
+	if UnitIsPVPFreeForAll(unit) or UnitIsPVP(unit)then
+		local clock = GetPVPTimer()
+		if clock  ~= 301000 and clock  ~= -1 then
+			local dur1 = floor(clock  /  1000  /  60)
+			local dur2 = floor(clock  /  1000 - dur1  *  60)
+			return("%s (%01.f:%02.f)"):format(PVP, dur1, dur2)
+		else
+			return PVP
+		end
+	else
+		return ""
+	end
+end
diff --git a/SVUI_UnitFrames/frames.lua b/SVUI_UnitFrames/frames.lua
new file mode 100644
index 0000000..4b86c96
--- /dev/null
+++ b/SVUI_UnitFrames/frames.lua
@@ -0,0 +1,1082 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--LUA
+local unpack        = unpack;
+local select        = select;
+local pairs         = pairs;
+local type          = type;
+local rawset        = rawset;
+local rawget        = rawget;
+local tostring      = tostring;
+local tonumber      = tonumber;
+local error         = error;
+local next          = next;
+local pcall         = pcall;
+local getmetatable  = getmetatable;
+local setmetatable  = setmetatable;
+local assert        = assert;
+--BLIZZARD
+local _G            = _G;
+local tinsert       = _G.tinsert;
+local tremove       = _G.tremove;
+local twipe         = _G.wipe;
+--STRING
+local string        = string;
+local format        = string.format;
+local sub           = string.sub;
+local upper         = string.upper;
+local match         = string.match;
+local gsub          = string.gsub;
+--MATH
+local math          = math;
+local numMin        = math.min;
+--TABLE
+local table         = table;
+local tsort         = table.sort;
+local tremove       = table.remove;
+
+local SV = _G['SVUI']
+local L = SV.L;
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local MOD = SV.UnitFrames
+
+if(not MOD) then return end
+
+local oUF_SVUI = MOD.oUF
+assert(oUF_SVUI, "SVUI UnitFrames: unable to locate oUF.")
+--[[
+##########################################################
+LOCALIZED GLOBALS
+##########################################################
+]]--
+local UIParent              = _G.UIParent;
+local GameTooltip           = _G.GameTooltip;
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+local IsAddOnLoaded         = _G.IsAddOnLoaded;
+local IsInInstance          = _G.IsInInstance;
+
+local UnitIsUnit            = _G.UnitIsUnit;
+local UnitReaction          = _G.UnitReaction;
+local UnitIsPlayer          = _G.UnitIsPlayer;
+local UnitClass             = _G.UnitClass;
+local UnitFrame_OnEnter     = _G.UnitFrame_OnEnter;
+local UnitFrame_OnLeave     = _G.UnitFrame_OnLeave;
+
+local RegisterStateDriver       = _G.RegisterStateDriver;
+local UnregisterStateDriver     = _G.UnregisterStateDriver;
+local RegisterAttributeDriver   = _G.RegisterAttributeDriver;
+local UnregisterAttributeDriver = _G.UnregisterAttributeDriver;
+
+local RegisterUnitWatch          = _G.RegisterUnitWatch;
+local UnregisterUnitWatch        = _G.UnregisterUnitWatch;
+local FOCUSTARGET                = _G.FOCUSTARGET;
+local CLEAR_FOCUS                = _G.CLEAR_FOCUS;
+local FACTION_BAR_COLORS         = _G.FACTION_BAR_COLORS;
+local RAID_CLASS_COLORS          = _G.RAID_CLASS_COLORS;
+local CUSTOM_CLASS_COLORS        = _G.CUSTOM_CLASS_COLORS
+local LOCALIZED_CLASS_NAMES_MALE = _G.LOCALIZED_CLASS_NAMES_MALE;
+--[[
+##########################################################
+LOCAL DATA
+##########################################################
+]]--
+local CONSTRUCTORS = {}
+local lastArenaFrame, lastBossFrame
+--[[
+##########################################################
+ALL UNIT HELPERS
+##########################################################
+]]--
+local unitLayoutPostSizeFunc = function(self, width, height)
+  SV.db.UnitFrames[self.___key].width = width;
+  SV.db.UnitFrames[self.___key].height = height;
+  self:Update()
+end
+
+local enemyLayoutPostSizeFunc = function(self, width, height)
+  SV.db.UnitFrames[self.___key].width = width;
+  SV.db.UnitFrames[self.___key].height = height;
+  for i=1, self.___maxCount do
+    local frame = MOD.Units[self.___key .. i];
+    if(frame) then
+      frame:Update()
+    end
+  end
+end
+
+local UpdateTargetGlow = function(self)
+    if not self.unit then return end
+    local unit = self.unit;
+    if(UnitIsUnit(unit, "target")) then
+        self.TargetGlow:Show()
+        local reaction = UnitReaction(unit, "player")
+        if(reaction) then
+            local colors = FACTION_BAR_COLORS[reaction]
+            self.TargetGlow:SetBackdropBorderColor(colors.r, colors.g, colors.b)
+        else
+            self.TargetGlow:SetBackdropBorderColor(0.2, 1, 0.3)
+        end
+    else
+        self.TargetGlow:Hide()
+    end
+end
+
+local AllowElement = function(self)
+    if InCombatLockdown() then return; end
+    -- print('Allowed')
+    -- print(self.unit)
+    -- print(self.isForced)
+    if not self.isForced then
+        self.sourceElement = self.unit;
+        self.unit = "player"
+        self.isForced = true;
+        self.sourceEvent = self:GetScript("OnUpdate")
+    end
+
+    self:SetScript("OnUpdate", nil)
+    self.forceShowAuras = true;
+    UnregisterUnitWatch(self)
+    RegisterUnitWatch(self, true)
+
+    self:Show()
+    if self:IsVisible() and self.Update then
+        self:Update()
+    end
+end
+
+local RestrictElement = function(self)
+    if(InCombatLockdown() or (not self.isForced)) then return; end
+    -- print('Restricted')
+    -- print(self.unit)
+    -- print(self.isForced)
+    self.forceShowAuras = nil
+    self.isForced = nil
+
+    UnregisterUnitWatch(self)
+    RegisterUnitWatch(self)
+
+    if self.sourceEvent then
+        self:SetScript("OnUpdate", self.sourceEvent)
+        self.sourceEvent = nil
+    end
+
+    self.unit = self.sourceElement or self.unit;
+
+    if self:IsVisible() and self.Update then
+        self:Update()
+    end
+end
+--[[
+##########################################################
+PLAYER
+##########################################################
+]]--
+local UpdatePlayerFrame = function(self)
+    local db = SV.db.UnitFrames["player"]
+    local UNIT_WIDTH = db.width;
+    local UNIT_HEIGHT = db.height;
+    local USE_CLASSBAR = db.classbar.enable;
+    local classBarHeight = db.classbar.height;
+    local classBarWidth = db.width * 0.4;
+    local iconDB = db.icons
+    self:RegisterForClicks(SV.db.UnitFrames.fastClickTarget and "AnyDown" or "AnyUp")
+
+    MOD.RefreshUnitMedia(self, "player")
+
+    self.colors = oUF_SVUI.colors;
+    self:SetSize(UNIT_WIDTH, UNIT_HEIGHT)
+    self.Grip:SetSize(self:GetSize())
+    local lossSize = UNIT_WIDTH * 0.6
+    self.LossOfControl.stunned:SetSize(lossSize, lossSize)
+
+    MOD:RefreshUnitLayout(self, "player")
+
+    do
+        local resting = self.Resting;
+        if resting then
+            if iconDB and iconDB.restIcon and iconDB.restIcon.enable then
+                local size = iconDB.restIcon.size;
+                resting:ClearAllPoints()
+                resting:SetSize(size, size)
+                SV:SetReversePoint(resting, iconDB.restIcon.attachTo, self, iconDB.restIcon.xOffset, iconDB.restIcon.yOffset)
+                if not self:IsElementEnabled("Resting")then
+                    self:EnableElement("Resting")
+                end
+            elseif self:IsElementEnabled("Resting")then
+                self:DisableElement("Resting")
+                resting:Hide()
+            end
+        end
+    end
+    do
+        local combat = self.Combat;
+        if combat then
+            if iconDB and iconDB.combatIcon and iconDB.combatIcon.enable then
+                local size = iconDB.combatIcon.size;
+                combat:ClearAllPoints()
+                combat:SetSize(size, size)
+                SV:SetReversePoint(combat, iconDB.combatIcon.attachTo, self, iconDB.combatIcon.xOffset, iconDB.combatIcon.yOffset)
+                if not self:IsElementEnabled("Combat")then
+                    self:EnableElement("Combat")
+                end
+            elseif self:IsElementEnabled("Combat")then
+                self:DisableElement("Combat")
+                combat:Hide()
+            end
+        end
+    end
+    do
+        local aggro = self.Aggro;
+        if aggro then
+            if iconDB and iconDB.aggroIcon then
+                aggro.isEnabled = iconDB.aggroIcon.enable;
+                if(iconDB.aggroIcon.enable) then
+                local size = iconDB.aggroIcon.size;
+                    aggro:ClearAllPoints()
+                    aggro:SetSize(size, size)
+                    SV:SetReversePoint(aggro, iconDB.aggroIcon.attachTo, self, iconDB.aggroIcon.xOffset, iconDB.aggroIcon.yOffset)
+                end
+            end
+        end
+    end
+    do
+        local pvp = self.PvPText;
+        local point = db.pvp.position;
+        pvp:ClearAllPoints()
+        pvp:SetPoint(db.pvp.position, self, db.pvp.position)
+        self:Tag(pvp, db.pvp.tags)
+    end
+    do
+        if(self.ClassBar) then
+            if USE_CLASSBAR and self.RefreshClassBar then
+                self.RefreshClassBar(self)
+            end
+            local classBar = self[self.ClassBar];
+            if USE_CLASSBAR then
+                if(not self:IsElementEnabled(self.ClassBar)) then
+                    self:EnableElement(self.ClassBar)
+                end
+                classBar:Show()
+            else
+                if(self:IsElementEnabled(self.ClassBar)) then
+                    self:DisableElement(self.ClassBar)
+                end
+                classBar:Hide()
+            end
+        end
+    end
+
+    do
+        self.CombatFade = db.combatfade;
+        if(self.CombatFade and (not self:IsElementEnabled("CombatFade"))) then
+            self:EnableElement("CombatFade")
+        elseif(self:IsElementEnabled("CombatFade") and (not self.CombatFade)) then
+            self:DisableElement("CombatFade")
+        end
+    end
+
+    self:UpdateAllElements()
+end
+
+CONSTRUCTORS["player"] = function(self, unit)
+    local key = "player"
+    self.unit = unit
+    self.___key = key
+
+    self:SetScript("OnEnter", UnitFrame_OnEnter)
+    self:SetScript("OnLeave", UnitFrame_OnLeave)
+    self:SetFrameLevel(2)
+
+    MOD:SetActionPanel(self, key)
+    self.Health = MOD:CreateHealthBar(self, true)
+    self.Health.frequentUpdates = true
+    self.Power = MOD:CreatePowerBar(self)
+    self.Power.frequentUpdates = true
+    MOD:CreatePortrait(self, false, true)
+    MOD:CreateAuraFrames(self, key, true)
+    self.Castbar = MOD:CreateCastbar(self, false, L["Player Castbar"], true, true, false, true)
+    MOD:CreateExperienceRepBar(self)
+    self.ClassBar = MOD:CreateClassBar(self)
+    self.RaidIcon = MOD:CreateRaidIcon(self)
+    MOD:CreatePlayerIndicators(self)
+    self.PvPText = self.TextGrip:CreateFontString(nil,'OVERLAY')
+    self.PvPText:SetFontObject(SpellFont_Small)
+    self.Afflicted = MOD:CreateAfflicted(self)
+    self.HealPrediction = MOD:CreateHealPrediction(self, true)
+    self.ResolveBar = MOD:CreateResolveBar(self)
+    self.CombatFade = false;
+    self:SetPoint("BOTTOMRIGHT", SV.Screen, "BOTTOM", -80, 182)
+    SV:NewAnchor(self, L["Player Frame"])
+    SV:SetAnchorResizing(self, unitLayoutPostSizeFunc, 10, 500)
+
+    self.MediaUpdate = MOD.RefreshUnitMedia
+    self.Update = UpdatePlayerFrame
+
+    return self
+end
+--[[
+##########################################################
+TARGET
+##########################################################
+]]--
+local UpdateTargetFrame = function(self)
+    local db = SV.db.UnitFrames["target"]
+    local UNIT_WIDTH = db.width;
+    local UNIT_HEIGHT = db.height;
+    local USE_COMBOBAR = db.combobar.enable;
+    local comboBarHeight = db.combobar.height;
+    self:RegisterForClicks(SV.db.UnitFrames.fastClickTarget and "AnyDown" or "AnyUp")
+
+    MOD.RefreshUnitMedia(self, "target")
+    self.colors = oUF_SVUI.colors;
+    self:SetSize(UNIT_WIDTH, UNIT_HEIGHT)
+    self.Grip:SetSize(self:GetSize())
+    if not self:IsElementEnabled("ActionPanel")then
+        self:EnableElement("ActionPanel")
+    end
+
+    if not self:IsElementEnabled("Friendship")then
+        self:EnableElement("Friendship")
+    end
+    MOD:RefreshUnitLayout(self, "target")
+
+    if(not IsAddOnLoaded("Clique")) then
+        if db.middleClickFocus then
+            self:SetAttribute("type3", "focus")
+        elseif self:GetAttribute("type3") == "focus"then
+            self:SetAttribute("type3", nil)
+        end
+    end
+
+    self:UpdateAllElements()
+end
+
+CONSTRUCTORS["target"] = function(self, unit)
+    local key = "target"
+    self.unit = unit
+    self.___key = key
+
+    self:SetScript("OnEnter", UnitFrame_OnEnter)
+    self:SetScript("OnLeave", UnitFrame_OnLeave)
+    self:SetFrameLevel(2)
+
+    MOD:SetActionPanel(self, key)
+
+    self.Health = MOD:CreateHealthBar(self, true)
+    self.Health.frequentUpdates = true
+    self.HealPrediction = MOD:CreateHealPrediction(self, true)
+
+    self.Power = MOD:CreatePowerBar(self)
+    self.Power.frequentUpdates = true
+
+    MOD:CreatePortrait(self)
+
+    self.Castbar = MOD:CreateCastbar(self, true, L["Target Castbar"], true, false, false, true)
+
+    MOD:CreateAuraFrames(self, key, true)
+    self.Afflicted = MOD:CreateAfflicted(self)
+    self.RaidIcon = MOD:CreateRaidIcon(self)
+
+    local xray = CreateFrame("Button", "SVUI_XRayFocus", self, "SecureActionButtonTemplate")
+    xray:SetPoint("TOPRIGHT", 12, 12)
+    xray:EnableMouse(true)
+    xray:RegisterForClicks("AnyUp")
+    xray:SetAttribute("type", "macro")
+    xray:SetAttribute("macrotext", "/focus")
+    xray:SetSize(64,64)
+    xray:SetFrameStrata("MEDIUM")
+    xray.icon = xray:CreateTexture(nil,"ARTWORK")
+    xray.icon:SetTexture([[Interface\Addons\SVUI_!Core\assets\textures\Doodads\UNIT-XRAY]])
+    xray.icon:SetAllPoints(xray)
+    xray.icon:SetAlpha(0)
+    xray:SetScript("OnLeave", function(self) GameTooltip:Hide() self.icon:SetAlpha(0) end)
+    xray:SetScript("OnEnter", function(self)
+        self.icon:SetAlpha(1)
+        local anchor1, anchor2 = SV:GetScreenXY(self)
+        GameTooltip:SetOwner(self, "ANCHOR_NONE")
+        GameTooltip:SetPoint(anchor1, self, anchor2)
+        GameTooltip:SetText(FOCUSTARGET)
+    end)
+
+    self.XRay = xray
+
+    self.Friendship = MOD:CreateFriendshipBar(self)
+    self.Range = { insideAlpha = 1, outsideAlpha = 1 }
+
+    self:SetPoint("BOTTOMLEFT", SV.Screen, "BOTTOM", 80, 182)
+    SV:NewAnchor(self, L["Target Frame"])
+    SV:SetAnchorResizing(self, unitLayoutPostSizeFunc, 10, 500)
+
+    self.MediaUpdate = MOD.RefreshUnitMedia
+    self.Update = UpdateTargetFrame
+    return self
+end
+--[[
+##########################################################
+TARGET OF TARGET
+##########################################################
+]]--
+local UpdateTargetTargetFrame = function(self)
+    local db = SV.db.UnitFrames["targettarget"]
+    local UNIT_WIDTH = db.width
+    local UNIT_HEIGHT = db.height
+    self:RegisterForClicks(SV.db.UnitFrames.fastClickTarget and "AnyDown" or "AnyUp")
+    MOD.RefreshUnitMedia(self, "targettarget")
+    self.colors = oUF_SVUI.colors;
+    self:SetSize(UNIT_WIDTH, UNIT_HEIGHT)
+    self.Grip:SetSize(self:GetSize())
+    MOD:RefreshUnitLayout(self, "targettarget")
+    self:UpdateAllElements()
+end
+
+CONSTRUCTORS["targettarget"] = function(self, unit)
+    local key = "targettarget"
+    self.unit = unit
+    self.___key = key
+
+    self:SetScript("OnEnter", UnitFrame_OnEnter)
+    self:SetScript("OnLeave", UnitFrame_OnLeave)
+    self:SetFrameLevel(2)
+
+    MOD:SetActionPanel(self, key)
+    self.Health = MOD:CreateHealthBar(self, true)
+    self.Power = MOD:CreatePowerBar(self)
+    MOD:CreatePortrait(self, true)
+    MOD:CreateAuraFrames(self, key)
+    self.RaidIcon = MOD:CreateRaidIcon(self)
+    self.Range = { insideAlpha = 1, outsideAlpha = 1 }
+    self:SetPoint("LEFT", SVUI_Target, "RIGHT", 4, 0)
+    SV:NewAnchor(self, L["TargetTarget Frame"])
+    SV:SetAnchorResizing(self, unitLayoutPostSizeFunc, 10, 500)
+
+    self.MediaUpdate = MOD.RefreshUnitMedia
+    self.Update = UpdateTargetTargetFrame
+    return self
+end
+--[[
+##########################################################
+PET
+##########################################################
+]]--
+local UpdatePetFrame = function(self)
+    local db = SV.db.UnitFrames["pet"]
+    local UNIT_WIDTH = db.width;
+    local UNIT_HEIGHT = db.height;
+    self:RegisterForClicks(SV.db.UnitFrames.fastClickTarget and "AnyDown" or "AnyUp")
+    MOD.RefreshUnitMedia(self, "pet")
+    self.colors = oUF_SVUI.colors;
+    self:SetSize(UNIT_WIDTH, UNIT_HEIGHT)
+    self.Grip:SetSize(self:GetSize())
+    MOD:RefreshUnitLayout(self, "pet")
+    do
+        if SVUI_Player and not InCombatLockdown()then
+            self:SetParent(SVUI_Player)
+        end
+    end
+    self:UpdateAllElements()
+end
+
+CONSTRUCTORS["pet"] = function(self, unit)
+    local key = "pet"
+    self.unit = unit
+    self.___key = key
+    self:SetScript("OnEnter", UnitFrame_OnEnter)
+    self:SetScript("OnLeave", UnitFrame_OnLeave)
+    self:SetFrameLevel(2)
+    MOD:SetActionPanel(self, key)
+    self.Health = MOD:CreateHealthBar(self, true)
+    self.Health.frequentUpdates = true;
+    self.HealPrediction = MOD:CreateHealPrediction(self)
+    self.Power = MOD:CreatePowerBar(self)
+    self.Power.frequentUpdates = false;
+    MOD:CreatePortrait(self, true)
+    self.Castbar = MOD:CreateCastbar(self, false, L["Pet Castbar"], false)
+    MOD:CreateAuraFrames(self, key)
+    self.AuraWatch = MOD:CreateAuraWatch(self, key)
+    self.RaidIcon = MOD:CreateRaidIcon(self)
+    self.Range = { insideAlpha = 1, outsideAlpha = 1 }
+    self:SetPoint("RIGHT", SVUI_Player, "LEFT", -4, 0)
+    SV:NewAnchor(self, L["Pet Frame"])
+    SV:SetAnchorResizing(self, unitLayoutPostSizeFunc, 10, 500)
+    self.MediaUpdate = MOD.RefreshUnitMedia
+    self.Update = UpdatePetFrame
+    return self
+end
+--[[
+##########################################################
+TARGET OF PET
+##########################################################
+]]--
+local UpdatePetTargetFrame = function(self)
+    local db = SV.db.UnitFrames["pettarget"]
+    local UNIT_WIDTH = db.width;
+    local UNIT_HEIGHT = db.height;
+    self:RegisterForClicks(SV.db.UnitFrames.fastClickTarget and "AnyDown" or "AnyUp")
+    MOD.RefreshUnitMedia(self, "pettarget")
+    self.colors = oUF_SVUI.colors;
+    self:SetSize(UNIT_WIDTH, UNIT_HEIGHT)
+    self.Grip:SetSize(self:GetSize())
+    MOD:RefreshUnitLayout(self, "pettarget")
+    do
+        if SVUI_Pet and not InCombatLockdown()then
+            self:SetParent(SVUI_Pet)
+        end
+    end
+    self:UpdateAllElements()
+end
+
+CONSTRUCTORS["pettarget"] = function(self, unit)
+    local key = "pettarget"
+    self.unit = unit
+    self.___key = key
+
+    self:SetScript("OnEnter", UnitFrame_OnEnter)
+    self:SetScript("OnLeave", UnitFrame_OnLeave)
+    self:SetFrameLevel(2)
+
+    MOD:SetActionPanel(self, key)
+    self.Health = MOD:CreateHealthBar(self, true)
+    self.Power = MOD:CreatePowerBar(self)
+    MOD:CreateAuraFrames(self, key)
+    self.Range = { insideAlpha = 1, outsideAlpha = 1 }
+    self:SetPoint("BOTTOM", SVUI_Pet, "TOP", 0, 7)
+    self.snapOffset = -7
+    SV:NewAnchor(self, L["PetTarget Frame"])
+    SV:SetAnchorResizing(self, unitLayoutPostSizeFunc, 10, 500)
+
+    self.MediaUpdate = MOD.RefreshUnitMedia
+    self.Update = UpdatePetTargetFrame
+    return self
+end
+--[[
+##########################################################
+FOCUS
+##########################################################
+]]--
+local UpdateFocusFrame = function(self)
+    local db = SV.db.UnitFrames["focus"]
+    local UNIT_WIDTH = db.width;
+    local UNIT_HEIGHT = db.height;
+    self:RegisterForClicks(SV.db.UnitFrames.fastClickTarget and "AnyDown" or "AnyUp")
+    MOD.RefreshUnitMedia(self, "focus")
+    self.colors = oUF_SVUI.colors;
+    self:SetSize(UNIT_WIDTH, UNIT_HEIGHT)
+    self.Grip:SetSize(self:GetSize())
+    MOD:RefreshUnitLayout(self, "focus")
+
+    self:UpdateAllElements()
+end
+
+CONSTRUCTORS["focus"] = function(self, unit)
+    local key = "focus"
+    self.unit = unit
+    self.___key = key
+
+    self:SetScript("OnEnter", UnitFrame_OnEnter)
+    self:SetScript("OnLeave", UnitFrame_OnLeave)
+    self:SetFrameLevel(2)
+
+    MOD:SetActionPanel(self, key)
+
+    self.Health = MOD:CreateHealthBar(self, true)
+    self.Health.frequentUpdates = true
+
+    self.HealPrediction = MOD:CreateHealPrediction(self, true)
+    self.Power = MOD:CreatePowerBar(self)
+
+    self.Castbar = MOD:CreateCastbar(self, false, L["Focus Castbar"])
+    self.Castbar.SafeZone = nil
+
+    self.Castbar.LatencyTexture:Hide()
+    MOD:CreateAuraFrames(self, key, true)
+    self.AuraWatch = MOD:CreateAuraWatch(self, key)
+    self.RaidIcon = MOD:CreateRaidIcon(self)
+    self.Range = { insideAlpha = 1, outsideAlpha = 1 }
+
+    local xray = CreateFrame("Button", "SVUI_XRayFocusClear", self, "SecureActionButtonTemplate")
+    xray:SetPoint("RIGHT", 20, 0)
+    xray:EnableMouse(true)
+    xray:RegisterForClicks("AnyUp")
+    xray:SetAttribute("type", "macro")
+    xray:SetAttribute("macrotext", "/clearfocus")
+    xray:SetSize(50,50)
+    xray:SetFrameStrata("MEDIUM")
+    xray.icon = xray:CreateTexture(nil,"ARTWORK")
+    xray.icon:SetTexture([[Interface\Addons\SVUI_!Core\assets\textures\Doodads\UNIT-XRAY-CLOSE]])
+    xray.icon:SetAllPoints(xray)
+    xray.icon:SetAlpha(0)
+    xray.icon:SetVertexColor(1,0.2,0.1)
+    xray:SetScript("OnLeave", function(self) GameTooltip:Hide() self.icon:SetAlpha(0) end)
+    xray:SetScript("OnEnter",function(self)
+        self.icon:SetAlpha(1)
+        local anchor1, anchor2 = SV:GetScreenXY(self)
+        GameTooltip:SetOwner(self, "ANCHOR_NONE")
+        GameTooltip:SetPoint(anchor1, self, anchor2)
+        GameTooltip:SetText(CLEAR_FOCUS)
+    end)
+
+    self.XRay = xray
+
+    self:SetPoint("BOTTOMRIGHT", SVUI_Target, "TOPRIGHT", 0, 220)
+    SV:NewAnchor(self, L["Focus Frame"])
+    SV:SetAnchorResizing(self, unitLayoutPostSizeFunc, 10, 500)
+
+    self.MediaUpdate = MOD.RefreshUnitMedia
+    self.Update = UpdateFocusFrame
+    return self
+end
+--[[
+##########################################################
+TARGET OF FOCUS
+##########################################################
+]]--
+local UpdateFocusTargetFrame = function(self)
+    local db = SV.db.UnitFrames["focustarget"]
+    local UNIT_WIDTH = db.width;
+    local UNIT_HEIGHT = db.height;
+    self:RegisterForClicks(SV.db.UnitFrames.fastClickTarget and "AnyDown" or "AnyUp")
+    MOD.RefreshUnitMedia(self, "focustarget")
+    self.colors = oUF_SVUI.colors;
+    self:SetSize(UNIT_WIDTH, UNIT_HEIGHT)
+    self.Grip:SetSize(self:GetSize())
+    MOD:RefreshUnitLayout(self, "focustarget")
+    self:UpdateAllElements()
+end
+
+CONSTRUCTORS["focustarget"] = function(self, unit)
+    local key = "focustarget"
+    self.unit = unit
+    self.___key = key
+
+    self:SetScript("OnEnter", UnitFrame_OnEnter)
+    self:SetScript("OnLeave", UnitFrame_OnLeave)
+    self:SetFrameLevel(2)
+
+    MOD:SetActionPanel(self, key)
+    self.Health = MOD:CreateHealthBar(self, true)
+    self.Power = MOD:CreatePowerBar(self)
+    MOD:CreateAuraFrames(self, key)
+    self.RaidIcon = MOD:CreateRaidIcon(self)
+    self.Range = { insideAlpha = 1, outsideAlpha = 1 }
+    self:SetPoint("LEFT", SVUI_Focus, "RIGHT", 12, 0)
+    self.snapOffset = -7
+    SV:NewAnchor(self, L["FocusTarget Frame"])
+    SV:SetAnchorResizing(self, unitLayoutPostSizeFunc, 10, 500)
+
+    self.MediaUpdate = MOD.RefreshUnitMedia
+    self.Update = UpdateFocusTargetFrame
+    return self
+end
+--[[
+##########################################################
+BOSS
+##########################################################
+]]--
+local UpdateBossFrame = function(self)
+    local db = SV.db.UnitFrames["boss"]
+    local INDEX = self:GetID() or 1;
+    local holder = _G['SVUI_Boss1_MOVE']
+    local UNIT_WIDTH = db.width;
+    local UNIT_HEIGHT = db.height;
+
+    MOD.RefreshUnitMedia(self, "boss")
+
+    self.colors = oUF_SVUI.colors;
+    self:SetSize(UNIT_WIDTH, UNIT_HEIGHT)
+    self.Grip:SetSize(self:GetSize())
+
+    if(holder and (tonumber(INDEX) > 1) and (not self.Grip:HasMoved())) then
+      self.Grip:ClearAllPoints()
+      local yOffset = (UNIT_HEIGHT + 12 + db.castbar.height) * (INDEX - 1)
+      if db.showBy == "UP" then
+          self.Grip:SetPoint("BOTTOMRIGHT", holder, "BOTTOMRIGHT", 0, yOffset)
+      else
+          self.Grip:SetPoint("TOPRIGHT", holder, "TOPRIGHT", 0, -yOffset)
+      end
+    end
+
+    self:RegisterForClicks(SV.db.UnitFrames.fastClickTarget and "AnyDown" or "AnyUp")
+    MOD:RefreshUnitLayout(self, "boss")
+    self:UpdateAllElements()
+end
+
+CONSTRUCTORS["boss"] = function(self, unit)
+    local key = "boss"
+    local selfID = unit:match('boss(%d)')
+    self.unit = unit
+    self.___key = key;
+    self:SetID(selfID)
+
+    self:SetScript("OnEnter", UnitFrame_OnEnter)
+    self:SetScript("OnLeave", UnitFrame_OnLeave)
+    self:SetFrameLevel(2)
+
+    MOD:SetActionPanel(self, key)
+    self.Health = MOD:CreateHealthBar(self, true)
+    self.Health.frequentUpdates = true
+    self.Power = MOD:CreatePowerBar(self)
+    MOD:CreatePortrait(self)
+    MOD:CreateAuraFrames(self, key)
+    self.Afflicted = MOD:CreateAfflicted(self)
+    self.Castbar = MOD:CreateCastbar(self, true, nil, true, nil, true)
+    self.RaidIcon = MOD:CreateRaidIcon(self)
+    --self.AltPowerBar = MOD:CreateAltPowerBar(self)
+
+    self.Restrict = RestrictElement
+    self.Allow = AllowElement
+
+    self.Range = { insideAlpha = 1, outsideAlpha = 1 }
+    self:SetAttribute("type2", "focus")
+
+    local db = SV.db.UnitFrames["boss"]
+    local UNIT_WIDTH = db.width;
+    local UNIT_HEIGHT = db.height;
+    local yOffset = 12 + db.castbar.height
+    self:SetSize(UNIT_WIDTH, UNIT_HEIGHT)
+
+    if(db.showBy == "UP") then
+      if(not lastBossFrame) then
+          self:SetPoint("RIGHT", SV.Screen, "RIGHT", -100, -190)
+      else
+          self:SetPoint("BOTTOMRIGHT", lastBossFrame, "TOPRIGHT", 0, yOffset)
+      end
+    else
+      if(not lastBossFrame) then
+          self:SetPoint("RIGHT", SV.Screen, "RIGHT", -85, 190)
+      else
+          self:SetPoint("TOPRIGHT", lastBossFrame, "BOTTOMRIGHT", 0, -yOffset)
+      end
+    end
+    SV:NewAnchor(self, L["Boss Frame "..selfID])
+    SV:SetAnchorResizing(self, enemyLayoutPostSizeFunc, 10, 500)
+
+    self.MediaUpdate = MOD.RefreshUnitMedia
+    self.Update = UpdateBossFrame
+    lastBossFrame = self
+    return self
+end
+--[[
+##########################################################
+ARENA
+##########################################################
+]]--
+local UpdateArenaFrame = function(self)
+    local db = SV.db.UnitFrames["arena"]
+    local INDEX = self:GetID() or 1;
+    local holder = _G['SVUI_Arena1_MOVE'];
+    local UNIT_WIDTH = db.width;
+    local UNIT_HEIGHT = db.height
+
+    MOD.RefreshUnitMedia(self, "arena")
+
+    self.colors = oUF_SVUI.colors;
+    self:SetSize(UNIT_WIDTH, UNIT_HEIGHT)
+    self.Grip:SetSize(self:GetSize())
+    self:RegisterForClicks(SV.db.UnitFrames.fastClickTarget and "AnyDown" or "AnyUp")
+
+    if(holder and (tonumber(INDEX) > 1) and (not self.Grip:HasMoved())) then
+      self.Grip:ClearAllPoints()
+      local yOffset = (UNIT_HEIGHT + 12 + db.castbar.height) * (INDEX - 1)
+      if(db.showBy == "UP") then
+          self.Grip:SetPoint("BOTTOMRIGHT", holder, "BOTTOMRIGHT", 0, yOffset)
+      else
+          self.Grip:SetPoint("TOPRIGHT", holder, "TOPRIGHT", 0, -yOffset)
+      end
+    end
+
+    MOD:RefreshUnitLayout(self, "arena")
+
+    if(self.Gladiator) then
+        local pvp = self.Gladiator
+        local trinket = pvp.Trinket
+        local badge = pvp.Badge
+        local trinketsize = db.pvp.trinketSize
+        local specsize = db.pvp.specSize
+
+        local leftAnchor = self
+        local rightAnchor = self
+
+        local trinketSize = db.pvp.trinketSize
+        local specSize = db.pvp.specSize
+        trinket:SetSize(trinketSize, trinketSize)
+        trinket:ClearAllPoints()
+        if(db.pvp.trinketPosition == "RIGHT") then
+            trinket:SetPoint("LEFT", rightAnchor, "RIGHT", db.pvp.trinketX, db.pvp.trinketY)
+            rightAnchor = trinket
+        else
+            trinket:SetPoint("RIGHT", leftAnchor, "LEFT", db.pvp.trinketX, db.pvp.trinketY)
+            leftAnchor = trinket
+        end
+
+        badge:SetSize(specSize, specSize)
+        badge:ClearAllPoints()
+        if(db.pvp.specPosition == "RIGHT") then
+            badge:SetPoint("LEFT", rightAnchor, "RIGHT", db.pvp.specX, db.pvp.specY)
+            rightAnchor = badge
+        else
+            badge:SetPoint("RIGHT", leftAnchor, "LEFT", db.pvp.specX, db.pvp.specY)
+            leftAnchor = badge
+        end
+
+        pvp:ClearAllPoints()
+        pvp:SetPoint("TOPLEFT", leftAnchor, "TOPLEFT", 0, 0)
+        pvp:SetPoint("BOTTOMRIGHT", rightAnchor, "BOTTOMRIGHT", 0, 0)
+
+        if(db.pvp.enable and (not self:IsElementEnabled("Gladiator"))) then
+            self:EnableElement("Gladiator")
+            pvp:Show()
+        elseif((not db.pvp.enable) and self:IsElementEnabled("Gladiator")) then
+            self:DisableElement("Gladiator")
+            pvp:Hide()
+        end
+    end
+
+    self:UpdateAllElements()
+end
+
+CONSTRUCTORS["arena"] = function(self, unit)
+    local key = "arena"
+    local selfID = unit:match('arena(%d)')
+    self.unit = unit
+    self.___key = key
+    self:SetID(selfID)
+
+    self:SetScript("OnEnter", UnitFrame_OnEnter)
+    self:SetScript("OnLeave", UnitFrame_OnLeave)
+    self:SetFrameLevel(2)
+
+    local selfName = self:GetName()
+    local prepName = selfName.."PrepFrame";
+
+
+    MOD:SetActionPanel(self, key)
+    self.Health = MOD:CreateHealthBar(self, true)
+    self.Power = MOD:CreatePowerBar(self)
+    MOD:CreatePortrait(self)
+    MOD:CreateAuraFrames(self, key)
+    self.Castbar = MOD:CreateCastbar(self, true, nil, true, nil, true)
+    self.Gladiator = MOD:CreateGladiator(self)
+    self.Range = { insideAlpha = 1, outsideAlpha = 1 }
+    self:SetAttribute("type2", "focus")
+
+    self.Restrict = RestrictElement
+    self.Allow = AllowElement
+
+    if(not _G[prepName]) then
+        local prep = CreateFrame("Frame", prepName, UIParent)
+        prep:SetFrameStrata("MEDIUM")
+        prep:SetAllPoints(self)
+        prep:SetID(selfID)
+        prep:SetStyle("Frame", "Bar", true, 3, 1, 1)
+
+        local health = CreateFrame("StatusBar", nil, prep)
+        health:SetAllPoints(prep)
+        health:SetStatusBarTexture(SV.media.statusbar.default)
+        prep.Health = health
+
+        local icon = CreateFrame("Frame", nil, prep)
+        icon:SetSize(45,45)
+        icon:SetPoint("LEFT", prep, "RIGHT", 2, 0)
+        icon:SetBackdrop({
+            bgFile = [[Interface\BUTTONS\WHITE8X8]],
+            tile = false,
+            tileSize = 0,
+            edgeFile = [[Interface\BUTTONS\WHITE8X8]],
+            edgeSize = 2,
+            insets = {
+                left = 0,
+                right = 0,
+                top = 0,
+                bottom = 0
+            }
+        })
+        icon:SetBackdropColor(0, 0, 0, 0)
+        icon:SetBackdropBorderColor(0, 0, 0)
+        icon.Icon = icon:CreateTexture(nil, "OVERLAY")
+        icon.Icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+        icon.Icon:InsetPoints(icon, 2, 2)
+        prep.SpecIcon = icon
+
+        local text = prep.Health:CreateFontString(nil, "OVERLAY")
+        text:SetFont(SV.media.font.dialog, 16, "OUTLINE")
+        text:SetTextColor(1, 1, 1)
+        text:SetPoint("CENTER")
+        prep.SpecClass = text
+
+        prep:Hide()
+    end
+
+    local db = SV.db.UnitFrames["arena"]
+    local UNIT_WIDTH = db.width;
+    local UNIT_HEIGHT = db.height
+    local yOffset = 12 + db.castbar.height
+    self:SetSize(UNIT_WIDTH, UNIT_HEIGHT)
+
+    if(db.showBy == "UP") then
+      if(not lastArenaFrame) then
+          self:SetPoint("RIGHT", SV.Screen, "RIGHT", -85, -200)
+      else
+          self:SetPoint("BOTTOMRIGHT", lastArenaFrame, "TOPRIGHT", 0, yOffset)
+      end
+    else
+      if(not lastArenaFrame) then
+          self:SetPoint("RIGHT", SV.Screen, "RIGHT", -85, 200)
+      else
+          self:SetPoint("TOPRIGHT", lastArenaFrame, "BOTTOMRIGHT", 0, -yOffset)
+      end
+    end
+
+    SV:NewAnchor(self, L["Arena Frame "..selfID])
+    SV:SetAnchorResizing(self, enemyLayoutPostSizeFunc, 10, 500)
+
+    self.MediaUpdate = MOD.RefreshUnitMedia
+    self.Update = UpdateArenaFrame
+    lastArenaFrame = self
+    return self
+end
+--[[
+##########################################################
+PREP FRAME
+##########################################################
+]]--
+local ArenaPrepHandler = CreateFrame("Frame")
+local ArenaPrepHandler_OnEvent = function(self, event)
+    local prepframe
+    local _, instanceType = IsInInstance()
+    if(not SV.db or not SV.db.UnitFrames or not SV.db.UnitFrames.arena or not SV.db.UnitFrames.arena.enable or instanceType ~= "arena") then return end
+    if event == "PLAYER_LOGIN" then
+        for i = 1, 5 do
+            prepframe = _G["SVUI_Arena"..i.."PrepFrame"]
+            if(prepframe) then
+                prepframe:SetAllPoints(_G["SVUI_Arena"..i])
+            end
+        end
+    elseif event == "ARENA_OPPONENT_UPDATE" then
+        for i = 1, 5 do
+            prepframe = _G["SVUI_Arena"..i.."PrepFrame"]
+            if(prepframe and prepframe:IsShown()) then
+                prepframe:Hide()
+            end
+        end
+    else
+        local numOpps = GetNumArenaOpponentSpecs()
+        if numOpps > 0 then
+            for i = 1, 5 do
+                prepframe = _G["SVUI_Arena"..i.."PrepFrame"]
+                if(prepframe) then
+                    if i <= numOpps then
+                        local s = GetArenaOpponentSpec(i)
+                        local _, spec, classToken, icon = nil, "UNKNOWN", "UNKNOWN", [[INTERFACE\ICONS\INV_MISC_QUESTIONMARK]]
+                        if s and s > 0 then
+                            _, spec, _, icon, _, _, classToken = GetSpecializationInfoByID(s)
+                        end
+                        if classToken and spec then
+                            prepframe.SpecClass:SetText(spec .. " - " .. LOCALIZED_CLASS_NAMES_MALE[classToken])
+                            prepframe.SpecIcon.Icon:SetTexture(icon or [[INTERFACE\ICONS\INV_MISC_QUESTIONMARK]])
+
+                            local color = CUSTOM_CLASS_COLORS[classToken]
+                            if(not SV.db.general.customClassColor) then
+                                color = RAID_CLASS_COLORS[classToken]
+                            end
+                            local textcolor = RAID_CLASS_COLORS[class] or color
+                            if color then
+                                prepframe.Health:SetStatusBarColor(color.r, color.g, color.b)
+                                prepframe.SpecClass:SetTextColor(textcolor.r, textcolor.g, textcolor.b)
+                            else
+                                prepframe.Health:SetStatusBarColor(0.25, 0.25, 0.25)
+                                prepframe.SpecClass:SetTextColor(1, 1, 1)
+                            end
+
+                            prepframe:Show()
+                        end
+                    else
+                        prepframe:Hide()
+                    end
+                end
+            end
+        else
+            for i = 1, 5 do
+                prepframe = _G["SVUI_Arena"..i.."PrepFrame"]
+                if(prepframe and prepframe:IsShown()) then
+                    prepframe:Hide()
+                end
+            end
+        end
+    end
+end
+
+ArenaPrepHandler:RegisterEvent("PLAYER_LOGIN")
+ArenaPrepHandler:RegisterEvent("PLAYER_ENTERING_WORLD")
+ArenaPrepHandler:RegisterEvent("ARENA_OPPONENT_UPDATE")
+ArenaPrepHandler:RegisterEvent("ARENA_PREP_OPPONENT_SPECIALIZATIONS")
+ArenaPrepHandler:SetScript("OnEvent", ArenaPrepHandler_OnEvent)
+--[[
+##########################################################
+LOAD/UPDATE METHOD
+##########################################################
+]]--
+function MOD:SetUnitFrame(key)
+    if(InCombatLockdown()) then self:RegisterEvent("PLAYER_REGEN_ENABLED"); return end
+    local unit = key
+    local realName = unit:gsub("(.)", upper, 1)
+    realName = realName:gsub("t(arget)", "T%1")
+    local styleName = "SVUI_"..realName
+    local frame
+    if not self.Units[unit] then
+        oUF_SVUI:RegisterStyle(styleName, CONSTRUCTORS[key])
+        oUF_SVUI:SetActiveStyle(styleName)
+        frame = oUF_SVUI:Spawn(unit, styleName)
+        self.Units[unit] = frame
+    else
+        frame = self.Units[unit]
+    end
+    if frame:GetParent() ~= SVUI_UnitFrameParent then
+        frame:SetParent(SVUI_UnitFrameParent)
+    end
+    if(SV.db.UnitFrames[key].enable) then
+        frame:Enable()
+        frame:Update()
+    else
+        frame:Disable()
+    end
+end
+
+function MOD:SetEnemyFrame(key, maxCount)
+    if(InCombatLockdown()) then self:RegisterEvent("PLAYER_REGEN_ENABLED"); return end
+    for i = 1, maxCount do
+        local unit = key..i
+        local realName = unit:gsub("(.)", upper, 1)
+        realName = realName:gsub("t(arget)", "T%1")
+        local styleName = "SVUI_"..realName
+        local frame
+        if not self.Units[unit] then
+            oUF_SVUI:RegisterStyle(styleName, CONSTRUCTORS[key])
+            oUF_SVUI:SetActiveStyle(styleName)
+            frame = oUF_SVUI:Spawn(unit, styleName)
+            frame.___maxCount = maxCount;
+            self.Units[unit] = frame
+        else
+            frame = self.Units[unit]
+        end
+        if frame:GetParent() ~= SVUI_UnitFrameParent then
+            frame:SetParent(SVUI_UnitFrameParent)
+        end
+        if(SV.db.UnitFrames[key].enable) then
+            frame:Enable()
+            frame:Update()
+        else
+            frame:Disable()
+        end
+
+        if(frame.isForced) then
+            frame:Allow()
+        end
+    end
+end
+
+-- tinsert(self.__elements, ELEMENT_FUNCTION)
+-- self:RegisterEvent(ELEMENT_EVENT, ELEMENT_FUNCTION)
diff --git a/SVUI_UnitFrames/groups.lua b/SVUI_UnitFrames/groups.lua
new file mode 100644
index 0000000..9ba6120
--- /dev/null
+++ b/SVUI_UnitFrames/groups.lua
@@ -0,0 +1,1211 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+--]]
+--LUA
+local unpack        = unpack;
+local select        = select;
+local pairs         = pairs;
+local type          = type;
+local rawset        = rawset;
+local rawget        = rawget;
+local tostring      = tostring;
+local error         = error;
+local next          = next;
+local pcall         = pcall;
+local getmetatable  = getmetatable;
+local setmetatable  = setmetatable;
+local assert        = assert;
+--BLIZZARD
+local _G            = _G;
+local tinsert       = _G.tinsert;
+local tremove       = _G.tremove;
+local twipe         = _G.wipe;
+--STRING
+local string        = string;
+local format        = string.format;
+local sub           = string.sub;
+local upper         = string.upper;
+local match         = string.match;
+local gsub          = string.gsub;
+--MATH
+local math          = math;
+local numMin        = math.min;
+--TABLE
+local table         = table;
+local tsort         = table.sort;
+local tremove       = table.remove;
+
+local SV = _G['SVUI']
+local L = SV.L;
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local MOD = SV.UnitFrames
+
+if(not MOD) then return end
+
+local oUF_SVUI = MOD.oUF
+assert(oUF_SVUI, "SVUI UnitFrames: unable to locate oUF.")
+--[[
+##########################################################
+LOCALIZED GLOBALS
+##########################################################
+]]--
+local CreateFrame           = _G.CreateFrame;
+local InCombatLockdown      = _G.InCombatLockdown;
+
+local UnitIsUnit            = _G.UnitIsUnit;
+local UnitReaction          = _G.UnitReaction;
+local UnitIsPlayer          = _G.UnitIsPlayer;
+local UnitClass             = _G.UnitClass;
+local UnitFrame_OnEnter     = _G.UnitFrame_OnEnter;
+local UnitFrame_OnLeave     = _G.UnitFrame_OnLeave;
+
+local RegisterStateDriver       = _G.RegisterStateDriver;
+local UnregisterStateDriver     = _G.UnregisterStateDriver;
+local RegisterAttributeDriver   = _G.RegisterAttributeDriver;
+local UnregisterAttributeDriver = _G.UnregisterAttributeDriver;
+
+local RegisterUnitWatch     = _G.RegisterUnitWatch;
+local UnregisterUnitWatch   = _G.UnregisterUnitWatch;
+local FACTION_BAR_COLORS    = _G.FACTION_BAR_COLORS;
+local RAID_CLASS_COLORS     = _G.RAID_CLASS_COLORS
+--[[
+##########################################################
+LOCAL DATA
+##########################################################
+]]--
+local GroupCounts = {
+    ['raid'] = 8,
+    ['raidpet'] = 2,
+    ['party'] = 1
+};
+
+local sortMapping = {
+    ["DOWN_RIGHT"]  = { [1] = "TOP",    [2] = "TOPLEFT",        [3] = "LEFT",   [4] = 1,    [5] = -1,   [6] = false },
+    ["DOWN_LEFT"]   = { [1] = "TOP",    [2] = "TOPRIGHT",       [3] = "RIGHT",  [4] = 1,    [5] = -1,   [6] = false },
+    ["UP_RIGHT"]    = { [1] = "BOTTOM", [2] = "BOTTOMLEFT",     [3] = "LEFT",   [4] = 1,    [5] = 1,    [6] = false },
+    ["UP_LEFT"]     = { [1] = "BOTTOM", [2] = "BOTTOMRIGHT",    [3] = "RIGHT",  [4] = -1,   [5] = 1,    [6] = false },
+    ["RIGHT_DOWN"]  = { [1] = "LEFT",   [2] = "TOPLEFT",        [3] = "TOP",    [4] = 1,    [5] = -1,   [6] = true  },
+    ["RIGHT_UP"]    = { [1] = "LEFT",   [2] = "BOTTOMLEFT",     [3] = "BOTTOM", [4] = 1,    [5] = 1,    [6] = true  },
+    ["LEFT_DOWN"]   = { [1] = "RIGHT",  [2] = "TOPRIGHT",       [3] = "TOP",    [4] = -1,   [5] = -1,   [6] = true  },
+    ["LEFT_UP"]     = { [1] = "RIGHT",  [2] = "BOTTOMRIGHT",    [3] = "BOTTOM", [4] = -1,   [5] = 1,    [6] = true  },
+    ["UP"]          = { [1] = "BOTTOM", [2] = "BOTTOM",         [3] = "BOTTOM", [4] = 1,    [5] = 1,    [6] = false },
+    ["DOWN"]        = { [1] = "TOP",    [2] = "TOP",            [3] = "TOP",    [4] = 1,    [5] = 1,    [6] = false },
+};
+
+local groupTagPoints = {
+    ["DOWN_RIGHT"]  = { [1] = "BOTTOM",     [2] = "TOP",        [3] = 1     },
+    ["DOWN_LEFT"]   = { [1] = "BOTTOM",     [2] = "TOP",        [3] = 1     },
+    ["UP_RIGHT"]    = { [1] = "TOP",        [2] = "BOTTOM",     [3] = -1    },
+    ["UP_LEFT"]     = { [1] = "TOP",        [2] = "BOTTOM",     [3] = -1    },
+    ["RIGHT_DOWN"]  = { [1] = "RIGHT",      [2] = "LEFT",       [3] = -1    },
+    ["RIGHT_UP"]    = { [1] = "RIGHT",      [2] = "LEFT",       [3] = -1    },
+    ["LEFT_DOWN"]   = { [1] = "LEFT",       [2] = "RIGHT",      [3] = 1     },
+    ["LEFT_UP"]     = { [1] = "LEFT",       [2] = "RIGHT",      [3] = 1     },
+    ["UP"]          = { [1] = "TOP",        [2] = "BOTTOM",     [3] = -1    },
+    ["DOWN"]        = { [1] = "BOTTOM",     [2] = "TOP",        [3] = 1     },
+};
+
+local GroupDistributor = {
+    ["CLASS"] = function(x)
+        x:SetAttribute("groupingOrder","DEATHKNIGHT,DRUID,HUNTER,MAGE,PALADIN,PRIEST,SHAMAN,WARLOCK,WARRIOR,MONK,DEMONHUNTER")
+        x:SetAttribute("sortMethod","NAME")
+        x:SetAttribute("groupBy","CLASS")
+    end,
+    ["MTMA"] = function(x)
+        x:SetAttribute("groupingOrder","MAINTANK,MAINASSIST,NONE")
+        x:SetAttribute("sortMethod","NAME")
+        x:SetAttribute("groupBy","ROLE")
+    end,
+    ["ROLE_TDH"] = function(x)
+        x:SetAttribute("groupingOrder","TANK,DAMAGER,HEALER,NONE")
+        x:SetAttribute("sortMethod","NAME")
+        x:SetAttribute("groupBy","ASSIGNEDROLE")
+    end,
+    ["ROLE_HTD"] = function(x)
+        x:SetAttribute("groupingOrder","HEALER,TANK,DAMAGER,NONE")
+        x:SetAttribute("sortMethod","NAME")
+        x:SetAttribute("groupBy","ASSIGNEDROLE")
+    end,
+    ["ROLE_HDT"] = function(x)
+        x:SetAttribute("groupingOrder","HEALER,DAMAGER,TANK,NONE")
+        x:SetAttribute("sortMethod","NAME")
+        x:SetAttribute("groupBy","ASSIGNEDROLE")
+    end,
+    ["ROLE"] = function(x)
+        x:SetAttribute("groupingOrder","TANK,HEALER,DAMAGER,NONE")
+        x:SetAttribute("sortMethod","NAME")
+        x:SetAttribute("groupBy","ASSIGNEDROLE")
+    end,
+    ["NAME"] = function(x)
+        x:SetAttribute("groupingOrder","1,2,3,4,5,6,7,8")
+        x:SetAttribute("sortMethod","NAME")
+        x:SetAttribute("groupBy",nil)
+    end,
+    ["GROUP"] = function(x)
+        x:SetAttribute("groupingOrder","1,2,3,4,5,6,7,8")
+        x:SetAttribute("sortMethod","INDEX")
+        x:SetAttribute("groupBy","GROUP")
+    end,
+    ["PETNAME"] = function(x)
+        x:SetAttribute("groupingOrder","1,2,3,4,5,6,7,8")
+        x:SetAttribute("sortMethod","NAME")
+        x:SetAttribute("groupBy", nil)
+        x:SetAttribute("filterOnPet", true)
+    end
+}
+--[[
+##########################################################
+FRAME HELPERS
+##########################################################
+]]--
+local groupLayoutPostSizeFunc = function(self, width, height)
+    if(not SV.db.UnitFrames[self.___key]) then return end;
+    SV.db.UnitFrames[self.___key].width = width;
+    SV.db.UnitFrames[self.___key].height = height;
+    self:Update()
+end
+
+local DetachSubFrames = function(...)
+    for i = 1, select("#", ...) do
+        local frame = select(i,...)
+        frame:ClearAllPoints()
+    end
+end
+
+local UpdateTargetGlow = function(self)
+    if not self.unit then return end
+    local unit = self.unit;
+    if(UnitIsUnit(unit, "target")) then
+        self.TargetGlow:Show()
+        local reaction = UnitReaction(unit, "player")
+        if(reaction) then
+            local colors = FACTION_BAR_COLORS[reaction]
+            self.TargetGlow:SetBackdropBorderColor(colors.r, colors.g, colors.b)
+        else
+            self.TargetGlow:SetBackdropBorderColor(0.2, 1, 0.3)
+        end
+    else
+        self.TargetGlow:Hide()
+    end
+end
+--[[
+##########################################################
+TEMPLATES AND PROTOTYPES
+##########################################################
+]]--
+local BuildTemplates = {};
+local UpdateTemplates = {};
+--[[
+##########################################################
+COMMON
+##########################################################
+]]--
+local PARTY_VIS1 = "[group:party,nogroup:raid] show;hide";
+local PARTY_VIS2 = "[group:party,nogroup:raid][@raid6,noexists,group:raid] show;hide";
+local RAID_VIS1 = "[group:raid] show;hide";
+local RAID_VIS2 = "[@raid6,exists,group:raid] show;hide";
+local VISIBILITY_OPTIONS = { party = PARTY_VIS1, raid = RAID_VIS1 };
+
+local Update5ManVisibility = function(token)
+    local partyVis = "[group:party,nogroup:raid] show;hide";
+    local raidVis = "[group:raid] show;hide";
+
+    if(SV.db.UnitFrames.party.useFor5man) then
+        VISIBILITY_OPTIONS.party = PARTY_VIS2;
+        VISIBILITY_OPTIONS.raid = RAID_VIS2;
+    else
+        VISIBILITY_OPTIONS.party = PARTY_VIS1;
+        VISIBILITY_OPTIONS.raid = RAID_VIS1;
+    end
+
+    SV.db.UnitFrames.party.visibility = VISIBILITY_OPTIONS.party
+    SV.db.UnitFrames.raid.visibility = VISIBILITY_OPTIONS.raid
+
+    if(token) then
+        return VISIBILITY_OPTIONS[token] or "";
+    end
+end
+
+local AllowElement = function(self)
+    if InCombatLockdown() then return; end
+
+    if not self.isForced then
+        self.sourceElement = self.unit;
+        self.unit = "player"
+        self.isForced = true;
+        self.sourceEvent = self:GetScript("OnUpdate")
+    end
+
+    self:SetScript("OnUpdate", nil)
+    --self.forceShowAuras = true;
+    UnregisterUnitWatch(self)
+    RegisterUnitWatch(self, true)
+
+    self:Show()
+    if self:IsVisible() and self.Update then
+        self:Update()
+    end
+end
+
+local RestrictElement = function(self)
+    if(InCombatLockdown() or (not self.isForced)) then return; end
+
+    self.forceShowAuras = nil
+    self.isForced = nil
+    UnregisterUnitWatch(self)
+    RegisterUnitWatch(self)
+
+    if self.sourceEvent then
+        self:SetScript("OnUpdate", self.sourceEvent)
+        self.sourceEvent = nil
+    end
+
+    self.unit = self.sourceElement or self.unit;
+
+    if self:IsVisible() and self.Update then
+        self:Update()
+    end
+end
+--[[
+##########################################################
+PARTY FRAMES
+##########################################################
+]]--
+local PartyUnitUpdate = function(self)
+    local db = SV.db.UnitFrames.party
+    self.colors = oUF_SVUI.colors;
+    self:RegisterForClicks(SV.db.UnitFrames.fastClickTarget and 'AnyDown' or 'AnyUp')
+    MOD.RefreshUnitMedia(self, "party")
+
+    if self.isChild then
+      local altDB = db.petsGroup;
+      if self == _G[self.originalParent:GetName()..'Target'] then
+          altDB = db.targetsGroup
+      end
+      if not self.originalParent.childList then
+          self.originalParent.childList = {}
+      end
+      self.originalParent.childList[self] = true;
+      if not InCombatLockdown()then
+        if altDB.enable then
+            local UNIT_WIDTH, UNIT_HEIGHT = MOD:GetActiveSize(altDB)
+            self:SetParent(self.originalParent)
+            self:SetSize(UNIT_WIDTH, UNIT_HEIGHT)
+            self:ClearAllPoints()
+            SV:SetReversePoint(self, altDB.anchorPoint, self.originalParent, altDB.xOffset, altDB.yOffset)
+        else
+            self:SetParent(SV.Hidden)
+        end
+      end
+      do
+          local health = self.Health;
+          health.Smooth = nil;
+          health.frequentUpdates = nil;
+          health.colorSmooth = nil;
+          health.colorHealth = nil;
+          health.colorClass = true;
+          health.colorReaction = true;
+          health:ClearAllPoints()
+          health:SetPoint("TOPRIGHT", self, "TOPRIGHT", -1, -1)
+          health:SetPoint("BOTTOMLEFT", self, "BOTTOMLEFT", 1, 1)
+      end
+      do
+          local nametext = self.TextGrip.Name
+          self:Tag(nametext, altDB.tags)
+      end
+    else
+        if not InCombatLockdown() then
+            local UNIT_WIDTH, UNIT_HEIGHT = MOD:GetActiveSize(db, "party")
+            self:SetSize(UNIT_WIDTH, UNIT_HEIGHT)
+        end
+        MOD:RefreshUnitLayout(self, "party")
+    end
+    self:EnableElement('ReadyCheck')
+    self:UpdateAllElements()
+end
+
+UpdateTemplates["party"] = function(self)
+    if(SV.NeedsFrameAudit) then return end
+    local visibility = Update5ManVisibility("party")
+    local db = SV.db.UnitFrames.party
+    local groupFrame = self:GetParent()
+    if not self.isForced then
+        RegisterStateDriver(groupFrame, "visibility", visibility)
+    end
+
+    if not groupFrame.positioned then
+        groupFrame:ClearAllPoints()
+        groupFrame:SetPoint("BOTTOMLEFT", SV.Dock.BottomLeft, "TOPLEFT", 0, 80)
+        SV:NewAnchor(groupFrame, L['Party Frames']);
+        SV:SetAnchorResizing(groupFrame, groupLayoutPostSizeFunc, 10, 500)
+        groupFrame.positioned = true;
+    end
+
+    local index = 1;
+    local attIndex = ("child%d"):format(index)
+    local childFrame = self:GetAttribute(attIndex)
+    local childName, petFrame, targetFrame;
+
+    while childFrame do
+        childFrame:UnitUpdate()
+
+        childName = childFrame:GetName()
+        petFrame = _G[("%sPet"):format(childName)]
+        targetFrame = _G[("%sTarget"):format(childName)]
+
+        if(petFrame) then
+            petFrame:UnitUpdate()
+        end
+
+        if(targetFrame) then
+            targetFrame:UnitUpdate()
+        end
+
+        index = index + 1;
+        attIndex = ("child%d"):format(index)
+        childFrame = self:GetAttribute(attIndex)
+    end
+end
+
+BuildTemplates["party"] = function(self, unit)
+    self.unit = unit
+    self.___key = "party"
+    self:SetScript("OnEnter", UnitFrame_OnEnter)
+    self:SetScript("OnLeave", UnitFrame_OnLeave)
+
+    MOD:SetActionPanel(self, "party")
+    self.Health = MOD:CreateHealthBar(self, true)
+    self.Health.debug = true
+    if self.isChild then
+        self.originalParent = self:GetParent()
+        MOD:CreatePortrait(self, true)
+    else
+        self.Power = MOD:CreatePowerBar(self)
+        self.Power.frequentUpdates = false
+        MOD:CreatePortrait(self, true)
+        MOD:CreateAuraFrames(self, "party")
+        self.AuraWatch = MOD:CreateAuraWatch(self, "party")
+        self.RaidDebuffs = MOD:CreateRaidDebuffs(self)
+        self.Afflicted = MOD:CreateAfflicted(self)
+        self.ResurrectIcon = MOD:CreateResurectionIcon(self)
+        self.LFDRole = MOD:CreateRoleIcon(self)
+        self.RaidRoleFramesAnchor = MOD:CreateRaidRoleFrames(self)
+        self.RaidIcon = MOD:CreateRaidIcon(self)
+        self.ReadyCheck = MOD:CreateReadyCheckIcon(self)
+        self.HealPrediction = MOD:CreateHealPrediction(self)
+        self.TargetGlow = self.Threat
+        tinsert(self.__elements, UpdateTargetGlow)
+        self:RegisterEvent("PLAYER_TARGET_CHANGED", UpdateTargetGlow)
+        self:RegisterEvent("PLAYER_ENTERING_WORLD", UpdateTargetGlow)
+        self:RegisterEvent("GROUP_ROSTER_UPDATE", UpdateTargetGlow)
+    end
+
+    self.Range = { insideAlpha = 1, outsideAlpha = 1 }
+
+    self.Restrict = RestrictElement
+    self.Allow = AllowElement
+    self.UnitUpdate = PartyUnitUpdate
+
+    return self
+end
+--[[
+##########################################################
+RAID FRAMES
+##########################################################
+]]--
+local RaidUnitUpdate = function(self)
+    local token = self.___key
+    local db = SV.db.UnitFrames[token]
+    self.colors = oUF_SVUI.colors;
+    self:RegisterForClicks(SV.db.UnitFrames.fastClickTarget and "AnyDown" or "AnyUp")
+
+    local UNIT_WIDTH, UNIT_HEIGHT = MOD:GetActiveSize(db)
+    if not InCombatLockdown() then
+        self:SetSize(UNIT_WIDTH, UNIT_HEIGHT)
+    end
+
+    MOD.RefreshUnitMedia(self, token)
+    MOD:RefreshUnitLayout(self, token)
+
+    if(token ~= "raidpet") then
+        self:EnableElement("ReadyCheck")
+    end
+    self:UpdateAllElements()
+end
+
+UpdateTemplates["raid"] = function(self)
+    if(SV.NeedsFrameAudit) then return end
+    local visibility = Update5ManVisibility("raid")
+    local db = SV.db.UnitFrames.raid
+    local groupFrame = self:GetParent()
+    if not self.isForced then
+        RegisterStateDriver(groupFrame, "visibility", visibility)
+    end
+
+    if not groupFrame.positioned then
+        groupFrame:ClearAllPoints()
+        groupFrame:SetPoint("BOTTOMLEFT", SV.Dock.BottomLeft, "TOPLEFT", 0, 80)
+        SV:NewAnchor(groupFrame, "Raid Frames")
+        SV:SetAnchorResizing(groupFrame, groupLayoutPostSizeFunc, 10, 500)
+        groupFrame.positioned = true
+    end
+
+    local index = 1;
+    local attIndex = ("child%d"):format(index)
+    local childFrame = self:GetAttribute(attIndex)
+    local childName, petFrame, targetFrame;
+
+    while childFrame do
+        childFrame:UnitUpdate()
+
+        childName = childFrame:GetName()
+        petFrame = _G[("%sPet"):format(childName)]
+        targetFrame = _G[("%sTarget"):format(childName)]
+
+        if(petFrame) then
+            petFrame:UnitUpdate()
+        end
+
+        if(targetFrame) then
+            targetFrame:UnitUpdate()
+        end
+
+        index = index + 1;
+        attIndex = ("child%d"):format(index)
+        childFrame = self:GetAttribute(attIndex)
+    end
+end
+
+BuildTemplates["raid"] = function(self, unit)
+    self.unit = unit
+    self.___key = "raid"
+    MOD:SetActionPanel(self, "raid")
+    self.Health = MOD:CreateHealthBar(self, true)
+    self.Health.frequentUpdates = false
+    self.Power = MOD:CreatePowerBar(self)
+    self.Power.frequentUpdates = false
+    MOD:CreateAuraFrames(self, "raid")
+    self.AuraWatch = MOD:CreateAuraWatch(self, "raid")
+    self.RaidDebuffs = MOD:CreateRaidDebuffs(self)
+    self.Afflicted = MOD:CreateAfflicted(self)
+    self.ResurrectIcon = MOD:CreateResurectionIcon(self)
+    self.LFDRole = MOD:CreateRoleIcon(self)
+    self.RaidRoleFramesAnchor = MOD:CreateRaidRoleFrames(self)
+    self.RaidIcon = MOD:CreateRaidIcon(self)
+    self.ReadyCheck = MOD:CreateReadyCheckIcon(self)
+    self.HealPrediction = MOD:CreateHealPrediction(self)
+    self.Range = { insideAlpha = 1, outsideAlpha = 1 }
+
+    self.Restrict = RestrictElement
+    self.Allow = AllowElement
+    self.UnitUpdate = RaidUnitUpdate
+    self.TargetGlow = self.Threat
+    tinsert(self.__elements, UpdateTargetGlow)
+
+    self:SetScript("OnEnter", UnitFrame_OnEnter)
+    self:SetScript("OnLeave", UnitFrame_OnLeave)
+    self:RegisterEvent("PLAYER_TARGET_CHANGED", UpdateTargetGlow)
+    self:RegisterEvent("PLAYER_ENTERING_WORLD", UpdateTargetGlow)
+
+    return self
+end
+--[[
+##########################################################
+RAID PETS
+##########################################################
+]]--
+UpdateTemplates["raidpet"] = function(self)
+    if(SV.NeedsFrameAudit) then return end
+    local db = SV.db.UnitFrames.raidpet
+    local groupFrame = self:GetParent()
+
+    if not groupFrame.positioned then
+        groupFrame:ClearAllPoints()
+        groupFrame:SetPoint("BOTTOMLEFT", SV.Screen, "BOTTOMLEFT", 4, 433)
+        RegisterStateDriver(groupFrame, "visibility", "[group:raid] show;hide")
+        SV:NewAnchor(groupFrame, L["Raid Pet Frames"])
+        SV:SetAnchorResizing(groupFrame, groupLayoutPostSizeFunc, 10, 500)
+        groupFrame.positioned = true;
+    end
+
+    local index = 1;
+    local attIndex = ("child%d"):format(index)
+    local childFrame = self:GetAttribute(attIndex)
+    local childName, petFrame, targetFrame;
+
+    while childFrame do
+        childFrame:UnitUpdate()
+
+        childName = childFrame:GetName()
+        petFrame = _G[("%sPet"):format(childName)]
+        targetFrame = _G[("%sTarget"):format(childName)]
+
+        if(petFrame) then
+            petFrame:UnitUpdate()
+        end
+
+        if(targetFrame) then
+            targetFrame:UnitUpdate()
+        end
+
+        index = index + 1;
+        attIndex = ("child%d"):format(index)
+        childFrame = self:GetAttribute(attIndex)
+    end
+end
+
+BuildTemplates["raidpet"] = function(self, unit)
+    self.unit = unit
+    self.___key = "raidpet"
+    self:SetScript("OnEnter", UnitFrame_OnEnter)
+    self:SetScript("OnLeave", UnitFrame_OnLeave)
+    MOD:SetActionPanel(self, "raidpet")
+    self.Health = MOD:CreateHealthBar(self, true)
+    MOD:CreateAuraFrames(self, "raidpet")
+    self.AuraWatch = MOD:CreateAuraWatch(self, "raidpet")
+    self.RaidDebuffs = MOD:CreateRaidDebuffs(self)
+    self.Afflicted = MOD:CreateAfflicted(self)
+    self.RaidIcon = MOD:CreateRaidIcon(self)
+    self.Range = { insideAlpha = 1, outsideAlpha = 1 }
+
+    self.Restrict = RestrictElement
+    self.Allow = AllowElement
+    self.UnitUpdate = RaidUnitUpdate
+
+    self.TargetGlow = self.Threat
+    tinsert(self.__elements, UpdateTargetGlow)
+
+    self:RegisterEvent("PLAYER_TARGET_CHANGED", UpdateTargetGlow)
+    self:RegisterEvent("PLAYER_ENTERING_WORLD", UpdateTargetGlow)
+    return self
+end
+--[[
+##########################################################
+TANK
+##########################################################
+]]--
+local TankUnitUpdate = function(self)
+    local db = SV.db.UnitFrames.tank
+    self.colors = oUF_SVUI.colors;
+    self:RegisterForClicks(SV.db.UnitFrames.fastClickTarget and "AnyDown" or "AnyUp")
+    MOD.RefreshUnitMedia(self, "tank")
+    if self.isChild and self.originalParent then
+        local targets = db.targetsGroup;
+        if not self.originalParent.childList then
+            self.originalParent.childList = {}
+        end
+        self.originalParent.childList[self] = true;
+        if not InCombatLockdown()then
+            if targets.enable then
+                local UNIT_WIDTH, UNIT_HEIGHT = MOD:GetActiveSize(targets)
+                self:SetParent(self.originalParent)
+                self:SetSize(UNIT_WIDTH, UNIT_HEIGHT)
+                self:ClearAllPoints()
+                SV:SetReversePoint(self, targets.anchorPoint, self.originalParent, targets.xOffset, targets.yOffset)
+            else
+                self:SetParent(SV.Hidden)
+            end
+        end
+    elseif not InCombatLockdown() then
+        local UNIT_WIDTH, UNIT_HEIGHT = MOD:GetActiveSize(db)
+        self:SetSize(UNIT_WIDTH, UNIT_HEIGHT)
+    end
+    MOD:RefreshUnitLayout(self, "tank")
+    do
+        local nametext = self.TextGrip.Name;
+        if oUF_SVUI.colors.healthclass then
+            self:Tag(nametext, "[name:10]")
+        else
+            self:Tag(nametext, "[name:color][name:10]")
+        end
+    end
+    self:UpdateAllElements()
+end
+
+UpdateTemplates["tank"] = function(self)
+    if(SV.NeedsFrameAudit) then return end
+    local db = SV.db.UnitFrames.tank
+
+    if db.enable ~= true then
+        UnregisterAttributeDriver(self, "state-visibility")
+        self:Hide()
+        return
+    end
+
+    self:Hide()
+    DetachSubFrames(self:GetChildren())
+    self:SetAttribute("startingIndex", -1)
+    RegisterAttributeDriver(self, "state-visibility", "show")
+    self.dirtyWidth, self.dirtyHeight = self:GetSize()
+    RegisterAttributeDriver(self, "state-visibility", "[group:raid] show;hide")
+    self:SetAttribute("startingIndex", 1)
+    self:SetAttribute("point", "BOTTOM")
+    self:SetAttribute("columnAnchorPoint", "LEFT")
+    DetachSubFrames(self:GetChildren())
+    self:SetAttribute("yOffset", 7)
+
+    if not self.positioned then
+        self:ClearAllPoints()
+        self:SetPoint("BOTTOMLEFT", SV.Dock.TopLeft, "BOTTOMLEFT", 0, 0)
+        SV:NewAnchor(self, L["Tank Frames"])
+        SV:SetAnchorResizing(self, groupLayoutPostSizeFunc, 10, 500)
+        self.Grip.positionOverride = "TOPLEFT"
+        self:SetAttribute("minHeight", self.dirtyHeight)
+        self:SetAttribute("minWidth", self.dirtyWidth)
+        self.positioned = true
+    end
+
+    local childFrame, childName, petFrame, targetFrame
+    for i = 1, self:GetNumChildren() do
+        childFrame = select(i, self:GetChildren())
+        childFrame:UnitUpdate()
+
+        childName = childFrame:GetName()
+        petFrame = _G[("%sPet"):format(childName)]
+        targetFrame = _G[("%sTarget"):format(childName)]
+
+        if(petFrame) then
+            petFrame:UnitUpdate()
+        end
+        if(targetFrame) then
+            targetFrame:UnitUpdate()
+        end
+    end
+end
+
+BuildTemplates["tank"] = function(self, unit)
+    local db = SV.db.UnitFrames.tank
+    self.unit = unit
+    self.___key = "tank"
+    self:SetScript("OnEnter", UnitFrame_OnEnter)
+    self:SetScript("OnLeave", UnitFrame_OnLeave)
+    MOD:SetActionPanel(self, "tank")
+    self.Health = MOD:CreateHealthBar(self, true)
+    self.RaidIcon = MOD:CreateRaidIcon(self)
+    self.RaidIcon:SetPoint("BOTTOMRIGHT")
+
+    self.Restrict = RestrictElement
+    self.Allow = AllowElement
+    self.UnitUpdate = TankUnitUpdate
+
+    self.Range = { insideAlpha = 1, outsideAlpha = 1 }
+    self.originalParent = self:GetParent()
+
+    self:UnitUpdate()
+    return self
+end
+--[[
+##########################################################
+ASSIST
+##########################################################
+]]--
+local AssistUnitUpdate = function(self)
+    local db = SV.db.UnitFrames.assist
+    self.colors = oUF_SVUI.colors;
+    self:RegisterForClicks(SV.db.UnitFrames.fastClickTarget and "AnyDown" or "AnyUp")
+    MOD.RefreshUnitMedia(self, "assist")
+    if self.isChild and self.originalParent then
+        local targets = db.targetsGroup;
+        if not self.originalParent.childList then
+            self.originalParent.childList = {}
+        end
+        self.originalParent.childList[self] = true;
+        if not InCombatLockdown()then
+            if targets.enable then
+                local UNIT_WIDTH, UNIT_HEIGHT = MOD:GetActiveSize(targets)
+                self:SetParent(self.originalParent)
+                self:SetSize(UNIT_WIDTH, UNIT_HEIGHT)
+                self:ClearAllPoints()
+                SV:SetReversePoint(self, targets.anchorPoint, self.originalParent, targets.xOffset, targets.yOffset)
+            else
+                self:SetParent(SV.Hidden)
+            end
+        end
+    elseif not InCombatLockdown() then
+        local UNIT_WIDTH, UNIT_HEIGHT = MOD:GetActiveSize(db)
+        self:SetSize(UNIT_WIDTH, UNIT_HEIGHT)
+    end
+
+    MOD:RefreshUnitLayout(self, "assist")
+
+    do
+        local nametext = self.TextGrip.Name;
+        if oUF_SVUI.colors.healthclass then
+            self:Tag(nametext, "[name:10]")
+        else
+            self:Tag(nametext, "[name:color][name:10]")
+        end
+    end
+    self:UpdateAllElements()
+end
+
+UpdateTemplates["assist"] = function(self)
+    if(SV.NeedsFrameAudit) then return end
+    local db = SV.db.UnitFrames.assist
+
+    if db.enable ~= true then
+        UnregisterAttributeDriver(self, "state-visibility")
+        self:Hide()
+        return
+    end
+
+    self:Hide()
+    DetachSubFrames(self:GetChildren())
+    self:SetAttribute("startingIndex", -1)
+    RegisterAttributeDriver(self, "state-visibility", "show")
+    self.dirtyWidth, self.dirtyHeight = self:GetSize()
+    RegisterAttributeDriver(self, "state-visibility", "[group:raid] show;hide")
+    self:SetAttribute("startingIndex", 1)
+    self:SetAttribute("point", "BOTTOM")
+    self:SetAttribute("columnAnchorPoint", "LEFT")
+    DetachSubFrames(self:GetChildren())
+    self:SetAttribute("yOffset", 7)
+
+    if not self.positioned then
+        self:ClearAllPoints()
+        self:SetPoint("TOPLEFT", SV.Dock.TopLeft, "BOTTOMLEFT", 0, -10)
+        SV:NewAnchor(self, L["Assist Frames"])
+        SV:SetAnchorResizing(self, groupLayoutPostSizeFunc, 10, 500)
+        self.Grip.positionOverride = "TOPLEFT"
+        self:SetAttribute("minHeight", self.dirtyHeight)
+        self:SetAttribute("minWidth", self.dirtyWidth)
+        self.positioned = true
+    end
+
+    local childFrame, childName, petFrame, targetFrame
+    for i = 1, self:GetNumChildren() do
+        childFrame = select(i, self:GetChildren())
+        childFrame:UnitUpdate()
+
+        childName = childFrame:GetName()
+        petFrame = _G[("%sPet"):format(childName)]
+        targetFrame = _G[("%sTarget"):format(childName)]
+
+        if(petFrame) then
+            petFrame:UnitUpdate()
+        end
+        if(targetFrame) then
+            targetFrame:UnitUpdate()
+        end
+    end
+end
+
+BuildTemplates["assist"] = function(self, unit)
+    local db = SV.db.UnitFrames.assist
+    self.unit = unit
+    self.___key = "assist"
+    self:SetScript("OnEnter", UnitFrame_OnEnter)
+    self:SetScript("OnLeave", UnitFrame_OnLeave)
+    MOD:SetActionPanel(self, "assist")
+    self.Health = MOD:CreateHealthBar(self, true)
+    self.RaidIcon = MOD:CreateRaidIcon(self)
+    self.RaidIcon:SetPoint("BOTTOMRIGHT")
+    self.Range = { insideAlpha = 1, outsideAlpha = 1 }
+
+    self.Restrict = RestrictElement
+    self.Allow = AllowElement
+    self.UnitUpdate = AssistUnitUpdate
+
+    self.originalParent = self:GetParent()
+
+    self:UnitUpdate()
+    return self
+end
+--[[
+##########################################################
+HEADER CONSTRUCTS
+##########################################################
+]]--
+local HeaderMediaUpdate = function(self)
+    local token = self.___groupkey
+    local index = 1;
+    local attIndex = ("child%d"):format(index)
+    local childFrame = self:GetAttribute(attIndex)
+    local childName, petFrame, targetFrame;
+
+    while childFrame do
+        MOD.RefreshUnitMedia(childFrame, token)
+
+        childName = childFrame:GetName()
+        petFrame = _G[("%sPet"):format(childName)]
+        targetFrame = _G[("%sTarget"):format(childName)]
+
+        if(petFrame) then
+            MOD.RefreshUnitMedia(petFrame, token)
+        end
+
+        if(targetFrame) then
+            MOD.RefreshUnitMedia(targetFrame, token)
+        end
+
+        index = index + 1;
+        attIndex = ("child%d"):format(index)
+        childFrame = self:GetAttribute(attIndex)
+    end
+end
+
+local HeaderUnsetAttributes = function(self)
+    self:Hide()
+    self:SetAttribute("showPlayer", true)
+    self:SetAttribute("showSolo", true)
+    self:SetAttribute("showParty", true)
+    self:SetAttribute("showRaid", true)
+    self:SetAttribute("columnSpacing", nil)
+    self:SetAttribute("columnAnchorPoint", nil)
+    self:SetAttribute("sortMethod", nil)
+    self:SetAttribute("groupFilter", nil)
+    self:SetAttribute("groupingOrder", nil)
+    self:SetAttribute("maxColumns", nil)
+    self:SetAttribute("nameList", nil)
+    self:SetAttribute("point", nil)
+    self:SetAttribute("sortDirection", nil)
+    self:SetAttribute("sortMethod", "NAME")
+    self:SetAttribute("startingIndex", nil)
+    self:SetAttribute("strictFiltering", nil)
+    self:SetAttribute("unitsPerColumn", nil)
+    self:SetAttribute("xOffset", nil)
+    self:SetAttribute("yOffset", nil)
+end
+
+local HeaderEnableChildren = function(self)
+    self.isForced = true;
+    for i=1, select("#", self:GetChildren()) do
+        local childFrame = select(i, self:GetChildren())
+        if(childFrame and childFrame.RegisterForClicks) then
+            childFrame:RegisterForClicks(nil)
+            childFrame:SetID(i)
+            childFrame.TargetGlow:SetAlpha(0)
+            childFrame:Allow()
+        end
+    end
+end
+
+local HeaderDisableChildren = function(self)
+    self.isForced = nil;
+    for i=1, select("#", self:GetChildren()) do
+        local childFrame = select(i, self:GetChildren())
+        if(childFrame and childFrame.RegisterForClicks) then
+            childFrame:RegisterForClicks(SV.db.UnitFrames.fastClickTarget and 'AnyDown' or 'AnyUp')
+            childFrame.TargetGlow:SetAlpha(1)
+            childFrame:Restrict()
+        end
+    end
+end
+
+function MOD:SetGroupHeader(parentFrame, filter, layout, headerName, token, groupTag)
+    local db = SV.db.UnitFrames[token]
+
+    local template1, template2
+    if(token == "raidpet") then
+        template1 = "SVUI_UNITPET"
+        template2 = "SecureGroupPetHeaderTemplate"
+    elseif(token == "party") then
+        template1 = "SVUI_UNITPET, SVUI_UNITTARGET"
+    elseif(token == "tank") then
+        filter = "MAINTANK"
+        template1 = "SVUI_UNITTARGET"
+    elseif(token == "assist") then
+        filter = "MAINASSIST"
+        template1 = "SVUI_UNITTARGET"
+    end
+
+    local UNIT_WIDTH, UNIT_HEIGHT = self:GetActiveSize(db)
+    local groupHeader = oUF_SVUI:SpawnHeader(headerName, template2, nil,
+        "oUF-initialConfigFunction", ("self:SetWidth(%d); self:SetHeight(%d); self:SetFrameLevel(5)"):format(UNIT_WIDTH, UNIT_HEIGHT),
+        "groupFilter", filter,
+        "showParty", true,
+        "showRaid", true,
+        "showSolo", true,
+        template1 and "template", template1
+    )
+    groupHeader.___groupkey = token;
+    groupHeader:SetParent(parentFrame);
+    groupHeader.Update = UpdateTemplates[token];
+    groupHeader.MediaUpdate = HeaderMediaUpdate;
+    groupHeader.UnsetAttributes = HeaderUnsetAttributes;
+    groupHeader.EnableChildren = HeaderEnableChildren;
+    groupHeader.DisableChildren = HeaderDisableChildren;
+
+    if(groupTag) then
+        local icon = MOD.media.groupNumbers[groupTag]
+        local tag = CreateFrame("Frame", nil, groupHeader);
+        tag:SetSize(16,16)
+        tag:SetPoint('RIGHT', groupHeader, 'LEFT', -10, 0)
+        tag.Icon = tag:CreateTexture(nil, 'BORDER')
+        tag.Icon:SetAllPoints(tag)
+        tag.Icon:SetTexture(icon)
+
+        groupHeader.GroupTag = tag
+    end
+
+    return groupHeader
+end
+--[[
+##########################################################
+GROUP CONSTRUCTS
+##########################################################
+]]--
+local GroupUpdate = function(self)
+    local token = self.___groupkey
+    if SV.db.UnitFrames[token].enable ~= true then
+        UnregisterAttributeDriver(self, "state-visibility")
+        self:Hide()
+        return
+    end
+    for i=1,#self.groups do
+        self.groups[i]:Update()
+    end
+end
+
+local GroupMediaUpdate = function(self)
+    for i=1,#self.groups do
+        self.groups[i]:MediaUpdate()
+    end
+end
+
+local GroupSetVisibility = function(self)
+    --print(self.isForced)
+    if not self.isForced then
+        local token = self.___groupkey
+        local db = SV.db.UnitFrames[token]
+        if(db) then
+            for i=1, #self.groups do
+                local frame = self.groups[i]
+                if(db.allowedGroup[i]) then
+                    frame:Show()
+                else
+                    if frame.forceShow then
+                        frame:Hide()
+                        frame:DisableChildren()
+                        frame:SetAttribute('startingIndex',1)
+                    else
+                        frame:UnsetAttributes()
+                    end
+                end
+            end
+        end
+    end
+end
+
+local GroupConfigure = function(self)
+    local token = self.___groupkey
+    local groupCount = self.___groupcount
+    local settings = SV.db.UnitFrames[token]
+    local UNIT_WIDTH, UNIT_HEIGHT = MOD:GetActiveSize(settings)
+    local sorting = settings.showBy
+    local sortMethod = settings.sortMethod
+    local rows, cols, groupIncrement = 0, 1, 0;
+    local xLabelCalc, yLabelCalc = 0, 0;
+    local point, anchorPoint, columnAnchor, horizontal, vertical, isHorizontal = unpack(sortMapping[sorting]);
+    local tagPoint1, tagPoint2, mod = unpack(groupTagPoints[sorting]);
+
+    local groupWidth = (isHorizontal) and ((UNIT_WIDTH + settings.wrapXOffset) * 5) or (UNIT_WIDTH + settings.wrapXOffset);
+    local groupHeight = (isHorizontal) and (UNIT_HEIGHT + settings.wrapYOffset) or ((UNIT_HEIGHT + settings.wrapYOffset) * 5);
+
+    self.groupCount = groupCount;
+
+    for i = 1, groupCount do
+        local frame = self.groups[i]
+        local frameEnabled = true;
+
+        if(frame) then
+            if(settings.showBy == "UP") then
+                settings.showBy = "UP_RIGHT"
+            end
+
+            if(settings.showBy == "DOWN") then
+                settings.showBy = "DOWN_RIGHT"
+            end
+
+            if(isHorizontal) then
+                frame:SetAttribute("xOffset", settings.wrapXOffset * horizontal)
+                frame:SetAttribute("yOffset", 0)
+                frame:SetAttribute("columnSpacing", settings.wrapYOffset)
+            else
+                frame:SetAttribute("xOffset", 0)
+                frame:SetAttribute("yOffset", settings.wrapYOffset * vertical)
+                frame:SetAttribute("columnSpacing", settings.wrapXOffset)
+            end
+
+            if(not frame.isForced) then
+                if not frame.initialized then
+                    frame:SetAttribute("startingIndex", -4)
+                    frame:Show()
+                    frame.initialized = true
+                end
+                frame:SetAttribute("startingIndex", 1)
+            end
+
+            frame:ClearAllPoints()
+            frame:SetAttribute("columnAnchorPoint", columnAnchor)
+
+            DetachSubFrames(frame:GetChildren())
+
+            frame:SetAttribute("point", point)
+
+            if(not frame.isForced) then
+                frame:SetAttribute("maxColumns", 1)
+                frame:SetAttribute("unitsPerColumn", 5)
+                GroupDistributor[sortMethod](frame)
+                frame:SetAttribute("sortDirection", settings.sortDir)
+                frame:SetAttribute("showPlayer", settings.showPlayer)
+            end
+
+            frame:SetAttribute("groupFilter", tostring(i))
+
+            if(frame.GroupTag) then
+                if(settings.showGroupNumber) then
+                    local x,y = 0,0;
+                    local size = settings.height * 0.75;
+                    if(isHorizontal) then
+                        x,y = (4 * mod),0;
+                        xLabelCalc = size + 4
+                    else
+                        x,y = 0,(4 * mod);
+                        yLabelCalc = size + 4
+                    end
+                    frame.GroupTag:Show()
+                    frame.GroupTag:SetSize(size, size)
+                    frame.GroupTag:SetPoint(tagPoint1, frame, tagPoint2, x, y)
+                else
+                    frame.GroupTag:Hide()
+                end
+            end
+
+            if(not settings.allowedGroup[i]) then
+                frame:Hide()
+                frameEnabled = false;
+            else
+                frame:Show()
+            end
+        end
+
+        if(frameEnabled) then
+            local yIncrementOffset,xIncrementOffset = 0,0;
+            if(groupIncrement == 0) then
+                rows = rows + 1;
+                cols = 1;
+                xIncrementOffset = xLabelCalc;
+                yIncrementOffset = yLabelCalc;
+            elseif(isHorizontal) then
+                if(groupIncrement % settings.gRowCol == 0) then
+                    rows = rows + 1;
+                    cols = 1;
+                    xIncrementOffset = xLabelCalc;
+                    yIncrementOffset = ((groupHeight + yLabelCalc) * (rows - 1));
+                else
+                    xIncrementOffset = (groupWidth * cols) + (xLabelCalc * (cols + 1));
+                    yIncrementOffset = (groupHeight * (rows - 1)) + (yLabelCalc * rows);
+                    cols = cols + 1;
+                end
+            else
+                if(groupIncrement % settings.gRowCol == 0) then
+                    rows = rows + 1;
+                    cols = 1;
+                    xIncrementOffset = ((groupWidth + xLabelCalc) * (rows - 1));
+                    yIncrementOffset = yLabelCalc;
+                else
+                    xIncrementOffset = (groupWidth * (rows - 1)) + (xLabelCalc * rows);
+                    yIncrementOffset = ((groupHeight * cols) + (yLabelCalc * cols)) + yLabelCalc;
+                    cols = cols + 1;
+                end
+            end
+
+            groupIncrement = groupIncrement + 1;
+            frame:ClearAllPoints()
+            frame:SetPoint(anchorPoint, self, anchorPoint, (xIncrementOffset * horizontal), (yIncrementOffset * vertical));
+        end
+    end
+
+    if(isHorizontal) then
+        local w = ((groupWidth + xLabelCalc) * settings.gRowCol) - settings.wrapXOffset;
+        local h = ((groupHeight + yLabelCalc) * rows) - settings.wrapYOffset;
+        self:SetSize(w, h)
+    else
+        local w = ((groupWidth + xLabelCalc) * rows) - settings.wrapXOffset;
+        local h = ((groupHeight + yLabelCalc) * settings.gRowCol) - settings.wrapYOffset;
+        self:SetSize(w, h)
+    end
+end
+
+function MOD:GetGroupFrame(token, layout)
+    if(not self.Headers[token]) then
+        oUF_SVUI:RegisterStyle(layout, BuildTemplates[token])
+        oUF_SVUI:SetActiveStyle(layout)
+        local groupFrame = CreateFrame("Frame", layout, _G.SVUI_UnitFrameParent, "SecureHandlerStateTemplate")
+        groupFrame.___groupkey = token;
+        groupFrame.___groupcount = GroupCounts[token] or 1
+        groupFrame.groups = {}
+        groupFrame.Update = GroupUpdate
+        groupFrame.MediaUpdate = GroupMediaUpdate
+        groupFrame.SetVisibility = GroupSetVisibility
+        groupFrame.Configure = GroupConfigure
+
+        groupFrame:Show()
+        self.Headers[token] = groupFrame
+    end
+    return self.Headers[token]
+end
+
+function MOD:SetCustomFrame(token, layout)
+    if(not self.Headers[token]) then
+        oUF_SVUI:RegisterStyle(layout, BuildTemplates[token])
+        oUF_SVUI:SetActiveStyle(layout)
+        local groupFrame = self:SetGroupHeader(_G.SVUI_UnitFrameParent, nil, layout, layout, token)
+        self.Headers[token] = groupFrame
+    end
+    self.Headers[token]:Show()
+    self.Headers[token]:Update()
+end
+
+function MOD:SetGroupFrame(token, forceUpdate)
+    if(InCombatLockdown()) then self:RegisterEvent("PLAYER_REGEN_ENABLED"); return end
+    Update5ManVisibility()
+    local settings = SV.db.UnitFrames[token]
+    local realName = token:gsub("(.)", upper, 1)
+    local layout = "SVUI_"..realName
+
+    if(token == "tank" or token == "assist") then
+        return self:SetCustomFrame(token, layout)
+    end
+
+    local groupFrame = self:GetGroupFrame(token, layout)
+
+    if(token ~= "raidpet" and settings.enable ~= true) then
+        UnregisterStateDriver(groupFrame, "visibility")
+        groupFrame:Hide()
+        return
+    end
+
+    local groupCount = GroupCounts[token] or 1
+    local groupName;
+    for i = 1, groupCount do
+        if(not groupFrame.groups[i]) then
+            groupName = layout .. "Group" .. i;
+            groupFrame.groups[i] = self:SetGroupHeader(groupFrame, i, layout, groupName, token, i)
+            --groupFrame.groups[i]:SetStyle("LiteButton")
+            groupFrame.groups[i]:Show()
+        end
+    end
+
+    groupFrame:SetVisibility()
+
+    if(forceUpdate or not groupFrame.Grip) then
+        groupFrame:Configure()
+        if(not groupFrame.isForced and settings.visibility) then
+            RegisterStateDriver(groupFrame, "visibility", settings.visibility)
+        end
+    else
+        groupFrame:Configure()
+        groupFrame:Update()
+    end
+
+    if(token == "raidpet" and settings.enable ~= true) then
+        UnregisterStateDriver(groupFrame, "visibility")
+        groupFrame:Hide()
+        return
+    end
+    --print('SetGroupFrame')
+end
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_ActionPanel/oUF_ActionPanel.lua b/SVUI_UnitFrames/libs/Plugins/oUF_ActionPanel/oUF_ActionPanel.lua
new file mode 100644
index 0000000..a842d77
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_ActionPanel/oUF_ActionPanel.lua
@@ -0,0 +1,142 @@
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local type         	= _G.type;
+--BLIZZARD API
+local UnitIsConnected 		= _G.UnitIsConnected;
+local UnitIsTapDenied       = _G.UnitIsTapDenied;
+local UnitIsPlayer       	= _G.UnitIsPlayer;
+local UnitIsFriend       	= _G.UnitIsFriend;
+local UnitIsDeadOrGhost  	= _G.UnitIsDeadOrGhost;
+local UnitClassification 	= _G.UnitClassification;
+
+local parent, ns = ...
+local oUF = ns.oUF
+
+local textureCopy;
+
+local Update = function(self, event, unit)
+	if(self.unit ~= unit) or not unit then return end
+	local action = self.ActionPanel
+	--local border = action.border
+	local special = action.special
+	local class = action.class
+	local showSpecial = false
+	local react = UnitReaction("player", unit)
+	local canShowSpecial = (react and (react < 5)) or false;
+	local r,g,b = 0,0,0;
+	local category = UnitClassification(unit)
+
+	if(UnitIsDeadOrGhost(unit)) then
+		r,g,b = 0.15,0.1,0.2;
+	else
+		if(category == "elite") then
+			r,g,b = 1,0.75,0;
+			showSpecial = canShowSpecial
+		elseif(category == "rare" or category == "rareelite") then
+			r,g,b = 0.59,0.79,1;
+			showSpecial = canShowSpecial
+		end
+	end
+
+	if(action.border) then
+		action.border[1]:SetTexture(r,g,b)
+		action.border[2]:SetTexture(r,g,b)
+		action.border[3]:SetTexture(r,g,b)
+		action.border[4]:SetTexture(r,g,b)
+	end
+
+	if(special) then
+		if(showSpecial) then
+			special[1]:SetVertexColor(r,g,b)
+			special[2]:SetVertexColor(r,g,b)
+			--special[3]:SetVertexColor(r,g,b)
+			special:Show()
+		else
+			special:Hide()
+		end
+	end
+
+	if(class and class:IsShown()) then
+		local className, classFileName = UnitClass(unit)
+		local coords = CLASS_ICON_TCOORDS[classFileName]
+		if(coords) then
+			class:Show()
+			class.texture:SetTexCoord(unpack(coords))
+		else
+			class:Hide()
+		end
+	end
+
+	local status = self.StatusPanel
+	if(status) then
+		local texture = status.texture
+		local media = status.media
+
+		if(not UnitIsConnected(unit)) then
+			texture:SetAlpha(1)
+			texture:SetTexture(media[1])
+			--texture:SetGradient("VERTICAL",0,1,1,1,1,0)
+		elseif(UnitIsDeadOrGhost(unit)) then
+			texture:SetAlpha(1)
+			texture:SetTexture(media[2])
+			--texture:SetGradient("VERTICAL",0,0,1,0,1,0)
+		elseif(unit ~= "player" and (unit ~= "vehicle" and (not UnitIsFriend(unit, "player")) and (not UnitIsPlayer(unit)) and UnitIsTapDenied(unit))) then
+			texture:SetAlpha(1)
+			texture:SetTexture(media[3])
+			--texture:SetGradient("VERTICAL",1,1,0,1,0,0)
+		else
+			texture:SetColorTexture(0,0,0,0)
+		end
+	end
+end
+
+local Path = function(self, ...)
+	return (self.ActionPanel.Override or Update) (self, ...)
+end
+
+local ForceUpdate = function(element)
+	return Path(element.__owner, 'ForceUpdate', element.__owner.unit)
+end
+
+local Enable = function(self, unit)
+	local action = self.ActionPanel
+	if(action) then
+		action.__owner = self
+		action.ForceUpdate = ForceUpdate
+		local status = self.StatusPanel
+		if(status and status.texture) then
+			self:RegisterEvent('UNIT_FLAGS', Path)
+			self:RegisterEvent('UNIT_FACTION', Path)
+		end
+		self:RegisterEvent("UNIT_TARGET", Path, true)
+		self:RegisterEvent("PLAYER_TARGET_CHANGED", Path, true)
+		return true
+	end
+end
+
+local Disable = function(self)
+	local action = self.ActionPanel
+	if(action) then
+		local status = self.StatusPanel
+		if(status) then
+			if(self:IsEventRegistered("UNIT_FLAGS")) then
+				self:UnregisterEvent("UNIT_FLAGS", Path)
+			end
+			if(self:IsEventRegistered("UNIT_FACTION")) then
+				self:UnregisterEvent("UNIT_FACTION", Path)
+			end
+		end
+		if(self:IsEventRegistered("PLAYER_TARGET_CHANGED")) then
+			self:UnregisterEvent("PLAYER_TARGET_CHANGED", Path)
+		end
+		if(self:IsEventRegistered("UNIT_TARGET")) then
+			self:UnregisterEvent("UNIT_TARGET", Path)
+		end
+	end
+end
+
+oUF:AddElement('ActionPanel', Path, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_ActionPanel/oUF_ActionPanel.toc b/SVUI_UnitFrames/libs/Plugins/oUF_ActionPanel/oUF_ActionPanel.toc
new file mode 100644
index 0000000..9cc266c
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_ActionPanel/oUF_ActionPanel.toc
@@ -0,0 +1,10 @@
+## Interface: 50001
+## Title: oUF ActionPanel
+## Notes: Adds a backing to all unit frames that provides many utilities.
+## Author: Failcoder
+## Version: 1.1.0
+## X-Category: oUF
+## Dependencies: oUF
+
+
+oUF_ActionPanel.lua
\ No newline at end of file
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_AdvancedAuras/oUF_AdvancedAuras.lua b/SVUI_UnitFrames/libs/Plugins/oUF_AdvancedAuras/oUF_AdvancedAuras.lua
new file mode 100644
index 0000000..f58b8b8
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_AdvancedAuras/oUF_AdvancedAuras.lua
@@ -0,0 +1,859 @@
+--[[ MODIFIED FOR SVUI BY SVUILUNCH ]]--
+
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local type         	= _G.type;
+--STRING
+local string        = _G.string;
+local format        = string.format;
+--MATH
+local math          = math;
+local floor         = math.floor
+local ceil         	= math.ceil
+local hugeMath 		= math.huge;
+local min 			= math.min;
+--TABLE
+local table 		= _G.table;
+local tsort 		= table.sort;
+local tinsert 		= _G.tinsert;
+--BLIZZARD API
+local GetTime       = _G.GetTime;
+local CreateFrame   = _G.CreateFrame;
+local UnitAura      = _G.UnitAura;
+local UnitIsFriend  = _G.UnitIsFriend;
+local GameTooltip  	= _G.GameTooltip;
+local GetSpellInfo  = _G.GetSpellInfo;
+local DebuffTypeColor  = _G.DebuffTypeColor;
+local NumberFontNormal  = _G.NumberFontNormal;
+
+local _, ns = ...
+local oUF = oUF or ns.oUF
+assert(oUF, 'oUF_Auras was unable to locate oUF install.')
+
+local DAY, HOUR, MINUTE = 86400, 3600, 60;
+local BUFF_FILTER = 'HELPFUL';
+local DEBUFF_FILTER = 'HARMFUL';
+local VISIBLE = 1;
+local HIDDEN = 0;
+
+local function FormatTime(seconds)
+	if seconds < MINUTE then
+		return ("%.1fs"):format(seconds)
+	elseif seconds < HOUR then
+		return ("%dm %ds"):format(seconds/60%60, seconds%60)
+	elseif seconds < DAY then
+		return ("%dh %dm"):format(seconds/(60*60), seconds/60%60)
+	else
+		return ("%dd %dh"):format(seconds/DAY, (seconds / HOUR) - (floor(seconds/DAY) * 24))
+	end
+end
+
+local SORTING_METHODS = {
+	["TIME_REMAINING"] = function(a, b)
+		local compA = a.noTime and hugeMath or a.expirationTime
+		local compB = b.noTime and hugeMath or b.expirationTime
+		return compA > compB
+	end,
+	["TIME_REMAINING_REVERSE"] = function(a, b)
+		local compA = a.noTime and hugeMath or a.expirationTime
+		local compB = b.noTime and hugeMath or b.expirationTime
+		return compA < compB
+	end,
+	["TIME_DURATION"] = function(a, b)
+		local compA = a.noTime and hugeMath or a.duration
+		local compB = b.noTime and hugeMath or b.duration
+		return compA > compB
+	end,
+	["TIME_DURATION_REVERSE"] = function(a, b)
+		local compA = a.noTime and hugeMath or a.duration
+		local compB = b.noTime and hugeMath or b.duration
+		return compA < compB
+	end,
+	["NAME"] = function(a, b)
+		return a.name > b.name
+	end,
+}
+
+local SetSorting = function(self, sorting)
+	if(sorting) then
+		if((type(sorting) == "string") and SORTING_METHODS[sorting]) then
+			self.sort = SORTING_METHODS[sorting];
+		else
+			self.sort = SORTING_METHODS["TIME_REMAINING"];
+		end
+	else
+		self.sort = nil;
+	end
+end
+
+local genericFilter = function(self, frame, _, name, _, _, _, _, _, _, caster, _, shouldConsolidate)
+	local isPlayer
+
+	if(caster == 'player' or caster == 'vehicle') then
+		isPlayer = true
+	end
+
+	if((self.onlyShowPlayer and isPlayer) or (not self.onlyShowPlayer and name)) then
+		if(frame) then
+			frame.isPlayer = isPlayer
+			frame.owner = caster
+		end
+		if(not shouldConsolidate) then
+			return true
+		end
+	end
+end
+
+local Aura_OnEnter = function(self)
+	if(not self:IsVisible()) then return end
+	GameTooltip:SetOwner(self, "ANCHOR_BOTTOMRIGHT")
+	GameTooltip:SetUnitAura(self.unit, self.index, self.filter)
+end
+
+local Aura_OnLeave = function()
+	GameTooltip:Hide()
+end
+
+local AuraBars_OnUpdate = function(self)
+	local timeNow = GetTime()
+	for index = 1, #self do
+		local frame = self[index]
+		local bar = frame.statusBar
+		if not frame:IsVisible() then
+			break
+		end
+		if frame.noTime then
+			bar.spelltime:SetText()
+			bar.spark:Hide()
+		else
+			local timeleft = frame.expirationTime - timeNow
+			bar:SetValue(timeleft)
+			bar.spelltime:SetText(FormatTime(timeleft))
+			if self.spark == true then
+				bar.spark:Show()
+			end
+		end
+	end
+end
+
+local AuraIcon_OnUpdate = function(self, elapsed)
+	self.expiration = self.expiration - elapsed;
+
+	if(self.nextUpdate > 0) then
+		self.nextUpdate = self.nextUpdate - elapsed;
+		return;
+	end
+
+	if(self.expiration <= 0) then
+		self:SetScript("OnUpdate", nil)
+		self.text:SetText('')
+		return;
+	end
+
+	local expires = self.expiration;
+	local calc, timeLeft = 0, 0;
+	if expires < 4 then
+        self.nextUpdate = 0.051
+        self.text:SetFormattedText("|cffff0000%.1f|r", expires)
+    elseif expires < 60 then
+        self.nextUpdate = 0.51
+        self.text:SetFormattedText("|cffffff00%d|r", floor(expires))
+    elseif expires < 3600 then
+        timeLeft = ceil(expires / 60);
+        calc = floor((expires / 60) + .5);
+        self.nextUpdate = calc > 1 and ((expires - calc) * 29.5) or (expires - 59.5);
+        self.text:SetFormattedText("|cffffffff%dm|r", timeLeft)
+    elseif expires < 86400 then
+        timeLeft = ceil(expires / 3600);
+        calc = floor((expires / 3600) + .5);
+        self.nextUpdate = calc > 1 and ((expires - calc) * 1799.5) or (expires - 3570);
+        self.text:SetFormattedText("|cff66ffff%dh|r", timeLeft)
+    else
+        timeLeft = ceil(expires / 86400);
+        calc = floor((expires / 86400) + .5);
+        self.nextUpdate = calc > 1 and ((expires - calc) * 43199.5) or (expires - 85680);
+        if(timeLeft > 7) then
+            self.text:SetFormattedText("|cff6666ff%s|r", "long")
+        else
+            self.text:SetFormattedText("|cff6666ff%dd|r", timeLeft)
+        end
+    end
+end
+
+local SetBarLayout = function(self, visible, cache)
+	local auras = self.Bars;
+
+	local newHeight = 1;
+	if(visible > 0) then
+		newHeight = 1 + ((self.auraSize + self.spacing) * visible);
+	end
+	self:SetHeight(newHeight)
+
+	local width = self:GetWidth();
+	local height = self.barHeight or 16;
+	local growDown = self.down or false;
+	local spacing = self.spacing or 0;
+
+	for i = visible + 1, #auras do
+		auras[i]:Hide()
+	end
+
+	local lastBar;
+	if(cache) then
+		for i = 1, #cache do
+			local info = cache[i]
+			local bar = auras[info.ref]
+			if(bar and bar:IsShown()) then
+				bar:SetHeight(height)
+				bar:SetWidth(width)
+				bar.iconHolder:SetWidth(height)
+				bar:ClearAllPoints()
+				if(growDown) then
+					if(not lastBar) then
+						bar:SetPoint('TOPLEFT', self, 'TOPLEFT', 0, 0)
+					else
+						bar:SetPoint('TOPLEFT', lastBar, 'BOTTOMLEFT', 0, -spacing)
+					end
+				else
+					if(not lastBar) then
+						bar:SetPoint('BOTTOMLEFT', self, 'BOTTOMLEFT', 0, 0)
+					else
+						bar:SetPoint('BOTTOMLEFT', lastBar, 'TOPLEFT', 0, spacing)
+					end
+				end
+				lastBar = bar
+			end
+		end
+	else
+		for index = 1, #auras do
+			local bar = auras[index]
+			if(bar and bar:IsShown()) then
+				bar:SetHeight(height)
+				bar:SetWidth(width)
+				bar.iconHolder:SetWidth(height)
+				bar:ClearAllPoints()
+				if(growDown) then
+					if(not lastBar) then
+						bar:SetPoint('TOPLEFT', self, 'TOPLEFT', 0, 0)
+					else
+						bar:SetPoint('TOPLEFT', lastBar, 'BOTTOMLEFT', 0, -spacing)
+					end
+				else
+					if(not lastBar) then
+						bar:SetPoint('BOTTOMLEFT', self, 'BOTTOMLEFT', 0, 0)
+					else
+						bar:SetPoint('BOTTOMLEFT', lastBar, 'TOPLEFT', 0, spacing)
+					end
+				end
+				lastBar = bar
+			end
+		end
+	end
+end
+
+local SetIconLayout = function(self, visible, cache)
+	local auras = self.Icons
+
+	local newHeight = 1;
+	if(visible > 0) then
+		local visibleRows = ceil(visible / self.maxColumns);
+		newHeight = 1 + ((self.auraSize + self.spacing) * visibleRows);
+	end
+	self:SetHeight(newHeight)
+
+	local col = 0
+	local row = 0
+	local gap = self.gap
+	local size = self.auraSize + self.spacing
+	local anchor = self.initialAnchor or "BOTTOMLEFT"
+	local growthx = (self["growth-x"] == "LEFT" and -1) or 1
+	local growthy = (self["growth-y"] == "DOWN" and -1) or 1
+	local cols = floor(self:GetWidth() / size + .5)
+	local rows = floor(self:GetHeight() / size + .5)
+
+	for i = visible + 1, #auras do
+		auras[i]:Hide()
+	end
+
+	if(cache) then
+		for i = 1, #cache do
+			local info = cache[i]
+			local button = auras[info.ref]
+			if(button and button:IsShown()) then
+				if(gap and button.debuff) then
+					if(col > 0) then
+						col = col + 1
+					end
+					gap = false
+				end
+
+				if(col >= cols) then
+					col = 0
+					row = row + 1
+				end
+				button:ClearAllPoints()
+				button:SetPoint(anchor, self, anchor, col * size * growthx, row * size * growthy)
+				button:SetWidth(self.auraSize)
+				button:SetHeight(self.auraSize)
+				col = col + 1
+			elseif(not button) then
+				break
+			end
+		end
+	else
+		for i = 1, #auras do
+			local button = auras[i]
+			if(button and button:IsShown()) then
+				if(gap and button.debuff) then
+					if(col > 0) then
+						col = col + 1
+					end
+					gap = false
+				end
+
+				if(col >= cols) then
+					col = 0
+					row = row + 1
+				end
+				button:ClearAllPoints()
+				button:SetPoint(anchor, self, anchor, col * size * growthx, row * size * growthy)
+				button:SetWidth(self.auraSize)
+				button:SetHeight(self.auraSize)
+				col = col + 1
+			elseif(not button) then
+				break
+			end
+		end
+	end
+end
+
+--[[ ICON SPECIFIC ]]--
+
+local CreateAuraIcon = function(self, index)
+	local button = CreateFrame("Button", nil, self)
+	button:EnableMouse(true)
+	button:RegisterForClicks'RightButtonUp'
+
+	button:SetWidth(self.auraSize or 16)
+	button:SetHeight(self.auraSize or 16)
+
+	local cd = CreateFrame("Cooldown", nil, button, "CooldownFrameTemplate")
+	cd:SetAllPoints(button)
+
+	local icon = button:CreateTexture(nil, "BORDER")
+	icon:SetAllPoints(button)
+
+	local count = button:CreateFontString(nil, "OVERLAY")
+	count:SetFontObject(NumberFontNormal)
+	count:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -1, 0)
+
+	local overlay = button:CreateTexture(nil, "OVERLAY")
+	overlay:SetTexture"Interface\\Buttons\\UI-Debuff-Overlays"
+	overlay:SetAllPoints(button)
+	overlay:SetTexCoord(.296875, .5703125, 0, .515625)
+	button.overlay = overlay
+
+	local stealable = button:CreateTexture(nil, 'OVERLAY')
+	stealable:SetTexture[[Interface\TargetingFrame\UI-TargetingFrame-Stealable]]
+	stealable:SetPoint('TOPLEFT', -3, 3)
+	stealable:SetPoint('BOTTOMRIGHT', 3, -3)
+	stealable:SetBlendMode'ADD'
+	button.stealable = stealable
+
+	button:SetScript("OnEnter", Aura_OnEnter)
+	button:SetScript("OnLeave", Aura_OnLeave)
+
+	button.icon = icon
+	button.count = count
+	button.cooldown = cd
+
+	if(self.PostCreateIcon) then self:PostCreateIcon(button) end
+
+	return button
+end
+
+--[[ BAR SPECIFIC ]]--
+
+local CreateAuraBar = function(self, index)
+	local frame = CreateFrame("Button", nil, self)
+
+	frame:SetScript('OnEnter', Aura_OnEnter)
+	frame:SetScript('OnLeave', Aura_OnLeave)
+
+	local iconHolder = CreateFrame('Frame', nil, frame)
+	iconHolder:SetPoint('TOPLEFT', frame, 'TOPLEFT', 0, 0)
+	iconHolder:SetPoint('BOTTOMLEFT', frame, 'BOTTOMLEFT', 0, 0)
+	iconHolder:SetWidth(frame:GetHeight())
+	iconHolder:SetBackdrop({
+        bgFile = [[Interface\BUTTONS\WHITE8X8]],
+        edgeFile = [[Interface\BUTTONS\WHITE8X8]],
+        tile = false,
+        tileSize = 0,
+        edgeSize = 1,
+        insets =
+        {
+            left = 0,
+            right = 0,
+            top = 0,
+            bottom = 0,
+        },
+    })
+    iconHolder:SetBackdropColor(0,0,0,0.5)
+    iconHolder:SetBackdropBorderColor(0,0,0)
+	frame.iconHolder = iconHolder
+
+	frame.icon = frame.iconHolder:CreateTexture(nil, 'BORDER')
+	frame.icon:SetTexCoord(.1, .9, .1, .9)
+	frame.icon:SetPoint("TOPLEFT", frame.iconHolder, "TOPLEFT", 1, -1)
+	frame.icon:SetPoint("BOTTOMRIGHT", frame.iconHolder, "BOTTOMRIGHT", -1, 1)
+
+	frame.count = frame.iconHolder:CreateFontString(nil, "OVERLAY")
+	frame.count:SetFontObject(NumberFontNormal)
+	frame.count:SetPoint("BOTTOMRIGHT", frame.iconHolder, "BOTTOMRIGHT", -1, 0)
+
+	local barHolder = CreateFrame('Frame', nil, frame)
+	barHolder:SetPoint('BOTTOMLEFT', frame.iconHolder, 'BOTTOMRIGHT', self.gap, 0)
+	barHolder:SetPoint('TOPRIGHT', frame, 'TOPRIGHT', 0, 0)
+	barHolder:SetBackdrop({
+        bgFile = [[Interface\BUTTONS\WHITE8X8]],
+        edgeFile = [[Interface\BUTTONS\WHITE8X8]],
+        tile = false,
+        tileSize = 0,
+        edgeSize = 1,
+        insets =
+        {
+            left = 0,
+            right = 0,
+            top = 0,
+            bottom = 0,
+        },
+    })
+    barHolder:SetBackdropColor(0,0,0,0.5)
+    barHolder:SetBackdropBorderColor(0,0,0)
+	frame.barHolder = barHolder
+
+	-- the main bar
+	frame.statusBar = CreateFrame("StatusBar", nil, frame.barHolder)
+	frame.statusBar:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]])
+	frame.statusBar:SetAlpha(self.fgalpha or 1)
+	frame.statusBar:SetPoint("TOPLEFT", frame.barHolder, "TOPLEFT", 1, -1)
+	frame.statusBar:SetPoint("BOTTOMRIGHT", frame.barHolder, "BOTTOMRIGHT", -1, 1)
+
+	local spark = frame.statusBar:CreateTexture(nil, "OVERLAY", nil);
+	spark:SetTexture([[Interface\CastingBar\UI-CastingBar-Spark]]);
+	spark:SetWidth(12);
+	spark:SetBlendMode("ADD");
+	spark:SetPoint('CENTER', frame.statusBar:GetStatusBarTexture(), 'RIGHT')
+	frame.statusBar.spark = spark
+
+	frame.statusBar.spelltime = frame.statusBar:CreateFontString(nil, 'ARTWORK')
+	frame.statusBar.spellname = frame.statusBar:CreateFontString(nil, 'ARTWORK')
+
+	--print("New Bar #" .. index)
+
+	if self.PostCreateBar then
+		self.PostCreateBar(frame)
+	else
+		frame.statusBar.spelltime:SetFont([[Fonts\FRIZQT__.TTF]], 10, "NONE")
+		frame.statusBar.spelltime:SetTextColor(1 ,1, 1)
+		frame.statusBar.spelltime:SetShadowOffset(1, -1)
+	  	frame.statusBar.spelltime:SetShadowColor(0, 0, 0)
+		frame.statusBar.spelltime:SetJustifyH'RIGHT'
+		frame.statusBar.spelltime:SetJustifyV'CENTER'
+		frame.statusBar.spelltime:SetPoint'RIGHT'
+		frame.statusBar.spellname:SetFont([[Fonts\FRIZQT__.TTF]], 10, "NONE")
+		frame.statusBar.spellname:SetTextColor(1, 1, 1)
+		frame.statusBar.spellname:SetShadowOffset(1, -1)
+	  	frame.statusBar.spellname:SetShadowColor(0, 0, 0)
+		frame.statusBar.spellname:SetJustifyH'LEFT'
+		frame.statusBar.spellname:SetJustifyV'CENTER'
+		frame.statusBar.spellname:SetPoint'LEFT'
+		frame.statusBar.spellname:SetPoint('RIGHT', frame.statusBar.spelltime, 'LEFT')
+	end
+	return frame
+end
+
+local UpdateIconAuras = function(self, cache, unit, index, filter, visible, isFriend)
+	if not unit then return; end
+
+	local isDebuff = filter == DEBUFF_FILTER
+	local timeNow = GetTime()
+	local auras = self.Icons;
+
+	local name, rank, texture, count, debuffType, duration, timeLeft, caster, isStealable, shouldConsolidate, spellID, canApplyAura, isBossDebuff;
+
+	if(self.forceShow) then
+		spellID = 47540
+		name, rank, texture = GetSpellInfo(spellID)
+		count, debuffType, duration, timeLeft, caster, isStealable, shouldConsolidate, canApplyAura, isBossDebuff = 5, 'Magic', 0, 60, 'player', nil, nil, nil, nil
+	else
+		name, rank, texture, count, debuffType, duration, timeLeft, caster, isStealable, shouldConsolidate, spellID, canApplyAura, isBossDebuff = UnitAura(unit, index, filter);
+	end
+
+	if(name) then
+		local show = true
+		if(not self.forceShow) then
+			show = (self.CustomFilter or genericFilter) (self, false, unit, name, rank, texture, count, debuffType, duration, timeLeft, caster, isStealable, shouldConsolidate, spellID, canApplyAura, isBossDebuff)
+		end
+
+		if(show) then
+			local i = visible + 1
+			local this = auras[i]
+			if(not this) then
+				this = (self.CreateAuraIcon or CreateAuraIcon) (self, i)
+				auras[i] = this
+			end
+
+			duration = duration or 0;
+			timeLeft = timeLeft or 0;
+			count = count or 0;
+			local noTime = (duration == 0 and timeLeft == 0)
+			--FOR TOOLTIPS
+			this.unit = unit
+			this.index = index
+			this.filter = filter
+			--FOR ONCLICK EVENTS
+			this.name = name
+			this.spellID = spellID
+			--FOR ONUPDATE EVENTS
+			this.expirationTime = timeLeft
+			this.noTime = noTime
+
+			this.icon:SetTexture(texture)
+			this.count:SetText((count > 1 and count))
+
+			this:Show()
+
+			--SORTING CACHE
+			local cached = {
+				ref = i,
+				noTime = noTime,
+				duration = duration,
+				expirationTime = timeLeft
+			}
+			tinsert(cache, cached)
+
+			local cd = this.cooldown
+			if(cd and not self.disableCooldown) then
+				if(noTime) then
+					cd:Hide()
+				else
+					cd:SetCooldown(timeLeft - duration, duration)
+					cd:Show()
+				end
+			end
+
+			if(isDebuff) then
+				local color = DebuffTypeColor[debuffType] or DebuffTypeColor.none
+				if((not isFriend) and caster and (caster ~= "player") and (caster ~= "vehicle")) then
+					this:SetBackdropBorderColor(0.9, 0.1, 0.1, 1)
+					this.bg:SetBackdropColor(1, 0, 0, 1)
+					this.icon:SetDesaturated((unit and not unit:find('arena%d')) and true or false)
+				else
+					this:SetBackdropBorderColor(color.r * 0.6, color.g * 0.6, color.b * 0.6, 1)
+					this.bg:SetBackdropColor(color.r, color.g, color.b, 1)
+					this.icon:SetDesaturated(false)
+				end
+
+				this.bg:SetBackdropBorderColor(0, 0, 0, 1)
+
+				if(self.showType and this.overlay) then
+					this.overlay:SetVertexColor(color.r, color.g, color.b)
+					this.overlay:Show()
+				else
+					this.overlay:Hide()
+				end
+			else
+				if((isStealable) and (not isFriend)) then
+					this:SetBackdropBorderColor(0.92, 0.91, 0.55, 1)
+					this.bg:SetBackdropColor(1, 1, 0.5, 1)
+					this.bg:SetBackdropBorderColor(0, 0, 0, 1)
+				else
+					this:SetBackdropBorderColor(0, 0, 0, 1)
+					this.bg:SetBackdropColor(0, 0, 0, 0)
+					this.bg:SetBackdropBorderColor(0, 0, 0, 0)
+				end
+			end
+
+			if(noTime) then
+				this:SetScript('OnUpdate', nil)
+				this.text:SetText('')
+			elseif(not this:GetScript('OnUpdate')) then
+				this.expirationTime = timeLeft
+				this.expiration = timeLeft - timeNow
+				this.nextUpdate = -1
+				this:SetScript('OnUpdate', AuraIcon_OnUpdate)
+			elseif(this.expirationTime ~= timeLeft) then
+				this.expirationTime = timeLeft
+				this.expiration = timeLeft - timeNow
+				this.nextUpdate = -1
+			end
+
+			return VISIBLE
+		else
+			return HIDDEN
+		end
+	end
+end
+
+local UpdateBarAuras = function(self, cache, unit, index, filter, visible, isFriend)
+	if not unit then return; end
+	local isDebuff = filter == DEBUFF_FILTER
+	local timeNow = GetTime()
+	local auras = self.Bars;
+
+	local name, rank, texture, count, debuffType, duration, timeLeft, caster, isStealable, shouldConsolidate, spellID, canApplyAura, isBossDebuff = UnitAura(unit, index, filter);
+
+	if(self.forceShow) then
+		spellID = 47540
+		name, rank, texture = GetSpellInfo(spellID)
+		count, debuffType, duration, timeLeft, caster, isStealable, shouldConsolidate, canApplyAura, isBossDebuff = 5, 'Magic', 0, 60, 'player', nil, nil, nil, nil
+	end
+
+	if(name) then
+		local show = true
+		if(not self.forceShow) then
+			show = (self.CustomFilter or genericFilter) (self, false, unit, name, rank, texture, count, debuffType, duration, timeLeft, caster, isStealable, shouldConsolidate, spellID, canApplyAura, isBossDebuff)
+		end
+
+		if(show) then
+			local i = visible + 1
+			local this = auras[i]
+			if(not this) then
+				this = (self.CreateAuraBar or CreateAuraBar) (self, i)
+				auras[i] = this
+			end
+
+			duration = duration or 0;
+			timeLeft = timeLeft or 0;
+			count = count or 0;
+			local noTime = (duration == 0 and timeLeft == 0)
+			--FOR TOOLTIPS
+			this.unit = unit
+			this.index = index
+			this.filter = filter
+			--FOR ONCLICK EVENTS
+			this.name = name
+			this.spellID = spellID
+			--FOR ONUPDATE EVENTS
+			this.expirationTime = timeLeft
+			this.noTime = noTime
+
+			this.icon:SetTexture(texture)
+			this.count:SetText((count > 1 and count))
+
+			this:Show()
+
+			--SORTING CACHE
+			local cached = {
+				ref = i,
+				noTime = noTime,
+				duration = duration,
+				expirationTime = timeLeft
+			}
+			tinsert(cache, cached)
+
+			local bar = this.statusBar
+			if(noTime) then
+				bar:SetMinMaxValues(0, 1)
+				bar:SetValue(1)
+				bar.spelltime:SetText('')
+			else
+				local value = timeLeft - timeNow
+				bar:SetMinMaxValues(0, duration)
+				bar:SetValue(value)
+				bar.spelltime:SetText(value)
+			end
+			bar.spellname:SetText(count > 1 and format("%s [%d]", name, count) or name)
+
+			if self.PostBarUpdate then
+				self:PostBarUpdate(bar, spellID, isDebuff, debuffType)
+			elseif(isDebuff) then
+				bar:SetStatusBarColor(.9, 0, 0)
+			else
+				bar:SetStatusBarColor(.2, .6, 1)
+			end
+
+			return VISIBLE
+		else
+			return HIDDEN
+		end
+	end
+end
+
+local ParseIconAuras = function(self, unit)
+	local limit = self.maxCount or 0;
+	local filter = self.filtering;
+	local index = 1;
+	local visible = 0;
+	local cache = {};
+	local isFriend = (UnitIsFriend('player', unit) == 1) and true or false;
+
+	while(visible < limit) do
+		if(self.forceShow and visible > 8) then break end
+		local result = UpdateIconAuras(self, cache, unit, index, filter, visible, isFriend)
+		if(not result) then
+			break
+		elseif(result == VISIBLE) then
+			visible = visible + 1
+		end
+
+		index = index + 1
+	end
+
+	if(self.sort and type(self.sort) == 'function' and (#cache > 0)) then
+		tsort(cache, self.sort)
+		SetIconLayout(self, visible, cache)
+	else
+		SetIconLayout(self, visible)
+	end
+end
+
+local ParseBarAuras = function(self, unit)
+	local limit = self.maxCount or 0;
+	local filter = self.filtering;
+	local index = 1;
+	local visible = 0;
+	local cache = {};
+
+	local isFriend = (UnitIsFriend('player', unit) == 1) and true or false;
+
+	while(visible < limit) do
+		if(self.forceShow and visible > 8) then break end
+		local result = UpdateBarAuras(self, cache, unit, index, filter, visible, isFriend)
+		if(not result) then
+			break
+		elseif(result == VISIBLE) then
+			visible = visible + 1
+		end
+
+		index = index + 1
+	end
+
+	if(self.sort and type(self.sort) == 'function' and (#cache > 0)) then
+		tsort(cache, self.sort)
+		SetBarLayout(self, visible, cache)
+	else
+		SetBarLayout(self, visible)
+	end
+end
+
+--[[ SETUP AND ENABLE/DISABLE ]]--
+
+local Update = function(self, event, unit)
+	if((not unit) or (self.unit ~= unit)) then return end
+
+	local buffs = self.Buffs
+	if(buffs) then
+		--if(self.unit == 'player') then print(event)print(buffs.UseBars) end
+		if(buffs.UseBars and (buffs.UseBars == true)) then
+			--if(self.unit == 'player') then print('Parsing BUFF BARS') end
+			ParseBarAuras(buffs, unit)
+		else
+			--if(self.unit == 'player') then print('Parsing BUFF ICONS') end
+			ParseIconAuras(buffs, unit)
+		end
+	end
+
+	local debuffs = self.Debuffs
+	if(debuffs) then
+		--if(self.unit == 'player') then print(event)print(debuffs.UseBars) end
+		if(debuffs.UseBars and (debuffs.UseBars == true)) then
+			--if(self.unit == 'player') then print('Parsing DEBUFF BARS') end
+			ParseBarAuras(debuffs, unit)
+		else
+			--if(self.unit == 'player') then print('Parsing DEBUFF ICONS') end
+			ParseIconAuras(debuffs, unit)
+		end
+	end
+end
+
+local ForceUpdate = function(element)
+	return Update(element.__owner, 'ForceUpdate', element.unit)
+end
+
+local Enable = function(self)
+	if(self.Buffs or self.Debuffs) then
+		self:RegisterEvent('UNIT_AURA', Update)
+
+		local barsAvailable = self.AuraBarsAvailable;
+
+		local buffs = self.Buffs
+		if(buffs) then
+			buffs.__owner 		= self;
+			buffs.gap 			= buffs.gap or 2;
+			buffs.spacing 		= buffs.spacing or 2;
+			buffs.auraSize 		= buffs.auraSize or 16;
+			buffs.maxRows 		= buffs.maxRows or 2;
+			buffs.maxColumns 	= buffs.maxColumns or 8;
+			buffs.maxCount 		= buffs.maxCount or 16;
+			buffs.maxHeight 	= buffs.maxHeight or 20;
+			buffs.filtering 	= BUFF_FILTER;
+			buffs.ForceUpdate 	= ForceUpdate;
+			buffs.SetSorting 	= SetSorting;
+
+			buffs:SetHeight(1)
+
+			buffs.Icons = buffs.Icons or CreateFrame("Frame", nil, buffs)
+			buffs.Icons:SetAllPoints(buffs)
+
+			if(barsAvailable) then
+				buffs.spark = true;
+				buffs.UseBars = false;
+				buffs.barHeight = buffs.barHeight or 16
+				buffs.Bars = buffs.Bars or CreateFrame("Frame", nil, buffs)
+				buffs.Bars:SetAllPoints(buffs)
+				buffs.Bars:SetScript('OnUpdate', AuraBars_OnUpdate)
+			end
+		end
+
+		local debuffs = self.Debuffs
+		if(debuffs) then
+			debuffs.__owner 	= self;
+			debuffs.gap 		= debuffs.gap or 2;
+			debuffs.spacing 	= debuffs.spacing or 2;
+			debuffs.auraSize 	= debuffs.auraSize or 16;
+			debuffs.maxRows 	= debuffs.maxRows or 2;
+			debuffs.maxColumns 	= debuffs.maxColumns or 8;
+			debuffs.maxCount 	= debuffs.maxCount or 16;
+			debuffs.maxHeight 	= debuffs.maxHeight or 20;
+			debuffs.filtering 	= DEBUFF_FILTER;
+			debuffs.ForceUpdate = ForceUpdate;
+			debuffs.SetSorting 	= SetSorting;
+
+			debuffs:SetHeight(1)
+
+			debuffs.Icons = debuffs.Icons or CreateFrame("Frame", nil, debuffs)
+			debuffs.Icons:SetAllPoints(debuffs)
+
+			if(barsAvailable) then
+				debuffs.spark = true;
+				debuffs.UseBars = false;
+				debuffs.barHeight = debuffs.barHeight or 16
+				debuffs.Bars = debuffs.Bars or CreateFrame("Frame", nil, debuffs)
+				debuffs.Bars:SetAllPoints(debuffs)
+				debuffs.Bars:SetScript('OnUpdate', AuraBars_OnUpdate)
+			end
+		end
+
+		return true
+	end
+end
+
+local Disable = function(self)
+	if(self.Buffs or self.Debuffs) then
+		self:UnregisterEvent('UNIT_AURA', Update)
+		if(self.Buffs and self.Buffs.Bars) then
+			self.Buffs.Bars:SetScript('OnUpdate', nil)
+		end
+		if(self.Debuffs and self.Debuffs.Bars) then
+			self.Debuffs.Bars:SetScript('OnUpdate', nil)
+		end
+	end
+end
+
+oUF:AddElement('Auras', Update, Enable, Disable)
\ No newline at end of file
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_Afflicted/oUF_Afflicted.lua b/SVUI_UnitFrames/libs/Plugins/oUF_Afflicted/oUF_Afflicted.lua
new file mode 100644
index 0000000..73a22df
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_Afflicted/oUF_Afflicted.lua
@@ -0,0 +1,173 @@
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local type         	= _G.type;
+--MATH
+local math          = _G.math;
+local floor         = math.floor
+local ceil          = math.ceil
+local random 				= math.random
+--BLIZZARD API
+local UnitAura       	 = _G.UnitAura;
+local UnitCanAssist      = _G.UnitCanAssist;
+local GetSpellInfo       = _G.GetSpellInfo;
+local GetSpecialization  = _G.GetSpecialization;
+local GetActiveSpecGroup = _G.GetActiveSpecGroup;
+
+local _, ns = ...
+local oUF = oUF or ns.oUF
+if not oUF then return end
+
+local playerClass = select(2,UnitClass("player"))
+local CanDispel = {
+	PRIEST = { Magic = true, Disease = true },
+	SHAMAN = { Magic = false, Curse = true },
+	PALADIN = { Magic = false, Poison = true, Disease = true },
+	MAGE = { Curse = true },
+	DRUID = { Magic = false, Curse = true, Poison = true, Disease = false },
+	MONK = { Magic = false, Poison = true, Disease = true }
+}
+
+local AfflictedColor = { };
+AfflictedColor["none"] = { r = 1, g = 0, b = 0 };
+AfflictedColor["Magic"]    = { r = 0, g = 0.4, b = 1 };
+AfflictedColor["Curse"]    = { r = 0.6, g = 0.1, b = 1 };
+AfflictedColor["Disease"]  = { r = 1, g = 0.4, b = 0 };
+AfflictedColor["Poison"]   = { r = 0.4, g = 1, b = 0 };
+AfflictedColor[""] = AfflictedColor["none"];
+
+local DEMO_COLORS = {"none", "Magic", "Curse", "Disease", "Poison"};
+
+local SymbiosisName = GetSpellInfo(110309)
+local CleanseName = GetSpellInfo(4987)
+local dispellist = CanDispel[playerClass] or {}
+local blackList = {
+	[GetSpellInfo(140546)] = true, --Fully Mutated
+	[GetSpellInfo(136184)] = true, --Thick Bones
+	[GetSpellInfo(136186)] = true, --Clear mind
+	[GetSpellInfo(136182)] = true, --Improved Synapses
+	[GetSpellInfo(136180)] = true, --Keen Eyesight
+}
+
+local function GetDebuffType(unit, filter)
+	if not unit or not UnitCanAssist("player", unit) then return nil end
+	local i = 1
+	while true do
+		local name, _, texture, _, debufftype = UnitAura(unit, i, "HARMFUL")
+		if not texture then break end
+		if debufftype and (not filter or (filter and dispellist[debufftype])) and not blackList[name] then
+			return debufftype, texture
+		end
+		i = i + 1
+	end
+end
+
+local function UpdateTalentSpec(self, event, levels)
+	if event == "CHARACTER_POINTS_CHANGED" and levels > 0 then return end
+
+	local currentSpec = 0;
+	local activeGroup = GetActiveSpecGroup()
+
+	if(activeGroup) then
+		currentSpec = GetSpecialization(false, false, activeGroup)
+	end;
+
+	if playerClass == "PRIEST" then
+		if currentSpec == 3 then
+			dispellist.Disease = false
+		else
+			dispellist.Disease = true
+		end
+	elseif playerClass == "PALADIN" then
+		if currentSpec == 1 then
+			dispellist.Magic = true
+		else
+			dispellist.Magic = false
+		end
+	elseif playerClass == "SHAMAN" then
+		if currentSpec == 3 then
+			dispellist.Magic = true
+		else
+			dispellist.Magic = false
+		end
+	elseif playerClass == "DRUID" then
+		if currentSpec == 4 then
+			dispellist.Magic = true
+		else
+			dispellist.Magic = false
+		end
+	elseif playerClass == "MONK" then
+		if currentSpec == 2 then
+			dispellist.Magic = true
+		else
+			dispellist.Magic = false
+		end
+	end
+end
+
+local function CheckSymbiosis()
+	if GetSpellInfo(SymbiosisName) == CleanseName then
+		dispellist.Disease = true
+	else
+		dispellist.Disease = false
+	end
+end
+
+local function Update(self, event, unit)
+	if(unit ~= self.unit and (not self.Afflicted.forceShow)) then return; end
+	local afflicted = self.Afflicted
+	if afflicted.forceShow then
+		local color = AfflictedColor[DEMO_COLORS[random(1,#DEMO_COLORS)]]
+		afflicted.Texture:SetVertexColor(color.r, color.g, color.b, 0.2)
+		afflicted:SetBackdropBorderColor(color.r, color.g, color.b, 0.5)
+	else
+		local debuffType, texture  = GetDebuffType(unit, afflicted.ClassFilter)
+		if debuffType then
+			local color = AfflictedColor[debuffType]
+			afflicted.Texture:SetVertexColor(color.r, color.g, color.b, 0.2)
+			afflicted:SetBackdropBorderColor(color.r, color.g, color.b, 0.5)
+		else
+			afflicted.Texture:SetVertexColor(0,0,0,0)
+			afflicted:SetBackdropBorderColor(0,0,0,0)
+		end
+	end
+end
+
+local function Enable(self)
+	local afflicted = self.Afflicted
+	if(not afflicted) then return end
+	if(afflicted.ClassFilter and (not CanDispel[playerClass])) then return end
+
+	self:RegisterEvent("UNIT_AURA", Update)
+	self:RegisterEvent("PLAYER_TALENT_UPDATE", UpdateTalentSpec)
+	self:RegisterEvent("CHARACTER_POINTS_CHANGED", UpdateTalentSpec)
+
+	UpdateTalentSpec(self)
+
+  	self:RegisterUnitEvent("UNIT_AURA", self.unit)
+
+	if playerClass == "DRUID" then
+    self:RegisterEvent("SPELLS_CHANGED", CheckSymbiosis)
+	end
+
+	return true
+end
+
+local function Disable(self)
+	local afflicted = self.Afflicted
+	if(not afflicted) then return end
+	self:UnregisterEvent("UNIT_AURA", Update)
+	self:UnregisterEvent("PLAYER_TALENT_UPDATE", UpdateTalentSpec)
+	self:UnregisterEvent("CHARACTER_POINTS_CHANGED", UpdateTalentSpec)
+
+	if playerClass == "DRUID" then
+    self:UnregisterEvent("SPELLS_CHANGED", CheckSymbiosis)
+	end
+	afflicted.Texture:SetVertexColor(0,0,0,0)
+	afflicted:SetBackdropBorderColor(0,0,0,0)
+end
+
+oUF:AddElement('Afflicted', Update, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_Afflicted/oUF_Afflicted.toc b/SVUI_UnitFrames/libs/Plugins/oUF_Afflicted/oUF_Afflicted.toc
new file mode 100644
index 0000000..3aa4eed
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_Afflicted/oUF_Afflicted.toc
@@ -0,0 +1,10 @@
+## Interface: 50001
+## Title: oUF Afflicted
+## Notes: Adds Custom Debuff Highlighting to oUF.
+## Author: Failcoder
+## Version: 1.1.0
+## X-Category: oUF
+## Dependencies: oUF
+
+
+oUF_ActionPanel.lua
\ No newline at end of file
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_AuraWatch/oUF_AuraWatch.lua b/SVUI_UnitFrames/libs/Plugins/oUF_AuraWatch/oUF_AuraWatch.lua
new file mode 100644
index 0000000..1ecf042
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_AuraWatch/oUF_AuraWatch.lua
@@ -0,0 +1,476 @@
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local error         = _G.error;
+local print         = _G.print;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local tostring      = _G.tostring;
+local setmetatable  = _G.setmetatable;
+--STRING
+local string        = _G.string;
+local format        = string.format;
+--MATH
+local math          = _G.math;
+local floor         = math.floor
+local ceil          = math.ceil
+--BLIZZARD API
+local GetTime       	= _G.GetTime;
+local CreateFrame       = _G.CreateFrame;
+local UnitAura         	= _G.UnitAura;
+local GetSpellInfo      = _G.GetSpellInfo;
+local NumberFontNormal  = _G.NumberFontNormal;
+
+local _, ns = ...
+local oUF = oUF or ns.oUF
+assert(oUF, "oUF_AuraWatch cannot find an instance of oUF. If your oUF is embedded into a layout, it may not be embedded properly.")
+
+local UnitBuff, UnitDebuff, UnitGUID = UnitBuff, UnitDebuff, UnitGUID
+local CACHED_GUIDS = {};
+local CACHED_IDS = {};
+local PLAYER_UNITS = {
+	player = true,
+	vehicle = true,
+	pet = true,
+};
+local COUNT_OFFSETS = {
+	["TOPLEFT"] = {6, 1},
+	["TOPRIGHT"] = {-6, 1},
+	["BOTTOMLEFT"] = {6, 1},
+	["BOTTOMRIGHT"] = {-6, 1},
+	["LEFT"] = {6, 1},
+	["RIGHT"] = {-6, 1},
+	["TOP"] = {0, 0},
+	["BOTTOM"] = {0, 0},
+};
+local TEXT_OFFSETS = {
+	["TOPLEFT"] = {"LEFT", "RIGHT", -2, 0},
+	["TOPRIGHT"] = {"RIGHT", "LEFT", 2, 0},
+	["BOTTOMLEFT"] = {"LEFT", "RIGHT", -2, 0},
+	["BOTTOMRIGHT"] = {"RIGHT", "LEFT", 2, 0},
+	["LEFT"] = {"LEFT", "RIGHT", -2, 0},
+	["RIGHT"] = {"RIGHT", "LEFT", 2, 0},
+	["TOP"] = {"RIGHT", "LEFT", 2, 0},
+	["BOTTOM"] = {"RIGHT", "LEFT", 2, 0},
+};
+
+local setupGUID
+do
+	local cache = setmetatable({}, {__type = "k"})
+
+	local frame = CreateFrame"Frame"
+	frame:SetScript("OnEvent", function(self, event)
+		for k,t in pairs(CACHED_GUIDS) do
+			CACHED_GUIDS[k] = nil
+			for a in pairs(t) do
+				t[a] = nil
+			end
+			cache[t] = true
+		end
+	end)
+	frame:RegisterEvent"PLAYER_REGEN_ENABLED"
+	frame:RegisterEvent"PLAYER_ENTERING_WORLD"
+
+	function setupGUID(guid)
+		local t = next(cache)
+		if t then
+			cache[t] = nil
+		else
+			t = {}
+		end
+		CACHED_GUIDS[guid] = t
+	end
+end
+
+local day, hour, minute, second = 86400, 3600, 60, 1;
+
+local function formatTime(s)
+	if s >= day then
+		return format("%dd", ceil(s / hour))
+	elseif s >= hour then
+		return format("%dh", ceil(s / hour))
+	elseif s >= minute then
+		return format("%dm", ceil(s / minute))
+	elseif s >= 5 then
+		return floor(s)
+	end
+
+	return format("%.1f", s)
+end
+
+local function updateText(self, elapsed)
+	if self.timeLeft then
+		self.elapsed = (self.elapsed or 0) + elapsed
+		if self.elapsed >= 0.1 then
+			if not self.first then
+				self.timeLeft = self.timeLeft - self.elapsed
+			else
+				self.timeLeft = self.timeLeft - GetTime()
+				self.first = false
+			end
+			if self.timeLeft > 0 and ((self.timeLeft <= self.textThreshold) or self.textThreshold == -1) then
+				local time = formatTime(self.timeLeft)
+				self.text:SetText(time)
+			else
+				self.text:SetText('')
+				self:SetScript("OnUpdate", nil)
+			end
+			self.elapsed = 0
+		end
+	end
+end
+
+
+local function resetIcon(icon, frame, count, duration, remaining)
+	if icon.onlyShowMissing then
+		icon:Hide()
+	else
+		icon:Show()
+		if icon.cooldown then
+			if duration and duration > 0 and icon.style ~= 'NONE' then
+				icon.cooldown:SetCooldown(remaining - duration, duration)
+				icon.cooldown:Show()
+			else
+				icon.cooldown:Hide()
+			end
+		end
+
+		if icon.displayText then
+			icon.timeLeft = remaining
+			icon.first = true;
+			icon:SetScript('OnUpdate', updateText)
+		end
+
+		if icon.count then
+			icon.count:SetText((count > 1 and count))
+		end
+		if icon.overlay then
+			icon.overlay:Hide()
+		end
+		icon:SetAlpha(icon.presentAlpha)
+	end
+end
+
+local function expireIcon(icon, frame)
+	if icon.onlyShowPresent then
+		icon:Hide()
+	else
+		if (icon.cooldown) then icon.cooldown:Hide() end
+		if (icon.count) then icon.count:SetText() end
+		icon:SetAlpha(icon.missingAlpha)
+		if icon.overlay then
+			icon.overlay:Show()
+		end
+		icon:Show()
+	end
+end
+
+local Update = function(self, event, unit)
+	if self.unit ~= unit or not unit then return end
+	local watch = self.AuraWatch
+	local index, watching = 1, watch.Active
+
+	local guid = UnitGUID(unit)
+	if not guid then return end
+	if not CACHED_GUIDS[guid] then setupGUID(guid) end
+
+	for _, aura in pairs(watching) do
+		if not aura.onlyShowMissing then
+			aura:Hide()
+		end
+	end
+
+	local _, name, texture, count, duration, remaining, caster, key, aura, spellID;
+	local filter = "HELPFUL";
+	while true do
+		name, _, texture, count, _, duration, remaining, caster, _, _, spellID = UnitAura(unit, index, filter)
+		if not name then
+			if filter == "HELPFUL" then
+				filter = "HARMFUL"
+				index = 1
+			else
+				break
+			end
+		else
+			if watch.strictMatching then
+				key = spellID
+			else
+				key = name..texture
+			end
+			aura = watching[key]
+
+			if aura and (aura.anyUnit or (caster and aura.fromUnits and aura.fromUnits[caster])) then
+				resetIcon(aura, watch, count, duration, remaining)
+				CACHED_GUIDS[guid][key] = true
+				CACHED_IDS[key] = true
+			end
+			index = index + 1
+		end
+	end
+
+	for cacheKey in pairs(CACHED_GUIDS[guid]) do
+		if watching[cacheKey] and not CACHED_IDS[cacheKey] then
+			expireIcon(watching[cacheKey], watch)
+		end
+	end
+
+	for cacheKey in pairs(CACHED_IDS) do
+		CACHED_IDS[cacheKey] = nil
+	end
+end
+
+local UpdateIcons = function(self)
+	local auras = self.Cache
+
+	for _,aura in pairs(auras) do
+
+		local name, _, image = GetSpellInfo(aura.spellID)
+
+		if name then
+			aura.name = name
+
+			if not aura.cooldown and not (self.hideCooldown or aura.hideCooldown) then
+				local cd = CreateFrame("Cooldown", nil, aura, "CooldownFrameTemplate")
+				cd:SetAllPoints(aura)
+				aura.cooldown = cd
+			end
+
+			if not aura.icon then
+				local tex = aura:CreateTexture(nil, "BACKGROUND")
+				tex:SetAllPoints(aura)
+				tex:SetTexture(image)
+				aura.icon = tex
+				if not aura.overlay then
+					local overlay = aura:CreateTexture(nil, "OVERLAY")
+					overlay:SetTexture"Interface\\Buttons\\UI-Debuff-Overlays"
+					overlay:SetAllPoints(aura)
+					overlay:SetTexCoord(.296875, .5703125, 0, .515625)
+					overlay:SetVertexColor(1, 0, 0)
+					aura.overlay = overlay
+				end
+			end
+
+			if not aura.count and not (self.hideCount or aura.hideCount) then
+				local count = aura:CreateFontString(nil, "OVERLAY")
+				count:SetFontObject(NumberFontNormal)
+				count:SetPoint("BOTTOMRIGHT", aura, "BOTTOMRIGHT", -1, 0)
+				aura.count = count
+			end
+
+			if aura.onlyShowMissing == nil then
+				aura.onlyShowMissing = self.onlyShowMissing
+			end
+			if aura.onlyShowPresent == nil then
+				aura.onlyShowPresent = self.onlyShowPresent
+			end
+			if aura.presentAlpha == nil then
+				aura.presentAlpha = self.presentAlpha
+			end
+			if aura.missingAlpha == nil then
+				aura.missingAlpha = self.missingAlpha
+			end
+			if aura.fromUnits == nil then
+				aura.fromUnits = self.fromUnits or PLAYER_UNITS
+			end
+			if aura.anyUnit == nil then
+				aura.anyUnit = self.anyUnit
+			end
+
+			if self.strictMatching then
+				self.Active[aura.spellID] = aura
+			else
+				self.Active[name..image] = aura
+			end
+
+			if self.PostCreateIcon then self:PostCreateIcon(aura, aura.spellID, name, self) end
+		--else
+			--print("oUF_AuraWatch error: no spell with "..tostring(aura.spellID).." spell ID exists")
+		end
+	end
+end
+
+local ForceUpdate = function(self)
+	if self.PreForcedUpdate then self:PreForcedUpdate() end
+	local frame = self:GetParent()
+
+	if(not self.watchEnabled) then
+		self:Hide();
+		return;
+	else
+		self:Show();
+	end
+
+	local watchsize = self.watchSize;
+	local watchfilter = self.watchFilter;
+
+	if(watchfilter) then
+		if self.Cache then
+			for i = 1, #self.Cache do
+				local iconTest = false;
+				for id, data in pairs(watchfilter) do
+					if(data.id and (data.id == self.Cache[i])) then
+						iconTest = true;
+						break
+					end
+				end
+				if not iconTest then
+					self.Cache[i]:Hide()
+					self.Cache[i] = nil
+				end
+			end
+		end
+
+		for stringID, data in pairs(watchfilter) do
+			local id = data.id;
+			local buffName, _, buffTexture = GetSpellInfo(id)
+			if buffName then
+				local aura;
+				if not self.Cache[id] then
+					aura = CreateFrame("Frame", nil, self)
+				else
+					aura = self.Cache[id]
+				end
+				aura.name = buffName;
+				aura.image = buffTexture;
+				aura.spellID = id;
+				aura.anyUnit = data.anyUnit;
+				aura.style = data.style or "NONE";
+				aura.onlyShowMissing = data.onlyShowMissing;
+				aura.presentAlpha = aura.onlyShowMissing and 0 or 1;
+				aura.missingAlpha = aura.onlyShowMissing and 1 or 0;
+				aura.textThreshold = data.textThreshold or -1;
+				aura.displayText = data.displayText;
+				aura:SetWidth(watchsize)
+				aura:SetHeight(watchsize)
+				aura:ClearAllPoints()
+
+				aura:SetPoint(data.point, frame.Health, data.point, data.xOffset, data.yOffset)
+				if not aura.icon then
+					aura.icon = aura:CreateTexture(nil, "BORDER")
+					aura.icon:SetAllPoints(aura)
+				end
+				if not aura.border then
+					aura.border = aura:CreateTexture(nil, "BACKGROUND")
+					aura.border:SetPoint("TOPLEFT", -1, 1)
+					aura.border:SetPoint("BOTTOMRIGHT", 1, -1)
+					aura.border:SetTexture([[Interface\BUTTONS\WHITE8X8]])
+					aura.border:SetVertexColor(0, 0, 0)
+				end
+				if not aura.cooldown then
+					aura.cooldown = CreateFrame("Cooldown", nil, aura, "CooldownFrameTemplate")
+					aura.cooldown:SetAllPoints(aura)
+					aura.cooldown:SetReverse(true)
+					aura.cooldown:SetHideCountdownNumbers(true)
+					aura.cooldown:SetFrameLevel(aura:GetFrameLevel())
+				end
+				if not aura.grip then
+					aura.grip = CreateFrame("Frame", nil, aura);
+					aura.grip:SetAllPoints(aura);
+				end
+				if not aura.text then
+					aura.text = aura.grip:CreateFontString(nil, "BORDER");
+					aura.text:SetFontObject(NumberFontNormal);
+				end
+				if not aura.count then
+					aura.count = aura.grip:CreateFontString(nil, "OVERLAY");
+					aura.count:SetFontObject(NumberFontNormal);
+				end
+
+				if(aura.style == "coloredIcon") then
+					aura.icon:SetTexture([[Interface\BUTTONS\WHITE8X8]])
+					if(data.color) then
+						aura.icon:SetVertexColor(data.color.r, data.color.g, data.color.b)
+					else
+						aura.icon:SetVertexColor(0.8, 0.8, 0.8)
+					end
+					aura.icon:Show()
+					aura.border:Show()
+					aura.cooldown:SetAlpha(1)
+				elseif(aura.style == "texturedIcon") then
+					aura.icon:SetVertexColor(1, 1, 1)
+					aura.icon:SetTexCoord(.18, .82, .18, .82)
+					aura.icon:SetTexture(aura.image)
+					aura.icon:Show()
+					aura.border:Show()
+					aura.cooldown:SetAlpha(1)
+				else
+					aura.border:Hide()
+					aura.icon:Hide()
+					aura.cooldown:SetAlpha(0)
+				end
+
+				if aura.displayText then
+					aura.text:Show()
+					local r, g, b = 1, 1, 1;
+					if(data.textColor) then
+						r, g, b = data.textColor.r, data.textColor.g, data.textColor.b
+					end
+					aura.text:SetTextColor(r, g, b)
+				else
+					aura.text:Hide()
+				end
+
+				aura.text:ClearAllPoints();
+				aura.text:SetPoint(data.point, aura, data.point);
+				aura.count:ClearAllPoints()
+				if aura.displayText then
+					local anchor, relative, x, y = unpack(TEXT_OFFSETS[data.point])
+					aura.count:SetPoint(anchor, aura.text, relative, x, y)
+				else
+					aura.count:SetPoint("CENTER", unpack(COUNT_OFFSETS[data.point]))
+				end
+
+				if(not data.enable) then
+					self.Cache[id] = nil;
+					if self.Active then
+						self.Active[id] = nil
+					end
+					aura:Hide()
+					aura = nil
+				else
+					self.Cache[id] = aura;
+					if self.Active then
+						self.Active[id] = aura
+					end
+				end
+			end
+		end
+	end
+	self:UpdateIcons()
+end
+
+local Enable = function(self)
+	local watch = self.AuraWatch;
+	if watch then
+		watch.__owner = self
+		watch.UpdateIcons = UpdateIcons
+		watch.ForceUpdate = ForceUpdate
+		watch.Cache = {}
+		watch.Active = {}
+
+		self:RegisterEvent("UNIT_AURA", Update)
+
+		watch:ForceUpdate()
+
+		return true
+	else
+		return false
+	end
+end
+
+local Disable = function(self)
+	local watch = self.AuraWatch;
+	if watch then
+
+		self:UnregisterEvent("UNIT_AURA", Update)
+
+		for _,icon in pairs(watch.Cache) do
+			icon:Hide()
+		end
+	end
+end
+
+oUF:AddElement("AuraWatch", Update, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_AuraWatch/oUF_AuraWatch.toc b/SVUI_UnitFrames/libs/Plugins/oUF_AuraWatch/oUF_AuraWatch.toc
new file mode 100644
index 0000000..7a536b4
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_AuraWatch/oUF_AuraWatch.toc
@@ -0,0 +1,10 @@
+## Interface: 30300
+## Title: oUF AuraWatch
+## Author: Astromech
+## Version: 1.3.58-6
+## Notes: Adds aura timers to oUF
+## OptionalDeps: oUF
+## X-oUF: oUF
+
+
+oUF_AuraWatch.lua
\ No newline at end of file
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_CombatFader/oUF_CombatFader.lua b/SVUI_UnitFrames/libs/Plugins/oUF_CombatFader/oUF_CombatFader.lua
new file mode 100644
index 0000000..bcfd71d
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_CombatFader/oUF_CombatFader.lua
@@ -0,0 +1,142 @@
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local error         = _G.error;
+local print         = _G.print;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local tostring      = _G.tostring;
+local type  		= _G.type;
+
+--BLIZZARD API
+local InCombatLockdown  = _G.InCombatLockdown;
+local UnitHealth        = _G.UnitHealth;
+local UnitExists        = _G.UnitExists;
+local UnitHealthMax     = _G.UnitHealthMax;
+local UnitCastingInfo   = _G.UnitCastingInfo;
+local UnitChannelInfo   = _G.UnitChannelInfo;
+
+local parent, ns = ...
+local oUF = ns.oUF
+local frames, allFrames = {}, {}
+local showStatus
+
+local CheckForReset = function()
+	for frame, unit in pairs(allFrames) do
+		if frame.___fadereset then
+			frame:SetAlpha(1)
+			frame.___fadereset = nil
+		end
+	end
+end
+
+local FadeFramesInOut = function(fade, unit)
+	for frame, unit in pairs(frames) do
+		if not UnitExists(unit) then return end
+		if fade then
+			if(frame:GetAlpha() ~= 1 or (frame.___fadeset and frame.___fadeset[2] == 0)) then
+				frame:FadeIn(0.15)
+			end
+		else
+			if frame:GetAlpha() ~= 0 then
+				frame:FadeOut(0.15)
+				frame:FadeCallback(CheckForReset)
+			else
+				showStatus = false;
+				return
+			end
+		end
+	end
+
+	if unit == 'player' then
+		showStatus = fade
+	end
+end
+
+local Update = function(self, arg1, arg2)
+	if arg1 == "UNIT_HEALTH" and self and self.unit ~= arg2 then return end
+	if type(arg1) == 'boolean' and not frames[self] then return end
+
+	if(not frames[self]) then
+		self:FadeIn(0.15)
+		self.___fadereset = true
+		return
+	end
+
+	local combat = InCombatLockdown()
+	local cur, max = UnitHealth("player"), UnitHealthMax("player")
+	local cast, channel = UnitCastingInfo("player"), UnitChannelInfo("player")
+	local target, focus = UnitExists("target"), UnitExists("focus")
+
+	if (cast or channel) and showStatus ~= true then
+		FadeFramesInOut(true, frames[self])
+	elseif cur ~= max and showStatus ~= true then
+		FadeFramesInOut(true, frames[self])
+	elseif (target or focus) and showStatus ~= true then
+		FadeFramesInOut(true, frames[self])
+	elseif arg1 == true and showStatus ~= true then
+		FadeFramesInOut(true, frames[self])
+	else
+		if combat and showStatus ~= true then
+			FadeFramesInOut(true, frames[self])
+		elseif not target and not combat and not focus and (cur == max) and not (cast or channel) then
+			FadeFramesInOut(false, frames[self])
+		end
+	end
+end
+
+local Enable = function(self, unit)
+	if(self.CombatFade) then
+		frames[self] = self.unit
+		allFrames[self] = self.unit
+
+		if unit == 'player' then
+			showStatus = false;
+		end
+
+		self:RegisterEvent("PLAYER_ENTERING_WORLD", Update)
+		self:RegisterEvent("PLAYER_REGEN_ENABLED", Update)
+		self:RegisterEvent("PLAYER_REGEN_DISABLED", Update)
+		self:RegisterEvent("PLAYER_TARGET_CHANGED", Update)
+		self:RegisterEvent("PLAYER_FOCUS_CHANGED", Update)
+		self:RegisterEvent("UNIT_HEALTH", Update)
+		self:RegisterEvent("UNIT_SPELLCAST_START", Update)
+		self:RegisterEvent("UNIT_SPELLCAST_STOP", Update)
+		self:RegisterEvent("UNIT_SPELLCAST_CHANNEL_START", Update)
+		self:RegisterEvent("UNIT_SPELLCAST_CHANNEL_STOP", Update)
+		self:RegisterEvent("UNIT_PORTRAIT_UPDATE", Update)
+		self:RegisterEvent("UNIT_MODEL_CHANGED", Update)
+
+		if not self.CombatFadeHooked then
+			self:HookScript("OnEnter", function(self) Update(self, true) end)
+			self:HookScript("OnLeave", function(self) Update(self, false) end)
+			self.CombatFadeHooked = true
+		end
+		return true
+	end
+end
+
+local Disable = function(self)
+	if(self.CombatFade) then
+		frames[self] = nil
+		Update(self)
+
+		self:UnregisterEvent("PLAYER_ENTERING_WORLD", Update)
+		self:UnregisterEvent("PLAYER_REGEN_ENABLED", Update)
+		self:UnregisterEvent("PLAYER_REGEN_DISABLED", Update)
+		self:UnregisterEvent("PLAYER_TARGET_CHANGED", Update)
+		self:UnregisterEvent("PLAYER_FOCUS_CHANGED", Update)
+		self:UnregisterEvent("UNIT_HEALTH", Update)
+		self:UnregisterEvent("UNIT_SPELLCAST_START", Update)
+		self:UnregisterEvent("UNIT_SPELLCAST_STOP", Update)
+		self:UnregisterEvent("UNIT_SPELLCAST_CHANNEL_START", Update)
+		self:UnregisterEvent("UNIT_SPELLCAST_CHANNEL_STOP", Update)
+		self:UnregisterEvent("UNIT_PORTRAIT_UPDATE", Update)
+		self:UnregisterEvent("UNIT_MODEL_CHANGED", Update)
+	end
+end
+
+oUF:AddElement('CombatFade', Update, Enable, Disable)
\ No newline at end of file
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_CombatFader/oUF_CombatFader.toc b/SVUI_UnitFrames/libs/Plugins/oUF_CombatFader/oUF_CombatFader.toc
new file mode 100644
index 0000000..f912f94
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_CombatFader/oUF_CombatFader.toc
@@ -0,0 +1,9 @@
+## Interface: 40200
+## Title: oUF Combat Fader
+## Notes: Adds combat fade ability to oUF
+## Author: SV
+## Version: 1.1.0
+## Dependencies: oUF
+
+
+oUF_CombatFader.lua
\ No newline at end of file
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_Conqueror/oUF_Conqueror.lua b/SVUI_UnitFrames/libs/Plugins/oUF_Conqueror/oUF_Conqueror.lua
new file mode 100644
index 0000000..e1c66fa
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_Conqueror/oUF_Conqueror.lua
@@ -0,0 +1,123 @@
+if(select(2, UnitClass('player')) ~= 'WARRIOR') then return end
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+--BLIZZARD API
+local UnitDebuff      	= _G.UnitDebuff;
+
+local parent, ns = ...
+local oUF = ns.oUF
+
+local ENRAGE_ID = 12880;
+
+local function getEnrageAmount()
+	for i = 1, 40 do
+		local _, _, _, count, _, duration, expires, _, _, _, spellID =
+			UnitBuff("player", i)
+		if(spellID and spellID == ENRAGE_ID) then
+			return floor(expires), duration
+		end
+	end
+	return 0,0
+end
+
+local BarOnUpdate = function(self, elapsed)
+	if not self.duration then return end
+	self.elapsed = (self.elapsed or 0) + elapsed
+	if self.elapsed >= 0.5 then
+		local timeLeft = (self.duration - GetTime())
+		if timeLeft > 0 then
+			self:SetValue(timeLeft)
+		else
+			self.start = nil
+			self.duration = nil
+			self:SetValue(0)
+			self:Hide()
+			self:SetScript("OnUpdate", nil)
+		end
+	end
+end
+
+local EnrageOnUpdate = function(self, elapsed)
+	if not self.duration then return end
+	self.elapsed = (self.elapsed or 0) + elapsed
+	if self.elapsed >= 0.5 then
+		local timeLeft = (self.duration - self.elapsed)
+		if timeLeft > 0 then
+			self.bar:SetValue(timeLeft)
+		else
+			self.start = 0;
+			self.duration = 8;
+			self.elapsed = 0;
+			self.bar:SetValue(0);
+			self:SetScript("OnUpdate", nil);
+			self:FadeOut();
+		end
+	end
+end
+
+local Update = function(self, event, unit)
+	local element = self.Conqueror
+	local enrage = element.Enrage
+	if(element.PreUpdate) then element:PreUpdate(event) end
+
+	if(enrage:IsShown()) then
+		local start, duration = getEnrageAmount()
+		if(duration and start and (start ~= enrage.start)) then
+			enrage.bar:SetMinMaxValues(0, duration)
+			enrage.bar:SetValue(duration)
+
+			enrage.elapsed = 0;
+			enrage.start = start
+			enrage.duration = duration
+			enrage:SetScript('OnUpdate', EnrageOnUpdate)
+			enrage:FadeIn();
+		end
+	end
+
+	if(element.PostUpdate) then
+		return element:PostUpdate(event)
+	end
+end
+
+local Path = function(self, ...)
+	return (self.Conqueror.Override or Update)(self, ...)
+end
+
+local ForceUpdate = function(element)
+	return Path(element.__owner, 'ForceUpdate')
+end
+
+local Enable = function(self)
+	local bar = self.Conqueror
+
+	if(bar) then
+		bar.__owner = self
+		bar.ForceUpdate = ForceUpdate
+
+		self:RegisterEvent('UNIT_AURA', Path, true)
+
+		local enrage = bar.Enrage;
+		if(enrage.bar:IsObjectType'Texture' and not enrage.bar:GetTexture()) then
+			enrage.bar:SetTexture[[Interface\TargetingFrame\UI-StatusBar]]
+		end
+		enrage.bar:SetMinMaxValues(0, 100)
+		enrage.bar:SetValue(0)
+		enrage:FadeOut()
+
+		return true
+	end
+end
+
+local Disable = function(self)
+	local bar = self.Conqueror
+
+	if (bar) then
+		self:UnregisterEvent('UNIT_AURA', Path)
+	end
+end
+
+oUF:AddElement('Conqueror', Path, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_Druidness/oUF_Druidness.lua b/SVUI_UnitFrames/libs/Plugins/oUF_Druidness/oUF_Druidness.lua
new file mode 100644
index 0000000..0c9b3d9
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_Druidness/oUF_Druidness.lua
@@ -0,0 +1,231 @@
+if(select(2, UnitClass('player')) ~= 'DRUID') then return end
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local error         = _G.error;
+local print         = _G.print;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local tostring      = _G.tostring;
+local type  		= _G.type;
+--STRING
+local string        = _G.string;
+local format        = string.format;
+--MATH
+local math          = _G.math;
+local floor         = math.floor
+local ceil          = math.ceil
+--TABLE
+local table         = _G.table;
+local wipe          = _G.wipe;
+--BLIZZARD API
+local BEAR_FORM       		= _G.BEAR_FORM;
+local CAT_FORM 				= _G.CAT_FORM;
+local SPELL_POWER_MANA      = _G.SPELL_POWER_MANA;
+local UnitClass         	= _G.UnitClass;
+local UnitPower         	= _G.UnitPower;
+local UnitReaction         	= _G.UnitReaction;
+local UnitPowerMax         	= _G.UnitPowerMax;
+local UnitIsPlayer      	= _G.UnitIsPlayer;
+local UnitPlayerControlled  = _G.UnitPlayerControlled;
+local GetShapeshiftFormID 	= _G.GetShapeshiftFormID;
+
+local _, ns = ...
+local oUF = ns.oUF or oUF
+
+local ECLIPSE_BAR_SOLAR_BUFF_ID = _G.ECLIPSE_BAR_SOLAR_BUFF_ID
+local ECLIPSE_BAR_LUNAR_BUFF_ID = _G.ECLIPSE_BAR_LUNAR_BUFF_ID
+local SPELL_POWER_ECLIPSE = _G.SPELL_POWER_ECLIPSE
+local MOONKIN_FORM = _G.MOONKIN_FORM
+local ALERTED = false;
+local TextColors = {
+	[1]={1,0.1,0.1},
+	[2]={1,0.5,0.1},
+	[3]={1,1,0.1},
+	[4]={0.5,1,0.1},
+	[5]={0.1,1,0.1}
+};
+
+local ProxyShow = function(self)
+	if(not self.isEnabled) then return end
+	self:Show()
+end
+
+local function CatOverMana(mana, form)
+	if mana.ManaBar:GetValue() < UnitPowerMax('player', SPELL_POWER_MANA) then
+		mana:ProxyShow()
+		return false
+	else
+		mana:Hide()
+		return form == CAT_FORM
+	end
+end
+
+local UpdateVisibility = function(self, event)
+	local bar = self.Druidness
+	local cat = bar.Cat
+	local mana = bar.Mana
+	local form = GetShapeshiftFormID()
+
+	if(form) then
+		if (form == BEAR_FORM or form == CAT_FORM) then
+			if(CatOverMana(mana, form)) then
+				cat:ProxyShow()
+			else
+				cat:Hide()
+			end
+		else
+			cat:Hide()
+			mana:Hide()
+		end
+	else
+		mana:Hide()
+		cat:Hide()
+	end
+end
+
+local UpdatePower = function(self, event, unit, powerType)
+	if(self.unit ~= unit) then return end
+	local bar = self.Druidness
+
+	if(bar.Mana and bar.Mana.ManaBar) then
+		local mana = bar.Mana
+		if(mana.PreUpdate) then
+			mana:PreUpdate(unit)
+		end
+		local min, max = UnitPower('player', SPELL_POWER_MANA), UnitPowerMax('player', SPELL_POWER_MANA)
+
+		mana.ManaBar:SetMinMaxValues(0, max)
+		mana.ManaBar:SetValue(min)
+
+		local r, g, b, t
+		if(mana.colorPower) then
+			t = self.colors.power["MANA"]
+		elseif(mana.colorClass and UnitIsPlayer(unit)) or
+			(mana.colorClassNPC and not UnitIsPlayer(unit)) or
+			(mana.colorClassPet and UnitPlayerControlled(unit) and not UnitIsPlayer(unit)) then
+			local _, class = UnitClass(unit)
+			t = self.colors.class[class]
+		elseif(mana.colorReaction and UnitReaction(unit, 'player')) then
+			t = self.colors.reaction[UnitReaction(unit, "player")]
+		elseif(mana.colorSmooth) then
+			r, g, b = self.ColorGradient(min / max, unpack(mana.smoothGradient or self.colors.smooth))
+		end
+
+		if(t) then
+			r, g, b = t[1], t[2], t[3]
+		end
+
+		if(b) then
+			mana.ManaBar:SetStatusBarColor(r, g, b)
+
+			local bg = mana.bg
+			if(bg) then
+				local mu = bg.multiplier or 1
+				bg:SetVertexColor(r * mu, g * mu, b * mu)
+			end
+		end
+
+		if(mana.PostUpdatePower) then
+			mana:PostUpdatePower(unit, min, max)
+		end
+	end
+
+	UpdateVisibility(self)
+end
+
+local UpdateComboPoints = function(self, event, unit)
+	if(unit == 'pet') then return end
+	local bar = self.Druidness;
+	local cpoints = bar.Cat;
+
+	if(bar.PreUpdate) then
+		bar:PreUpdate()
+	end
+
+	local current = 0
+	if(UnitHasVehicleUI'player') then
+		current = UnitPower("vehicle", SPELL_POWER_COMBO_POINTS);
+	else
+		current = UnitPower("player", SPELL_POWER_COMBO_POINTS);
+	end
+
+	if(cpoints) then
+		local MAX_COMBO_POINTS = UnitPowerMax("player", SPELL_POWER_COMBO_POINTS);
+		for i=1, MAX_COMBO_POINTS do
+			if(i <= current) then
+				cpoints[i]:Show()
+				if(bar.PointShow) then
+					bar.PointShow(cpoints[i])
+				end
+			else
+				cpoints[i]:Hide()
+				if(bar.PointHide) then
+					bar.PointHide(cpoints[i], i)
+				end
+			end
+		end
+	end
+
+	if(bar.PostUpdateComboPoints) then
+		return bar:PostUpdateComboPoints(current)
+	end
+end
+
+local Update = function(self, ...)
+	UpdatePower(self, ...)
+	UpdateComboPoints(self, ...)
+	return UpdateVisibility(self, ...)
+end
+
+local ForceUpdate = function(element)
+	return Update(element.__owner, 'ForceUpdate', element.__owner.unit, 'ECLIPSE')
+end
+
+local function Enable(self)
+	local bar = self.Druidness
+
+	if(bar) then
+		local mana = bar.Mana;
+		local cpoints = bar.Cat;
+		mana.ProxyShow = ProxyShow;
+		cpoints.ProxyShow = ProxyShow;
+
+		self:RegisterEvent('UNIT_POWER_FREQUENT', UpdatePower)
+		self:RegisterEvent('PLAYER_TALENT_UPDATE', UpdateVisibility, true)
+		self:RegisterEvent('UPDATE_SHAPESHIFT_FORM', UpdateVisibility, true)
+		self:RegisterEvent('PLAYER_TARGET_CHANGED', UpdateComboPoints, true)
+		self:RegisterEvent('UNIT_DISPLAYPOWER', UpdateComboPoints, true)
+		self:RegisterEvent('UNIT_MAXPOWER', UpdateComboPoints, true)
+		self:RegisterUnitEvent('UNIT_DISPLAYPOWER', "player")
+		self:RegisterUnitEvent("UNIT_POWER_FREQUENT", "player")
+		self:RegisterUnitEvent("UNIT_MAXPOWER", "player")
+
+		UpdateVisibility(self)
+		return true
+	end
+end
+
+local function Disable(self)
+	local bar = self.Druidness
+
+	if(bar) then
+		--local chicken = bar.Chicken
+		local mana = bar.Mana
+		--chicken:Hide()
+		mana:Hide()
+
+		self:RegisterEvent('UNIT_POWER_FREQUENT', UpdatePower)
+		self:UnregisterEvent('PLAYER_TALENT_UPDATE', UpdateVisibility)
+		self:UnregisterEvent('UPDATE_SHAPESHIFT_FORM', UpdateVisibility)
+		self:UnregisterEvent('UNIT_COMBO_POINTS', UpdateComboPoints)
+		self:UnregisterEvent('PLAYER_TARGET_CHANGED', UpdateComboPoints)
+		self:UnregisterEvent('UNIT_DISPLAYPOWER', UpdateComboPoints)
+		self:UnregisterEvent('UNIT_MAXPOWER', UpdateComboPoints)
+	end
+end
+
+oUF:AddElement('BoomChicken', Update, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_Druidness/oUF_Druidness.toc b/SVUI_UnitFrames/libs/Plugins/oUF_Druidness/oUF_Druidness.toc
new file mode 100644
index 0000000..c21b460
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_Druidness/oUF_Druidness.toc
@@ -0,0 +1,11 @@
+## Interface: 40100
+## Title: oUF Druidness
+## Notes: Adds All the Druid Things!
+## Author: SV
+## Version: 1.0
+## X-Category: UnitFrame
+## Dependencies: oUF
+
+
+oUF_Druidness.lua
+
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_Experience/oUF_Experience.lua b/SVUI_UnitFrames/libs/Plugins/oUF_Experience/oUF_Experience.lua
new file mode 100644
index 0000000..9b00640
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_Experience/oUF_Experience.lua
@@ -0,0 +1,129 @@
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local error         = _G.error;
+local print         = _G.print;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local tostring      = _G.tostring;
+local type  		= _G.type;
+--STRING
+local string        = _G.string;
+local format        = string.format;
+--MATH
+local math          = _G.math;
+local floor         = math.floor
+--BLIZZARD API
+local UnitXP       		= _G.UnitXP;
+local UnitXPMax 		= _G.UnitXPMax;
+local GetXPExhaustion   = _G.GetXPExhaustion;
+local UnitLevel         = _G.UnitLevel;
+local UnitHasVehicleUI  = _G.UnitHasVehicleUI;
+local MAX_PLAYER_LEVEL  = _G.MAX_PLAYER_LEVEL;
+
+local __, ns = ...
+local oUF = ns.oUF or oUF
+assert(oUF, 'oUF Experience was unable to locate oUF install')
+
+for tag, func in pairs({
+	['curxp'] = function(unit)
+		return UnitXP(unit)
+	end,
+	['maxxp'] = function(unit)
+		return UnitXPMax(unit)
+	end,
+	['perxp'] = function(unit)
+		return floor(UnitXP(unit) / UnitXPMax(unit) * 100 + 0.5)
+	end,
+	['currested'] = function()
+		return GetXPExhaustion()
+	end,
+	['perrested'] = function(unit)
+		local rested = GetXPExhaustion()
+		if(rested and rested > 0) then
+			return floor(rested / UnitXPMax(unit) * 100 + 0.5)
+		end
+	end,
+}) do
+	oUF.Tags.Methods[tag] = func
+	oUF.Tags.Events[tag] = 'PLAYER_XP_UPDATE PLAYER_LEVEL_UP UPDATE_EXHAUSTION'
+end
+
+local function Update(self, event, unit)
+	if(self.unit ~= unit) then return end
+
+	local experience = self.Experience
+	if(experience.PreUpdate) then experience:PreUpdate(unit) end
+
+	if(UnitLevel(unit) == MAX_PLAYER_LEVEL or UnitHasVehicleUI('player')) then
+		return experience:Hide()
+	else
+		experience:Show()
+	end
+
+	local min, max = UnitXP(unit), UnitXPMax(unit)
+	experience:SetMinMaxValues(0, max)
+	experience:SetValue(min)
+
+	if(experience.Rested) then
+		local exhaustion = GetXPExhaustion() or 0
+		experience.Rested:SetMinMaxValues(0, max)
+		experience.Rested:SetValue(math.min(min + exhaustion, max))
+	end
+
+	if(experience.PostUpdate) then
+		return experience:PostUpdate(unit, min, max)
+	end
+end
+
+local function Path(self, ...)
+	return (self.Experience.Override or Update) (self, ...)
+end
+
+local function ForceUpdate(element)
+	return Path(element.__owner, 'ForceUpdate', element.__owner.unit)
+end
+
+local function Enable(self, unit)
+	local experience = self.Experience
+	if(experience) then
+		experience.__owner = self
+		experience.ForceUpdate = ForceUpdate
+
+		self:RegisterEvent('PLAYER_XP_UPDATE', Path)
+		self:RegisterEvent('PLAYER_LEVEL_UP', Path)
+
+		local rested = experience.Rested
+		if(rested) then
+			self:RegisterEvent('UPDATE_EXHAUSTION', Path)
+			rested:SetFrameLevel(experience:GetFrameLevel() - 1)
+
+			if(not rested:GetStatusBarTexture()) then
+				rested:SetStatusBarTexture([=[Interface\TargetingFrame\UI-StatusBar]=])
+			end
+		end
+
+		if(not experience:GetStatusBarTexture()) then
+			experience:SetStatusBarTexture([=[Interface\TargetingFrame\UI-StatusBar]=])
+		end
+
+		return true
+	end
+end
+
+local function Disable(self)
+	local experience = self.Experience
+	if(experience) then
+		self:UnregisterEvent('PLAYER_XP_UPDATE', Path)
+		self:UnregisterEvent('PLAYER_LEVEL_UP', Path)
+
+		if(experience.Rested) then
+			self:UnregisterEvent('UPDATE_EXHAUSTION', Path)
+		end
+	end
+end
+
+oUF:AddElement('Experience', Path, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_Experience/oUF_Experience.toc b/SVUI_UnitFrames/libs/Plugins/oUF_Experience/oUF_Experience.toc
new file mode 100644
index 0000000..6c789e4
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_Experience/oUF_Experience.toc
@@ -0,0 +1,9 @@
+## Interface: 50001
+## Author: p3lim
+## Version: 50001.12-Release
+## Title: oUF Experience
+## Notes: Experience Bar support for oUF layouts.
+## RequiredDeps: oUF
+
+
+oUF_Experience.lua
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_Friendship/oUF_Friendship.lua b/SVUI_UnitFrames/libs/Plugins/oUF_Friendship/oUF_Friendship.lua
new file mode 100644
index 0000000..b99ffcb
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_Friendship/oUF_Friendship.lua
@@ -0,0 +1,172 @@
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local error         = _G.error;
+local print         = _G.print;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local tostring      = _G.tostring;
+local type  		= _G.type;
+--STRING
+local string        = _G.string;
+local format        = string.format;
+--MATH
+local math          = _G.math;
+local floor         = math.floor
+local ceil          = math.ceil
+--TABLE
+local table         = _G.table;
+local wipe          = _G.wipe;
+--BLIZZARD API
+local UnitExists       			= _G.UnitExists;
+local UnitIsPlayer 				= _G.UnitIsPlayer;
+local UnitName         			= _G.UnitName;
+local GetFriendshipReputation	= _G.GetFriendshipReputation;
+local GameTooltip         		= _G.GameTooltip;
+local GameTooltip_Hide      	= _G.GameTooltip_Hide;
+
+local _, ns = ...
+local oUF = ns.oUF or oUF
+assert(oUF, 'oUF Friendship was unable to locate oUF install')
+
+--[[
+ If you find an npc with reputation that is not shown,
+ please let me (p3lim) know by PM/comment on the download site.
+ The list is currently generated with the following:
+
+ for index = 1100, 1500 do
+	if(GetFriendshipReputation(index)) then
+		friendships[GetFactionInfoByID(index)] = index
+	end
+ end
+--]]
+local friendships = {
+	[GetFactionInfoByID(1273)] = 1273,
+	[GetFactionInfoByID(1275)] = 1275,
+	[GetFactionInfoByID(1276)] = 1276,
+	[GetFactionInfoByID(1277)] = 1277,
+	[GetFactionInfoByID(1278)] = 1278,
+	[GetFactionInfoByID(1279)] = 1279,
+	[GetFactionInfoByID(1280)] = 1280,
+	[GetFactionInfoByID(1281)] = 1281,
+	[GetFactionInfoByID(1282)] = 1282,
+	[GetFactionInfoByID(1283)] = 1283,
+	-- [GetFactionInfoByID(1357)] = 1357,
+	[GetFactionInfoByID(1358)] = 1358,
+}
+
+local function GetFriendshipID()
+	if(not UnitExists('target')) then return end
+	if(UnitIsPlayer('target')) then return end
+
+	return friendships[UnitName('target')]
+end
+
+for tag, func in pairs({
+	['curfriendship'] = function()
+		local id = GetFriendshipID()
+		if(id) then
+			local _, cur, _, name, details, _, standing, threshold, maximum = GetFriendshipReputation(id)
+			return cur - threshold
+		end
+	end,
+	['currawfriendship'] = function()
+		local id = GetFriendshipID()
+		if(id) then
+			local _, cur = GetFriendshipReputation(id)
+			return cur
+		end
+	end,
+	['perfriendship'] = function()
+		local id = GetFriendshipID()
+		if(id) then
+			local _, cur, _, name, details, _, standing, threshold, maximum = GetFriendshipReputation(id)
+			return math.floor((cur - threshold) / 8400 * 100)
+		end
+	end,
+	['perfullfriendship'] = function()
+		local id = GetFriendshipID()
+		if(id) then
+			local _, cur = GetFriendshipReputation(id)
+			return math.floor(cur / 42999 * 100)
+		end
+	end,
+	['friendshipstanding'] = function()
+		local id = GetFriendshipID()
+		if(id) then
+			local _, cur, _, name, details, _, standing, threshold, maximum = GetFriendshipReputation(id)
+			return standing
+		end
+	end,
+}) do
+	oUF.Tags.Methods[tag] = func
+	oUF.Tags.Events[tag] = 'PLAYER_TARGET_CHANGED'
+end
+
+local function OnEnter(self)
+	local _, cur, _, name, details, _, standing, threshold, maximum = GetFriendshipReputation(GetFriendshipID())
+	GameTooltip:SetOwner(self, 'ANCHOR_BOTTOMRIGHT')
+	GameTooltip:SetText(UnitName('target'), 1, 1, 1)
+	GameTooltip:AddLine(details, nil, nil, nil, true)
+	GameTooltip:AddLine((cur - threshold) .. ' / 8400 (' .. standing .. ')', 1, 1, 1, true)
+	GameTooltip:Show()
+end
+
+local function Update(self)
+	local friendship = self.Friendship
+
+	local id = GetFriendshipID()
+	if(id) then
+		local _, cur, _, name, details, _, standing, threshold, maximum = GetFriendshipReputation(id)
+		friendship:SetMinMaxValues(0, 8400)
+		friendship:SetValue(cur - threshold)
+		friendship:Show()
+	else
+		friendship:Hide()
+	end
+
+	if(friendship.PostUpdate) then
+		return friendship:PostUpdate(id)
+	end
+end
+
+local function Path(self, ...)
+	return (self.Friendship.Override or Update) (self, ...)
+end
+
+local function ForceUpdate(element)
+	return Path(element.__owner, 'ForceUpdate')
+end
+
+local function Enable(self, unit)
+	local friendship = self.Friendship
+	if(friendship) then
+		friendship.__owner = self
+		friendship.ForceUpdate = ForceUpdate
+
+		self:RegisterEvent('PLAYER_TARGET_CHANGED', Path)
+
+		if(friendship.Tooltip) then
+			friendship:EnableMouse(true)
+			friendship:HookScript('OnEnter', OnEnter)
+			friendship:HookScript('OnLeave', GameTooltip_Hide)
+		end
+
+		if(not friendship:GetStatusBarTexture()) then
+			friendship:SetStatusBarTexture([=[Interface\TargetingFrame\UI-StatusBar]=])
+		end
+
+		return true
+	end
+end
+
+local function Disable(self)
+	if(self.Friendship) then
+		self:UnregisterEvent('PLAYER_TARGET_CHANGED', Path)
+	end
+end
+
+oUF:AddElement('Friendship', Path, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_Friendship/oUF_Friendship.toc b/SVUI_UnitFrames/libs/Plugins/oUF_Friendship/oUF_Friendship.toc
new file mode 100644
index 0000000..0640f62
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_Friendship/oUF_Friendship.toc
@@ -0,0 +1,9 @@
+## Interface: 50001
+## Author: p3lim
+## Version: 50001.3-Beta
+## Title: oUF Friendship
+## Notes: NPC Friendship Bar support for oUF layouts.
+## RequiredDeps: oUF
+
+
+oUF_Friendship.lua
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_Gladiator/oUF_Gladiator.lua b/SVUI_UnitFrames/libs/Plugins/oUF_Gladiator/oUF_Gladiator.lua
new file mode 100644
index 0000000..dcf266c
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_Gladiator/oUF_Gladiator.lua
@@ -0,0 +1,188 @@
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local error         = _G.error;
+local print         = _G.print;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local tostring      = _G.tostring;
+local setmetatable  = _G.setmetatable;
+--STRING
+local string        = _G.string;
+local format        = string.format;
+--MATH
+local math          = _G.math;
+local floor         = math.floor
+local ceil          = math.ceil
+--BLIZZARD API
+local GetTime       			= _G.GetTime;
+local CreateFrame       		= _G.CreateFrame;
+local UnitIsEnemy         		= _G.UnitIsEnemy;
+local UnitGUID      			= _G.UnitGUID;
+local IsActiveBattlefieldArena  = _G.IsActiveBattlefieldArena;
+local UnitFactionGroup 			= _G.UnitFactionGroup;
+local GetNumArenaOpponentSpecs 	= _G.GetNumArenaOpponentSpecs;
+local GetArenaOpponentSpec      = _G.GetArenaOpponentSpec;
+local GetSpecializationInfoByID = _G.GetSpecializationInfoByID;
+local UnitName       			= _G.UnitName;
+local SendChatMessage  			= _G.SendChatMessage;
+local CooldownFrame_Set 	= _G.CooldownFrame_Set;
+
+local _, ns = ...
+local oUF = ns.oUF
+
+local trinketSpells = {
+	[59752] = 120,
+	[42292] = 120,
+	[7744] = 45,
+}
+
+local timeLeft = 0
+local Trinket_OnUpdate = function(self, elapsed)
+	local expires = (self.duration - (GetTime() - self.start));
+	if(expires == 0) then
+		local parent = self:GetParent()
+		parent.Icon:SetDesaturated(false)
+		parent.Unavailable:Hide()
+		self:SetScript("OnUpdate", nil)
+	end
+end
+
+local function GetPVPIcons(unit, frameID)
+	local _, trinket, badge
+	local unitFactionGroup = UnitFactionGroup(unit)
+	if unitFactionGroup == "Horde" then
+		trinket, badge = [[Interface\Icons\INV_Jewelry_TrinketPVP_02]], [[Interface\Icons\INV_BannerPVP_01]]
+	elseif unitFactionGroup == "Alliance" then
+		trinket, badge = [[Interface\Icons\INV_Jewelry_TrinketPVP_01]], [[Interface\Icons\INV_BannerPVP_02]]
+	else
+		trinket, badge = [[Interface\Icons\INV_MISC_QUESTIONMARK]], [[Interface\Icons\INV_MISC_QUESTIONMARK]]
+	end
+	if(frameID) then
+		local numOpps = GetNumArenaOpponentSpecs()
+		local specID = GetArenaOpponentSpec(frameID)
+		if((numOpps > 0) and specID) then
+			_, _, _, badge = GetSpecializationInfoByID(specID)
+		end
+	end
+	return trinket, badge
+end
+
+local function LogUpdate(self, event, ...)
+	local arenaMatch = IsActiveBattlefieldArena()
+	local element = self.Gladiator
+	local trinket = element.Trinket
+	local alert = element.Alert
+	if not arenaMatch then trinket:Hide() return end
+	trinket:Show()
+	if(event == "COMBAT_LOG_EVENT_UNFILTERED") then
+		local _, eventType, _, sourceGUID, _, _, _, _, _, _, _, spellID = ...
+		if eventType == "SPELL_CAST_SUCCESS" and sourceGUID == UnitGUID(self.unit) and trinketSpells[spellID] then
+			local startTime = GetTime()
+			local duration = trinketSpells[spellID]
+			trinket.CD.start = startTime
+			trinket.CD.duration = duration
+			trinket.CD.nextUpdate = 0
+			trinket.CD:SetScript("OnUpdate", Trinket_OnUpdate)
+			trinket.Icon:SetDesaturated(true)
+			trinket.Unavailable:Show()
+			CooldownFrame_Set(trinket.CD, startTime, duration, 1)
+		end
+	elseif(alert and event == "UNIT_SPELLCAST_SUCCEEDED") then
+		local unitID, spellName, _, _, spellID = ...
+		if UnitIsEnemy("player", unitID) and (spellID == 118358 or spellID == 104270 or spellName:find("Drink")) then
+			SendChatMessage(("%s is drinking."):format(UnitName(self.unit)), "RAID_WARNING")
+		end
+	end
+end
+
+local Update = function(self, event, ...)
+	local unit, unitType = ...
+	if(event == "COMBAT_LOG_EVENT_UNFILTERED" or event == "UNIT_SPELLCAST_SUCCEEDED") then return LogUpdate(self, event, ...) end
+	if(not unit or unit ~= self.unit) then return end
+	local element = self.Gladiator
+	local trinket = element.Trinket
+	local badge = element.Badge
+	local arenaMatch = IsActiveBattlefieldArena()
+	local frameID = arenaMatch and self:GetID()
+	local tIcon, bIcon = GetPVPIcons(unit, frameID)
+	if(badge) then badge.Icon:SetTexture(bIcon) end
+	if(trinket) then
+		if(not arenaMatch) then trinket:Hide() return end
+		trinket.Icon:SetTexture(tIcon)
+		trinket:Show()
+		if event == 'PLAYER_ENTERING_WORLD' then
+			CooldownFrame_Set(trinket.CD, 1, 1, 1)
+		end
+	end
+end
+
+local Enable = function(self, unit)
+	--if(not unit:match("arena%d")) then return end
+	local element = self.Gladiator
+
+	if(element) then
+		local trinket = element.Trinket
+		local badge = element.Badge
+		self:RegisterEvent("ARENA_OPPONENT_UPDATE", Update)
+		self:RegisterEvent("PLAYER_ENTERING_WORLD", Update)
+
+		if(trinket) then
+			self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED", Update)
+			self:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED", Update)
+			if not trinket.CD then
+				trinket.CD = CreateFrame("Cooldown", nil, trinket, "CooldownFrameTemplate")
+				trinket.CD:SetAllPoints(trinket)
+			end
+
+			if not trinket.Icon then
+				trinket.Icon = trinket:CreateTexture(nil, "BORDER")
+				trinket.Icon:SetAllPoints(trinket)
+				trinket.Icon:SetTexture([[INTERFACE\ICONS\INV_MISC_QUESTIONMARK]])
+			end
+
+			if not trinket.Unavailable then
+				trinket.Unavailable = trinket:CreateTexture(nil, "OVERLAY")
+				trinket.Unavailable:SetAllPoints(trinket)
+				trinket.Unavailable:SetTexture([[Interface\BUTTONS\UI-GroupLoot-Pass-Up]])
+			end
+			trinket:Show()
+		end
+
+		if(badge) then
+			self:RegisterEvent("ARENA_PREP_OPPONENT_SPECIALIZATIONS", Update)
+			if not badge.Icon then
+				badge.Icon = badge:CreateTexture(nil, "OVERLAY")
+				badge.Icon:SetAllPoints(badge)
+				badge.Icon:SetTexture([[INTERFACE\ICONS\INV_MISC_QUESTIONMARK]])
+			end
+			badge:Show()
+		end
+
+		return true
+	end
+end
+
+local Disable = function(self)
+	local element = self.Gladiator
+	local trinket = element.Trinket
+	local badge = element.Badge
+	if(trinket or badge) then
+		self:UnregisterEvent("ARENA_OPPONENT_UPDATE", Update)
+		self:UnregisterEvent("PLAYER_ENTERING_WORLD", Update)
+		if trinket then
+			self:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED", Update)
+			self:UnregisterEvent("UNIT_SPELLCAST_SUCCEEDED", Update)
+			trinket:Hide()
+		end
+		if badge then
+			self:UnregisterEvent("ARENA_PREP_OPPONENT_SPECIALIZATIONS", Update)
+			badge:Hide()
+		end
+	end
+end
+
+oUF:AddElement('Gladiator', Update, Enable, Disable)
\ No newline at end of file
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_Gladiator/oUF_Gladiator.toc b/SVUI_UnitFrames/libs/Plugins/oUF_Gladiator/oUF_Gladiator.toc
new file mode 100644
index 0000000..b4477d0
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_Gladiator/oUF_Gladiator.toc
@@ -0,0 +1,10 @@
+## Interface: 50001
+## Title: oUF Gladiator
+## Notes: Adds PvP trinket status and spec icons to oUF frames.
+## Author: Failcoder
+## Version: 1.1.0
+## X-Category: oUF
+## Dependencies: oUF
+
+
+oUF_Gladiator.lua
\ No newline at end of file
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_HunterTraps/oUF_HunterTraps.lua b/SVUI_UnitFrames/libs/Plugins/oUF_HunterTraps/oUF_HunterTraps.lua
new file mode 100644
index 0000000..479019f
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_HunterTraps/oUF_HunterTraps.lua
@@ -0,0 +1,226 @@
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local type         	= _G.type;
+--BLIZZARD API
+local GetTime       	= _G.GetTime;
+local GetSpecialization = _G.GetSpecialization;
+local UnitDebuff      	= _G.UnitDebuff;
+
+if select(2, UnitClass('player')) ~= "HUNTER" then return end
+
+local _, ns = ...
+local oUF = oUF or ns.oUF
+if not oUF then return end
+
+local TRAP_MASTERY_ID = 63458;
+local TRAP_MASTERY = IsSpellKnown(TRAP_MASTERY_ID);
+local ENHANCED_TRAPS_ID = 157751;
+local ENHANCED_TRAPS = IsSpellKnown(ENHANCED_TRAPS_ID);
+local FIRE_TRAP = GetSpellInfo(13813);
+local FROST_TRAP = GetSpellInfo(1499);
+local ICE_TRAP = GetSpellInfo(13809);
+local SNAKE_TRAP, SNAKE_RANK, SNAKE_ICON = GetSpellInfo(34600);
+
+local FIRE_COLOR = {1,0.25,0};
+local FROST_COLOR = {0.5,1,1};
+local ICE_COLOR = {0.1,0.9,1};
+local SNAKE_COLOR = {0.2,0.8,0};
+--/script print(IsSpellKnown(34600))
+--/script print(IsSpellKnown(13809))
+local TRAP_IDS = {
+	[1] = FIRE_TRAP,
+	[2] = FROST_TRAP,
+	[3] = ICE_TRAP,
+};
+local TRAP_COLORS = {
+	[1] = FIRE_COLOR,
+	[2] = FROST_COLOR,
+	[3] = ICE_COLOR,
+};
+
+local HAS_SNAKE_TRAP = false;
+
+local function UpdateTrap(self, elapsed)
+	if not self.duration then return end
+	self.elapsed = (self.elapsed or 0) + elapsed
+	if self.elapsed >= 0.5 then
+		local timeLeft = (self.duration - (self.duration - (GetTime() - self.start))) * 1000
+		if timeLeft < self.duration then
+			self:SetValue(timeLeft)
+			self:SetStatusBarColor(unpack(TRAP_COLORS[self.colorIndex]))
+		else
+			self:SetStatusBarColor(0.9,0.9,0.9)
+			self.elapsed = 0
+			self.start = nil
+			self.duration = nil
+			self:SetScript("OnUpdate", nil)
+			self:Update(true)
+		end
+	end
+end
+
+local function UpdateSnakeTrap(self, elapsed)
+	if not self.duration then return end
+	self.elapsed = (self.elapsed or 0) + elapsed
+	if self.elapsed >= 0.5 then
+		local timeLeft = (self.duration - (self.duration - (GetTime() - self.start))) * 1000
+		if timeLeft < self.duration then
+			self:SetValue(timeLeft)
+			self:SetStatusBarColor(unpack(TRAP_COLORS[self.colorIndex]))
+		else
+			self:SetStatusBarColor(0.9,0.9,0.9)
+			self.elapsed = 0
+			self.start = nil
+			self.duration = nil
+			self:SetScript("OnUpdate", nil)
+			self:Update(true, HAS_SNAKE_TRAP)
+		end
+	end
+end
+
+local Update = function(self, event, ...)
+	local bar = self.HunterTraps
+	if(event and event == "SPELLS_CHANGED") then
+		ENHANCED_TRAPS = IsSpellKnown(ENHANCED_TRAPS_ID);
+		TRAP_MASTERY = IsSpellKnown(TRAP_MASTERY_ID);
+		local ice_icon = select(3, GetSpellInfo(13809));
+		if(ice_icon == SNAKE_ICON) then
+			TRAP_IDS[3] = SNAKE_TRAP
+			TRAP_COLORS[3] = SNAKE_COLOR
+			HAS_SNAKE_TRAP = true
+		else
+			TRAP_IDS[3] = ICE_TRAP
+			TRAP_COLORS[3] = ICE_COLOR
+			HAS_SNAKE_TRAP = false
+		end
+		bar[3]:Update(nil, HAS_SNAKE_TRAP, true)
+	end
+
+	if(bar.PreUpdate) then bar:PreUpdate(event) end
+
+	local name, start, duration, isReady, enable;
+	local unit, _, _, _, spellID = ...
+	if(unit and (self.unit ~= unit)) then
+		return
+	end
+	if(spellID) then
+		name = GetSpellInfo(spellID)
+		start, isReady, enable = GetSpellCooldown(spellID)
+		duration = GetSpellBaseCooldown(spellID)
+		if(duration and duration > 0) then
+			if(TRAP_MASTERY) then
+				duration = duration - 6;
+			end
+			if(ENHANCED_TRAPS) then
+				duration = duration * 0.5
+			end
+		end
+	end
+
+	if bar:IsShown() then
+		for i = 1, 3 do
+			--bar[i]:SetStatusBarColor(unpack(TRAP_COLORS[i]))
+			if(name and TRAP_IDS[i] == name and isReady == 1) then
+				bar[i]:Show()
+				if((start and start > 0) and (duration and duration > 0)) then
+					bar[i]:SetMinMaxValues(0, duration)
+					bar[i]:SetValue(0)
+					bar[i].start = start
+					bar[i].duration = duration
+					if(i == 3) then
+						bar[i]:SetScript('OnUpdate', UpdateSnakeTrap)
+						bar[i]:Update(false, HAS_SNAKE_TRAP)
+					else
+						bar[i]:SetScript('OnUpdate', UpdateTrap)
+						bar[i]:Update()
+					end
+				end
+			end
+		end
+	end
+
+	if(bar.PostUpdate) then
+		return bar:PostUpdate(event)
+	end
+end
+
+
+local Path = function(self, ...)
+	return (self.HunterTraps.Override or Update) (self, ...)
+end
+
+local ForceUpdate = function(element)
+	return Path(element.__owner, 'ForceUpdate', element.__owner.unit)
+end
+
+local function Enable(self, unit)
+	local bar = self.HunterTraps
+
+	if(bar) then
+		self:RegisterEvent("SPELLS_CHANGED", Path)
+		self:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED", Path)
+		self:RegisterEvent("PLAYER_TALENT_UPDATE", Path)
+		self:RegisterEvent("PLAYER_ENTERING_WORLD", Path)
+		bar.__owner = self
+		bar.ForceUpdate = ForceUpdate
+
+		local barWidth,barHeight = bar:GetSize()
+		local trapSize = barWidth * 0.25
+
+		local ice_icon = select(3, GetSpellInfo(13809));
+		if(ice_icon == SNAKE_ICON) then
+			TRAP_IDS[3] = SNAKE_TRAP
+			TRAP_COLORS[3] = SNAKE_COLOR
+			HAS_SNAKE_TRAP = true
+		else
+			TRAP_IDS[3] = ICE_TRAP
+			TRAP_COLORS[3] = ICE_COLOR
+			HAS_SNAKE_TRAP = false
+		end
+		for i = 1, 3 do
+			if not bar[i] then
+				bar[i] = CreateFrame("Statusbar", nil, bar)
+				bar[i]:SetPoint("LEFT", bar, "LEFT", (trapSize * (i - 1)), 0)
+				bar[i]:SetSize(trapSize,trapSize)
+			end
+
+			bar[i].colorIndex = i;
+
+			if not bar[i]:GetStatusBarTexture() then
+				bar[i]:SetStatusBarTexture([=[Interface\TargetingFrame\UI-StatusBar]=])
+			end
+
+			bar[i]:SetFrameLevel(bar:GetFrameLevel() + 1)
+			bar[i]:GetStatusBarTexture():SetHorizTile(false)
+			bar[i]:SetStatusBarColor(0.9,0.9,0.9)
+
+			if bar[i].bg then
+				bar[i].bg:SetAllPoints()
+			end
+
+			bar[i]:SetMinMaxValues(0, 1)
+			bar[i]:SetValue(1)
+			bar[i]:Update(true, HAS_SNAKE_TRAP)
+		end
+
+		return true;
+	end
+end
+
+local function Disable(self,unit)
+	local bar = self.HunterTraps
+
+	if(bar) then
+		self:UnregisterEvent("SPELLS_CHANGED", Path)
+		self:UnregisterEvent('UNIT_SPELLCAST_SUCCEEDED', Path)
+		self:UnregisterEvent("PLAYER_TALENT_UPDATE", Path)
+		self:UnregisterEvent("PLAYER_ENTERING_WORLD", Path)
+		bar:Hide()
+	end
+end
+
+oUF:AddElement("HunterTraps",Path,Enable,Disable)
\ No newline at end of file
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_HyperCombo/oUF_HyperCombo.lua b/SVUI_UnitFrames/libs/Plugins/oUF_HyperCombo/oUF_HyperCombo.lua
new file mode 100644
index 0000000..007e596
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_HyperCombo/oUF_HyperCombo.lua
@@ -0,0 +1,139 @@
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+
+local class = select(2, UnitClass("player"));
+if(class ~= "ROGUE") then return end;
+
+local assert        = _G.assert;
+local error         = _G.error;
+local print         = _G.print;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local tostring      = _G.tostring;
+local type  		= _G.type;
+--STRING
+local string        = _G.string;
+local format        = string.format;
+--MATH
+local math          = _G.math;
+local floor         = math.floor
+local ceil          = math.ceil
+--TABLE
+local table         = _G.table;
+local wipe          = _G.wipe;
+--BLIZZARD API
+local GetShapeshiftForm         = _G.GetShapeshiftForm;
+local UnitHasVehicleUI 			= _G.UnitHasVehicleUI;
+local UnitBuff         			= _G.UnitBuff;
+local MAX_COMBO_POINTS      	= _G.MAX_COMBO_POINTS;
+local GetSpellInfo      		= _G.GetSpellInfo;
+local GetComboPoints  			= _G.GetComboPoints;
+
+local parent, ns = ...
+local oUF = ns.oUF
+
+local ALERTED = false
+local TextColors = {
+	[1]={1,0.1,0.1},
+	[2]={1,0.5,0.1},
+	[3]={1,1,0.1},
+	[4]={0.5,1,0.1},
+	[5]={0.1,1,0.1}
+};
+
+local Update = function(self, event, unit)
+	if(not (unit == 'player')) then return end
+	local bar = self.HyperCombo;
+	local cpoints = bar.Combo;
+	local current = 0
+	if(UnitHasVehicleUI'player') then
+		current = UnitPower("vehicle", SPELL_POWER_COMBO_POINTS);
+	else
+		current = UnitPower("player", SPELL_POWER_COMBO_POINTS);
+	end
+
+	if(cpoints and current) then
+		if(bar.PreUpdate) then
+			bar:PreUpdate()
+		end
+
+		local MAX_COMBO_POINTS = UnitPowerMax("player", SPELL_POWER_COMBO_POINTS);
+		for i=1, MAX_COMBO_POINTS do
+			if(i <= current) then
+				cpoints[i]:Show()
+				if(bar.PointShow) then
+					bar.PointShow(cpoints[i])
+				end
+			else
+				cpoints[i]:Hide()
+				if(bar.PointHide) then
+					bar.PointHide(cpoints[i], i)
+				end
+			end
+		end
+
+		if(bar.PostUpdate) then
+			return bar:PostUpdate(current)
+		end
+	end
+end
+
+local Path = function(self, ...)
+	return (self.HyperCombo.Override or Update) (self, ...)
+end
+
+local ForceUpdate = function(element)
+	return Path(element.__owner, 'ForceUpdate', element.__owner.unit)
+end
+
+local Enable = function(self)
+	local bar = self.HyperCombo
+	if(bar) then
+		bar.__owner = self
+		bar.ForceUpdate = ForceUpdate
+		self:RegisterEvent('PLAYER_ENTERING_WORLD', Path, true)
+		self:RegisterEvent('PLAYER_TARGET_CHANGED', Path, true)
+		self:RegisterEvent('UNIT_DISPLAYPOWER', Path, true)
+		self:RegisterUnitEvent('UNIT_DISPLAYPOWER', "player")
+		self:RegisterEvent('UNIT_POWER_FREQUENT', Path, true)
+		self:RegisterUnitEvent("UNIT_POWER_FREQUENT", "player")
+		self:RegisterEvent('UNIT_MAXPOWER', Path, true)
+		self:RegisterUnitEvent("UNIT_MAXPOWER", "player")
+
+		local cpoints = bar.Combo;
+		if(cpoints) then
+			local maxComboPoints = UnitPowerMax("player", SPELL_POWER_COMBO_POINTS);
+			for index = 1, maxComboPoints do
+				local cpoint = cpoints[index]
+				if(cpoint:IsObjectType'Texture' and not cpoint:GetTexture()) then
+					cpoint:SetTexture[[Interface\ComboFrame\ComboPoint]]
+					cpoint:SetTexCoord(0, 0.375, 0, 1)
+				end
+			end
+		end
+		return true
+	end
+end
+
+local Disable = function(self)
+	local bar = self.HyperCombo
+	if(bar) then
+		local cpoints = bar.Combo;
+		if(cpoints) then
+			local maxComboPoints = UnitPowerMax(self.unit, SPELL_POWER_COMBO_POINTS);
+			for index = 1, maxComboPoints do
+				cpoints[index]:Hide()
+			end
+		end
+		self:UnregisterEvent('PLAYER_ENTERING_WORLD', Path)
+		self:UnregisterEvent('UNIT_DISPLAYPOWER', Path)
+		self:UnregisterEvent('PLAYER_TARGET_CHANGED', Path)
+		self:UnregisterEvent('UNIT_POWER_FREQUENT', Path)
+		self:UnregisterEvent('UNIT_MAXPOWER', Path)
+	end
+end
+
+oUF:AddElement('HyperCombo', Path, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_KungFu/oUF_KungFu.lua b/SVUI_UnitFrames/libs/Plugins/oUF_KungFu/oUF_KungFu.lua
new file mode 100644
index 0000000..109bc6c
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_KungFu/oUF_KungFu.lua
@@ -0,0 +1,303 @@
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local error         = _G.error;
+local print         = _G.print;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local tostring      = _G.tostring;
+local type  		= _G.type;
+
+if select(2, UnitClass('player')) ~= "MONK" then return end
+
+--BLIZZARD API
+local UnitStagger 		= _G.UnitStagger;
+local UnitPower     	= _G.UnitPower;
+local UnitPowerMax 		= _G.UnitPowerMax;
+local UnitHealthMax 	= _G.UnitHealthMax;
+local UnitHasVehicleUI 	= _G.UnitHasVehicleUI;
+local GetLocale 					= _G.GetLocale;
+local GetShapeshiftFormID 			= _G.GetShapeshiftFormID;
+local UnitAura         				= _G.UnitAura;
+local UnitHasVehiclePlayerFrameUI 	= _G.UnitHasVehiclePlayerFrameUI;
+local MonkStaggerBar 				= _G.MonkStaggerBar;
+local SPELL_POWER_CHI 				= _G.SPELL_POWER_CHI;
+
+
+local parent, ns = ...
+local oUF = ns.oUF
+local floor = math.floor;
+local DM_L = {};
+
+if GetLocale() == "enUS" then
+	DM_L["Stagger"] = "Stagger"
+	DM_L["Light Stagger"] = "Light Stagger"
+	DM_L["Moderate Stagger"] = "Moderate Stagger"
+	DM_L["Heavy Stagger"] = "Heavy Stagger"
+
+elseif GetLocale() == "frFR" then
+	DM_L["Stagger"] = "Report"
+	DM_L["Light Stagger"] = "Report mineur"
+	DM_L["Moderate Stagger"] = "Report mod??"
+	DM_L["Heavy Stagger"] = "Report majeur"
+
+elseif GetLocale() == "itIT" then
+	DM_L["Stagger"] = "Noncuranza"
+	DM_L["Light Stagger"] = "Noncuranza Parziale"
+	DM_L["Moderate Stagger"] = "Noncuranza Moderata"
+	DM_L["Heavy Stagger"] = "Noncuranza Totale"
+
+elseif GetLocale() == "deDE" then
+	DM_L["Stagger"] = "Staffelung"
+	DM_L["Light Stagger"] = "Leichte Staffelung"
+	DM_L["Moderate Stagger"] = "Moderate Staffelung"
+	DM_L["Heavy Stagger"] = "Schwere Staffelung"
+
+elseif GetLocale() == "zhCN" then
+	DM_L["Stagger"] = "醉拳"
+	DM_L["Light Stagger"] = "轻度醉拳"
+	DM_L["Moderate Stagger"] = "中度醉拳"
+	DM_L["Heavy Stagger"] = "重度醉拳"
+
+elseif GetLocale() == "ruRU" then
+	DM_L["Stagger"] = "Пошатывание"
+	DM_L["Light Stagger"] = "Легкое пошатывание"
+	DM_L["Moderate Stagger"] = "Умеренное пошатывание"
+	DM_L["Heavy Stagger"] = "Сильное пошатывание"
+
+else
+	DM_L["Stagger"] = "Stagger"
+	DM_L["Light Stagger"] = "Light Stagger"
+	DM_L["Moderate Stagger"] = "Moderate Stagger"
+	DM_L["Heavy Stagger"] = "Heavy Stagger"
+end
+
+local STANCE_OF_THE_STURY_OX_ID = 23;
+local DEFAULT_BREW_COLOR = {0.91, 0.75, 0.25, 0.5};
+local BREW_COLORS = {
+	[124275] = {0, 1, 0, 1}, -- Light
+	[124274] = {1, 0.5, 0, 1}, -- Moderate
+	[124273] = {1, 0, 0, 1}, -- Heavy
+};
+local DEFAULT_STAGGER_COLOR = {1, 1, 1, 0.5};
+local STAGGER_COLORS = {
+	[124275] = {0.2, 0.8, 0.2, 1}, -- Light
+	[124274] = {1.0, 0.8, 0.2, 1}, -- Moderate
+	[124273] = {1.0, 0.4, 0.2, 1}, -- Heavy
+};
+local STAGGER_DEBUFFS = {
+	[124275] = true, -- Light
+	[124274] = true, -- Moderate
+	[124273] = true, -- Heavy
+};
+local CURRENT_STAGGER_COLOR = {1, 1, 1, 0.5};
+local CURRENT_BREW_COLOR = {0.91, 0.75, 0.25, 0.5};
+local CHI_COLORS = {
+	[1] = {.57, .63, .35, 1},
+	[2] = {.47, .63, .35, 1},
+	[3] = {.37, .63, .35, 1},
+	[4] = {.27, .63, .33, 1},
+	[5] = {.17, .63, .33, 1},
+	[6] = {0, .63, .33, 1},
+}
+
+local function getStaggerAmount()
+	for i = 1, 40 do
+		local _, _, _, _, _, _, _, _, _, _, spellID, _, _, _, amount =
+			UnitDebuff("player", i)
+		if STAGGER_DEBUFFS[spellID] then
+			if (spellID) then
+				CURRENT_STAGGER_COLOR = STAGGER_COLORS[spellID] or DEFAULT_STAGGER_COLOR
+				CURRENT_BREW_COLOR = BREW_COLORS[spellID] or DEFAULT_BREW_COLOR
+			else
+				CURRENT_STAGGER_COLOR = DEFAULT_STAGGER_COLOR
+				CURRENT_BREW_COLOR = DEFAULT_BREW_COLOR
+			end
+			return amount
+		end
+	end
+	return 0
+end
+
+local Update = function(self, event, unit)
+	if(unit and unit ~= self.unit) then return end
+	local bar = self.KungFu
+	local stagger = bar.DrunkenMaster
+
+	if(bar.PreUpdate) then bar:PreUpdate(event) end
+
+	local light = UnitPower("player", SPELL_POWER_CHI)
+	local numPoints = UnitPowerMax("player", SPELL_POWER_CHI)
+
+	for i = 1, numPoints do
+		local orb = bar[i]
+		if(orb) then
+			if i <= light then
+				orb:Show()
+			else
+				orb:Hide()
+			end
+		end
+	end
+
+	if UnitHasVehicleUI("player") then
+		bar:Hide()
+	else
+		bar:Show()
+	end
+
+	if bar.numPoints ~= numPoints then
+		if numPoints == 6 then
+			bar[5]:Show()
+			bar[6]:Show()
+		elseif numPoints == 5 then
+			bar[5]:Show()
+			bar[6]:Hide()
+		else
+			bar[5]:Hide()
+			bar[6]:Hide()
+		end
+	end
+
+	bar.numPoints = numPoints
+
+	if(stagger.available) then
+		local staggering = getStaggerAmount()
+		if staggering == 0 then
+			stagger:SetValue(0)
+			stagger:FadeOut()
+		else
+			stagger:FadeIn()
+			local health = UnitHealth("player")
+			local maxHealth = UnitHealthMax("player")
+			local staggerTotal = UnitStagger("player")
+			if staggerTotal == 0 and staggering > 0 then
+				staggerTotal = staggering * 10
+			end
+
+			local staggerPercent = staggerTotal / maxHealth * 100
+			local currentStagger = floor(staggerPercent)
+			stagger:SetMinMaxValues(0, 100)
+
+			if(staggerPercent == 0) then
+				stagger:SetStatusBarColor(unpack(DEFAULT_BREW_COLOR))
+			else
+				stagger:SetStatusBarColor(unpack(CURRENT_BREW_COLOR))
+			end
+
+			stagger:SetValue(staggerPercent)
+
+			-- local icon = stagger.icon
+			-- if(icon) then
+			-- 	icon:SetVertexColor(unpack(CURRENT_STAGGER_COLOR))
+			-- end
+			if(stagger.PostUpdate) then
+				stagger:PostUpdate(maxHealth, currentStagger, staggerPercent)
+			end
+		end
+	end
+
+	if(bar.PostUpdate) then bar:PostUpdate(event) end
+end
+
+local ProxyDisable = function(self, element)
+	if(element:IsShown()) then
+		element:Hide()
+	end
+	element.available = false;
+	self:UnregisterEvent('UNIT_AURA', Update)
+end
+
+local ProxyEnable = function(self, element)
+	if(not element.isEnabled) then
+		element.available = false;
+		return
+	end
+	element:Show()
+	element.available = true;
+	self:RegisterEvent('UNIT_AURA', Update)
+end
+
+local Visibility = function(self, ...)
+	local bar = self.KungFu;
+	local stagger = bar.DrunkenMaster;
+	if(STANCE_OF_THE_STURY_OX_ID ~= GetShapeshiftFormID() or UnitHasVehiclePlayerFrameUI("player")) then
+		ProxyDisable(self, stagger)
+	else
+		ProxyEnable(self, stagger)
+		return Update(self, ...)
+	end
+end
+
+local Path = function(self, ...)
+	return (self.KungFu.Override or Visibility)(self, ...)
+end
+
+local ForceUpdate = function(element)
+	return Path(element.__owner, "ForceUpdate", element.__owner.unit)
+end
+
+local function Enable(self, unit)
+	if(unit ~= 'player') then return end
+	local bar = self.KungFu
+
+	if bar then
+		local stagger = bar.DrunkenMaster
+		stagger.__owner = self
+		stagger.ForceUpdate = ForceUpdate
+
+		self:RegisterEvent("PLAYER_ENTERING_WORLD", Update)
+		self:RegisterEvent("UNIT_POWER", Update)
+		self:RegisterEvent("PLAYER_LEVEL_UP", Update)
+		self:RegisterEvent('UNIT_DISPLAYPOWER', Path)
+		self:RegisterEvent('UPDATE_SHAPESHIFT_FORM', Path)
+
+		for i = 1, 6 do
+			if not bar[i]:GetStatusBarTexture() then
+				bar[i]:SetStatusBarTexture([=[Interface\TargetingFrame\UI-StatusBar]=])
+			end
+
+			bar[i]:SetStatusBarColor(unpack(CHI_COLORS[i]))
+			bar[i]:SetFrameLevel(bar:GetFrameLevel() + 1)
+			bar[i]:GetStatusBarTexture():SetHorizTile(false)
+		end
+		bar.numPoints = 6
+
+		if(stagger:IsObjectType'StatusBar' and not stagger:GetStatusBarTexture()) then
+			stagger:SetStatusBarTexture(0.91, 0.75, 0.25)
+		end
+		stagger:SetStatusBarColor(unpack(DEFAULT_BREW_COLOR))
+		stagger:SetMinMaxValues(0, 100)
+		stagger:SetValue(0)
+
+		MonkStaggerBar.Hide = MonkStaggerBar.Show
+		MonkStaggerBar:UnregisterEvent'PLAYER_ENTERING_WORLD'
+		MonkStaggerBar:UnregisterEvent'PLAYER_SPECIALIZATION_CHANGED'
+		MonkStaggerBar:UnregisterEvent'UNIT_DISPLAYPOWER'
+		MonkStaggerBar:UnregisterEvent'UPDATE_VEHICLE_ACTION_BAR'
+
+		return true
+	end
+end
+
+local function Disable(self)
+	if self.KungFu then
+		self:UnregisterEvent("PLAYER_ENTERING_WORLD", Update)
+		self:UnregisterEvent("UNIT_POWER", Update)
+		self:UnregisterEvent("PLAYER_LEVEL_UP", Update)
+		self:UnregisterEvent("UNIT_DISPLAYPOWER", Path)
+		self:UnregisterEvent('UPDATE_SHAPESHIFT_FORM', Path)
+
+		MonkStaggerBar.Show = nil
+		MonkStaggerBar:Show()
+		MonkStaggerBar:UnregisterEvent'PLAYER_ENTERING_WORLD'
+		MonkStaggerBar:UnregisterEvent'PLAYER_SPECIALIZATION_CHANGED'
+		MonkStaggerBar:UnregisterEvent'UNIT_DISPLAYPOWER'
+		MonkStaggerBar:UnregisterEvent'UPDATE_VEHICLE_ACTION_BAR'
+	end
+end
+
+oUF:AddElement('KungFu', Update, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_Maelstrom/oUF_Maelstrom.lua b/SVUI_UnitFrames/libs/Plugins/oUF_Maelstrom/oUF_Maelstrom.lua
new file mode 100644
index 0000000..570a442
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_Maelstrom/oUF_Maelstrom.lua
@@ -0,0 +1,75 @@
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+--BLIZZARD API
+local GameTooltip   = _G.GameTooltip;
+local MAX_TOTEMS 	= _G.MAX_TOTEMS;
+local TotemFrame 	= _G.TotemFrame;
+
+local class = select(2, UnitClass('player'))
+if(class ~= 'SHAMAN') then return end
+
+local parent, ns = ...
+local oUF = ns.oUF
+
+local Update = function(self, event)
+	local maelstrom = self.Maelstrom
+	local bar = maelstrom.Bar
+	local current = UnitPower("player", SPELL_POWER_MAELSTROM);
+	local max = UnitPowerMax("player", SPELL_POWER_MAELSTROM);
+
+	if(maelstrom.PreUpdate) then maelstrom:PreUpdate() end
+	bar:SetMinMaxValues(0,max)
+	bar:SetValue(current)
+	if(bar.text) then
+		bar.text:SetText(current)
+	end
+	if(maelstrom.PostUpdate) then
+		return maelstrom:PostUpdate(current)
+	end
+end
+
+local Path = function(self, ...)
+	return (self.Maelstrom.Override or Update) (self, ...)
+end
+
+local ForceUpdate = function(element)
+	return Path(element.__owner, 'ForceUpdate')
+end
+
+local Enable = function(self)
+	local maelstrom = self.Maelstrom
+
+	if(maelstrom and maelstrom.Bar) then
+		local bar = maelstrom.Bar
+		bar.__owner = self
+		bar.ForceUpdate = ForceUpdate
+
+		bar:SetMinMaxValues(0,100)
+		bar:SetValue(0)
+
+		self:RegisterEvent('UNIT_DISPLAYPOWER', Path, true)
+		self:RegisterUnitEvent('UNIT_DISPLAYPOWER', "player")
+		self:RegisterEvent('UNIT_POWER_FREQUENT', Path, true)
+		self:RegisterUnitEvent("UNIT_POWER_FREQUENT", "player")
+		self:RegisterEvent('UNIT_MAXPOWER', Path, true)
+		self:RegisterUnitEvent("UNIT_MAXPOWER", "player")
+
+		return true
+	end
+end
+
+local Disable = function(self)
+	if(self.Maelstrom) then
+		self.Maelstrom:Hide()
+		self:UnregisterEvent('PLAYER_ENTERING_WORLD', Path)
+		self:UnregisterEvent('UNIT_DISPLAYPOWER', Path)
+		self:UnregisterEvent('PLAYER_TARGET_CHANGED', Path)
+		self:UnregisterEvent('UNIT_POWER_FREQUENT', Path)
+		self:UnregisterEvent('UNIT_MAXPOWER', Path)
+	end
+end
+
+oUF:AddElement("Maelstrom", Path, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_MageMagic/oUF_MageMagic.lua b/SVUI_UnitFrames/libs/Plugins/oUF_MageMagic/oUF_MageMagic.lua
new file mode 100644
index 0000000..c5b67f6
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_MageMagic/oUF_MageMagic.lua
@@ -0,0 +1,357 @@
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local type         	= _G.type;
+--BLIZZARD API
+local GetTime       	= _G.GetTime;
+local GetSpecialization = _G.GetSpecialization;
+local UnitDebuff      	= _G.UnitDebuff;
+
+if select(2, UnitClass('player')) ~= "MAGE" then return end
+
+local _, ns = ...
+local oUF = oUF or ns.oUF
+if not oUF then return end
+
+local playerGUID;
+
+local ARCANE_CHARGE_ID = 36032;
+local ARCANE_BARRAGE_ID = 44425;
+local IGNITE_ID = 12654;
+local COMBUSTION_ID = 83853;
+local PYROBLAST_ID = 11366;
+--local ICICLE_ID = 148022;
+local ICICLE_ID = 205473;
+local FROSTBOLT_ID = 116;
+local FROSTFIREBOLT_ID = 44614;
+local ICELANCE_ID = 30455;
+local ICYVEINS_NAME = GetSpellInfo(12472);
+local ALTERTIME_ID = 108978;
+local ALTERTIMEAURA_ID = 110909;
+
+local CAST_SUCCESS = 'SPELL_CAST_SUCCESS';
+local AURA_REMOVED = 'SPELL_AURA_REMOVED';
+local SPELL_START = 'SPELL_CAST_START';
+
+local DAMAGECOUNT = 0;
+local DAMAGETOTAL = 0;
+local SPELLCOUNT = 0;
+local ALTERCOUNT = 0;
+local LASTRECORD = 0;
+
+local SpecMaximum = {
+	[1] = 4,
+	[2] = 4,
+	[3] = 5,
+};
+
+local ResetMagic = function(self)
+	local bar = self.MageMagic;
+	local ignite = bar.Ignite;
+	local igniteBar = ignite.Bar;
+	SPELLCOUNT = 0;
+	ALTERCOUNT = 0;
+	LASTRECORD = 0;
+	DAMAGETOTAL = 0;
+	for i = 1, 5 do
+		bar[i].start = 0
+		bar[i].duration = 0
+		bar[i]:SetValue(0)
+		bar[i]:Hide()
+		bar[i]:SetScript("OnUpdate", nil)
+	end
+
+	igniteBar.start = 0
+	igniteBar.duration = 0
+	igniteBar:SetValue(0)
+	ignite:Hide()
+	igniteBar:SetScript("OnUpdate", nil)
+end
+
+local GetResources = {
+	[1] = function(self, event, ...)
+		SPELLCOUNT = UnitPower("player", SPELL_POWER_ARCANE_CHARGES);
+		return 0,0
+	end,
+	[2] = function(self, event, ...)
+		if(event == 'COMBAT_LOG_EVENT_UNFILTERED') then
+			local _, eventType, _, srcGUID, _, _, _, destGUID, _, _, _, spellID, _, _, amount = ...
+			if(srcGUID == playerGUID) then
+				if(eventType:find("_DAMAGE")) then
+					if(spellID == IGNITE_ID) then
+						DAMAGETOTAL = amount
+					elseif(spellID == COMBUSTION_ID) then
+						DAMAGETOTAL = 0
+					end
+				end
+			end
+		elseif(event == 'UNIT_AURA') then
+			local unit = ...;
+			if(unit == 'player') then
+				for index = 1, 30 do
+					local name, rank, icon, count, dispelType, duration, expires, caster, isStealable, shouldConsolidate, spellID = UnitDebuff('target', index)
+					if(spellID == IGNITE_ID) then
+						return floor(expires), duration
+					end
+				end
+			end
+		end
+		return 0,0,true
+	end,
+	[3] = function(self, event, ...)
+		--SPELLCOUNT = 0;
+		if(event == 'COMBAT_LOG_EVENT_UNFILTERED') then
+			local _, eventType, _, srcGUID, _, _, _, _, _, _, _, spellID, _, _, amount = ...
+			if (srcGUID == playerGUID) then
+				if((eventType == CAST_SUCCESS) and (spellID == ICELANCE_ID)) then
+					SPELLCOUNT = 0
+					return 0,0;
+				elseif(eventType:find("_DAMAGE") and (spellID == ICICLE_ID)) then
+					if(SPELLCOUNT > 0) then
+						SPELLCOUNT = SPELLCOUNT - 1
+						return 0,0;
+					end
+				end
+			end
+		elseif(event == 'UNIT_AURA') then
+			local unit = ...;
+			if(unit == 'player') then
+				for index = 1, 30 do
+					local name, rank, icon, count, dispelType, duration, expires, caster, isStealable, shouldConsolidate, spellID = UnitBuff(unit, index)
+					if(spellID == ICICLE_ID) then
+						SPELLCOUNT = count
+						return floor(expires), duration
+					end
+				end
+				SPELLCOUNT = 0
+			end
+		end
+		return 0,0,true;
+	end,
+};
+
+local BarOnUpdate = function(self, elapsed)
+	if not self.duration then return end
+	self.elapsed = (self.elapsed or 0) + elapsed
+	if self.elapsed >= 0.5 then
+		local timeLeft = (self.duration - GetTime())
+		if timeLeft > 0 then
+			self:SetValue(timeLeft)
+		else
+			if(SPELLCOUNT > 0) then
+				SPELLCOUNT = SPELLCOUNT - 1
+			end
+			self.start = 0;
+			self.duration = 0;
+			self.elapsed = 0;
+			self:SetValue(0)
+			self:Hide()
+			self:SetScript("OnUpdate", nil)
+		end
+	end
+end
+
+local IgniteOnUpdate = function(self, elapsed)
+	if not self.duration then return end
+	self.elapsed = (self.elapsed or 0) + elapsed
+	if self.elapsed >= 0.5 then
+		local timeLeft = (self.duration - self.elapsed)
+		local remaining = floor(timeLeft * DAMAGETOTAL)
+		if timeLeft > 0 then
+			self:SetValue(timeLeft)
+			self.text:SetText(remaining)
+		else
+			self.text:SetText('0')
+			DAMAGETOTAL = 0;
+			self.start = 0;
+			self.duration = 5;
+			self.elapsed = 0;
+			self:SetValue(0);
+			self:SetScript("OnUpdate", nil);
+		end
+	end
+end
+
+local IcicleOnUpdate = function(self, elapsed)
+	if not self.duration then return end
+	self.elapsed = (self.elapsed or 0) + elapsed
+	if self.elapsed >= 0.5 then
+		local timeLeft = (self.duration - self.elapsed)
+		if((SPELLCOUNT > 0) and timeLeft > 0) then
+			self:SetValue(timeLeft)
+		else
+			if(SPELLCOUNT > 0) then
+				SPELLCOUNT = SPELLCOUNT - 1
+			end
+			self.start = 0;
+			self.duration = 5;
+			self.elapsed = 0;
+			self:SetValue(0);
+			self:Hide();
+			self:SetScript("OnUpdate", nil);
+		end
+	end
+end
+
+local Update = function(self, event, ...)
+	local bar = self.MageMagic
+	local spec = bar.CurrentSpec;
+	if(not spec) then return end
+
+	if(bar.PreUpdate) then bar:PreUpdate(spec) end
+
+	local maxCount = SpecMaximum[spec];
+	local start, duration, reset = GetResources[spec](self, event, ...);
+	if(not reset) then
+		if(spec == 2) then
+			local ignite = bar.Ignite;
+			local igniteBar = ignite.Bar;
+			if(not ignite:IsShown()) then ignite:Show() end
+			if(duration and start and (start > igniteBar.start)) then
+				igniteBar.start = start
+				igniteBar.duration = duration
+				igniteBar.elapsed = 0
+				igniteBar:SetMinMaxValues(0, duration)
+				igniteBar:SetValue(duration)
+				igniteBar:SetScript('OnUpdate', IgniteOnUpdate)
+			end
+		else
+			for i = 1, 5 do
+				if(i > maxCount) then
+					bar[i]:SetValue(0)
+					bar[i]:Hide()
+				else
+					if(not bar[i]:IsShown()) then bar[i]:Show() end
+					if(spec == 1) then
+						if i <= SPELLCOUNT then
+							bar[i]:Show()
+							bar[i]:SetMinMaxValues(0, 100)
+							bar[i]:SetValue(100)
+							bar[i]:SetScript('OnUpdate', nil)
+						else
+							bar[i]:SetValue(0)
+							bar[i]:Hide()
+						end
+					else
+						if i <= SPELLCOUNT then
+							bar[i]:FadeIn()
+							if(duration and start and (start > bar[i].start)) then
+								bar[i].start = start
+								bar[i].duration = duration
+								bar[i].elapsed = 0
+								bar[i]:SetMinMaxValues(0, duration)
+								bar[i]:SetValue(duration)
+								bar[i]:SetScript('OnUpdate', IcicleOnUpdate)
+							end
+						else
+							bar[i].start = 0
+							bar[i].duration = 0
+							bar[i].elapsed = 0
+							bar[i]:SetValue(0)
+							bar[i]:SetScript('OnUpdate', nil)
+							bar[i]:FadeOut()
+						end
+					end
+				end
+			end
+		end
+	end
+
+	if(bar.PostUpdate) then
+		return bar:PostUpdate(event, SPELLCOUNT, maxCount)
+	end
+end
+
+local Proxy = function(self, ...)
+	local bar = self.MageMagic
+	local spec = GetSpecialization()
+	if(not playerGUID) then
+		playerGUID = UnitGUID('player')
+	end
+	if((not bar.CurrentSpec) or (bar.CurrentSpec ~= spec)) then
+		ResetMagic(self);
+		if(spec) then
+			bar.CurrentSpec = spec;
+			if(spec == 3) then
+				self:RegisterEvent('UNIT_AURA', Update)
+				self:RegisterEvent('COMBAT_LOG_EVENT_UNFILTERED', Update, true)
+				--print("Switch To Frost")
+			elseif(spec == 2) then
+				self:RegisterEvent('UNIT_AURA', Update)
+				self:RegisterEvent('COMBAT_LOG_EVENT_UNFILTERED', Update, true)
+				if(not bar.Ignite:IsShown()) then bar.Ignite:Show() end
+				bar.Ignite.Bar:SetValue(0)
+				--print("Switch To Fire")
+			elseif(spec == 1) then
+				self:RegisterEvent('UNIT_AURA', Update)
+				self:RegisterEvent('COMBAT_LOG_EVENT_UNFILTERED', Update, true)
+				--print("Switch To Arcane")
+			end
+			if(bar.PostTalentUpdate) then bar:PostTalentUpdate(spec) end
+		else
+			self:UnregisterEvent('UNIT_AURA', Update)
+			self:UnregisterEvent('COMBAT_LOG_EVENT_UNFILTERED', Update)
+		end
+	end
+	return Update(self, ...)
+end
+
+local Path = function(self, ...)
+	return (self.MageMagic.Override or Proxy) (self, ...)
+end
+
+local ForceUpdate = function(element)
+	return Path(element.__owner, 'ForceUpdate', element.__owner.unit)
+end
+
+local Enable = function(self, unit)
+	local bar = self.MageMagic
+
+	if(bar) then
+		self:RegisterEvent("PLAYER_TALENT_UPDATE", Path)
+		self:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED", Path)
+		self:RegisterEvent("PLAYER_ENTERING_WORLD", Path)
+		bar.__owner = self
+		bar.ForceUpdate = ForceUpdate
+
+		for i = 1, 5 do
+			if not bar[i]:GetStatusBarTexture() then
+				bar[i]:SetStatusBarTexture([=[Interface\TargetingFrame\UI-StatusBar]=])
+			end
+
+			bar[i]:SetFrameLevel(bar:GetFrameLevel() + 1)
+			bar[i]:GetStatusBarTexture():SetHorizTile(false)
+
+			if bar[i].bg then
+				bar[i]:SetMinMaxValues(0, 1)
+				bar[i]:SetValue(0)
+				bar[i].bg:SetAlpha(0.4)
+				bar[i].bg:SetAllPoints()
+				bar[i]:Hide()
+			end
+		end
+		bar.Ignite.Bar:SetMinMaxValues(0, 5)
+		bar.Ignite.Bar:SetValue(0)
+		bar.Ignite:Hide()
+
+		return true;
+	end
+end
+
+local Disable = function(self, unit)
+	local bar = self.MageMagic
+
+	if(bar) then
+		self:UnregisterEvent("UNIT_AURA", Update)
+		self:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED", Update)
+		self:UnregisterEvent("PLAYER_TALENT_UPDATE", Path)
+		self:UnregisterEvent("ACTIVE_TALENT_GROUP_CHANGED", Path)
+		self:UnregisterEvent("PLAYER_ENTERING_WORLD", Path)
+		bar:Hide()
+	end
+end
+
+oUF:AddElement("MageMagic", Path, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_MageMagic/oUF_MageMagic.toc b/SVUI_UnitFrames/libs/Plugins/oUF_MageMagic/oUF_MageMagic.toc
new file mode 100644
index 0000000..1f128a6
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_MageMagic/oUF_MageMagic.toc
@@ -0,0 +1,9 @@
+## Interface: 50001
+## Title: oUF Mage Magic
+## Notes: Adds support for mage spell indicators to oUF.
+## Author: Failcoder
+## Version: 1.1.0
+## Dependencies: oUF
+
+
+oUF_MageMagic.lua
\ No newline at end of file
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_Necromancy/oUF_Necromancy.lua b/SVUI_UnitFrames/libs/Plugins/oUF_Necromancy/oUF_Necromancy.lua
new file mode 100644
index 0000000..a32b2ad
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_Necromancy/oUF_Necromancy.lua
@@ -0,0 +1,117 @@
+if select(2, UnitClass("player")) ~= "DEATHKNIGHT" then return end
+
+
+local parent, ns = ...
+local oUF = ns.oUF
+local floor = math.floor
+
+local runeColors = {
+	{0.75, 0, 0},   -- blood
+	{0, 0.75, 1},   -- frost
+	{0.1, 0.75, 0},  -- unholy
+	{0.75, 0, 1}, -- death
+}
+
+local runemap = { 1, 2, 5, 6, 3, 4 }
+local BLOOD_OF_THE_NORTH = 54637
+local OnUpdate = function(self, elapsed)
+	local duration = self.duration + elapsed
+	if(duration >= self.max) then
+		return self:SetScript("OnUpdate", nil)
+	else
+		self.duration = duration
+		return self:SetValue(duration)
+	end
+end
+
+local spellName = GetSpellInfo(54637)
+local UpdateType = function(self, event, rid)
+	local spec = GetSpecialization()
+	local isUsable = IsUsableSpell(spellName)
+	local rune = self.Necromancy[rid]
+	local colors = runeColors[spec]
+	if (rune and colors) then
+		local r, g, b = colors[1], colors[2], colors[3]
+		rune.bar:SetStatusBarColor(r, g, b)
+		if(rune.bar.Change) then
+			rune.bar:Change(rid)
+		end
+	end
+end
+
+local UpdateRune = function(self, event, rid)
+	local rune = self.Necromancy[rid]
+	if(rune) then
+		local start, duration, runeReady = GetRuneCooldown(rid)
+		start = start or 0;
+		duration = duration or 1;
+		if(runeReady) then
+			rune.bar:SetMinMaxValues(0, 1)
+			rune.bar:SetValue(1)
+			rune.bar:SetScript("OnUpdate", nil)
+		else
+			rune.bar.duration = GetTime() - start
+			rune.bar.max = duration
+			rune.bar:SetMinMaxValues(1, duration)
+			rune.bar:SetScript("OnUpdate", OnUpdate)
+		end
+	end
+end
+
+local Update = function(self, event)
+	for i=1, 6 do
+		UpdateRune(self, event, i)
+	end
+end
+
+local function UpdateAllRuneTypes(self)
+	if(self) then
+		for i=1, 6 do
+			UpdateType(self, nil, i)
+		end
+	end
+end
+
+local ForceUpdate = function(element)
+	return Update(element.__owner, 'ForceUpdate')
+end
+
+local Enable = function(self, unit)
+	local runes = self.Necromancy
+	if(runes and unit == 'player') then
+		runes.__owner = self
+		runes.ForceUpdate = ForceUpdate
+		self:RegisterEvent("PLAYER_TALENT_UPDATE", UpdateAllRuneTypes)
+		self:RegisterEvent("RUNE_POWER_UPDATE", UpdateRune, true)
+		self:RegisterEvent("RUNE_TYPE_UPDATE", UpdateType, true)	--I have no idea why this won't fire on initial login.
+		self:RegisterEvent("PLAYER_ENTERING_WORLD", UpdateAllRuneTypes)
+
+		if not runes.UpdateAllRuneTypes then runes.UpdateAllRuneTypes = UpdateAllRuneTypes end
+
+		for i=1, 6 do
+			UpdateType(self, nil, i)
+		end
+
+		RuneFrame.Show = RuneFrame.Hide
+		RuneFrame:Hide()
+
+		return true
+	end
+end
+
+local Disable = function(self)
+	RuneFrame.Show = nil
+	RuneFrame:Show()
+
+
+	local runes = self.Necromancy
+	if(runes) then
+		runes:SetScript('OnUpdate', nil)
+		self:UnregisterEvent("PLAYER_TALENT_UPDATE", UpdateAllRuneTypes)
+		self:UnregisterEvent("RUNE_POWER_UPDATE", UpdateRune)
+		self:UnregisterEvent("RUNE_TYPE_UPDATE", UpdateType)
+		self:UnregisterEvent("PLAYER_ENTERING_WORLD", UpdateAllRuneTypes)
+	end
+end
+
+oUF:AddElement("Necromancy", Update, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_PallyPower/oUF_PallyPower.lua b/SVUI_UnitFrames/libs/Plugins/oUF_PallyPower/oUF_PallyPower.lua
new file mode 100644
index 0000000..6b731b1
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_PallyPower/oUF_PallyPower.lua
@@ -0,0 +1,69 @@
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+--BLIZZARD API
+local UnitPower     	= _G.UnitPower;
+local UnitPowerMax 		= _G.UnitPowerMax;
+local UnitHasVehicleUI 	= _G.UnitHasVehicleUI;
+
+if(select(2, UnitClass('player')) ~= 'PALADIN') then return end
+
+local parent, ns = ...
+local oUF = ns.oUF
+
+local SPELL_POWER_HOLY_POWER = SPELL_POWER_HOLY_POWER
+local MAX_HOLY_POWER = MAX_HOLY_POWER
+
+local Update = function(self, event, unit, powerType)
+	if(self.unit ~= unit or (powerType and powerType ~= 'HOLY_POWER')) then return end
+
+	local hp = self.HolyPower
+	if(hp.PreUpdate) then hp:PreUpdate() end
+
+	local num = UnitPower('player', SPELL_POWER_HOLY_POWER)
+	local MAX_HOLY_POWER = UnitPowerMax('player', SPELL_POWER_HOLY_POWER);
+	for i = 1, MAX_HOLY_POWER do
+		if(i <= num) then
+			hp[i]:Show()
+		else
+			hp[i]:Hide()
+		end
+	end
+
+	if(hp.PostUpdate) then
+		return hp:PostUpdate(num)
+	end
+end
+
+local Path = function(self, ...)
+	return (self.HolyPower.Override or Update) (self, ...)
+end
+
+local ForceUpdate = function(element)
+	return Path(element.__owner, 'ForceUpdate', element.__owner.unit, 'HOLY_POWER')
+end
+
+local function Enable(self, unit)
+	if(unit ~= 'player') then return end
+	local hp = self.HolyPower
+	if(hp) then
+		hp.__owner = self
+		hp.ForceUpdate = ForceUpdate
+
+		self:RegisterEvent('UNIT_POWER', Path)
+
+		return true
+	end
+end
+
+local function Disable(self)
+	local hp = self.HolyPower
+	if(hp) then
+		self:UnregisterEvent('UNIT_POWER', Path)
+	end
+end
+
+oUF:AddElement('HolyPower', Path, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_PriestOrbs/oUF_PriestOrbs.lua b/SVUI_UnitFrames/libs/Plugins/oUF_PriestOrbs/oUF_PriestOrbs.lua
new file mode 100644
index 0000000..674680f
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_PriestOrbs/oUF_PriestOrbs.lua
@@ -0,0 +1,140 @@
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+--BLIZZARD API
+local UnitPower     	= _G.UnitPower;
+local UnitPowerMax 		= _G.UnitPowerMax;
+local UnitHasVehicleUI 	= _G.UnitHasVehicleUI;
+local GetSpecialization = _G.GetSpecialization;
+local UnitLevel 		= _G.UnitLevel;
+local UnitBuff 			= _G.UnitBuff;
+
+local SPELL_POWER_SHADOW_ORBS = _G.SPELL_POWER_SHADOW_ORBS;
+
+if select(2, UnitClass('player')) ~= "PRIEST" then return end
+
+local _, ns = ...
+local oUF = ns.oUF or oUF
+
+local SPEC_PRIEST_DISC = 1
+local SPEC_PRIEST_HOLY = 2
+local SPEC_PRIEST_SHADOW = 3
+
+local SHADOW_ORBS_SHOW_LEVEL = SHADOW_ORBS_SHOW_LEVEL
+local HOLY_ORBS_SHOW_LEVEL = 44
+local DISC_ORBS_SHOW_LEVEL = 44
+
+local EVANGELISM = GetSpellInfo(81662) or GetSpellInfo(81661) or GetSpellInfo(81660)
+local DARK_EVANGELISM = GetSpellInfo(87118) or GetSpellInfo(87117)
+local SERENDIPITY = GetSpellInfo(63733)
+
+local OrbColors = {
+	[1] = {1, 1, 0},
+	[2] = {1, 1, 0},
+	[3] = {0.6, 0.06, 1}
+};
+
+local function Update(self, event, unit)
+	local pb = self.PriestOrbs
+
+	local numOrbs, invalid = 0, false
+	local spec = GetSpecialization()
+	local level = UnitLevel("player")
+	local color = OrbColors[spec]
+	local name, _, icon, count
+	if(spec == SPEC_PRIEST_SHADOW and level >= SHADOW_ORBS_SHOW_LEVEL) then
+		if (DARK_EVANGELISM) then
+			numOrbs = UnitPower("player", SPELL_POWER_SHADOW_ORBS)
+			pb:Show()
+		end;
+	elseif(spec == SPEC_PRIEST_DISC and level >= DISC_ORBS_SHOW_LEVEL) then
+		if (EVANGELISM) then
+			name, _, icon, count = UnitBuff("player", EVANGELISM)
+			numOrbs = count or 0
+			pb:Show()
+		end;
+	elseif(spec == SPEC_PRIEST_HOLY and level >= HOLY_ORBS_SHOW_LEVEL) then
+		if (SERENDIPITY) then
+			name, _, icon, count = UnitBuff("player", SERENDIPITY)
+			numOrbs = count or 0
+			pb:Show()
+		end;
+	else
+		invalid = true;
+		pb:Hide()
+	end
+
+	if(not invalid) then
+		if(pb.PreUpdate) then
+			pb:PreUpdate(spec)
+		end
+
+		for i = 1, 5 do
+			pb[i]:SetStatusBarColor(unpack(color))
+			if i <= numOrbs then
+				pb[i]:Show()
+			else
+				pb[i]:Hide()
+			end
+		end
+		self:RegisterEvent("UNIT_DISPLAYPOWER", Update)
+		self:RegisterEvent("UNIT_POWER_FREQUENT", Update)
+		self:RegisterEvent("UNIT_AURA", Update)
+
+		if(pb.PostUpdate) then
+			pb:PostUpdate(spec)
+		end
+	else
+		for i = 1, 5 do
+			pb[i]:Hide()
+		end
+		self:UnregisterEvent("UNIT_DISPLAYPOWER", Update)
+		self:UnregisterEvent("UNIT_POWER_FREQUENT", Update)
+		self:UnregisterEvent("UNIT_AURA", Update)
+	end
+end
+
+local ForceUpdate = function(element)
+	return Update(element.__owner, "ForceUpdate")
+end
+
+local function Enable(self, unit)
+	if(unit ~= 'player') then return end
+	local pb = self.PriestOrbs
+	if pb then
+		pb.__owner = self
+		pb.ForceUpdate = ForceUpdate
+
+		self:RegisterEvent("PLAYER_LEVEL_UP", Update)
+		self:RegisterEvent("PLAYER_TALENT_UPDATE", Update)
+		self:RegisterEvent("UNIT_DISPLAYPOWER", Update)
+		self:RegisterEvent("UNIT_POWER_FREQUENT", Update)
+		self:RegisterEvent("UNIT_AURA", Update)
+
+		for i = 1, 5 do
+			if not pb[i]:GetStatusBarTexture() then
+				pb[i]:SetStatusBarTexture([=[Interface\TargetingFrame\UI-StatusBar]=])
+			end
+
+			pb[i]:SetFrameLevel(pb:GetFrameLevel() + 1)
+			pb[i]:GetStatusBarTexture():SetHorizTile(false)
+		end
+
+		return true
+	end
+end
+
+local function Disable(self)
+	if self.PriestOrbs then
+		self:UnregisterEvent("PLAYER_LEVEL_UP", Update)
+		self:UnregisterEvent("PLAYER_TALENT_UPDATE", Update)
+		self:UnregisterEvent("UNIT_DISPLAYPOWER", Update)
+		self:UnregisterEvent("UNIT_POWER_FREQUENT", Update)
+		self:UnregisterEvent("UNIT_AURA", Update)
+	end
+end
+
+oUF:AddElement('PriestOrbs', Update, Enable, Disable)
\ No newline at end of file
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_RaidDebuffs/oUF_RaidDebuffs.lua b/SVUI_UnitFrames/libs/Plugins/oUF_RaidDebuffs/oUF_RaidDebuffs.lua
new file mode 100644
index 0000000..592be97
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_RaidDebuffs/oUF_RaidDebuffs.lua
@@ -0,0 +1,354 @@
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local error         = _G.error;
+local print         = _G.print;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local tostring      = _G.tostring;
+local type  		= _G.type;
+--STRING
+local string        = _G.string;
+local format        = string.format;
+--MATH
+local math          = _G.math;
+local floor         = math.floor
+local ceil          = math.ceil
+local random 				= math.random
+--TABLE
+local table         = _G.table;
+local wipe          = _G.wipe;
+--BLIZZARD API
+local GetTime       		= _G.GetTime;
+local GetSpecialization 	= _G.GetSpecialization;
+local UnitAura         		= _G.UnitAura;
+local UnitIsCharmed         = _G.UnitIsCharmed;
+local UnitCanAttack         = _G.UnitCanAttack;
+local GetSpellInfo      	= _G.GetSpellInfo;
+local GetActiveSpecGroup  	= _G.GetActiveSpecGroup;
+
+local _, ns = ...
+local oUF = ns.oUF or oUF
+
+local SymbiosisName = GetSpellInfo(110309)
+local CleanseName = GetSpellInfo(4987)
+
+local addon = {}
+ns.oUF_RaidDebuffs = addon
+_G.oUF_RaidDebuffs = ns.oUF_RaidDebuffs
+
+local debuff_data = {}
+addon.DebuffData = debuff_data
+
+
+addon.ShowDispelableDebuff = true
+addon.FilterDispellableDebuff = true
+addon.MatchBySpellName = true
+
+
+addon.priority = 10
+
+local function add(spell, priority)
+	if addon.MatchBySpellName and type(spell) == 'number' then
+		spell = GetSpellInfo(spell)
+	end
+
+	debuff_data[spell] = addon.priority + priority
+end
+
+function addon:RegisterDebuffs(t)
+	for spell, value in pairs(t) do
+		if type(t[spell]) == 'boolean' then
+			local oldValue = t[spell]
+			t[spell] = {
+				['enable'] = oldValue,
+				['priority'] = 0
+			}
+		else
+			if t[spell].enable then
+				add(spell, t[spell].priority)
+			end
+		end
+	end
+end
+
+function addon:ResetDebuffData()
+	wipe(debuff_data)
+end
+
+local DispellColor = {
+	['Magic']	= {.2, .6, 1},
+	['Curse']	= {.6, 0.1, 1},
+	['Disease']	= {.6, .4, 0},
+	['Poison']	= {0, .6, 0},
+	['none'] = { .23, .23, .23},
+}
+
+local DispellPriority = {
+	['Magic']	= 4,
+	['Curse']	= 3,
+	['Disease']	= 2,
+	['Poison']	= 1,
+}
+
+local DispellFilter
+do
+	local dispellClasses = {
+		['PRIEST'] = {
+			['Magic'] = true,
+			['Disease'] = true,
+		},
+		['SHAMAN'] = {
+			['Magic'] = false,
+			['Curse'] = true,
+		},
+		['PALADIN'] = {
+			['Poison'] = true,
+			['Magic'] = false,
+			['Disease'] = true,
+		},
+		['MAGE'] = {
+			['Curse'] = true,
+		},
+		['DRUID'] = {
+			['Magic'] = false,
+			['Curse'] = true,
+			['Poison'] = true,
+			['Disease'] = false,
+		},
+		['MONK'] = {
+			['Magic'] = false,
+			['Disease'] = true,
+			['Poison'] = true,
+		},
+	}
+
+	DispellFilter = dispellClasses[select(2, UnitClass('player'))] or {}
+end
+
+local DEMO_SPELLS = {116281,116784,116417,116942,116161,117708,118303,118048,118135,117878,117949}
+
+local function CheckTalentTree(tree)
+	local activeGroup = GetActiveSpecGroup()
+	if activeGroup and GetSpecialization(false, false, activeGroup) then
+		return tree == GetSpecialization(false, false, activeGroup)
+	end
+end
+
+local playerClass = select(2, UnitClass('player'))
+local function CheckSpec(self, event, levels)
+	-- Not interested in gained points from leveling
+	if event == "CHARACTER_POINTS_CHANGED" and levels > 0 then return end
+
+	--Check for certain talents to see if we can dispel magic or not
+	if playerClass == "PRIEST" then
+		if CheckTalentTree(3) then
+			DispellFilter.Disease = false
+		else
+			DispellFilter.Disease = true
+		end
+	elseif playerClass == "PALADIN" then
+		if CheckTalentTree(1) then
+			DispellFilter.Magic = true
+		else
+			DispellFilter.Magic = false
+		end
+	elseif playerClass == "SHAMAN" then
+		if CheckTalentTree(3) then
+			DispellFilter.Magic = true
+		else
+			DispellFilter.Magic = false
+		end
+	elseif playerClass == "DRUID" then
+		if CheckTalentTree(4) then
+			DispellFilter.Magic = true
+		else
+			DispellFilter.Magic = false
+		end
+	elseif playerClass == "MONK" then
+		if CheckTalentTree(2) then
+			DispellFilter.Magic = true
+		else
+			DispellFilter.Magic = false
+		end
+	end
+end
+
+local function CheckSymbiosis()
+	if GetSpellInfo(SymbiosisName) == CleanseName then
+		DispellFilter.Disease = true
+	else
+		DispellFilter.Disease = false
+	end
+end
+
+local function formatTime(s)
+	if s > 60 then
+		return format('%dm', s/60), s%60
+	elseif s < 1 then
+		return format("%.1f", s), s - floor(s)
+	else
+		return format('%d', s), s - floor(s)
+	end
+end
+
+local abs = math.abs
+local function OnUpdate(self, elapsed)
+	self.elapsed = (self.elapsed or 0) + elapsed
+	if self.elapsed >= 0.1 then
+		local timeLeft = self.endTime - GetTime()
+		if self.reverse then timeLeft = abs((self.endTime - GetTime()) - self.duration) end
+		if timeLeft > 0 then
+			local text = formatTime(timeLeft)
+			self.time:SetText(text)
+		else
+			self:SetScript('OnUpdate', nil)
+			self.time:Hide()
+		end
+		self.elapsed = 0
+	end
+end
+
+local function UpdateDebuff(self, name, icon, count, debuffType, duration, endTime, spellId)
+	local f = self.RaidDebuffs
+
+	if name then
+		f.icon:SetTexture(icon)
+		f.icon:Show()
+		f.duration = duration
+
+		if f.count then
+			if count and (count > 1) then
+				f.count:SetText(count)
+				f.count:Show()
+			else
+				f.count:SetText("")
+				f.count:Hide()
+			end
+		end
+
+		if f.time then
+			if duration and (duration > 0) then
+				f.endTime = endTime
+				f.nextUpdate = 0
+				f:SetScript('OnUpdate', OnUpdate)
+				f.time:Show()
+			else
+				f:SetScript('OnUpdate', nil)
+				f.time:Hide()
+			end
+		end
+
+		if f.cooldown then
+			if duration and (duration > 0) then
+				f.cooldown:SetCooldown(endTime - duration, duration)
+				f.cooldown:Show()
+			else
+				f.cooldown:Hide()
+			end
+		end
+
+		local c = DispellColor[debuffType] or DispellColor.none
+		f:SetBackdropBorderColor(c[1], c[2], c[3])
+
+		f:Show()
+		if (f.nameText) then f.nameText:Hide(); end
+	else
+		f:Hide()
+		if (f.nameText) then f.nameText:Show(); end
+	end
+end
+
+local blackList = {
+	[105171] = true, -- Deep Corruption
+	[108220] = true, -- Deep Corruption
+	[116095] = true, -- Disable, Slow
+	[137637] = true, -- Warbringer, Slow
+}
+
+local function Update(self, event, unit)
+	if unit ~= self.unit then return end
+	local _name, _icon, _count, _dtype, _duration, _endTime, _spellId
+	local _priority, priority = 0, 0
+
+	--store if the unit its charmed, mind controlled units (Imperial Vizier Zor'lok: Convert)
+	local isCharmed = UnitIsCharmed(unit)
+
+	--store if we cand attack that unit, if its so the unit its hostile (Amber-Shaper Un'sok: Reshape Life)
+	local canAttack = UnitCanAttack("player", unit)
+
+	for i = 1, 40 do
+		local name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, isStealable, shouldConsolidate, spellId, canApplyAura, isBossDebuff = UnitAura(unit, i, 'HARMFUL')
+		if (not name) then break end
+
+		--we coudln't dispell if the unit its charmed, or its not friendly
+		if addon.ShowDispelableDebuff and debuffType and (not isCharmed) and (not canAttack) then
+
+			if addon.FilterDispellableDebuff then
+				DispellPriority[debuffType] = (DispellPriority[debuffType] or 0) + addon.priority --Make Dispell buffs on top of Boss Debuffs
+				priority = DispellFilter[debuffType] and DispellPriority[debuffType] or 0
+				if priority == 0 then
+					debuffType = nil
+				end
+			else
+				priority = DispellPriority[debuffType] or 0
+			end
+
+			if priority > _priority then
+				_priority, _name, _icon, _count, _dtype, _duration, _endTime, _spellId = priority, name, icon, count, debuffType, duration, expirationTime, spellId
+			end
+		end
+
+		priority = debuff_data[addon.MatchBySpellName and name or spellId]
+		if priority and not blackList[spellId] and (priority > _priority) then
+			_priority, _name, _icon, _count, _dtype, _duration, _endTime, _spellId = priority, name, icon, count, debuffType, duration, expirationTime, spellId
+		end
+	end
+
+	if(self.RaidDebuffs.forceShow) then
+		_spellId = DEMO_SPELLS[random(1, #DEMO_SPELLS)];
+		_name, rank, _icon = GetSpellInfo(_spellId)
+		_count, _dtype, _duration, _endTime = 5, 'Magic', 0, 60
+	end
+
+	UpdateDebuff(self, _name, _icon, _count, _dtype, _duration, _endTime, _spellId)
+
+	--Reset the DispellPriority
+	DispellPriority = {
+		['Magic']	= 4,
+		['Curse']	= 3,
+		['Disease']	= 2,
+		['Poison']	= 1,
+	}
+end
+
+
+local function Enable(self)
+	if self.RaidDebuffs then
+		self:RegisterEvent('UNIT_AURA', Update)
+		return true
+	end
+	--Need to run these always
+	self:RegisterEvent("PLAYER_TALENT_UPDATE", CheckSpec)
+	self:RegisterEvent("CHARACTER_POINTS_CHANGED", CheckSpec)
+	if playerClass == "DRUID" then
+		self:RegisterEvent("SPELLS_CHANGED", CheckSymbiosis)
+	end
+end
+
+local function Disable(self)
+	if self.RaidDebuffs then
+		self:UnregisterEvent('UNIT_AURA', Update)
+		self.RaidDebuffs:Hide()
+	end
+	self:UnregisterEvent("PLAYER_TALENT_UPDATE", CheckSpec)
+	self:UnregisterEvent("CHARACTER_POINTS_CHANGED", CheckSpec)
+	if playerClass == "DRUID" then
+		self:UnregisterEvent("SPELLS_CHANGED", CheckSymbiosis)
+	end
+end
+
+oUF:AddElement('RaidDebuffs', Update, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_RaidDebuffs/oUF_RaidDebuffs.toc b/SVUI_UnitFrames/libs/Plugins/oUF_RaidDebuffs/oUF_RaidDebuffs.toc
new file mode 100644
index 0000000..7ad4bd1
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_RaidDebuffs/oUF_RaidDebuffs.toc
@@ -0,0 +1,8 @@
+## Interface: 30300
+## Title: oUF RaidDebuffs
+## Notes: Raid debuff mod for oUF
+## Version: 1.2
+## OptionalDeps: oUF
+
+
+oUF_RaidDebuffs.lua
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_Reputation/oUF_Reputation.lua b/SVUI_UnitFrames/libs/Plugins/oUF_Reputation/oUF_Reputation.lua
new file mode 100644
index 0000000..e06e668
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_Reputation/oUF_Reputation.lua
@@ -0,0 +1,112 @@
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local error         = _G.error;
+local print         = _G.print;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local tostring      = _G.tostring;
+local type  		= _G.type;
+--STRING
+local string        = _G.string;
+local format        = string.format;
+--MATH
+local math          = _G.math;
+local floor         = math.floor
+--BLIZZARD API
+local UnitXP       		= _G.UnitXP;
+local UnitXPMax 		= _G.UnitXPMax;
+local GetXPExhaustion   = _G.GetXPExhaustion;
+local UnitSex         	= _G.UnitSex;
+local GetText  			= _G.GetText;
+local GetWatchedFactionInfo = _G.GetWatchedFactionInfo;
+local FACTION_BAR_COLORS  	= _G.FACTION_BAR_COLORS;
+
+local __, ns = ...
+local oUF = ns.oUF or oUF
+assert(oUF, 'oUF Reputation was unable to locate oUF install')
+
+for tag, func in pairs({
+	['currep'] = function()
+		local __, __, min, __, value = GetWatchedFactionInfo()
+		return value - min
+	end,
+	['maxrep'] = function()
+		local __, __, min, max = GetWatchedFactionInfo()
+		return max - min
+	end,
+	['perrep'] = function()
+		local __, __, min, max, value = GetWatchedFactionInfo()
+		return math.floor((value - min) / (max - min) * 100 + 0.5)
+	end,
+	['standing'] = function()
+		local __, standing = GetWatchedFactionInfo()
+		return GetText('FACTION_STANDING_LABEL' .. standing, UnitSex('player'))
+	end,
+	['reputation'] = function()
+		return GetWatchedFactionInfo()
+	end,
+}) do
+	oUF.Tags.Methods[tag] = func
+	oUF.Tags.Events[tag] = 'UPDATE_FACTION'
+end
+
+oUF.Tags.SharedEvents.UPDATE_FACTION = true
+
+local function Update(self, event, unit)
+	local reputation = self.Reputation
+
+	local name, standing, min, max, value = GetWatchedFactionInfo()
+	if(not name) then
+		return reputation:Hide()
+	else
+		reputation:Show()
+	end
+
+	reputation:SetMinMaxValues(0, max - min)
+	reputation:SetValue(value - min)
+
+	if(reputation.colorStanding) then
+		local color = FACTION_BAR_COLORS[standing]
+		reputation:SetStatusBarColor(color.r, color.g, color.b)
+	end
+
+	if(reputation.PostUpdate) then
+		return reputation:PostUpdate(unit, name, standing, min, max, value)
+	end
+end
+
+local function Path(self, ...)
+	return (self.Reputation.Override or Update) (self, ...)
+end
+
+local function ForceUpdate(element)
+	return Path(element.__owner, 'ForceUpdate', element.__owner.unit)
+end
+
+local function Enable(self, unit)
+	local reputation = self.Reputation
+	if(reputation) then
+		reputation.__owner = self
+		reputation.ForceUpdate = ForceUpdate
+
+		self:RegisterEvent('UPDATE_FACTION', Path)
+
+		if(not reputation:GetStatusBarTexture()) then
+			reputation:SetStatusBarTexture([=[Interface\TargetingFrame\UI-StatusBar]=])
+		end
+
+		return true
+	end
+end
+
+local function Disable(self)
+	if(self.Reputation) then
+		self:UnregisterEvent('UPDATE_FACTION', Path)
+	end
+end
+
+oUF:AddElement('Reputation', Path, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_Reputation/oUF_Reputation.toc b/SVUI_UnitFrames/libs/Plugins/oUF_Reputation/oUF_Reputation.toc
new file mode 100644
index 0000000..d01a3fa
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_Reputation/oUF_Reputation.toc
@@ -0,0 +1,9 @@
+## Interface: 50001
+## Author: p3lim
+## Version: 50001.8-Release
+## Title: oUF Reputation
+## Notes: Reputation Bar support for oUF layouts.
+## RequiredDeps: oUF
+
+
+oUF_Reputation.lua
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_Smooth/oUF_Smooth.lua b/SVUI_UnitFrames/libs/Plugins/oUF_Smooth/oUF_Smooth.lua
new file mode 100644
index 0000000..6835963
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_Smooth/oUF_Smooth.lua
@@ -0,0 +1,78 @@
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local pairs         = _G.pairs;
+local type  		= _G.type;
+--MATH
+local math          = _G.math;
+local abs         	= math.abs;
+--BLIZZARD API
+local GetFramerate      = _G.GetFramerate;
+
+local _, ns = ...
+local oUF = ns.oUF or oUF
+if not oUF then return end
+
+local smoothing = {}
+local function Smooth(self, value)
+	if value ~= self:GetValue() or value == 0 then
+		smoothing[self] = value
+	else
+		smoothing[self] = nil
+	end
+end
+
+local function SmoothBar(bar)
+	if not bar.SetValue_ then
+		bar.SetValue_ = bar.SetValue;
+		bar.SetValue = Smooth;
+	end
+end
+
+local function ResetBar(bar)
+	if bar.SetValue_ then
+		bar.SetValue = bar.SetValue_;
+		bar.SetValue_ = nil;
+	end
+end
+
+local function hook(frame)
+	if frame.Health then
+		SmoothBar(frame.Health)
+	end
+	if frame.Power then
+		SmoothBar(frame.Power)
+	end
+	if frame.AltPowerBar then
+		SmoothBar(frame.AltPowerBar)
+	end
+end
+
+for i, frame in ipairs(oUF.objects) do hook(frame) end
+oUF:RegisterInitCallback(hook)
+
+local f, min, max = CreateFrame('Frame'), math.min, math.max
+f:SetScript('OnUpdate', function()
+	local rate = GetFramerate()
+	local limit = 30/rate
+
+	for bar, value in pairs(smoothing) do
+		local cur = bar:GetValue()
+		local new = cur + min((value-cur)/3, max(value-cur, limit))
+		if new ~= new then
+			-- Mad hax to prevent QNAN.
+			new = value
+		end
+		bar:SetValue_(new)
+		if (cur == value or abs(new - value) < 2) and bar.Smooth then
+			bar:SetValue_(value)
+			smoothing[bar] = nil
+		elseif not bar.Smooth then
+			bar:SetValue_(value)
+			smoothing[bar] = nil
+		end
+	end
+end)
\ No newline at end of file
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_TotemBars/oUF_TotemBars.lua b/SVUI_UnitFrames/libs/Plugins/oUF_TotemBars/oUF_TotemBars.lua
new file mode 100644
index 0000000..12e78da
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_TotemBars/oUF_TotemBars.lua
@@ -0,0 +1,119 @@
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+--BLIZZARD API
+local GameTooltip   = _G.GameTooltip;
+local MAX_TOTEMS 	= _G.MAX_TOTEMS;
+local TotemFrame 	= _G.TotemFrame;
+
+local class = select(2, UnitClass('player'))
+if(class ~= 'SHAMAN') then return end
+
+local parent, ns = ...
+local oUF = ns.oUF
+
+oUF.colors.totems = {
+	[FIRE_TOTEM_SLOT] = { 181/255, 073/255, 033/255 },
+	[EARTH_TOTEM_SLOT] = { 074/255, 142/255, 041/255 },
+	[WATER_TOTEM_SLOT] = { 057/255, 146/255, 181/255 },
+	[AIR_TOTEM_SLOT] = { 132/255, 056/255, 231/255 }
+}
+
+local GetTotemInfo, GetTime = GetTotemInfo, GetTime
+local priorities = SHAMAN_TOTEM_PRIORITIES or STANDARD_TOTEM_PRIORITIES
+
+local Totem_OnEnter = function(self)
+	if(not self:IsVisible()) then return end
+	GameTooltip:SetOwner(self, 'ANCHOR_BOTTOMRIGHT')
+	GameTooltip:SetTotem(self:GetID())
+end
+
+local Totem_OnLeave = function()
+	GameTooltip:Hide()
+end
+
+local Totem_OnUpdate = function(self, elapsed)
+	if not self.expirationTime then return end
+	self.elapsed = (self.elapsed or 0) + elapsed
+	if self.elapsed >= 0.5 then
+		local timeLeft = self.expirationTime - GetTime()
+		if timeLeft > 0 then
+			self:SetValue(timeLeft)
+		else
+			self:SetScript("OnUpdate", nil)
+		end
+	end
+end
+
+local Update = function(self, event)
+	local totems = self.TotemBars
+	if(totems.PreUpdate) then totems:PreUpdate() end
+	local haveTotem, name, start, duration, icon, timeLeft
+	for i = 1, MAX_TOTEMS do
+		local totem = totems[priorities[i]]
+		if(totem) then
+			haveTotem, name, start, duration, icon = GetTotemInfo(i)
+			timeLeft = (start + duration) - GetTime()
+			totem:SetMinMaxValues(0,duration)
+
+			if(timeLeft > 0) then
+				totem.expirationTime = (start + duration)
+				totem:SetValue(timeLeft)
+				totem:SetScript('OnUpdate', Totem_OnUpdate)
+			else
+				totem:SetValue(0)
+				totem:SetScript('OnUpdate', nil)
+			end
+		end
+	end
+
+	if(totems.PostUpdate) then
+		return totems:PostUpdate()
+	end
+end
+
+local Path = function(self, ...)
+	return (self.TotemBars.Override or Update) (self, ...)
+end
+
+local ForceUpdate = function(element)
+	return Path(element.__owner, 'ForceUpdate')
+end
+
+local Enable = function(self)
+	local totems = self.TotemBars
+
+	if(totems) then
+		totems.__owner = self
+		totems.__map = { unpack(priorities) }
+		totems.ForceUpdate = ForceUpdate
+
+		for i = 1, MAX_TOTEMS do
+			local totem = totems[i]
+			totem:SetID(priorities[i])
+
+			if(totem:IsMouseEnabled()) then
+				totem:SetScript('OnEnter', Totem_OnEnter)
+				totem:SetScript('OnLeave', Totem_OnLeave)
+			end
+		end
+
+		self:RegisterEvent('PLAYER_TOTEM_UPDATE', Path, true)
+
+		return true
+	end
+end
+
+local Disable = function(self)
+	if(self.TotemBars) then
+		for i = 1, MAX_TOTEMS do
+			self.TotemBars[i]:Hide()
+		end
+
+		self:UnregisterEvent('PLAYER_TOTEM_UPDATE', Path)
+	end
+end
+
+oUF:AddElement("TotemBars", Path, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_WarlockShards/oUF_WarlockShards.lua b/SVUI_UnitFrames/libs/Plugins/oUF_WarlockShards/oUF_WarlockShards.lua
new file mode 100644
index 0000000..19a24ac
--- /dev/null
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_WarlockShards/oUF_WarlockShards.lua
@@ -0,0 +1,130 @@
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+--MATH
+local math          = _G.math;
+local floor         = math.floor
+--BLIZZARD API
+local UnitPower     	= _G.UnitPower;
+local UnitPowerMax 		= _G.UnitPowerMax;
+local UnitHasVehicleUI 	= _G.UnitHasVehicleUI;
+local GetSpecialization = _G.GetSpecialization;
+
+if select(2, UnitClass('player')) ~= "WARLOCK" then return end
+
+local _, ns = ...
+local oUF = ns.oUF or oUF
+
+assert(oUF, 'oUF_WarlockShards was unable to locate oUF install')
+
+local shardColor = {
+	[1] = {0,0.72,0.1},
+	[2] = {0.57,0.08,1},
+	[3] = {1,0.25,0}
+}
+
+local Update = function(self, event, unit, powerType)
+	local bar = self.WarlockShards;
+
+	if(bar.PreUpdate) then bar:PreUpdate(unit) end
+
+	if UnitHasVehicleUI("player") then
+		bar:Hide()
+	else
+		bar:Show()
+	end
+
+	local spec = GetSpecialization()
+
+	if spec then
+		local colors = shardColor[spec]
+		local numShards = UnitPower("player", SPELL_POWER_SOUL_SHARDS);
+		bar.MaxCount = UnitPowerMax("player", SPELL_POWER_SOUL_SHARDS);
+
+		if not bar:IsShown() then
+			bar:Show()
+		end
+
+		if((not bar.CurrentSpec) or (bar.CurrentSpec ~= spec and bar.UpdateTextures)) then
+			bar:UpdateTextures(spec)
+		end
+
+		for i = 1, 5 do
+			if(i > bar.MaxCount) then
+				bar[i]:Hide()
+			else
+				bar[i]:Show()
+				bar[i]:SetStatusBarColor(unpack(colors))
+				bar[i]:SetMinMaxValues(0, 1)
+				local filled = (i <= numShards) and 1 or 0
+				bar[i]:SetValue(filled)
+				if(bar[i].Update) then
+					bar[i]:Update(filled)
+				end
+			end
+		end
+	else
+		if bar:IsShown() then bar:Hide() end;
+	end
+
+	if(bar.PostUpdate) then
+		return bar:PostUpdate(unit, spec)
+	end
+end
+
+local Path = function(self, ...)
+	return (self.WarlockShards.Override or Update) (self, ...)
+end
+
+local ForceUpdate = function(element)
+	return Path(element.__owner, 'ForceUpdate', element.__owner.unit, 'SOUL_SHARDS')
+end
+
+local function Enable(self, unit)
+	if(unit ~= 'player') then return end
+
+	local bar = self.WarlockShards
+	if(bar) then
+		bar.__owner = self
+		bar.ForceUpdate = ForceUpdate
+
+		self:RegisterEvent('UNIT_POWER', Path)
+		self:RegisterEvent("PLAYER_TALENT_UPDATE", Path)
+		self:RegisterEvent("PLAYER_ENTERING_WORLD", Path)
+		self:RegisterEvent('UNIT_DISPLAYPOWER', Path)
+		self:RegisterEvent("UNIT_POWER_FREQUENT", Path)
+		self:RegisterEvent("UNIT_MAXPOWER", Path)
+		self:RegisterUnitEvent('UNIT_DISPLAYPOWER', "player")
+		self:RegisterUnitEvent("UNIT_POWER_FREQUENT", "player")
+		self:RegisterUnitEvent("UNIT_MAXPOWER", "player")
+
+		for i = 1, 5 do
+			if not bar[i]:GetStatusBarTexture() then
+				bar[i]:SetStatusBarTexture([=[Interface\TargetingFrame\UI-StatusBar]=])
+			end
+
+			bar[i]:SetFrameLevel(bar:GetFrameLevel() + 1)
+			bar[i]:GetStatusBarTexture():SetHorizTile(false)
+		end
+
+		return true
+	end
+end
+
+local function Disable(self)
+	local bar = self.WarlockShards
+	if(bar) then
+		self:UnregisterEvent('UNIT_POWER', Path)
+		self:UnregisterEvent("PLAYER_TALENT_UPDATE", Path)
+		self:UnregisterEvent("PLAYER_ENTERING_WORLD", Path)
+		self:UnregisterEvent('UNIT_DISPLAYPOWER', Path)
+		self:UnregisterEvent("UNIT_POWER_FREQUENT", Path)
+		self:UnregisterEvent("UNIT_MAXPOWER", Path)
+		bar:Hide()
+	end
+end
+
+oUF:AddElement('WarlockShards', Path, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/_load.xml b/SVUI_UnitFrames/libs/_load.xml
new file mode 100644
index 0000000..4963bb5
--- /dev/null
+++ b/SVUI_UnitFrames/libs/_load.xml
@@ -0,0 +1,77 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/">
+
+	<!-- oUF Core Files -->
+	<Script file='oUF\init.lua' />
+	<Script file='oUF\private.lua' />
+	<Script file='oUF\ouf.lua' />
+	<Script file='oUF\events.lua'/>
+	<Script file='oUF\factory.lua' />
+	<Script file='oUF\blizzard.lua' />
+	<Script file='oUF\units.lua' />
+	<Script file='oUF\colors.lua' />
+	<Script file='oUF\finalize.lua' />
+
+	<Script file='oUF\elements\power.lua' />
+	<Script file='oUF\elements\aura.lua' />
+	<Script file='oUF\elements\health.lua' />
+	<Script file='oUF\elements\ricons.lua' />
+	<Script file='oUF\elements\leader.lua' />
+	<Script file='oUF\elements\combat.lua' />
+	<Script file='oUF\elements\resting.lua' />
+	<Script file='oUF\elements\pvp.lua' />
+	<Script file='oUF\elements\portraits.lua' />
+	<Script file='oUF\elements\range.lua' />
+	<Script file='oUF\elements\castbar.lua' />
+	<Script file='oUF\elements\threat.lua' />
+	<Script file='oUF\elements\tags.lua' />
+	<Script file='oUF\elements\masterlooter.lua' />
+	<Script file='oUF\elements\lfdrole.lua' />
+	<Script file='oUF\elements\healprediction.lua' />
+	<Script file='oUF\elements\picon.lua' />
+	<Script file='oUF\elements\readycheck.lua' />
+	<Script file='oUF\elements\qicon.lua' />
+	<Script file='oUF\elements\altpowerbar.lua' />
+	<Script file='oUF\elements\resurrect.lua' />
+	<Script file='oUF\elements\assistant.lua' />
+	<Script file='oUF\elements\maintank.lua' />
+
+	<!-- Clique support -->
+	<Button name="oUF_ClickCastUnitTemplate" virtual="true" inherits="SecureUnitButtonTemplate,SecureHandlerEnterLeaveTemplate">
+		<Attributes>
+			<Attribute name="_onenter" type="string" value="local snippet = self:GetAttribute('clickcast_onenter'); if snippet then self:Run(snippet) end"/>
+			<Attribute name="_onleave" type="string" value="local snippet = self:GetAttribute('clickcast_onleave'); if snippet then self:Run(snippet) end"/>
+		</Attributes>
+	</Button>
+
+	<!-- Pet Battle Hider Frame -->
+	<Frame name="oUF_PetBattleFrameHider" inherits="SecureHandlerStateTemplate" parent="UIParent" setAllPoints="true">
+		<Scripts>
+			<OnLoad>
+				RegisterStateDriver(self, "visibility", "[petbattle] hide; show")
+			</OnLoad>
+		</Scripts>
+	</Frame>
+
+	<!-- Custom oUF Plugins -->
+	<Script file="plugins\oUF_AuraWatch\oUF_AuraWatch.lua"/>
+	<Script file="plugins\oUF_RaidDebuffs\oUF_RaidDebuffs.lua"/>
+	<Script file="plugins\oUF_Smooth\oUF_Smooth.lua"/>
+	<Script file="plugins\oUF_CombatFader\oUF_CombatFader.lua"/>
+	<Script file="plugins\oUF_Experience\oUF_Experience.lua"/>
+	<Script file="plugins\oUF_Reputation\oUF_Reputation.lua"/>
+	<Script file="plugins\oUF_Friendship\oUF_Friendship.lua"/>
+	<Script file="plugins\oUF_MageMagic\oUF_MageMagic.lua"/>
+	<Script file="plugins\oUF_ActionPanel\oUF_ActionPanel.lua"/>
+	<Script file="plugins\oUF_Afflicted\oUF_Afflicted.lua"/>
+	<Script file="plugins\oUF_HunterTraps\oUF_HunterTraps.lua"/>
+	<Script file="plugins\oUF_PallyPower\oUF_PallyPower.lua"/>
+	<Script file="plugins\oUF_WarlockShards\oUF_WarlockShards.lua"/>
+	<Script file="plugins\oUF_PriestOrbs\oUF_PriestOrbs.lua"/>
+	<Script file="plugins\oUF_KungFu\oUF_KungFu.lua"/>
+	<Script file="plugins\oUF_Maelstrom\oUF_Maelstrom.lua"/>
+	<Script file="plugins\oUF_HyperCombo\oUF_HyperCombo.lua"/>
+	<Script file="plugins\oUF_Gladiator\oUF_Gladiator.lua"/>
+	<Script file="plugins\oUF_Necromancy\oUF_Necromancy.lua"/>
+	<Script file="plugins\oUF_Druidness\oUF_Druidness.lua"/>
+	<Script file="plugins\oUF_Conqueror\oUF_Conqueror.lua"/>
+</Ui>
\ No newline at end of file
diff --git a/SVUI_UnitFrames/libs/oUF/LICENSE b/SVUI_UnitFrames/libs/oUF/LICENSE
new file mode 100644
index 0000000..f67ac68
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/LICENSE
@@ -0,0 +1,22 @@
+Copyright (c) 2006-2012 Trond A Ekseth <troeks@gmail.com>
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/SVUI_UnitFrames/libs/oUF/blizzard.lua b/SVUI_UnitFrames/libs/oUF/blizzard.lua
new file mode 100644
index 0000000..9da0ae4
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/blizzard.lua
@@ -0,0 +1,101 @@
+local parent, ns = ...
+local oUF = ns.oUF
+
+local hiddenParent = CreateFrame("Frame")
+hiddenParent:Hide()
+
+local HandleFrame = function(baseName)
+	local frame
+	if(type(baseName) == 'string') then
+		frame = _G[baseName]
+	else
+		frame = baseName
+	end
+
+	if(frame) then
+		frame:UnregisterAllEvents()
+		frame:Hide()
+
+		-- Keep frame hidden without causing taint
+		frame:SetParent(hiddenParent)
+
+		local health = frame.healthbar
+		if(health) then
+			health:UnregisterAllEvents()
+		end
+
+		local power = frame.manabar
+		if(power) then
+			power:UnregisterAllEvents()
+		end
+
+		local spell = frame.spellbar
+		if(spell) then
+			spell:UnregisterAllEvents()
+		end
+
+		local altpowerbar = frame.powerBarAlt
+		if(altpowerbar) then
+			altpowerbar:UnregisterAllEvents()
+		end
+	end
+end
+
+function oUF:DisableBlizzard(unit)
+	if(not unit) or InCombatLockdown() then return end
+
+	if(unit == 'player') then
+		HandleFrame(PlayerFrame)
+
+		-- For the damn vehicle support:
+		PlayerFrame:RegisterUnitEvent('UNIT_ENTERING_VEHICLE', "player")
+		PlayerFrame:RegisterUnitEvent('UNIT_ENTERED_VEHICLE', "player")
+		PlayerFrame:RegisterUnitEvent('UNIT_EXITING_VEHICLE', "player")
+		PlayerFrame:RegisterUnitEvent('UNIT_EXITED_VEHICLE', "player")
+
+		-- User placed frames don't animate
+		PlayerFrame:SetUserPlaced(true)
+		PlayerFrame:SetDontSavePosition(true)
+	elseif(unit == 'pet') then
+		HandleFrame(PetFrame)
+	elseif(unit == 'target') then
+		HandleFrame(TargetFrame)
+		HandleFrame(ComboFrame)
+	elseif(unit == 'focus') then
+		HandleFrame(FocusFrame)
+		HandleFrame(TargetofFocusFrame)
+	elseif(unit == 'targettarget') then
+		HandleFrame(TargetFrameToT)
+	elseif(unit:match'(boss)%d?$' == 'boss') then
+		local id = unit:match'boss(%d)'
+		if(id) then
+			HandleFrame('Boss' .. id .. 'TargetFrame')
+		else
+			for i=1, 4 do
+				HandleFrame(('Boss%dTargetFrame'):format(i))
+			end
+		end
+	elseif(unit:match'(party)%d?$' == 'party') then
+		local id = unit:match'party(%d)'
+		if(id) then
+			HandleFrame('PartyMemberFrame' .. id)
+		else
+			for i=1, 4 do
+				HandleFrame(('PartyMemberFrame%d'):format(i))
+			end
+		end
+	elseif(unit:match'(arena)%d?$' == 'arena') then
+		local id = unit:match'arena(%d)'
+		if(id) then
+			HandleFrame('ArenaEnemyFrame' .. id)
+		else
+			for i=1, 4 do
+				HandleFrame(('ArenaEnemyFrame%d'):format(i))
+			end
+		end
+
+		-- Blizzard_ArenaUI should not be loaded
+		Arena_LoadUI = function() end
+		SetCVar('showArenaEnemyFrames', '0', 'SHOW_ARENA_ENEMY_FRAMES_TEXT')
+	end
+end
diff --git a/SVUI_UnitFrames/libs/oUF/colors.lua b/SVUI_UnitFrames/libs/oUF/colors.lua
new file mode 100644
index 0000000..f7a62f6
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/colors.lua
@@ -0,0 +1,160 @@
+local parent, ns = ...
+local oUF = ns.oUF
+local Private = oUF.Private
+
+local frame_metatable = Private.frame_metatable
+
+local colors = {
+	smooth = {
+		1, 0, 0,
+		1, 1, 0,
+		0, 1, 0
+	},
+	disconnected = {.6, .6, .6},
+	tapped = {.6,.6,.6},
+	class = {},
+	reaction = {},
+}
+
+-- We do this because people edit the vars directly, and changing the default
+-- globals makes SPICE FLOW!
+local customClassColors = function()
+	if(CUSTOM_CLASS_COLORS) then
+		local updateColors = function()
+			for eclass, color in next, CUSTOM_CLASS_COLORS do
+				colors.class[eclass] = {color.r, color.g, color.b}
+			end
+
+			for _, obj in next, oUF.objects do
+				obj:UpdateAllElements("CUSTOM_CLASS_COLORS")
+			end
+		end
+
+		updateColors()
+		CUSTOM_CLASS_COLORS:RegisterCallback(updateColors)
+
+		return true
+	end
+end
+if not customClassColors() then
+	for eclass, color in next, RAID_CLASS_COLORS do
+		colors.class[eclass] = {color.r, color.g, color.b}
+	end
+
+	local f = CreateFrame("Frame")
+	f:RegisterEvent("ADDON_LOADED")
+	f:SetScript("OnEvent", function()
+		if customClassColors() then
+			f:UnregisterEvent("ADDON_LOADED")
+			f:SetScript("OnEvent", nil)
+		end
+	end)
+end
+
+for eclass, color in next, FACTION_BAR_COLORS do
+	colors.reaction[eclass] = {color.r, color.g, color.b}
+end
+
+local function ColorsAndPercent(a, b, ...)
+	if a <= 0 or b == 0 then
+		return nil, ...
+	elseif a >= b then
+		return nil, select(select('#', ...) - 2, ...)
+	end
+
+	local num = select('#', ...) / 3
+	local segment, relperc = math.modf((a/b)*(num-1))
+	return relperc, select((segment*3)+1, ...)
+end
+
+-- http://www.wowwiki.com/ColorGradient
+local RGBColorGradient = function(...)
+	local relperc, r1, g1, b1, r2, g2, b2 = ColorsAndPercent(...)
+	if relperc then
+		return r1 + (r2-r1)*relperc, g1 + (g2-g1)*relperc, b1 + (b2-b1)*relperc
+	else
+		return r1, g1, b1
+	end
+end
+
+
+local function GetY(r, g, b)
+	return 0.3 * r + 0.59 * g + 0.11 * b
+end
+
+local function RGBToHCY(r, g, b)
+	local min, max = min(r, g, b), max(r, g, b)
+	local chroma = max - min
+	local hue
+	if chroma > 0 then
+		if r == max then
+			hue = ((g - b) / chroma) % 6
+		elseif g == max then
+			hue = (b - r) / chroma + 2
+		elseif b == max then
+			hue = (r - g) / chroma + 4
+		end
+		hue = hue / 6
+	end
+	return hue, chroma, GetY(r, g, b)
+end
+
+local abs = math.abs
+local function HCYtoRGB(hue, chroma, luma)
+	local r, g, b = 0, 0, 0
+	if hue then
+		local h2 = hue * 6
+		local x = chroma * (1 - abs(h2 % 2 - 1))
+		if h2 < 1 then
+			r, g, b = chroma, x, 0
+		elseif h2 < 2 then
+			r, g, b = x, chroma, 0
+		elseif h2 < 3 then
+			r, g, b = 0, chroma, x
+		elseif h2 < 4 then
+			r, g, b = 0, x, chroma
+		elseif h2 < 5 then
+			r, g, b = x, 0, chroma
+		else
+			r, g, b = chroma, 0, x
+		end
+	end
+	local m = luma - GetY(r, g, b)
+	return r + m, g + m, b + m
+end
+
+local HCYColorGradient = function(...)
+	local relperc, r1, g1, b1, r2, g2, b2 = ColorsAndPercent(...)
+	if not relperc then return r1, g1, b1 end
+	local h1, c1, y1 = RGBToHCY(r1, g1, b1)
+	local h2, c2, y2 = RGBToHCY(r2, g2, b2)
+	local c = c1 + (c2-c1) * relperc
+	local y = y1 + (y2-y1) * relperc
+	if h1 and h2 then
+		local dh = h2 - h1
+		if dh < -0.5  then
+			dh = dh + 1
+		elseif dh > 0.5 then
+			dh = dh - 1
+		end
+		return HCYtoRGB((h1 + dh * relperc) % 1, c, y)
+	else
+		return HCYtoRGB(h1 or h2, c, y)
+	end
+
+end
+
+local ColorGradient = function(...)
+	return (oUF.useHCYColorGradient and HCYColorGradient or RGBColorGradient)(...)
+end
+
+Private.colors = colors
+
+oUF.colors = colors
+oUF.ColorGradient = ColorGradient
+oUF.RGBColorGradient = RGBColorGradient
+oUF.HCYColorGradient = HCYColorGradient
+oUF.useHCYColorGradient = false
+
+frame_metatable.__index.colors = colors
+frame_metatable.__index.ColorGradient = ColorGradient
diff --git a/SVUI_UnitFrames/libs/oUF/elements/altpowerbar.lua b/SVUI_UnitFrames/libs/oUF/elements/altpowerbar.lua
new file mode 100644
index 0000000..ed2141c
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/elements/altpowerbar.lua
@@ -0,0 +1,86 @@
+local parent, ns = ...
+local oUF = ns.oUF
+
+local ALTERNATE_POWER_INDEX = ALTERNATE_POWER_INDEX
+
+local UpdatePower = function(self, event, unit, powerType)
+	if(self.unit ~= unit or powerType ~= 'ALTERNATE') or not unit then return end
+
+	local altpowerbar = self.AltPowerBar
+
+	if(altpowerbar.PreUpdate) then
+		altpowerbar:PreUpdate()
+	end
+
+	local barType, min = UnitAlternatePowerInfo(unit)
+	local cur = UnitPower(unit, ALTERNATE_POWER_INDEX)
+	local max = UnitPowerMax(unit, ALTERNATE_POWER_INDEX)
+
+	altpowerbar.barType = barType
+	altpowerbar:SetMinMaxValues(min, max)
+	altpowerbar:SetValue(cur)
+
+	if(altpowerbar.PostUpdate) then
+		return altpowerbar:PostUpdate(min, cur, max)
+	end
+end
+
+local ForceUpdate = function(element)
+	return UpdatePower(element.__owner, 'ForceUpdate', element.__owner.unit, 'ALTERNATE')
+end
+
+local Toggler = function(self, event, unit)
+	if(unit ~= self.unit) or not unit then return end
+	local altpowerbar = self.AltPowerBar
+
+	local barType, minPower, _, _, _, hideFromOthers = UnitAlternatePowerInfo(unit)
+	if(barType and (not hideFromOthers or unit == 'player' or self.realUnit == 'player')) then
+		self:RegisterEvent('UNIT_POWER', UpdatePower)
+		self:RegisterEvent('UNIT_MAXPOWER', UpdatePower)
+
+		ForceUpdate(altpowerbar)
+		altpowerbar:Show()
+	else
+		self:UnregisterEvent('UNIT_POWER', UpdatePower)
+		self:UnregisterEvent('UNIT_MAXPOWER', UpdatePower)
+
+		altpowerbar:Hide()
+	end
+end
+
+local Enable = function(self, unit)
+	local altpowerbar = self.AltPowerBar
+	if(altpowerbar) then
+		altpowerbar.__owner = self
+		altpowerbar.ForceUpdate = ForceUpdate
+
+		self:RegisterEvent('UNIT_POWER_BAR_SHOW', Toggler)
+		self:RegisterEvent('UNIT_POWER_BAR_HIDE', Toggler)
+
+		altpowerbar:Hide()
+
+		if(unit == 'player') then
+			PlayerPowerBarAlt:UnregisterEvent'UNIT_POWER_BAR_SHOW'
+			PlayerPowerBarAlt:UnregisterEvent'UNIT_POWER_BAR_HIDE'
+			PlayerPowerBarAlt:UnregisterEvent'PLAYER_ENTERING_WORLD'
+		end
+
+		return true
+	end
+end
+
+local Disable = function(self, unit)
+	local altpowerbar = self.AltPowerBar
+	if(altpowerbar) then
+		self:UnregisterEvent('UNIT_POWER_BAR_SHOW', Toggler)
+		self:UnregisterEvent('UNIT_POWER_BAR_HIDE', Toggler)
+
+		if(unit == 'player') then
+			PlayerPowerBarAlt:RegisterEvent'UNIT_POWER_BAR_SHOW'
+			PlayerPowerBarAlt:RegisterEvent'UNIT_POWER_BAR_HIDE'
+			PlayerPowerBarAlt:RegisterEvent'PLAYER_ENTERING_WORLD'
+		end
+	end
+end
+
+oUF:AddElement('AltPowerBar', Toggler, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/oUF/elements/assistant.lua b/SVUI_UnitFrames/libs/oUF/elements/assistant.lua
new file mode 100644
index 0000000..1d485d7
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/elements/assistant.lua
@@ -0,0 +1,56 @@
+local parent, ns = ...
+local oUF = ns.oUF
+
+local Update = function(self, event)
+	if not self.unit then return; end
+	local assistant = self.Assistant
+
+	if(assistant.PreUpdate) then
+		assistant:PreUpdate()
+	end
+
+	local unit = self.unit
+	local isAssistant = UnitInRaid(unit) and UnitIsRaidOfficer(unit) and not UnitIsGroupLeader(unit)
+	if(isAssistant) then
+		assistant:Show()
+	else
+		assistant:Hide()
+	end
+
+	if(assistant.PostUpdate) then
+		return assistant:PostUpdate(isAssistant)
+	end
+end
+
+local Path = function(self, ...)
+	return (self.Assistant.Override or Update) (self, ...)
+end
+
+local ForceUpdate = function(element)
+	return Path(element.__owner, 'ForceUpdate')
+end
+
+local Enable = function(self)
+	local assistant = self.Assistant
+	if(assistant) then
+		self:RegisterEvent("GROUP_ROSTER_UPDATE", Path, true)
+
+		if(assistant:IsObjectType"Texture" and not assistant:GetTexture()) then
+			assistant:SetTexture[[Interface\GroupFrame\UI-Group-AssistantIcon]]
+		end
+
+		assistant.__owner = self
+		assistant.ForceUpdate = ForceUpdate
+
+		return true
+	end
+end
+
+local Disable = function(self)
+	local assistant = self.Assistant
+	if(assistant) then
+		self:UnregisterEvent("GROUP_ROSTER_UPDATE", Path)
+	end
+end
+
+oUF:AddElement('Assistant', Path, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/oUF/elements/aura.lua b/SVUI_UnitFrames/libs/oUF/elements/aura.lua
new file mode 100644
index 0000000..ab1d271
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/elements/aura.lua
@@ -0,0 +1,854 @@
+--[[ MODIFIED FOR SVUI BY SVUILUNCH ]]--
+
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local type         	= _G.type;
+--STRING
+local string        = _G.string;
+local format        = string.format;
+--MATH
+local math          = math;
+local floor         = math.floor
+local ceil         	= math.ceil
+local hugeMath 			= math.huge;
+local min 					= math.min;
+local random 				= math.random;
+--TABLE
+local table 				= _G.table;
+local tsort 				= table.sort;
+local tinsert 			= _G.tinsert;
+--BLIZZARD API
+local GetTime       = _G.GetTime;
+local CreateFrame   = _G.CreateFrame;
+local UnitAura      = _G.UnitAura;
+local UnitIsFriend  = _G.UnitIsFriend;
+local GameTooltip  	= _G.GameTooltip;
+local GetSpellInfo  = _G.GetSpellInfo;
+local DebuffTypeColor  = _G.DebuffTypeColor;
+local NumberFontNormal  = _G.NumberFontNormal;
+
+local _, ns = ...
+local oUF = oUF or ns.oUF
+assert(oUF, 'oUF_Auras was unable to locate oUF install.')
+
+local DAY, HOUR, MINUTE = 86400, 3600, 60;
+local BUFF_FILTER = 'HELPFUL';
+local DEBUFF_FILTER = 'HARMFUL';
+local VISIBLE = 1;
+local HIDDEN = 0;
+
+local DEMO_SPELLS = {47540, 974, 111264, 57934, 124081}
+
+local function FormatTime(seconds)
+	if seconds < MINUTE then
+		return ("%.1f"):format(seconds)
+	elseif seconds < HOUR then
+		return ("%d:%d"):format(seconds/60%60, seconds%60)
+	elseif seconds < DAY then
+		return ("%dh %dm"):format(seconds/(60*60), seconds/60%60)
+	else
+		return ("%dd %dh"):format(seconds/DAY, (seconds / HOUR) - (floor(seconds/DAY) * 24))
+	end
+end
+
+local SORTING_METHODS = {
+	["TIME_REMAINING"] = function(a, b)
+		local compA = a.noTime and hugeMath or a.expirationTime
+		local compB = b.noTime and hugeMath or b.expirationTime
+		return compA > compB
+	end,
+	["TIME_REMAINING_REVERSE"] = function(a, b)
+		local compA = a.noTime and hugeMath or a.expirationTime
+		local compB = b.noTime and hugeMath or b.expirationTime
+		return compA < compB
+	end,
+	["TIME_DURATION"] = function(a, b)
+		local compA = a.noTime and hugeMath or a.duration
+		local compB = b.noTime and hugeMath or b.duration
+		return compA > compB
+	end,
+	["TIME_DURATION_REVERSE"] = function(a, b)
+		local compA = a.noTime and hugeMath or a.duration
+		local compB = b.noTime and hugeMath or b.duration
+		return compA < compB
+	end,
+	["NAME"] = function(a, b)
+		return a.name > b.name
+	end,
+}
+
+local SetSorting = function(self, sorting)
+	if(sorting) then
+		if((type(sorting) == "string") and SORTING_METHODS[sorting]) then
+			self.sort = SORTING_METHODS[sorting];
+		else
+			self.sort = SORTING_METHODS["TIME_REMAINING"];
+		end
+	else
+		self.sort = nil;
+	end
+end
+
+local Aura_OnEnter = function(self)
+	if(not self:IsVisible()) then return end
+	GameTooltip:SetOwner(self, "ANCHOR_BOTTOMRIGHT")
+	GameTooltip:SetUnitAura(self.unit, self.index, self.filter)
+end
+
+local Aura_OnLeave = function()
+	GameTooltip:Hide()
+end
+
+local AuraBars_OnUpdate = function(self)
+	local timeNow = GetTime()
+	for index = 1, #self do
+		local frame = self[index]
+		local bar = frame.statusBar
+		if not frame:IsVisible() then
+			break
+		end
+		if frame.noTime then
+			bar.spelltime:SetText()
+			bar.spark:Hide()
+		else
+			local timeleft = frame.expirationTime - timeNow
+			bar:SetValue(timeleft)
+			bar.spelltime:SetText(FormatTime(timeleft))
+			if self.spark == true then
+				bar.spark:Show()
+			end
+		end
+	end
+end
+
+local AuraIcon_OnUpdate = function(self, elapsed)
+	self.expiration = self.expiration - elapsed;
+
+	if(self.nextUpdate > 0) then
+		self.nextUpdate = self.nextUpdate - elapsed;
+		return;
+	end
+
+	if(self.expiration <= 0) then
+		self:SetScript("OnUpdate", nil)
+		self.text:SetText('')
+		return;
+	end
+
+	local expires = self.expiration;
+	local calc, timeLeft = 0, 0;
+	if expires < 4 then
+        self.nextUpdate = 0.051
+        self.text:SetFormattedText("|cffff0000%.1f|r", expires)
+    elseif expires < 60 then
+        self.nextUpdate = 0.51
+        self.text:SetFormattedText("|cffffff00%d|r", floor(expires))
+    elseif expires < 3600 then
+        timeLeft = ceil(expires / 60);
+        calc = floor((expires / 60) + .5);
+        self.nextUpdate = calc > 1 and ((expires - calc) * 29.5) or (expires - 59.5);
+        self.text:SetFormattedText("|cffffffff%dm|r", timeLeft)
+    elseif expires < 86400 then
+        timeLeft = ceil(expires / 3600);
+        calc = floor((expires / 3600) + .5);
+        self.nextUpdate = calc > 1 and ((expires - calc) * 1799.5) or (expires - 3570);
+        self.text:SetFormattedText("|cff66ffff%dh|r", timeLeft)
+    else
+        timeLeft = ceil(expires / 86400);
+        calc = floor((expires / 86400) + .5);
+        self.nextUpdate = calc > 1 and ((expires - calc) * 43199.5) or (expires - 85680);
+        if(timeLeft > 7) then
+            self.text:SetFormattedText("|cff6666ff%s|r", "long")
+        else
+            self.text:SetFormattedText("|cff6666ff%dd|r", timeLeft)
+        end
+    end
+end
+
+local SetBarLayout = function(self, visible, cache)
+	local auras = self.Bars;
+
+	local width = self.barWidth or self:GetParent():GetWidth();
+	local height = self.barHeight or 16;
+	local growDown = self.down or false;
+	local spacing = self.spacing or 0;
+	local gap = self.gap;
+	local size = self.auraSize + spacing;
+
+	if(visible > 0) then
+		local newHeight = 1 + (size * visible);
+		self:SetSize(width, newHeight)
+	else
+		self:SetSize(width, 1)
+	end
+
+	for i = visible + 1, #auras do
+		auras[i]:Hide()
+	end
+
+	local lastBar;
+	if(cache) then
+		for i = 1, #cache do
+			local info = cache[i]
+			local bar = auras[info.ref]
+			if(bar and bar:IsShown()) then
+				bar:SetHeight(height)
+				bar:SetWidth(width)
+				bar.iconHolder:SetWidth(height)
+				bar:ClearAllPoints()
+				if(growDown) then
+					if(not lastBar) then
+						bar:SetPoint('TOPLEFT', self, 'TOPLEFT', 0, 0)
+					else
+						bar:SetPoint('TOPLEFT', lastBar, 'BOTTOMLEFT', 0, -spacing)
+					end
+				else
+					if(not lastBar) then
+						bar:SetPoint('BOTTOMLEFT', self, 'BOTTOMLEFT', 0, 0)
+					else
+						bar:SetPoint('BOTTOMLEFT', lastBar, 'TOPLEFT', 0, spacing)
+					end
+				end
+				lastBar = bar
+			end
+		end
+	else
+		for index = 1, #auras do
+			local bar = auras[index]
+			if(bar and bar:IsShown()) then
+				bar:SetHeight(height)
+				bar:SetWidth(width)
+				bar.iconHolder:SetWidth(height)
+				bar:ClearAllPoints()
+				if(growDown) then
+					if(not lastBar) then
+						bar:SetPoint('TOPLEFT', self, 'TOPLEFT', 0, 0)
+					else
+						bar:SetPoint('TOPLEFT', lastBar, 'BOTTOMLEFT', 0, -spacing)
+					end
+				else
+					if(not lastBar) then
+						bar:SetPoint('BOTTOMLEFT', self, 'BOTTOMLEFT', 0, 0)
+					else
+						bar:SetPoint('BOTTOMLEFT', lastBar, 'TOPLEFT', 0, spacing)
+					end
+				end
+				lastBar = bar
+			end
+		end
+	end
+end
+
+local SetIconLayout = function(self, visible, cache)
+	local auras = self.Icons
+
+	local col = 0
+	local row = 0
+	local gap = self.gap
+	local size = self.auraSize + self.spacing
+	local anchor = self.initialAnchor or "BOTTOMLEFT"
+	local growthx = (self["growth-x"] == "LEFT" and -1) or 1
+	local growthy = (self["growth-y"] == "DOWN" and -1) or 1
+	local cols = self.maxColumns
+	local rows = self.maxRows
+
+	for i = visible + 1, #auras do
+		auras[i]:Hide()
+	end
+
+	if(cache) then
+		for i = 1, #cache do
+			local info = cache[i]
+			local button = auras[info.ref]
+			if(button and button:IsShown()) then
+				if(gap and button.debuff) then
+					if(col > 0) then
+						col = col + 1
+					end
+					gap = false
+				end
+
+				if(col >= cols) then
+					col = 0
+					row = row + 1
+				end
+				button:ClearAllPoints()
+				button:SetPoint(anchor, self, anchor, col * size * growthx, row * size * growthy)
+				button:SetWidth(self.auraSize)
+				button:SetHeight(self.auraSize)
+				col = col + 1
+			elseif(not button) then
+				break
+			end
+		end
+	else
+		for i = 1, #auras do
+			local button = auras[i]
+			if(button and button:IsShown()) then
+				if(gap and button.debuff) then
+					if(col > 0) then
+						col = col + 1
+					end
+					gap = false
+				end
+
+				if(col >= cols) then
+					col = 0
+					row = row + 1
+				end
+				button:ClearAllPoints()
+				button:SetPoint(anchor, self, anchor, col * size * growthx, row * size * growthy)
+				button:SetWidth(self.auraSize)
+				button:SetHeight(self.auraSize)
+				col = col + 1
+			elseif(not button) then
+				break
+			end
+		end
+	end
+
+	local newWidth, newHeight;
+	if(visible > 0) then
+		local visibleRows = ceil(visible / cols);
+		newHeight = 1 + (size * visibleRows);
+		if(visibleRows <= 1) then
+			newWidth = 1 + (size * col)
+		else
+			newWidth = 1 + (size * cols)
+		end
+	else
+		newWidth = 1 + (size * cols)
+		newHeight = 1
+	end
+	self:SetSize(newWidth, newHeight)
+end
+
+--[[ ICON SPECIFIC ]]--
+
+local CreateAuraIcon = function(self, index)
+	local button = CreateFrame("Button", nil, self)
+	button:EnableMouse(true)
+	button:RegisterForClicks'RightButtonUp'
+
+	button:SetWidth(self.auraSize or 16)
+	button:SetHeight(self.auraSize or 16)
+
+	local cd = CreateFrame("Cooldown", nil, button, "CooldownFrameTemplate")
+	cd:SetAllPoints(button)
+
+	local icon = button:CreateTexture(nil, "BORDER")
+	icon:SetAllPoints(button)
+
+	local count = button:CreateFontString(nil, "OVERLAY")
+	count:SetFontObject(NumberFontNormal)
+	count:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -1, 0)
+
+	local overlay = button:CreateTexture(nil, "OVERLAY")
+	overlay:SetTexture"Interface\\Buttons\\UI-Debuff-Overlays"
+	overlay:SetAllPoints(button)
+	overlay:SetTexCoord(.296875, .5703125, 0, .515625)
+	button.overlay = overlay
+
+	local stealable = button:CreateTexture(nil, 'OVERLAY')
+	stealable:SetTexture[[Interface\TargetingFrame\UI-TargetingFrame-Stealable]]
+	stealable:SetPoint('TOPLEFT', -3, 3)
+	stealable:SetPoint('BOTTOMRIGHT', 3, -3)
+	stealable:SetBlendMode'ADD'
+	button.stealable = stealable
+
+	button:SetScript("OnEnter", Aura_OnEnter)
+	button:SetScript("OnLeave", Aura_OnLeave)
+
+	button.icon = icon
+	button.count = count
+	button.cooldown = cd
+
+	if(self.PostCreateIcon) then self:PostCreateIcon(button) end
+
+	return button
+end
+
+--[[ BAR SPECIFIC ]]--
+
+local CreateAuraBar = function(self, index)
+	local frame = CreateFrame("Button", nil, self)
+
+	frame:SetScript('OnEnter', Aura_OnEnter)
+	frame:SetScript('OnLeave', Aura_OnLeave)
+
+	local iconHolder = CreateFrame('Frame', nil, frame)
+	iconHolder:SetPoint('TOPLEFT', frame, 'TOPLEFT', 0, 0)
+	iconHolder:SetPoint('BOTTOMLEFT', frame, 'BOTTOMLEFT', 0, 0)
+	iconHolder:SetWidth(frame:GetHeight())
+	iconHolder:SetBackdrop({
+        bgFile = [[Interface\BUTTONS\WHITE8X8]],
+        edgeFile = [[Interface\BUTTONS\WHITE8X8]],
+        tile = false,
+        tileSize = 0,
+        edgeSize = 1,
+        insets =
+        {
+            left = 0,
+            right = 0,
+            top = 0,
+            bottom = 0,
+        },
+    })
+    iconHolder:SetBackdropColor(0,0,0,0.5)
+    iconHolder:SetBackdropBorderColor(0,0,0)
+	frame.iconHolder = iconHolder
+
+	frame.icon = frame.iconHolder:CreateTexture(nil, 'BORDER')
+	frame.icon:SetTexCoord(.1, .9, .1, .9)
+	frame.icon:SetPoint("TOPLEFT", frame.iconHolder, "TOPLEFT", 1, -1)
+	frame.icon:SetPoint("BOTTOMRIGHT", frame.iconHolder, "BOTTOMRIGHT", -1, 1)
+
+	frame.count = frame.iconHolder:CreateFontString(nil, "OVERLAY")
+	frame.count:SetFontObject(NumberFontNormal)
+	frame.count:SetPoint("BOTTOMRIGHT", frame.iconHolder, "BOTTOMRIGHT", -1, 0)
+
+	local barHolder = CreateFrame('Frame', nil, frame)
+	barHolder:SetPoint('BOTTOMLEFT', frame.iconHolder, 'BOTTOMRIGHT', self.gap, 0)
+	barHolder:SetPoint('TOPRIGHT', frame, 'TOPRIGHT', 0, 0)
+	barHolder:SetBackdrop({
+        bgFile = [[Interface\BUTTONS\WHITE8X8]],
+        edgeFile = [[Interface\BUTTONS\WHITE8X8]],
+        tile = false,
+        tileSize = 0,
+        edgeSize = 1,
+        insets =
+        {
+            left = 0,
+            right = 0,
+            top = 0,
+            bottom = 0,
+        },
+    })
+    barHolder:SetBackdropColor(0,0,0,0.5)
+    barHolder:SetBackdropBorderColor(0,0,0)
+	frame.barHolder = barHolder
+
+	-- the main bar
+	frame.statusBar = CreateFrame("StatusBar", nil, frame.barHolder)
+	frame.statusBar:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]])
+	frame.statusBar:SetAlpha(self.fgalpha or 1)
+	frame.statusBar:SetPoint("TOPLEFT", frame.barHolder, "TOPLEFT", 1, -1)
+	frame.statusBar:SetPoint("BOTTOMRIGHT", frame.barHolder, "BOTTOMRIGHT", -1, 1)
+
+	local spark = frame.statusBar:CreateTexture(nil, "OVERLAY", nil);
+	spark:SetTexture([[Interface\CastingBar\UI-CastingBar-Spark]]);
+	spark:SetWidth(12);
+	spark:SetBlendMode("ADD");
+	spark:SetPoint('CENTER', frame.statusBar:GetStatusBarTexture(), 'RIGHT')
+	frame.statusBar.spark = spark
+
+	frame.statusBar.spelltime = frame.statusBar:CreateFontString(nil, 'ARTWORK')
+	frame.statusBar.spellname = frame.statusBar:CreateFontString(nil, 'ARTWORK')
+
+	--print("New Bar #" .. index)
+
+	if self.PostCreateBar then
+		self.PostCreateBar(frame)
+	else
+		frame.statusBar.spelltime:SetFont([[Fonts\FRIZQT__.TTF]], 10, "NONE")
+		frame.statusBar.spelltime:SetTextColor(1 ,1, 1)
+		frame.statusBar.spelltime:SetShadowOffset(1, -1)
+	  frame.statusBar.spelltime:SetShadowColor(0, 0, 0)
+		frame.statusBar.spelltime:SetJustifyH'RIGHT'
+		frame.statusBar.spelltime:SetJustifyV'CENTER'
+		frame.statusBar.spelltime:SetPoint'RIGHT'
+		frame.statusBar.spellname:SetFont([[Fonts\FRIZQT__.TTF]], 10, "NONE")
+		frame.statusBar.spellname:SetTextColor(1, 1, 1)
+		frame.statusBar.spellname:SetShadowOffset(1, -1)
+	  frame.statusBar.spellname:SetShadowColor(0, 0, 0)
+		frame.statusBar.spellname:SetJustifyH'LEFT'
+		frame.statusBar.spellname:SetJustifyV'CENTER'
+		frame.statusBar.spellname:SetPoint'LEFT'
+		frame.statusBar.spellname:SetPoint('RIGHT', frame.statusBar.spelltime, 'LEFT')
+	end
+	return frame
+end
+
+local UpdateIconAuras = function(self, cache, unit, index, filter, visible, isEnemy)
+	if not unit then return; end
+
+	local isDebuff = filter == DEBUFF_FILTER
+	local timeNow = GetTime()
+	local auras = self.Icons;
+
+	local name, rank, texture, count, debuffType, duration, timeLeft, caster, isStealable, shouldConsolidate, spellID, canApplyAura, isBossDebuff;
+
+	if(self.forceShow) then
+		spellID = DEMO_SPELLS[random(1, #DEMO_SPELLS)];
+		name, rank, texture = GetSpellInfo(spellID)
+		count, debuffType, duration, timeLeft, caster, isStealable, shouldConsolidate, canApplyAura, isBossDebuff = 5, 'Magic', 0, 60, 'player', nil, nil, nil, nil
+	else
+		name, rank, texture, count, debuffType, duration, timeLeft, caster, isStealable, shouldConsolidate, spellID, canApplyAura, isBossDebuff = UnitAura(unit, index, filter);
+	end
+
+	if(name) then
+		local show = true
+		local isPlayer = false;
+		if((not caster) or (caster == "player" or caster == "vehicle")) then isPlayer = true end;
+		if(self.CustomFilter and (not self.forceShow)) then
+			show = self:CustomFilter(isEnemy, isPlayer, name, spellID, debuffType, duration, shouldConsolidate)
+		end
+
+		if(show) then
+			local i = visible + 1
+			local this = auras[i]
+			if(not this) then
+				this = (self.CreateAuraIcon or CreateAuraIcon) (self, i)
+				auras[i] = this
+			end
+
+			duration = duration or 0;
+			timeLeft = timeLeft or 0;
+			count = count or 0;
+			local noTime = (duration == 0 and timeLeft == 0)
+			--FOR TOOLTIPS
+			this.unit = unit
+			this.index = index
+			this.filter = filter
+			--FOR ONCLICK EVENTS
+			this.name = name
+			this.spellID = spellID
+			--FOR ONUPDATE EVENTS
+			this.expirationTime = timeLeft
+			this.noTime = noTime
+
+			this.icon:SetTexture(texture)
+			this.count:SetText((count > 1 and count))
+
+			this:Show()
+
+			--SORTING CACHE
+			local cached = {
+				ref = i,
+				noTime = noTime,
+				duration = duration,
+				expirationTime = timeLeft
+			}
+			tinsert(cache, cached)
+
+			local cd = this.cooldown
+			if(cd and not self.disableCooldown) then
+				if(noTime) then
+					cd:Hide()
+				else
+					cd:SetCooldown(timeLeft - duration, duration)
+					cd:Show()
+				end
+			end
+
+			if(isDebuff) then
+				local color = DebuffTypeColor[debuffType] or DebuffTypeColor.none
+				if((isEnemy) and (not isPlayer)) then
+					this:SetBackdropBorderColor(0.9, 0.1, 0.1, 1)
+					this.bg:SetBackdropColor(1, 0, 0, 1)
+					this.icon:SetDesaturated((unit and not unit:find('arena%d')) and true or false)
+				else
+					this:SetBackdropBorderColor(color.r * 0.6, color.g * 0.6, color.b * 0.6, 1)
+					this.bg:SetBackdropColor(color.r, color.g, color.b, 1)
+					this.icon:SetDesaturated(false)
+				end
+
+				this.bg:SetBackdropBorderColor(0, 0, 0, 1)
+
+				if(self.showType and this.overlay) then
+					this.overlay:SetVertexColor(color.r, color.g, color.b)
+					this.overlay:Show()
+				else
+					this.overlay:Hide()
+				end
+			else
+				if((isStealable) and (isEnemy)) then
+					this:SetBackdropBorderColor(0.92, 0.91, 0.55, 1)
+					this.bg:SetBackdropColor(1, 1, 0.5, 1)
+					this.bg:SetBackdropBorderColor(0, 0, 0, 1)
+				else
+					this:SetBackdropBorderColor(0, 0, 0, 1)
+					this.bg:SetBackdropColor(0, 0, 0, 0)
+					this.bg:SetBackdropBorderColor(0, 0, 0, 0)
+				end
+			end
+
+			if(noTime) then
+				this:SetScript('OnUpdate', nil)
+				this.text:SetText('')
+			else
+				this.expirationTime = timeLeft
+				this.expiration = timeLeft - timeNow
+				this.nextUpdate = -1
+				if(not this:GetScript('OnUpdate')) then
+					this:SetScript('OnUpdate', AuraIcon_OnUpdate)
+				end
+			end
+
+			return VISIBLE
+		else
+			return HIDDEN
+		end
+	end
+end
+
+local UpdateBarAuras = function(self, cache, unit, index, filter, visible, isEnemy)
+	if not unit then return; end
+	local isDebuff = filter == DEBUFF_FILTER
+	local timeNow = GetTime()
+	local auras = self.Bars;
+
+	local name, rank, texture, count, debuffType, duration, timeLeft, caster, isStealable, shouldConsolidate, spellID, canApplyAura, isBossDebuff = UnitAura(unit, index, filter);
+
+	if(self.forceShow) then
+		spellID = DEMO_SPELLS[random(1, #DEMO_SPELLS)];
+		name, rank, texture = GetSpellInfo(spellID)
+		count, debuffType, duration, timeLeft, caster, isStealable, shouldConsolidate, canApplyAura, isBossDebuff = 5, 'Magic', 0, 60, 'player', nil, nil, nil, nil
+	end
+
+	if(name) then
+		local show = true
+		local isPlayer = false;
+		if((not caster) or (caster == "player" or caster == "vehicle")) then isPlayer = true end;
+		if((not self.forceShow) and self.CustomFilter) then
+			show = self:CustomFilter(isEnemy, isPlayer, name, spellID, debuffType, duration, shouldConsolidate)
+		end
+
+		if(show) then
+			local i = visible + 1
+			local this = auras[i]
+			if(not this) then
+				this = (self.CreateAuraBar or CreateAuraBar) (self, i)
+				auras[i] = this
+			end
+
+			duration = duration or 0;
+			timeLeft = timeLeft or 0;
+			count = count or 0;
+			local noTime = (duration == 0 and timeLeft == 0)
+			--FOR TOOLTIPS
+			this.unit = unit
+			this.index = index
+			this.filter = filter
+			--FOR ONCLICK EVENTS
+			this.name = name
+			this.spellID = spellID
+			--FOR ONUPDATE EVENTS
+			this.expirationTime = timeLeft
+			this.noTime = noTime
+
+			this.icon:SetTexture(texture)
+			this.count:SetText((count > 1 and count))
+
+			this:Show()
+
+			--SORTING CACHE
+			local cached = {
+				ref = i,
+				noTime = noTime,
+				duration = duration,
+				expirationTime = timeLeft
+			}
+			tinsert(cache, cached)
+
+			local bar = this.statusBar
+			if(noTime) then
+				bar:SetMinMaxValues(0, 1)
+				bar:SetValue(1)
+				bar.spelltime:SetText('')
+			else
+				local value = timeLeft - timeNow
+				bar:SetMinMaxValues(0, duration)
+				bar:SetValue(value)
+				bar.spelltime:SetText(value)
+			end
+			bar.spellname:SetText(count > 1 and format("%s [%d]", name, count) or name)
+
+			if self.PostBarUpdate then
+				self:PostBarUpdate(bar, spellID, isDebuff, debuffType)
+			elseif(isDebuff) then
+				bar:SetStatusBarColor(.9, 0, 0)
+			else
+				bar:SetStatusBarColor(.2, .6, 1)
+			end
+
+			return VISIBLE
+		else
+			return HIDDEN
+		end
+	end
+end
+
+local ParseIconAuras = function(self, unit)
+	local limit = self.maxCount or 0;
+	local filter = self.filtering;
+	local index = 1;
+	local visible = 0;
+	local cache = {};
+	local isEnemy = UnitIsEnemy('player', unit);
+
+	while(visible < limit) do
+		if(self.forceShow and visible > 8) then break end
+		local result = UpdateIconAuras(self, cache, unit, index, filter, visible, isEnemy)
+		if(not result) then
+			break
+		elseif(result == VISIBLE) then
+			visible = visible + 1
+		end
+
+		index = index + 1
+	end
+
+	if(self.sort and type(self.sort) == 'function' and (#cache > 0)) then
+		tsort(cache, self.sort)
+		SetIconLayout(self, visible, cache)
+	else
+		SetIconLayout(self, visible)
+	end
+end
+
+local ParseBarAuras = function(self, unit)
+	local limit = self.maxCount or 0;
+	local filter = self.filtering;
+	local index = 1;
+	local visible = 0;
+	local cache = {};
+	local isEnemy = UnitIsEnemy('player', unit);
+
+	while(visible < limit) do
+		if(self.forceShow and visible > 8) then break end
+		local result = UpdateBarAuras(self, cache, unit, index, filter, visible, isEnemy)
+		if(not result) then
+			break
+		elseif(result == VISIBLE) then
+			visible = visible + 1
+		end
+
+		index = index + 1
+	end
+
+	if(self.sort and type(self.sort) == 'function' and (#cache > 0)) then
+		tsort(cache, self.sort)
+		SetBarLayout(self, visible, cache)
+	else
+		SetBarLayout(self, visible)
+	end
+end
+
+--[[ SETUP AND ENABLE/DISABLE ]]--
+
+local Update = function(self, event, unit)
+	if((not unit) or (self.unit ~= unit)) then return end
+
+	local buffs = self.Buffs
+	if(buffs) then
+		--if(self.unit == 'player') then print(event)print(buffs.UseBars) end
+		if(buffs.UseBars and (buffs.UseBars == true)) then
+			--if(self.unit == 'player') then print('Parsing BUFF BARS') end
+			ParseBarAuras(buffs, unit)
+		else
+			--if(self.unit == 'player') then print('Parsing BUFF ICONS') end
+			ParseIconAuras(buffs, unit)
+		end
+	end
+
+	local debuffs = self.Debuffs
+	if(debuffs) then
+		--if(self.unit == 'player') then print(event)print(debuffs.UseBars) end
+		if(debuffs.UseBars and (debuffs.UseBars == true)) then
+			--if(self.unit == 'player') then print('Parsing DEBUFF BARS') end
+			ParseBarAuras(debuffs, unit)
+		else
+			--if(self.unit == 'player') then print('Parsing DEBUFF ICONS') end
+			ParseIconAuras(debuffs, unit)
+		end
+	end
+end
+
+local ForceUpdate = function(element)
+	return Update(element.__owner, 'ForceUpdate', element.unit)
+end
+
+local Enable = function(self)
+	if(self.Buffs or self.Debuffs) then
+		self:RegisterEvent('UNIT_AURA', Update)
+
+		local barsAvailable = self.AuraBarsAvailable;
+
+		local buffs = self.Buffs
+		if(buffs) then
+			buffs.__owner 		= self;
+			buffs.gap 			= buffs.gap or 2;
+			buffs.spacing 		= buffs.spacing or 2;
+			buffs.auraSize 		= buffs.auraSize or 16;
+			buffs.maxRows 		= buffs.maxRows or 2;
+			buffs.maxColumns 	= buffs.maxColumns or 8;
+			buffs.maxCount 		= buffs.maxCount or 16;
+			buffs.filtering 	= BUFF_FILTER;
+			buffs.ForceUpdate 	= ForceUpdate;
+			buffs.SetSorting 	= SetSorting;
+
+			buffs:SetHeight(1)
+
+			buffs.Icons = buffs.Icons or CreateFrame("Frame", nil, buffs)
+			buffs.Icons:SetAllPoints(buffs)
+
+			if(barsAvailable) then
+				buffs.spark = true;
+				buffs.UseBars = false;
+				buffs.barHeight = buffs.barHeight or 16
+				buffs.Bars = buffs.Bars or CreateFrame("Frame", nil, buffs)
+				buffs.Bars:SetAllPoints(buffs)
+				buffs.Bars:SetScript('OnUpdate', AuraBars_OnUpdate)
+			end
+		end
+
+		local debuffs = self.Debuffs
+		if(debuffs) then
+			debuffs.__owner 	= self;
+			debuffs.gap 		= debuffs.gap or 2;
+			debuffs.spacing 	= debuffs.spacing or 2;
+			debuffs.auraSize 	= debuffs.auraSize or 16;
+			debuffs.maxRows 	= debuffs.maxRows or 2;
+			debuffs.maxColumns 	= debuffs.maxColumns or 8;
+			debuffs.maxCount 	= debuffs.maxCount or 16;
+			debuffs.filtering 	= DEBUFF_FILTER;
+			debuffs.ForceUpdate = ForceUpdate;
+			debuffs.SetSorting 	= SetSorting;
+
+			debuffs:SetHeight(1)
+
+			debuffs.Icons = debuffs.Icons or CreateFrame("Frame", nil, debuffs)
+			debuffs.Icons:SetAllPoints(debuffs)
+
+			if(barsAvailable) then
+				debuffs.spark = true;
+				debuffs.UseBars = false;
+				debuffs.barHeight = debuffs.barHeight or 16
+				debuffs.Bars = debuffs.Bars or CreateFrame("Frame", nil, debuffs)
+				debuffs.Bars:SetAllPoints(debuffs)
+				debuffs.Bars:SetScript('OnUpdate', AuraBars_OnUpdate)
+			end
+		end
+
+		return true
+	end
+end
+
+local Disable = function(self)
+	if(self.Buffs or self.Debuffs) then
+		self:UnregisterEvent('UNIT_AURA', Update)
+		if(self.Buffs and self.Buffs.Bars) then
+			self.Buffs.Bars:SetScript('OnUpdate', nil)
+		end
+		if(self.Debuffs and self.Debuffs.Bars) then
+			self.Debuffs.Bars:SetScript('OnUpdate', nil)
+		end
+	end
+end
+
+oUF:AddElement('Auras', Update, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/oUF/elements/castbar.lua b/SVUI_UnitFrames/libs/oUF/elements/castbar.lua
new file mode 100644
index 0000000..6772dcd
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/elements/castbar.lua
@@ -0,0 +1,518 @@
+--[[ Element: Cast Bar
+
+	THIS FILE HEAVILY MODIFIED FOR USE WITH SUPERVILLAIN UI
+
+]]
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local error         = _G.error;
+local print         = _G.print;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local tostring      = _G.tostring;
+local setmetatable  = _G.setmetatable;
+--STRING
+local string        = _G.string;
+local format        = string.format;
+--MATH
+local math          = _G.math;
+local floor         = math.floor
+local ceil          = math.ceil
+--BLIZZARD API
+local GetTime       	= _G.GetTime;
+local CreateFrame       = _G.CreateFrame;
+local GetNetStats       = _G.GetNetStats;
+local UnitCastingInfo   = _G.UnitCastingInfo;
+local UnitChannelInfo   = _G.UnitChannelInfo;
+--local GetTradeskillRepeatCount  = _G.GetTradeskillRepeatCount;
+local CastingBarFrame   	= _G.CastingBarFrame;
+local PetCastingBarFrame   	= _G.PetCastingBarFrame;
+
+local parent, ns = ...
+local oUF = ns.oUF
+
+local updateSafeZone = function(self)
+	local sz = self.SafeZone
+	local width = self:GetWidth()
+	local _, _, _, ms = GetNetStats()
+
+	-- Guard against GetNetStats returning latencies of 0.
+	if(ms ~= 0) then
+		-- MADNESS!
+		local safeZonePercent = (width / self.max) * (ms / 1e5)
+		if(safeZonePercent > 1) then safeZonePercent = 1 end
+		sz:SetWidth(width * safeZonePercent)
+		sz:Show()
+	else
+		sz:Hide()
+	end
+end
+
+local UNIT_SPELLCAST_SENT = function (self, event, unit, spell, rank, target)
+	local castbar = self.Castbar
+	castbar.curTarget = (target and target ~= "") and target or nil
+end
+
+local UNIT_SPELLCAST_START = function(self, event, unit, spell)
+	if(self.unit ~= unit) or not unit then return end
+
+	local castbar = self.Castbar
+	local name, _, text, texture, startTime, endTime, tradeskill, castid, interrupt = UnitCastingInfo(unit)
+	if(not name) then
+		castbar:Hide()
+		return
+	end
+
+	endTime = endTime / 1e3
+	startTime = startTime / 1e3
+
+	local repeatCount = 1
+	local start = GetTime() - startTime
+
+	if(tradeskill and repeatCount >= 1) then
+		if(castbar.previous ~= name) then
+			castbar.recipecount = 1
+			castbar.maxrecipe = repeatCount
+			castbar.duration = start
+		else
+			castbar.recipecount = castbar.recipecount or 1
+			castbar.maxrecipe = castbar.maxrecipe or repeatCount
+			castbar.duration = castbar.duration or start
+		end
+	else
+		castbar.recipecount = nil
+		castbar.maxrecipe = 1
+		castbar.duration = start
+	end
+
+	castbar.previous = name
+	castbar.tradeskill = tradeskill
+	castbar.castid = castid
+
+	local max = (endTime - startTime) * castbar.maxrecipe
+
+	castbar.max = max
+	castbar.delay = 0
+	castbar.casting = true
+	castbar.interrupt = interrupt
+
+	castbar:SetMinMaxValues(0, max)
+	castbar:SetValue(0)
+
+	if(castbar.Text) then castbar.Text:SetText(text) end
+	if(castbar.Icon) then castbar.Icon:SetTexture(texture) end
+	if(castbar.Time) then castbar.Time:SetText() end
+
+	local shield = castbar.Shield
+	if(shield and interrupt) then
+		shield:Show()
+	elseif(shield) then
+		shield:Hide()
+	end
+
+	local sf = castbar.SafeZone
+	if(sf) then
+		sf:ClearAllPoints()
+		sf:SetPoint'RIGHT'
+		sf:SetPoint'TOP'
+		sf:SetPoint'BOTTOM'
+		updateSafeZone(castbar)
+	end
+
+	if(castbar.PostCastStart) then
+		castbar:PostCastStart(unit, name, castid)
+	end
+
+	castbar:Show()
+end
+
+local UNIT_SPELLCAST_FAILED = function(self, event, unit, spellname, _, castid)
+	if (self.unit ~= unit) or not unit then return end
+
+	local castbar = self.Castbar
+	if (castbar.castid ~= castid) then	return end
+
+	castbar.previous = nil
+	castbar.casting = nil
+	castbar.tradeskill = nil
+	castbar.recipecount = nil
+	castbar.maxrecipe = 1
+	castbar.interrupt = nil
+	castbar:SetValue(0)
+	castbar:Hide()
+
+	if(castbar.PostCastFailed) then
+		return castbar:PostCastFailed(unit, spellname, castid)
+	end
+end
+
+local UNIT_SPELLCAST_INTERRUPTED = function(self, event, unit, spellname, _, castid)
+	if(self.unit ~= unit) or not unit then return end
+
+	local castbar = self.Castbar
+	if (castbar.castid ~= castid) then	return end
+
+	castbar.previous = nil
+	castbar.casting = nil
+	castbar.tradeskill = nil
+	castbar.recipecount = nil
+	castbar.maxrecipe = 1
+	castbar.channeling = nil
+
+	castbar:SetValue(0)
+	castbar:Hide()
+
+	if(castbar.PostCastInterrupted) then
+		return castbar:PostCastInterrupted(unit, spellname, castid)
+	end
+end
+
+local UNIT_SPELLCAST_INTERRUPTIBLE = function(self, event, unit)
+	if(self.unit ~= unit) or not unit then return end
+
+	local shield = self.Castbar.Shield
+	if(shield) then
+		shield:Hide()
+	end
+
+	local castbar = self.Castbar
+	if(castbar.PostCastInterruptible) then
+		return castbar:PostCastInterruptible(unit)
+	end
+end
+
+local UNIT_SPELLCAST_NOT_INTERRUPTIBLE = function(self, event, unit)
+	if(self.unit ~= unit) or not unit then return end
+
+	local shield = self.Castbar.Shield
+	if(shield) then
+		shield:Show()
+	end
+
+	local castbar = self.Castbar
+	if(castbar.PostCastNotInterruptible) then
+		return castbar:PostCastNotInterruptible(unit)
+	end
+end
+
+local UNIT_SPELLCAST_DELAYED = function(self, event, unit, spellname, _, castid)
+	if(self.unit ~= unit) or not unit then return end
+
+	local castbar = self.Castbar
+	local name, _, text, texture, startTime, endTime = UnitCastingInfo(unit)
+	if(not startTime or not castbar:IsShown()) then return end
+
+	local duration = GetTime() - (startTime / 1000)
+	if(duration < 0) then duration = 0 end
+	castbar.previous = name
+	castbar.delay = castbar.delay + castbar.duration - duration
+	castbar.duration = duration
+
+	castbar:SetValue(duration)
+
+	if(castbar.PostCastDelayed) then
+		return castbar:PostCastDelayed(unit, name, castid)
+	end
+end
+
+local UNIT_SPELLCAST_STOP = function(self, event, unit, spellname, _, castid)
+	if (self.unit ~= unit) or not unit then return end
+	local castbar = self.Castbar
+	if (castbar.castid ~= castid) then return end
+
+	if(castbar.tradeskill and castbar.recipecount and castbar.recipecount >= 0) then
+		castbar.recipecount = castbar.recipecount + 1
+	else
+		castbar.previous = nil
+		castbar.casting = nil
+		castbar.interrupt = nil
+		castbar.tradeskill = nil
+		castbar.recipecount = nil
+		castbar.maxrecipe = 1
+		castbar:SetValue(0)
+	end
+
+	if((not castbar.recipecount) or (castbar.recipecount and castbar.recipecount < 2)) then
+		castbar:Hide()
+	end
+
+	if(castbar.PostCastStop) then
+		return castbar:PostCastStop(unit, spellname, castid)
+	end
+end
+
+local UNIT_SPELLCAST_CHANNEL_START = function(self, event, unit, spellname)
+	if (self.unit ~= unit) or not unit then return end
+
+	local castbar = self.Castbar
+	local name, _, text, texture, startTime, endTime, isTrade, interrupt = UnitChannelInfo(unit)
+	if (not name) then return end
+
+	endTime = endTime / 1e3
+	startTime = startTime / 1e3
+	local max = (endTime - startTime)
+	local duration = endTime - GetTime()
+
+	castbar.previous = name
+	castbar.duration = duration
+	castbar.max = max
+	castbar.delay = 0
+	castbar.startTime = startTime
+	castbar.endTime = endTime
+	castbar.extraTickRatio = 0
+	castbar.channeling = true
+	castbar.interrupt = interrupt
+
+	-- We have to do this, as it's possible for spell casts to never have _STOP
+	-- executed or be fully completed by the OnUpdate handler before CHANNEL_START
+	-- is called.
+	castbar.casting = nil
+	castbar.tradeskill = nil
+	castbar.recipecount = nil
+	castbar.maxrecipe = 1
+	castbar.castid = nil
+
+	castbar:SetMinMaxValues(0, max)
+	castbar:SetValue(duration)
+
+	if(castbar.Text) then castbar.Text:SetText(name) end
+	if(castbar.Icon) then castbar.Icon:SetTexture(texture) end
+	if(castbar.Time) then castbar.Time:SetText() end
+
+	local shield = castbar.Shield
+	if(shield and interrupt) then
+		shield:Show()
+	elseif(shield) then
+		shield:Hide()
+	end
+
+	local sf = castbar.SafeZone
+	if(sf) then
+		sf:ClearAllPoints()
+		sf:SetPoint'LEFT'
+		sf:SetPoint'TOP'
+		sf:SetPoint'BOTTOM'
+		updateSafeZone(castbar)
+	end
+
+	if(castbar.PostChannelStart) then castbar:PostChannelStart(unit, name) end
+	castbar:Show()
+end
+
+local UNIT_SPELLCAST_CHANNEL_UPDATE = function(self, event, unit, spellname)
+	if(self.unit ~= unit) or not unit then return end
+
+	local castbar = self.Castbar
+	local name, _, text, texture, startTime, endTime, oldStart = UnitChannelInfo(unit)
+	if(not name or not castbar:IsShown()) then
+		return
+	end
+
+	castbar.previous = name
+	local duration = (endTime / 1000) - GetTime()
+	local startDelay = castbar.startTime - startTime / 1000
+	castbar.startTime = startTime / 1000
+	castbar.endTime = endTime / 1000
+	castbar.delay = castbar.delay + startDelay
+
+	castbar.duration = duration
+	castbar.max = (endTime - startTime) / 1000
+
+	castbar:SetMinMaxValues(0, castbar.max)
+	castbar:SetValue(duration)
+
+	if(castbar.PostChannelUpdate) then
+		return castbar:PostChannelUpdate(unit, name)
+	end
+end
+
+local UNIT_SPELLCAST_CHANNEL_STOP = function(self, event, unit, spellname)
+	if(self.unit ~= unit) or not unit then return end
+
+	local castbar = self.Castbar
+	if(castbar:IsShown()) then
+		castbar.channeling = nil
+		castbar.interrupt = nil
+
+		castbar:SetValue(castbar.max)
+		castbar:Hide()
+
+		if(castbar.PostChannelStop) then
+			return castbar:PostChannelStop(unit, spellname)
+		end
+	end
+end
+
+local UpdateCastingTimeInfo = function(self, duration)
+	if(self.Time) then
+		if(self.delay ~= 0) then
+			if(self.CustomDelayText) then
+				self:CustomDelayText(duration)
+			else
+				self.Time:SetFormattedText("%.1f|cffff0000-%.1f|r", duration, self.delay)
+			end
+		elseif(self.recipecount and self.recipecount > 0 and self.maxrecipe and self.maxrecipe > 1) then
+			self.Time:SetText(self.recipecount .. "/" .. self.maxrecipe)
+		else
+			if(self.CustomTimeText) then
+				self:CustomTimeText(duration)
+			else
+				self.Time:SetFormattedText("%.1f", duration)
+			end
+		end
+	end
+	if(self.Spark) then
+		self.Spark:SetPoint("CENTER", self, "LEFT", (duration / self.max) * self:GetWidth(), 0)
+	end
+end
+
+local onUpdate = function(self, elapsed)
+	self.lastUpdate = (self.lastUpdate or 0) + elapsed
+
+	if not (self.casting or self.channeling) then
+		self.unitName = nil
+		self.previous = nil
+		self.casting = nil
+		self.tradeskill = nil
+		self.recipecount = nil
+		self.maxrecipe = 1
+		self.castid = nil
+		self.channeling = nil
+
+		self:SetValue(1)
+		self:Hide()
+		return
+	end
+
+	if(self.casting) then
+		local duration = self.duration + self.lastUpdate
+		if(duration >= self.max) then
+			self.previous = nil
+			self.casting = nil
+			self.tradeskill = nil
+			self.recipecount = nil
+			self.maxrecipe = 1
+			self:Hide()
+
+			if(self.PostCastStop) then self:PostCastStop(self.__owner.unit) end
+			return
+		end
+
+		UpdateCastingTimeInfo(self, duration)
+
+		self.duration = duration
+		self:SetValue(duration)
+	elseif(self.channeling) then
+		local duration = self.duration - self.lastUpdate
+
+		if(duration <= 0) then
+			self.channeling = nil
+			self:Hide()
+
+			if(self.PostChannelStop) then self:PostChannelStop(self.__owner.unit) end
+			return
+		end
+
+		UpdateCastingTimeInfo(self, duration)
+
+		self.duration = duration
+		self:SetValue(duration)
+	end
+
+	self.lastUpdate = 0
+end
+
+local Update = function(self, ...)
+	UNIT_SPELLCAST_START(self, ...)
+	return UNIT_SPELLCAST_CHANNEL_START(self, ...)
+end
+
+local ForceUpdate = function(element)
+	return Update(element.__owner, 'ForceUpdate', element.__owner.unit)
+end
+
+local Enable = function(object, unit)
+	local castbar = object.Castbar
+
+	if(castbar) then
+		castbar.__owner = object
+		castbar.ForceUpdate = ForceUpdate
+
+		if(not (unit and unit:match'%wtarget$')) then
+			object:RegisterEvent("UNIT_SPELLCAST_SENT", UNIT_SPELLCAST_SENT)
+			object:RegisterEvent("UNIT_SPELLCAST_START", UNIT_SPELLCAST_START)
+			object:RegisterEvent("UNIT_SPELLCAST_FAILED", UNIT_SPELLCAST_FAILED)
+			object:RegisterEvent("UNIT_SPELLCAST_STOP", UNIT_SPELLCAST_STOP)
+			object:RegisterEvent("UNIT_SPELLCAST_INTERRUPTED", UNIT_SPELLCAST_INTERRUPTED)
+			object:RegisterEvent("UNIT_SPELLCAST_INTERRUPTIBLE", UNIT_SPELLCAST_INTERRUPTIBLE)
+			object:RegisterEvent("UNIT_SPELLCAST_NOT_INTERRUPTIBLE", UNIT_SPELLCAST_NOT_INTERRUPTIBLE)
+			object:RegisterEvent("UNIT_SPELLCAST_DELAYED", UNIT_SPELLCAST_DELAYED)
+			object:RegisterEvent("UNIT_SPELLCAST_CHANNEL_START", UNIT_SPELLCAST_CHANNEL_START)
+			object:RegisterEvent("UNIT_SPELLCAST_CHANNEL_UPDATE", UNIT_SPELLCAST_CHANNEL_UPDATE)
+			object:RegisterEvent("UNIT_SPELLCAST_CHANNEL_STOP", UNIT_SPELLCAST_CHANNEL_STOP)
+			--object:RegisterEvent("UPDATE_TRADESKILL_RECAST", UPDATE_TRADESKILL_RECAST)
+		end
+
+		castbar:SetScript("OnUpdate", castbar.OnUpdate or onUpdate)
+
+		if(object.unit == "player") then
+			CastingBarFrame:UnregisterAllEvents()
+			CastingBarFrame.Show = CastingBarFrame.Hide
+			CastingBarFrame:Hide()
+		elseif(object.unit == 'pet') then
+			PetCastingBarFrame:UnregisterAllEvents()
+			PetCastingBarFrame.Show = PetCastingBarFrame.Hide
+			PetCastingBarFrame:Hide()
+		end
+
+		if(castbar:IsObjectType'StatusBar' and not castbar:GetStatusBarTexture()) then
+			castbar:SetStatusBarTexture[[Interface\TargetingFrame\UI-StatusBar]]
+		end
+
+		local spark = castbar.Spark
+		if(spark and spark:IsObjectType'Texture' and not spark:GetTexture()) then
+			spark:SetTexture[[Interface\CastingBar\UI-CastingBar-Spark]]
+		end
+
+		local shield = castbar.Shield
+		if(shield and shield:IsObjectType'Texture' and not shield:GetTexture()) then
+			shield:SetTexture[[Interface\CastingBar\UI-CastingBar-Small-Shield]]
+		end
+
+		local sz = castbar.SafeZone
+		if(sz and sz:IsObjectType'Texture' and not sz:GetTexture()) then
+			sz:SetColorTexture(1, 0, 0)
+		end
+
+		castbar:Hide()
+
+		return true
+	end
+end
+
+local Disable = function(object, unit)
+	local castbar = object.Castbar
+
+	if(castbar) then
+		object:UnregisterEvent("UNIT_SPELLCAST_SENT", UNIT_SPELLCAST_SENT)
+		object:UnregisterEvent("UNIT_SPELLCAST_START", UNIT_SPELLCAST_START)
+		object:UnregisterEvent("UNIT_SPELLCAST_FAILED", UNIT_SPELLCAST_FAILED)
+		object:UnregisterEvent("UNIT_SPELLCAST_STOP", UNIT_SPELLCAST_STOP)
+		object:UnregisterEvent("UNIT_SPELLCAST_INTERRUPTED", UNIT_SPELLCAST_INTERRUPTED)
+		object:UnregisterEvent("UNIT_SPELLCAST_INTERRUPTIBLE", UNIT_SPELLCAST_INTERRUPTIBLE)
+		object:UnregisterEvent("UNIT_SPELLCAST_NOT_INTERRUPTIBLE", UNIT_SPELLCAST_NOT_INTERRUPTIBLE)
+		object:UnregisterEvent("UNIT_SPELLCAST_DELAYED", UNIT_SPELLCAST_DELAYED)
+		object:UnregisterEvent("UNIT_SPELLCAST_CHANNEL_START", UNIT_SPELLCAST_CHANNEL_START)
+		object:UnregisterEvent("UNIT_SPELLCAST_CHANNEL_UPDATE", UNIT_SPELLCAST_CHANNEL_UPDATE)
+		object:UnregisterEvent("UNIT_SPELLCAST_CHANNEL_STOP", UNIT_SPELLCAST_CHANNEL_STOP)
+		--object:UnregisterEvent("UPDATE_TRADESKILL_RECAST", UPDATE_TRADESKILL_RECAST)
+
+		castbar:SetScript("OnUpdate", nil)
+	end
+end
+
+oUF:AddElement('Castbar', Update, Enable, Disable)
\ No newline at end of file
diff --git a/SVUI_UnitFrames/libs/oUF/elements/combat.lua b/SVUI_UnitFrames/libs/oUF/elements/combat.lua
new file mode 100644
index 0000000..0952fb5
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/elements/combat.lua
@@ -0,0 +1,60 @@
+local parent, ns = ...
+local oUF = ns.oUF
+
+local Update = function(self, event)
+	local combat = self.Combat
+	local aggro = self.Aggro
+
+	if(aggro and aggro:IsShown()) then return end
+
+	if(combat.PreUpdate) then
+		combat:PreUpdate()
+	end
+
+	local inCombat = UnitAffectingCombat('player')
+	if(inCombat) then
+		combat:Show()
+	else
+		combat:Hide()
+	end
+
+	if(combat.PostUpdate) then
+		return combat:PostUpdate(inCombat)
+	end
+end
+
+local Path = function(self, ...)
+	return (self.Combat.Override or Update) (self, ...)
+end
+
+local ForceUpdate = function(element)
+	return Path(element.__owner, 'ForceUpdate')
+end
+
+local Enable = function(self, unit)
+	local combat = self.Combat
+	if(combat and unit == 'player') then
+		combat.__owner = self
+		combat.ForceUpdate = ForceUpdate
+
+		self:RegisterEvent("PLAYER_REGEN_DISABLED", Path, true)
+		self:RegisterEvent("PLAYER_REGEN_ENABLED", Path, true)
+
+		if(combat:IsObjectType"Texture" and not combat:GetTexture()) then
+			combat:SetTexture[[Interface\CharacterFrame\UI-StateIcon]]
+			combat:SetTexCoord(.5, 1, 0, .49)
+		end
+
+		return true
+	end
+end
+
+local Disable = function(self)
+	if(self.Combat) then
+		self.Combat:Hide()
+		self:UnregisterEvent("PLAYER_REGEN_DISABLED", Path)
+		self:UnregisterEvent("PLAYER_REGEN_ENABLED", Path)
+	end
+end
+
+oUF:AddElement('Combat', Path, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/oUF/elements/healprediction.lua b/SVUI_UnitFrames/libs/oUF/elements/healprediction.lua
new file mode 100644
index 0000000..d730423
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/elements/healprediction.lua
@@ -0,0 +1,184 @@
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+--MATH
+local math          = _G.math;
+local max         	= math.max
+--BLIZZARD API
+local UnitHealth     			= _G.UnitHealth;
+local UnitHealthMax     		= _G.UnitHealthMax;
+local UnitGetTotalHealAbsorbs	= _G.UnitGetTotalHealAbsorbs;
+local UnitGetTotalAbsorbs 		= _G.UnitGetTotalAbsorbs;
+local UnitGetIncomingHeals 		= _G.UnitGetIncomingHeals;
+
+local _, ns = ...
+local oUF = ns.oUF
+
+local function Update(self, event, unit)
+	if(self.unit ~= unit) or not unit then return end
+
+	local hp = self.HealPrediction
+	hp.parent = self
+	if(hp.PreUpdate) then hp:PreUpdate(unit) end
+
+	local myIncomingHeal = UnitGetIncomingHeals(unit, 'player') or 0
+	local allIncomingHeal = UnitGetIncomingHeals(unit) or 0
+	local totalAbsorb = UnitGetTotalAbsorbs(unit) or 0
+	local myCurrentHealAbsorb = UnitGetTotalHealAbsorbs(unit) or 0
+	local health, maxHealth = UnitHealth(unit), UnitHealthMax(unit)
+
+	local overHealAbsorb = false
+	if(health < myCurrentHealAbsorb) then
+		overHealAbsorb = true
+		myCurrentHealAbsorb = health
+	end
+
+	if(health - myCurrentHealAbsorb + allIncomingHeal > maxHealth * hp.maxOverflow) then
+		allIncomingHeal = maxHealth * hp.maxOverflow - health + myCurrentHealAbsorb
+	end
+
+	local otherIncomingHeal = 0
+	if(allIncomingHeal < myIncomingHeal) then
+		myIncomingHeal = allIncomingHeal
+	else
+		otherIncomingHeal = allIncomingHeal - myIncomingHeal
+	end
+
+	local overAbsorb = false
+	if(health - myCurrentHealAbsorb + allIncomingHeal + totalAbsorb >= maxHealth or health + totalAbsorb >= maxHealth) then
+		if(totalAbsorb > 0) then
+			overAbsorb = true
+		end
+
+		if(allIncomingHeal > myCurrentHealAbsorb) then
+			totalAbsorb = max(0, maxHealth - (health - myCurrentHealAbsorb + allIncomingHeal))
+		else
+			totalAbsorb = max(0, maxHealth - health)
+		end
+	end
+
+	if(myCurrentHealAbsorb > allIncomingHeal) then
+		myCurrentHealAbsorb = myCurrentHealAbsorb - allIncomingHeal
+	else
+		myCurrentHealAbsorb = 0
+	end
+
+	if(hp.myBar) then
+		hp.myBar:SetMinMaxValues(0, maxHealth)
+		hp.myBar:SetValue(myIncomingHeal)
+		hp.myBar:Show()
+	end
+
+	if(hp.otherBar) then
+		hp.otherBar:SetMinMaxValues(0, maxHealth)
+		hp.otherBar:SetValue(otherIncomingHeal)
+		hp.otherBar:Show()
+	end
+
+	if(hp.absorbBar) then
+		hp.absorbBar:SetMinMaxValues(0, maxHealth)
+		hp.absorbBar:SetValue(totalAbsorb)
+		hp.absorbBar:Show()
+	end
+
+	if(hp.healAbsorbBar) then
+		hp.healAbsorbBar:SetMinMaxValues(0, maxHealth)
+		hp.healAbsorbBar:SetValue(myCurrentHealAbsorb)
+		hp.healAbsorbBar:Show()
+	end
+
+	if(hp.PostUpdate) then
+		return hp:PostUpdate(unit, overAbsorb, overHealAbsorb)
+	end
+end
+
+local function Path(self, ...)
+	return (self.HealPrediction.Override or Update) (self, ...)
+end
+
+local ForceUpdate = function(element)
+	return Path(element.__owner, 'ForceUpdate', element.__owner.unit)
+end
+
+local function Enable(self)
+	local hp = self.HealPrediction
+	if(hp) then
+		hp.__owner = self
+		hp.ForceUpdate = ForceUpdate
+
+		self:RegisterEvent('UNIT_HEAL_PREDICTION', Path)
+		self:RegisterEvent('UNIT_MAXHEALTH', Path)
+		if(hp.frequentUpdates) then
+			self:RegisterEvent('UNIT_HEALTH_FREQUENT', Path)
+		else
+			self:RegisterEvent('UNIT_HEALTH', Path)
+		end
+		self:RegisterEvent('UNIT_ABSORB_AMOUNT_CHANGED', Path)
+		self:RegisterEvent('UNIT_HEAL_ABSORB_AMOUNT_CHANGED', Path)
+
+		if(not hp.maxOverflow) then
+			hp.maxOverflow = 1.05
+		end
+
+		if(hp.myBar) then
+			if(hp.myBar:IsObjectType'StatusBar' and not hp.myBar:GetStatusBarTexture()) then
+				hp.myBar:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]])
+			end
+
+			hp.myBar:Show()
+		end
+		if(hp.otherBar) then
+			if(hp.otherBar:IsObjectType'StatusBar' and not hp.otherBar:GetStatusBarTexture()) then
+				hp.otherBar:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]])
+			end
+
+			hp.otherBar:Show()
+		end
+		if(hp.absorbBar) then
+			if(hp.absorbBar:IsObjectType'StatusBar' and not hp.absorbBar:GetStatusBarTexture()) then
+				hp.absorbBar:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]])
+			end
+
+			hp.absorbBar:Show()
+		end
+		if(hp.healAbsorbBar) then
+			if(hp.healAbsorbBar:IsObjectType'StatusBar' and not hp.healAbsorbBar:GetStatusBarTexture()) then
+				hp.healAbsorbBar:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]])
+			end
+
+			hp.healAbsorbBar:Show()
+		end
+
+		return true
+	end
+end
+
+local function Disable(self)
+	local hp = self.HealPrediction
+	if(hp) then
+		if(hp.myBar) then
+			hp.myBar:Hide()
+		end
+		if(hp.otherBar) then
+			hp.otherBar:Hide()
+		end
+		if(hp.absorbBar) then
+			hp.absorbBar:Hide()
+		end
+		if(hp.healAbsorbBar) then
+			hp.healAbsorbBar:Hide()
+		end
+
+		self:UnregisterEvent('UNIT_HEAL_PREDICTION', Path)
+		self:UnregisterEvent('UNIT_MAXHEALTH', Path)
+		self:UnregisterEvent('UNIT_HEALTH', Path)
+		self:UnregisterEvent('UNIT_HEALTH_FREQUENT', Path)
+		self:UnregisterEvent('UNIT_ABSORB_AMOUNT_CHANGED', Path)
+		self:UnregisterEvent('UNIT_HEAL_ABSORB_AMOUNT_CHANGED', Path)
+	end
+end
+
+oUF:AddElement('HealPrediction', Path, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/oUF/elements/health.lua b/SVUI_UnitFrames/libs/oUF/elements/health.lua
new file mode 100644
index 0000000..a75e020
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/elements/health.lua
@@ -0,0 +1,192 @@
+--[[ Element: Health Bar
+
+	THIS FILE HEAVILY MODIFIED FOR USE WITH SUPERVILLAIN UI
+
+]]
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+--MATH
+local math          = _G.math;
+local max         	= math.max
+local random 		= math.random
+--BLIZZARD API
+local UnitClass     			= _G.UnitClass;
+local UnitReaction     			= _G.UnitReaction;
+local UnitIsEnemy     			= _G.UnitIsEnemy;
+local GetCVarBool     			= _G.GetCVarBool;
+local SetCVar     				= _G.SetCVar;
+local UnitHealth     			= _G.UnitHealth;
+local UnitHealthMax     		= _G.UnitHealthMax;
+local UnitIsConnected			= _G.UnitIsConnected;
+local UnitIsDeadOrGhost 		= _G.UnitIsDeadOrGhost;
+local UnitIsPlayer 				= _G.UnitIsPlayer;
+local UnitPlayerControlled 		= _G.UnitPlayerControlled;
+local UnitIsTapDenied 			= _G.UnitIsTapDenied;
+
+
+local parent, ns = ...
+local oUF = ns.oUF
+
+oUF.colors.health = {49/255, 207/255, 37/255}
+--local UpdateFrequentUpdates
+
+local Update = function(self, event, unit)
+	if(self.unit ~= unit) or not unit then return end
+	local health = self.Health
+	local min, max = UnitHealth(unit), UnitHealthMax(unit)
+
+	if(health.PreUpdate) then
+		health:PreUpdate(unit, min, max)
+	else
+		local disconnected = not UnitIsConnected(unit)
+		local invisible = ((min == max) or UnitIsDeadOrGhost(unit) or disconnected)
+		if invisible then health.lowAlerted = false end
+
+		if health.fillInverted then
+			health:SetReverseFill(true)
+		end
+
+		health:SetMinMaxValues(0, max)
+		health:SetValue(disconnected and 0 or min)
+		health.percent = invisible and 100 or ((min / max) * 100)
+		health.disconnected = disconnected
+
+		local bg = health.bg;
+		local r, g, b, t, t2;
+		local _, class = UnitClass(unit);
+		local reaction = UnitReaction(unit, 'player');
+		local classColors = oUF.colors.class[class];
+		local bgColors = classColors or oUF.colors.reaction[reaction];
+		if(health.colorTapping and not UnitPlayerControlled(unit) and UnitIsTapDenied(unit)) then
+			t = oUF.colors.tapped
+		elseif(health.colorDisconnected and not UnitIsConnected(unit)) then
+			t = oUF.colors.disconnected
+		elseif(health.colorClass and UnitIsPlayer(unit)) or
+			(health.colorClassNPC and not UnitIsPlayer(unit)) or
+			(health.colorClassPet and UnitPlayerControlled(unit) and not UnitIsPlayer(unit)) then
+			local tmp = classColors or oUF.colors.health
+			t = {(tmp[1] * 0.75),(tmp[2] * 0.75),(tmp[3] * 0.75)}
+		elseif(health.colorReaction and reaction) then
+			t = oUF.colors.reaction[reaction]
+		elseif(health.colorSmooth) then
+			r, g, b = oUF.ColorGradient(min, max, unpack(health.smoothGradient or oUF.colors.smooth))
+		elseif(health.colorHealth) then
+			t = oUF.colors.health
+		end
+
+		if(t) then
+			r, g, b = t[1], t[2], t[3]
+		end
+
+		if(b) then
+			if((health.colorClass and health.colorSmooth) or (health.colorSmooth and self.isForced and not UnitIsTapDenied(unit))) then
+				r, g, b = self.ColorGradient(min,max,1,0,0,1,1,0,r,g,b)
+			end
+			health:SetStatusBarColor(r, g, b)
+			if(bg) then
+				local mu = bg.multiplier or 1
+				if(health.colorBackdrop and bgColors) then
+					r, g, b = bgColors[1], bgColors[2], bgColors[3]
+				elseif(oUF.colors.healthBackdrop) then
+					r, g, b = unpack(oUF.colors.healthBackdrop)
+				else
+					r, g, b = unpack(oUF.colors.health)
+				end
+				bg:SetVertexColor(r * mu, g * mu, b * mu)
+			end
+		end
+	end
+
+	-- if health.frequentUpdates ~= health.__frequentUpdates then
+	-- 	UpdateFrequentUpdates(self)
+	-- end
+
+	if self.ResurrectIcon then
+		self.ResurrectIcon:SetAlpha(min == 0 and 1 or 0)
+	end
+
+	if self.isForced then
+		min = random(1,max)
+		health:SetValue(min)
+	end
+
+	if(health.gridMode) then
+		health:SetOrientation("VERTICAL")
+	end
+
+	if(health.LowAlertFunc and UnitIsPlayer("target") and health.percent < 6 and UnitIsEnemy("target", "player") and not health.lowAlerted) then
+		health.lowAlerted = true
+		health.LowAlertFunc(self)
+	end
+
+	if(health.PostUpdate) then
+		return health.PostUpdate(self, health.percent)
+	end
+end
+
+local ForceUpdate = function(element)
+	return Update(element.__owner, 'ForceUpdate', element.__owner.unit)
+end
+
+-- function UpdateFrequentUpdates(self)
+-- 	local health = self.Health
+-- 	health.__frequentUpdates = health.frequentUpdates
+-- 	if health.frequentUpdates and not self:IsEventRegistered("UNIT_HEALTH_FREQUENT") then
+-- 		if GetCVarBool("predictedHealth") ~= 1 then
+-- 			SetCVar("predictedHealth", 1)
+-- 		end
+--
+-- 		self:RegisterEvent('UNIT_HEALTH_FREQUENT', Update)
+--
+-- 		if self:IsEventRegistered("UNIT_HEALTH") then
+-- 			self:UnregisterEvent("UNIT_HEALTH", Update)
+-- 		end
+-- 	elseif not self:IsEventRegistered("UNIT_HEALTH") then
+-- 		self:RegisterEvent('UNIT_HEALTH', Update)
+--
+-- 		if self:IsEventRegistered("UNIT_HEALTH_FREQUENT") then
+-- 			self:UnregisterEvent("UNIT_HEALTH_FREQUENT", Update)
+-- 		end
+-- 	end
+-- end
+
+local Enable = function(self, unit)
+	local health = self.Health
+	if(health) then
+		health.__owner = self
+		health.ForceUpdate = ForceUpdate
+		health.__frequentUpdates = health.frequentUpdates
+
+		self:RegisterEvent('UNIT_HEALTH', Update)
+		self:RegisterEvent("UNIT_MAXHEALTH", Update)
+		self:RegisterEvent('UNIT_CONNECTION', Update)
+		self:RegisterEvent('UNIT_FACTION', Update)
+		self:RegisterUnitEvent("UNIT_HEALTH", unit);
+		self:RegisterUnitEvent("UNIT_MAXHEALTH", unit);
+
+		if(health:IsObjectType'StatusBar' and not health:GetStatusBarTexture()) then
+			health:SetStatusBarTexture[[Interface\TargetingFrame\UI-StatusBar]]
+		end
+
+		return true
+	end
+end
+
+local Disable = function(self)
+	local health = self.Health
+	if(health) then
+		health:Hide()
+		self:UnregisterEvent('UNIT_HEALTH_FREQUENT', Update)
+		self:UnregisterEvent('UNIT_HEALTH', Update)
+		self:UnregisterEvent('UNIT_MAXHEALTH', Update)
+		self:UnregisterEvent('UNIT_CONNECTION', Update)
+
+		self:UnregisterEvent('UNIT_FACTION', Update)
+	end
+end
+
+oUF:AddElement('Health', Update, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/oUF/elements/leader.lua b/SVUI_UnitFrames/libs/oUF/elements/leader.lua
new file mode 100644
index 0000000..5246716
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/elements/leader.lua
@@ -0,0 +1,56 @@
+local parent, ns = ...
+local oUF = ns.oUF
+
+local Update = function(self, event)
+	local leader = self.Leader
+	if(leader.PreUpdate) then
+		leader:PreUpdate()
+	end
+
+	local unit = self.unit
+	local isLeader = (UnitInParty(unit) or UnitInRaid(unit)) and UnitIsGroupLeader(unit)
+	if(isLeader) then
+		leader:Show()
+	else
+		leader:Hide()
+	end
+
+	if(leader.PostUpdate) then
+		return leader:PostUpdate(isLeader)
+	end
+end
+
+local Path = function(self, ...)
+	return (self.Leader.Override or Update) (self, ...)
+end
+
+local ForceUpdate = function(element)
+	return Path(element.__owner, 'ForceUpdate')
+end
+
+local Enable = function(self)
+	local leader = self.Leader
+	if(leader) then
+		leader.__owner = self
+		leader.ForceUpdate = ForceUpdate
+
+		self:RegisterEvent("PARTY_LEADER_CHANGED", Path, true)
+		self:RegisterEvent("GROUP_ROSTER_UPDATE", Path, true)
+
+		if(leader:IsObjectType"Texture" and not leader:GetTexture()) then
+			leader:SetTexture[[Interface\GroupFrame\UI-Group-LeaderIcon]]
+		end
+
+		return true
+	end
+end
+
+local Disable = function(self)
+	local leader = self.Leader
+	if(leader) then
+		self:UnregisterEvent("PARTY_LEADER_CHANGED", Path)
+		self:UnregisterEvent("GROUP_ROSTER_UPDATE", Path)
+	end
+end
+
+oUF:AddElement('Leader', Path, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/oUF/elements/lfdrole.lua b/SVUI_UnitFrames/libs/oUF/elements/lfdrole.lua
new file mode 100644
index 0000000..b5ad1bc
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/elements/lfdrole.lua
@@ -0,0 +1,59 @@
+local parent, ns = ...
+local oUF = ns.oUF
+
+local Update = function(self, event)
+	local lfdrole = self.LFDRole
+	if(lfdrole.PreUpdate) then
+		lfdrole:PreUpdate()
+	end
+
+	local role = UnitGroupRolesAssigned(self.unit)
+	if(role == 'TANK' or role == 'HEALER' or role == 'DAMAGER') then
+		lfdrole:SetTexCoord(GetTexCoordsForRoleSmallCircle(role))
+		lfdrole:Show()
+	else
+		lfdrole:Hide()
+	end
+
+	if(lfdrole.PostUpdate) then
+		return lfdrole:PostUpdate(role)
+	end
+end
+
+local Path = function(self, ...)
+	return (self.LFDRole.Override or Update) (self, ...)
+end
+
+local ForceUpdate = function(element)
+	return Path(element.__owner, 'ForceUpdate')
+end
+
+local Enable = function(self)
+	local lfdrole = self.LFDRole
+	if(lfdrole) then
+		lfdrole.__owner = self
+		lfdrole.ForceUpdate = ForceUpdate
+
+		if(self.unit == "player") then
+			self:RegisterEvent("PLAYER_ROLES_ASSIGNED", Path, true)
+		else
+			self:RegisterEvent("GROUP_ROSTER_UPDATE", Path, true)
+		end
+
+		if(lfdrole:IsObjectType"Texture" and not lfdrole:GetTexture()) then
+			lfdrole:SetTexture[[Interface\LFGFrame\UI-LFG-ICON-PORTRAITROLES]]
+		end
+
+		return true
+	end
+end
+
+local Disable = function(self)
+	local lfdrole = self.LFDRole
+	if(lfdrole) then
+		self:UnregisterEvent("PLAYER_ROLES_ASSIGNED", Path)
+		self:UnregisterEvent("GROUP_ROSTER_UPDATE", Path)
+	end
+end
+
+oUF:AddElement('LFDRole', Path, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/oUF/elements/maintank.lua b/SVUI_UnitFrames/libs/oUF/elements/maintank.lua
new file mode 100644
index 0000000..9e2c149
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/elements/maintank.lua
@@ -0,0 +1,69 @@
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+--BLIZZARD API
+local UnitInRaid       		= _G.UnitInRaid;
+local GetRaidRosterInfo 	= _G.GetRaidRosterInfo;
+local UnitHasVehicleUI      = _G.UnitHasVehicleUI;
+
+local parent, ns = ...
+local oUF = ns.oUF
+
+local Update = function(self, event)
+	local raidID = UnitInRaid(self.unit)
+	if(not raidID) then return end
+
+	local maintank = self.MainTank
+	if(maintank.PreUpdate) then
+		maintank:PreUpdate()
+	end
+
+	local _, _, _, _, _, _, _, _, _, rinfo = GetRaidRosterInfo(raidID)
+	if(rinfo == 'MAINTANK' and not UnitHasVehicleUI(self.unit)) then
+		self.MainTank:Show()
+	else
+		self.MainTank:Hide()
+	end
+
+	if(maintank.PostUpdate) then
+		return maintank:PostUpdate(rinfo)
+	end
+end
+
+local Path = function(self, ...)
+	return (self.MainTank.Override or Update)(self, ...)
+end
+
+local ForceUpdate = function(element)
+	return Path(element.__owner, 'ForceUpdate')
+end
+
+local Enable = function(self)
+	local mt = self.MainTank
+
+	if(mt) then
+		mt.__owner = self
+		mt.ForceUpdate = ForceUpdate
+
+		self:RegisterEvent('GROUP_ROSTER_UPDATE', Path, true)
+
+		if(mt:IsObjectType'Texture' and not mt:GetTexture()) then
+			mt:SetTexture[[Interface\GROUPFRAME\UI-GROUP-MAINTANKICON]]
+		end
+
+		return true
+	end
+end
+
+local Disable = function(self)
+	local mt = self.MainTank
+
+	if (mt) then
+		self:UnregisterEvent('GROUP_ROSTER_UPDATE', Path)
+	end
+end
+
+oUF:AddElement('MainTank', Path, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/oUF/elements/masterlooter.lua b/SVUI_UnitFrames/libs/oUF/elements/masterlooter.lua
new file mode 100644
index 0000000..3299fab
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/elements/masterlooter.lua
@@ -0,0 +1,74 @@
+local parent, ns = ...
+local oUF = ns.oUF
+
+local Update = function(self, event)
+	local unit = self.unit
+	local masterlooter = self.MasterLooter
+	if(not (UnitInParty(unit) or UnitInRaid(unit))) then
+		return masterlooter:Hide()
+	end
+
+	if(masterlooter.PreUpdate) then
+		masterlooter:PreUpdate()
+	end
+
+	local method, pid, rid = GetLootMethod()
+	if(method == 'master') then
+		local mlUnit
+		if(pid) then
+			if(pid == 0) then
+				mlUnit = 'player'
+			else
+				mlUnit = 'party'..pid
+			end
+		elseif(rid) then
+			mlUnit = 'raid'..rid
+		end
+
+		if(UnitIsUnit(unit, mlUnit)) then
+			masterlooter:Show()
+		elseif(masterlooter:IsShown()) then
+			masterlooter:Hide()
+		end
+	else
+		masterlooter:Hide()
+	end
+
+	if(masterlooter.PostUpdate) then
+		return masterlooter:PostUpdate(masterlooter:IsShown())
+	end
+end
+
+local Path = function(self, ...)
+	return (self.MasterLooter.Override or Update) (self, ...)
+end
+
+local ForceUpdate = function(element)
+	return Path(element.__owner, 'ForceUpdate')
+end
+
+local function Enable(self, unit)
+	local masterlooter = self.MasterLooter
+	if(masterlooter) then
+		masterlooter.__owner = self
+		masterlooter.ForceUpdate = ForceUpdate
+
+		self:RegisterEvent('PARTY_LOOT_METHOD_CHANGED', Path, true)
+		self:RegisterEvent('GROUP_ROSTER_UPDATE', Path, true)
+
+		if(masterlooter:IsObjectType('Texture') and not masterlooter:GetTexture()) then
+			masterlooter:SetTexture([[Interface\GroupFrame\UI-Group-MasterLooter]])
+		end
+
+		return true
+	end
+end
+
+local function Disable(self)
+	if(self.MasterLooter) then
+		self:UnregisterEvent('PARTY_LOOT_METHOD_CHANGED', Path)
+		self:UnregisterEvent('GROUP_ROSTER_UPDATE', Path)
+	end
+end
+
+oUF:AddElement('MasterLooter', Path, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/oUF/elements/picon.lua b/SVUI_UnitFrames/libs/oUF/elements/picon.lua
new file mode 100644
index 0000000..ecfaefa
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/elements/picon.lua
@@ -0,0 +1,53 @@
+local parent, ns = ...
+local oUF = ns.oUF
+
+local Update = function(self, event)
+	local picon = self.PhaseIcon
+	if(picon.PreUpdate) then
+		picon:PreUpdate()
+	end
+
+	local inPhase = UnitInPhase(self.unit)
+	if(inPhase) then
+		picon:Hide()
+	else
+		picon:Show()
+	end
+
+	if(picon.PostUpdate) then
+		return picon:PostUpdate(inPhase)
+	end
+end
+
+local Path = function(self, ...)
+	return (self.PhaseIcon.Override or Update) (self, ...)
+end
+
+local ForceUpdate = function(element)
+	return Path(element.__owner, 'ForceUpdate')
+end
+
+local Enable = function(self)
+	local picon = self.PhaseIcon
+	if(picon) then
+		picon.__owner = self
+		picon.ForceUpdate = ForceUpdate
+
+		self:RegisterEvent('UNIT_PHASE', Path, true)
+
+		if(picon:IsObjectType'Texture' and not picon:GetTexture()) then
+			picon:SetTexture[[Interface\TargetingFrame\UI-PhasingIcon]]
+		end
+
+		return true
+	end
+end
+
+local Disable = function(self)
+	local picon = self.PhaseIcon
+	if(picon) then
+		self:UnregisterEvent('UNIT_PHASE', Path)
+	end
+end
+
+oUF:AddElement('PhaseIcon', Path, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/oUF/elements/portraits.lua b/SVUI_UnitFrames/libs/oUF/elements/portraits.lua
new file mode 100644
index 0000000..a35ea5c
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/elements/portraits.lua
@@ -0,0 +1,140 @@
+--[[ Element: Portraits
+
+	THIS FILE HEAVILY MODIFIED FOR USE WITH SUPERVILLAIN UI
+
+]]
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+--BLIZZARD API
+local UnitClass     			= _G.UnitClass;
+local UnitReaction     			= _G.UnitReaction;
+local UnitGUID     				= _G.UnitGUID;
+local UnitIsUnit     			= _G.UnitIsUnit;
+local UnitExists     			= _G.UnitExists;
+local UnitIsVisible     		= _G.UnitIsVisible;
+local UnitIsConnected			= _G.UnitIsConnected;
+local UnitIsPlayer 				= _G.UnitIsPlayer;
+local SetPortraitTexture 		= _G.SetPortraitTexture;
+
+local parent, ns = ...
+local oUF = ns.oUF
+
+local Update = function(self, event, unit, forced)
+	if(self.unit ~= unit) or not unit then return end
+
+	local portrait = self.Portrait
+	if(portrait.PreUpdate) then portrait:PreUpdate(unit) end
+
+	if(portrait:IsObjectType'Model') then
+		local guid = UnitGUID(unit)
+		local camera = portrait.UserCamDistance or 1
+		local rotate = portrait.UserRotation
+
+		if(not UnitExists(unit) or not UnitIsConnected(unit) or not UnitIsVisible(unit)) then
+			portrait:SetCamDistanceScale(1)
+			portrait:SetPortraitZoom(0)
+			portrait:SetPosition(4,-1,1)
+			portrait:ClearModel()
+			portrait:SetModel([[Spells\Monk_travelingmist_missile.m2]])
+			portrait.guid = nil
+			portrait:SetBackdropColor(0.25,0.25,0.25)
+			if portrait.UpdateColor then
+				portrait:UpdateColor(0.25,0.25,0.25)
+			end
+		elseif((forced) or (portrait.guid ~= guid) or (event == 'UNIT_MODEL_CHANGED')) then
+			portrait:ClearModel()
+			portrait:SetUnit(unit)
+			portrait:SetCamDistanceScale(camera)
+			portrait:SetPortraitZoom(1)
+			portrait:SetPosition(0,0,0)
+			portrait.guid = guid
+
+			if(rotate and (portrait:GetFacing() ~= (rotate / 60))) then
+				portrait:SetFacing(rotate / 60)
+			end
+
+			local r, g, b, color = 0.25, 0.25, 0.25
+			if not UnitIsPlayer(unit)then
+				color = self.colors.reaction[UnitReaction(unit,"player")]
+				if(color ~= nil) then
+					r,g,b = color[1]*0.35, color[2]*0.35, color[3]*0.35
+				end
+			else
+				local _,unitClass = UnitClass(unit)
+				if unitClass then
+					color = self.colors.class[unitClass]
+					r,g,b = color[1]*0.65, color[2]*0.65, color[3]*0.65
+				end
+			end
+			portrait:SetBackdropColor(r,g,b)
+			if portrait.UpdateColor then
+				portrait:UpdateColor(r,g,b)
+			end
+			portrait:RefreshCamera()
+		end
+	else
+		SetPortraitTexture(portrait, unit)
+	end
+
+	if(portrait.PostUpdate) then
+		return portrait:PostUpdate(unit)
+	end
+end
+
+local Path = function(self, ...)
+	return (self.Portrait.Override or Update) (self, ...)
+end
+
+local ForceTargetUpdate = function(self)
+	local portrait = self.Portrait
+	if(not portrait.__owner) then return end
+	return Path(portrait.__owner, 'ForceUpdate', portrait.__owner.unit)
+end
+
+local ForceUpdate = function(element)
+	if(not element.__owner) then return end
+	return Path(element.__owner, 'ForceUpdate', element.__owner.unit)
+end
+
+local Enable = function(self, unit)
+	local portrait = self.Portrait
+	if(portrait) then
+		portrait.__owner = self
+		portrait.ForceUpdate = ForceUpdate
+
+		self:RegisterEvent("UNIT_PORTRAIT_UPDATE", Path)
+		self:RegisterEvent("UNIT_MODEL_CHANGED", Path)
+		self:RegisterEvent('UNIT_CONNECTION', Path)
+		if(unit == 'target' or unit == 'targettarget') then
+			self:RegisterEvent('PLAYER_TARGET_CHANGED', ForceTargetUpdate)
+		end
+		-- The quest log uses PARTY_MEMBER_{ENABLE,DISABLE} to handle updating of
+		-- party members overlapping quests. This will probably be enough to handle
+		-- model updating.
+		--
+		-- DISABLE isn't used as it fires when we most likely don't have the
+		-- information we want.
+		if(unit == 'party') then
+			self:RegisterEvent('PARTY_MEMBER_ENABLE', Path)
+		end
+
+		return true
+	end
+end
+
+local Disable = function(self)
+	local portrait = self.Portrait
+	if(portrait) then
+		self:UnregisterEvent("UNIT_PORTRAIT_UPDATE", Path)
+		self:UnregisterEvent("UNIT_MODEL_CHANGED", Path)
+		self:UnregisterEvent('PARTY_MEMBER_ENABLE', Path)
+		self:UnregisterEvent('UNIT_CONNECTION', Path)
+		self:UnregisterEvent('PLAYER_TARGET_CHANGED', ForceTargetUpdate)
+	end
+end
+
+oUF:AddElement('Portrait', Path, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/oUF/elements/power.lua b/SVUI_UnitFrames/libs/oUF/elements/power.lua
new file mode 100644
index 0000000..98e612b
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/elements/power.lua
@@ -0,0 +1,136 @@
+local parent, ns = ...
+local oUF = ns.oUF
+
+oUF.colors.power = {}
+for power, color in next, PowerBarColor do
+	if(type(power) == 'string') then
+		oUF.colors.power[power] = {color.r, color.g, color.b}
+	end
+end
+
+local GetDisplayPower = function(power, unit)
+	if not unit then return; end
+	local _, _, _, _, _, _, showOnRaid = UnitAlternatePowerInfo(unit)
+	if(power.displayAltPower and showOnRaid) then
+		return ALTERNATE_POWER_INDEX
+	else
+		return (UnitPowerType(unit))
+	end
+end
+
+local Update = function(self, event, unit)
+	if(self.unit ~= unit) or not unit then return end
+	local power = self.Power
+
+	if(power.PreUpdate) then power:PreUpdate(unit) end
+
+	local displayType = GetDisplayPower(power, unit);
+	local min = UnitPower(unit, displayType);
+	local max = UnitPowerMax(unit, displayType);
+	local disconnected = not UnitIsConnected(unit)
+	if max == 0 then
+		max = 1
+	end
+	power:SetMinMaxValues(0, max)
+	if(disconnected) then
+		power:SetValue(max)
+	else
+		power:SetValue(min)
+	end
+
+	power.disconnected = disconnected
+	if power.frequentUpdates ~= power.__frequentUpdates then
+		power.__frequentUpdates = power.frequentUpdates
+	end
+
+	local r, g, b, t
+	if(power.colorTapping and not UnitPlayerControlled(unit) and UnitIsTapDenied(unit)) then
+		t = self.colors.tapped
+	elseif(power.colorDisconnected and not UnitIsConnected(unit)) then
+		t = self.colors.disconnected
+	elseif(power.colorPower) then
+		local ptype, ptoken, altR, altG, altB = UnitPowerType(unit)
+		t = self.colors.power[ptoken]
+		if(not t and altR) then
+			r, g, b = altR, altG, altB
+		end
+	elseif(power.colorClass and UnitIsPlayer(unit)) or
+		(power.colorClassNPC and not UnitIsPlayer(unit)) or
+		(power.colorClassPet and UnitPlayerControlled(unit) and not UnitIsPlayer(unit)) then
+		local _, class = UnitClass(unit)
+		t = self.colors.class[class]
+	elseif(power.colorReaction and UnitReaction(unit, 'player')) then
+		t = self.colors.reaction[UnitReaction(unit, "player")]
+	elseif(power.colorSmooth) then
+		r, g, b = self.ColorGradient(min, max, unpack(power.smoothGradient or self.colors.smooth))
+	end
+
+	if(t) then
+		r, g, b = t[1], t[2], t[3]
+	end
+
+	if(b) then
+		power:SetStatusBarColor(r, g, b)
+
+		local bg = power.bg
+		if(bg) then
+			local mu = bg.multiplier or 1
+			bg:SetVertexColor(r * mu, g * mu, b * mu)
+		end
+	end
+
+	if(power.PostUpdate) then
+		return power:PostUpdate(unit, min, max)
+	end
+end
+
+local Path = function(self, ...)
+	return (self.Power.Override or Update) (self, ...)
+end
+
+local ForceUpdate = function(element)
+	return Path(element.__owner, 'ForceUpdate', element.__owner.unit)
+end
+
+local Enable = function(self, unit)
+	local power = self.Power
+	if(power) then
+		power.__owner = self
+		power.ForceUpdate = ForceUpdate
+
+		power.__frequentUpdates = power.frequentUpdates
+
+		self:RegisterEvent('UNIT_POWER_BAR_SHOW', Path)
+		self:RegisterEvent('UNIT_POWER_BAR_HIDE', Path)
+		self:RegisterEvent('UNIT_DISPLAYPOWER', Path)
+		self:RegisterEvent('UNIT_CONNECTION', Path)
+		self:RegisterEvent('UNIT_FACTION', Path)
+		self:RegisterEvent('UNIT_MAXPOWER', Path)
+		self:RegisterEvent('UNIT_POWER', Path)
+		self:RegisterUnitEvent("UNIT_POWER", unit);
+		self:RegisterUnitEvent("UNIT_MAXPOWER", unit);
+
+
+		if(power:IsObjectType'StatusBar' and not power:GetStatusBarTexture()) then
+			power:SetStatusBarTexture[[Interface\TargetingFrame\UI-StatusBar]]
+		end
+
+		return true
+	end
+end
+
+local Disable = function(self)
+	local power = self.Power
+	if(power) then
+		self:UnregisterEvent('UNIT_POWER_FREQUENT', Path)
+		self:UnregisterEvent('UNIT_POWER', Path)
+		self:UnregisterEvent('UNIT_POWER_BAR_SHOW', Path)
+		self:UnregisterEvent('UNIT_POWER_BAR_HIDE', Path)
+		self:UnregisterEvent('UNIT_DISPLAYPOWER', Path)
+		self:UnregisterEvent('UNIT_CONNECTION', Path)
+		self:UnregisterEvent('UNIT_MAXPOWER', Path)
+		self:UnregisterEvent('UNIT_FACTION', Path)
+	end
+end
+
+oUF:AddElement('Power', Path, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/oUF/elements/pvp.lua b/SVUI_UnitFrames/libs/oUF/elements/pvp.lua
new file mode 100644
index 0000000..27d7d74
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/elements/pvp.lua
@@ -0,0 +1,61 @@
+local parent, ns = ...
+local oUF = ns.oUF
+
+local Update = function(self, event, unit)
+	if(unit ~= self.unit) then return end
+
+	local pvp = self.PvP
+	if(pvp.PreUpdate) then
+		pvp:PreUpdate()
+	end
+
+	local status
+	local factionGroup = UnitFactionGroup(unit)
+	if(UnitIsPVPFreeForAll(unit)) then
+		pvp:SetTexture[[Interface\TargetingFrame\UI-PVP-FFA]]
+		status = 'ffa'
+	elseif(factionGroup and factionGroup ~= 'Neutral' and UnitIsPVP(unit)) then
+		pvp:SetTexture([[Interface\TargetingFrame\UI-PVP-]]..factionGroup)
+		status = factionGroup
+	end
+
+	if(status) then
+		pvp:Show()
+	else
+		pvp:Hide()
+	end
+
+	if(pvp.PostUpdate) then
+		return pvp:PostUpdate(status)
+	end
+end
+
+local Path = function(self, ...)
+	return (self.PvP.Override or Update) (self, ...)
+end
+
+local ForceUpdate = function(element)
+	return Path(element.__owner, 'ForceUpdate', element.__owner.unit)
+end
+
+local Enable = function(self)
+	local pvp = self.PvP
+	if(pvp) then
+		pvp.__owner = self
+		pvp.ForceUpdate = ForceUpdate
+
+		self:RegisterEvent("UNIT_FACTION", Path)
+
+		return true
+	end
+end
+
+local Disable = function(self)
+	local pvp = self.PvP
+	if(pvp) then
+		pvp:Hide()
+		self:UnregisterEvent("UNIT_FACTION", Path)
+	end
+end
+
+oUF:AddElement('PvP', Path, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/oUF/elements/qicon.lua b/SVUI_UnitFrames/libs/oUF/elements/qicon.lua
new file mode 100644
index 0000000..cc2e4a6
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/elements/qicon.lua
@@ -0,0 +1,54 @@
+local parent, ns = ...
+local oUF = ns.oUF
+
+local Update = function(self, event, unit)
+	if(unit ~= self.unit) then return end
+
+	local qicon = self.QuestIcon
+	if(qicon.PreUpdate) then
+		qicon:PreUpdate()
+	end
+
+	local isQuestBoss = UnitIsQuestBoss(unit)
+	if(isQuestBoss) then
+		qicon:Show()
+	else
+		qicon:Hide()
+	end
+
+	if(qicon.PostUpdate) then
+		return qicon:PostUpdate(isQuestBoss)
+	end
+end
+
+local Path = function(self, ...)
+	return (self.QuestIcon.Override or Update) (self, ...)
+end
+
+local ForceUpdate = function(element)
+	return Path(element.__owner, 'ForceUpdate', element.__owner.unit)
+end
+
+local Enable = function(self)
+	local qicon = self.QuestIcon
+	if(qicon) then
+		qicon.__owner = self
+		qicon.ForceUpdate = ForceUpdate
+
+		self:RegisterEvent('UNIT_CLASSIFICATION_CHANGED', Path)
+
+		if(qicon:IsObjectType'Texture' and not qicon:GetTexture()) then
+			qicon:SetTexture[[Interface\TargetingFrame\PortraitQuestBadge]]
+		end
+
+		return true
+	end
+end
+
+local Disable = function(self)
+	if(self.QuestIcon) then
+		self:UnregisterEvent('UNIT_CLASSIFICATION_CHANGED', Path)
+	end
+end
+
+oUF:AddElement('QuestIcon', Path, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/oUF/elements/range.lua b/SVUI_UnitFrames/libs/oUF/elements/range.lua
new file mode 100644
index 0000000..3c07571
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/elements/range.lua
@@ -0,0 +1,253 @@
+local parent, ns = ...
+local oUF = ns.oUF
+
+local _FRAMES = {}
+local OnRangeFrame
+
+local UnitIsConnected = UnitIsConnected
+local tinsert, tremove, twipe = table.insert, table.remove, table.wipe
+
+local friendlySpells, resSpells, longEnemySpells, enemySpells, petSpells = {}, {}, {}, {}, {}
+
+local function AddSpell(table, spellID)
+	local name = GetSpellInfo(spellID)
+	if name then
+		local usable, nomana = IsUsableSpell(name)
+		if usable or nomana then
+			table[#table + 1] = name
+		end
+	end
+end
+
+local _,class = UnitClass("player")
+local function UpdateSpellList()
+	twipe(friendlySpells)
+	twipe(resSpells)
+	twipe(longEnemySpells)
+	twipe(enemySpells)
+	twipe(petSpells)
+
+	if class == "PRIEST" then
+		AddSpell(enemySpells, 585) -- Smite
+		AddSpell(longEnemySpells, 589) -- Shadow Word: Pain
+		AddSpell(friendlySpells, 2061) -- Flash Heal
+		AddSpell(resSpells, 2006) -- Resurrection
+	elseif class == "DRUID" then
+		AddSpell(enemySpells, 33786) -- Cyclone
+		AddSpell(longEnemySpells, 5176) -- Wrath
+		AddSpell(friendlySpells, 774) -- Rejuvenation
+		AddSpell(resSpells, 50769) -- Revive
+		AddSpell(resSpells, 20484) -- Rebirth
+	elseif class == "PALADIN" then
+		AddSpell(enemySpells, 20271) -- Judgement
+		AddSpell(friendlySpells, 85673) -- Word of Glory
+		AddSpell(resSpells, 7328) -- Redemption
+		AddSpell(longEnemySpells, 114165) -- Holy Prism
+		AddSpell(longEnemySpells, 114157) -- Execution Sentence
+	elseif class == "SHAMAN" then
+		AddSpell(enemySpells, 8042) -- Earth Shock
+		AddSpell(longEnemySpells, 403) -- Lightning Bolt
+		AddSpell(friendlySpells, 8004) -- Healing Surge
+		AddSpell(resSpells, 2008) -- Ancestral Spirit
+	elseif class == "WARLOCK" then
+		AddSpell(enemySpells, 5782) -- Fear
+		AddSpell(longEnemySpells, 172) -- Corruption
+		AddSpell(longEnemySpells, 686) -- Shadow Bolt
+		AddSpell(longEnemySpells, 17962) -- Conflag
+		AddSpell(petSpells, 755) -- Health Funnel
+		AddSpell(friendlySpells, 5697) -- Unending Breath
+	elseif class == "MAGE" then
+		AddSpell(enemySpells, 118) -- Polymorph
+		AddSpell(longEnemySpells, 44614) -- Frostfire Bolt
+		AddSpell(friendlySpells, 475) -- Remove Curse
+	elseif class == "HUNTER" then
+		AddSpell(petSpells, 136) -- Mend Pet
+		AddSpell(enemySpells, 75) -- Auto Shot
+	elseif class == "DEATHKNIGHT" then
+		AddSpell(enemySpells, 49576) -- Death Grip
+		AddSpell(friendlySpells, 47541) -- Death Coil
+		AddSpell(resSpells, 61999) -- Raise Ally
+	elseif class == "ROGUE" then
+		AddSpell(enemySpells, 2094) -- Blind
+		AddSpell(longEnemySpells, 1725) -- Distract
+		AddSpell(friendlySpells, 57934) -- Tricks of the Trade
+	elseif class == "WARRIOR" then
+		AddSpell(enemySpells, 5246) -- Intimidating Shout
+		AddSpell(enemySpells, 100) -- Charge
+		AddSpell(longEnemySpells, 355) -- Taunt
+	elseif class == "MONK" then
+		AddSpell(enemySpells, 115546) -- Provoke
+		AddSpell(friendlySpells, 115450) -- Detox
+		AddSpell(resSpells, 115178) -- Resuscitate
+	end
+end
+
+local function getUnit(unit)
+	if not unit:find("party") or not unit:find("raid") then
+		for i=1, 4 do
+			if UnitIsUnit(unit, "party"..i) then
+				return "party"..i
+			end
+		end
+
+		for i=1, 40 do
+			if UnitIsUnit(unit, "raid"..i) then
+				return "raid"..i
+			end
+		end
+	else
+		return unit
+	end
+end
+
+local function friendlyIsInRange(unit)
+	if CheckInteractDistance(unit, 1) then
+		return true
+	end
+
+	if UnitIsDeadOrGhost(unit) and #resSpells > 0 then
+		for _, name in ipairs(resSpells) do
+			if IsSpellInRange(name, unit) == 1 then
+				return true
+			end
+		end
+
+		return false
+	end
+
+	if #friendlySpells == 0 and (UnitInRaid(unit) or UnitInParty(unit)) then
+		unit = getUnit(unit)
+		return unit and UnitInRange(unit)
+	else
+		for _, name in ipairs(friendlySpells) do
+			if IsSpellInRange(name, unit) == 1 then
+				return true
+			end
+		end
+	end
+
+	return false
+end
+
+local function petIsInRange(unit)
+	if CheckInteractDistance(unit, 2) then
+		return true
+	end
+
+	for _, name in ipairs(friendlySpells) do
+		if IsSpellInRange(name, unit) == 1 then
+			return true
+		end
+	end
+	for _, name in ipairs(petSpells) do
+		if IsSpellInRange(name, unit) == 1 then
+			return true
+		end
+	end
+
+	return false
+end
+
+local function enemyIsInRange(unit)
+	if CheckInteractDistance(unit, 2) then
+		return true
+	end
+
+	for _, name in ipairs(enemySpells) do
+		if IsSpellInRange(name, unit) == 1 then
+			return true
+		end
+	end
+
+	return false
+end
+
+local function enemyIsInLongRange(unit)
+	for _, name in ipairs(longEnemySpells) do
+		if IsSpellInRange(name, unit) == 1 then
+			return true
+		end
+	end
+
+	return false
+end
+
+-- updating of range.
+local timer = 0
+local OnRangeUpdate = function(self, elapsed)
+	timer = timer + elapsed
+
+	if(timer >= .20) then
+		for _, object in next, _FRAMES do
+			if(object:IsShown()) then
+				local range = object.Range
+				local unit = object.unit
+				if(unit) then
+					if UnitCanAttack("player", unit) then
+						if enemyIsInRange(unit) then
+							object:SetAlpha(range.insideAlpha)
+						elseif enemyIsInLongRange(unit) then
+							object:SetAlpha(range.insideAlpha)
+						else
+							object:SetAlpha(range.outsideAlpha)
+						end
+					elseif UnitIsUnit(unit, "pet") then
+						if petIsInRange(unit) then
+							object:SetAlpha(range.insideAlpha)
+						else
+							object:SetAlpha(range.outsideAlpha)
+						end
+					else
+						if friendlyIsInRange(unit) and UnitIsConnected(unit) then
+							object:SetAlpha(range.insideAlpha)
+						else
+							object:SetAlpha(range.outsideAlpha)
+						end
+					end
+				else
+					object:SetAlpha(range.insideAlpha)
+				end
+			end
+		end
+
+		timer = 0
+	end
+end
+
+local Enable = function(self)
+	local range = self.Range
+	if(range and range.insideAlpha and range.outsideAlpha) then
+		tinsert(_FRAMES, self)
+
+		if(not OnRangeFrame) then
+			OnRangeFrame = CreateFrame"Frame"
+			OnRangeFrame:RegisterEvent("LEARNED_SPELL_IN_TAB");
+			OnRangeFrame:RegisterEvent("PLAYER_ENTERING_WORLD");
+			OnRangeFrame:SetScript("OnUpdate", OnRangeUpdate)
+			OnRangeFrame:SetScript("OnEvent", UpdateSpellList)
+		end
+
+		OnRangeFrame:Show()
+
+		return true
+	end
+end
+
+local Disable = function(self)
+	local range = self.Range
+	if(range) then
+		for k, frame in next, _FRAMES do
+			if(frame == self) then
+				tremove(_FRAMES, k)
+				frame:SetAlpha(1)
+				break
+			end
+		end
+
+		if(#_FRAMES == 0) then
+			OnRangeFrame:Hide()
+		end
+	end
+end
+
+oUF:AddElement('Range', nil, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/oUF/elements/readycheck.lua b/SVUI_UnitFrames/libs/oUF/elements/readycheck.lua
new file mode 100644
index 0000000..1326eb8
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/elements/readycheck.lua
@@ -0,0 +1,130 @@
+local parent, ns = ...
+local oUF = ns.oUF
+
+local _TIMERS = {}
+local ReadyCheckFrame
+
+local removeEntry = function(icon)
+	_TIMERS[icon] = nil
+	if(not next(_TIMERS)) then
+		return ReadyCheckFrame:Hide()
+	end
+end
+
+local Start = function(self)
+	removeEntry(self)
+
+	self:SetTexture(READY_CHECK_WAITING_TEXTURE)
+	self.state = 'waiting'
+	self:SetAlpha(1)
+	self:Show()
+end
+
+local Confirm = function(self, ready)
+	removeEntry(self)
+
+	if(ready) then
+		self:SetTexture(READY_CHECK_READY_TEXTURE)
+		self.state = 'ready'
+	else
+		self:SetTexture(READY_CHECK_NOT_READY_TEXTURE)
+		self.state = 'notready'
+	end
+
+	self:SetAlpha(1)
+	self:Show()
+end
+
+local Finish = function(self)
+	if(self.state == 'waiting') then
+		self:SetTexture(READY_CHECK_AFK_TEXTURE)
+		self.state = 'afk'
+	end
+
+	self.finishedTimer = self.finishedTime or 10
+	self.fadeTimer = self.fadeTime or 1.5
+
+	_TIMERS[self] = true
+	ReadyCheckFrame:Show()
+end
+
+local OnUpdate = function(self, elapsed)
+	self.elapsed = (self.elapsed or 0) + elapsed
+	if self.elapsed < .25 then return end
+
+	for icon in next, _TIMERS do
+		if(icon.finishedTimer) then
+			icon.finishedTimer = icon.finishedTimer - self.elapsed
+			if(icon.finishedTimer <= 0) then
+				icon.finishedTimer = nil
+			end
+		elseif(icon.fadeTimer) then
+			icon.fadeTimer = icon.fadeTimer - self.elapsed
+			icon:SetAlpha(icon.fadeTimer / (icon.fadeTime or 1.5))
+
+			if(icon.fadeTimer <= 0) then
+				icon:Hide()
+				removeEntry(icon)
+			end
+		end
+	end
+
+	self.elapsed = 0
+end
+
+local Update = function(self, event)
+	local unit = self.unit
+	local readyCheck = self.ReadyCheck
+	if(event == 'READY_CHECK_FINISHED') then
+		Finish(readyCheck)
+	else
+		local status = GetReadyCheckStatus(unit)
+		if(UnitExists(unit) and status) then
+			if(status == 'ready') then
+				Confirm(readyCheck, 1)
+			elseif(status == 'notready') then
+				Confirm(readyCheck)
+			else
+				Start(readyCheck)
+			end
+		end
+	end
+end
+
+local Path = function(self, ...)
+	return (self.ReadyCheck.Override or Update) (self, ...)
+end
+
+local ForceUpdate = function(element)
+	return Path(element.__owner, 'ForceUpdate')
+end
+
+local Enable = function(self, unit)
+	local readyCheck = self.ReadyCheck
+	if(readyCheck and (unit and (unit:sub(1, 5) == 'party' or unit:sub(1,4) == 'raid'))) then
+		readyCheck.__owner = self
+		readyCheck.ForceUpdate = ForceUpdate
+
+		if(not ReadyCheckFrame) then
+			ReadyCheckFrame = CreateFrame'Frame'
+			ReadyCheckFrame:SetScript('OnUpdate', OnUpdate)
+		end
+
+		self:RegisterEvent('READY_CHECK', Path, true)
+		self:RegisterEvent('READY_CHECK_CONFIRM', Path, true)
+		self:RegisterEvent('READY_CHECK_FINISHED', Path, true)
+
+		return true
+	end
+end
+
+local Disable = function(self)
+	local readyCheck = self.ReadyCheck
+	if(readyCheck) then
+		self:UnregisterEvent('READY_CHECK', Path)
+		self:UnregisterEvent('READY_CHECK_CONFIRM', Path)
+		self:UnregisterEvent('READY_CHECK_FINISHED', Path)
+	end
+end
+
+oUF:AddElement('ReadyCheck', Path, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/oUF/elements/resting.lua b/SVUI_UnitFrames/libs/oUF/elements/resting.lua
new file mode 100644
index 0000000..ab1de54
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/elements/resting.lua
@@ -0,0 +1,54 @@
+local parent, ns = ...
+local oUF = ns.oUF
+
+local Update = function(self, event)
+	local resting = self.Resting
+	if(resting.PreUpdate) then
+		resting:PreUpdate()
+	end
+
+	local isResting = IsResting()
+	if(isResting) then
+		resting:Show()
+	else
+		resting:Hide()
+	end
+
+	if(resting.PostUpdate) then
+		return resting:PostUpdate(isResting)
+	end
+end
+
+local Path = function(self, ...)
+	return (self.Resting.Override or Update) (self, ...)
+end
+
+local ForceUpdate = function(element)
+	return Path(element.__owner, 'ForceUpdate')
+end
+
+local Enable = function(self, unit)
+	local resting = self.Resting
+	if(resting and unit == 'player') then
+		resting.__owner = self
+		resting.ForceUpdate = ForceUpdate
+
+		self:RegisterEvent("PLAYER_UPDATE_RESTING", Path, true)
+
+		if(resting:IsObjectType"Texture" and not resting:GetTexture()) then
+			resting:SetTexture[[Interface\CharacterFrame\UI-StateIcon]]
+			resting:SetTexCoord(0, .5, 0, .421875)
+		end
+
+		return true
+	end
+end
+
+local Disable = function(self)
+	local resting = self.Resting
+	if(resting) then
+		self:UnregisterEvent("PLAYER_UPDATE_RESTING", Path)
+	end
+end
+
+oUF:AddElement('Resting', Path, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/oUF/elements/resurrect.lua b/SVUI_UnitFrames/libs/oUF/elements/resurrect.lua
new file mode 100644
index 0000000..e6fc1ab
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/elements/resurrect.lua
@@ -0,0 +1,54 @@
+local parent, ns = ...
+local oUF = ns.oUF
+
+local Update = function(self, event)
+	if not self.unit then return; end
+	local resurrect = self.ResurrectIcon
+	if(resurrect.PreUpdate) then
+		resurrect:PreUpdate()
+	end
+
+	local incomingResurrect = UnitHasIncomingResurrection(self.unit)
+	if(incomingResurrect) then
+		resurrect:Show()
+	else
+		resurrect:Hide()
+	end
+
+	if(resurrect.PostUpdate) then
+		return resurrect:PostUpdate(incomingResurrect)
+	end
+end
+
+local Path = function(self, ...)
+	return (self.ResurrectIcon.Override or Update) (self, ...)
+end
+
+local ForceUpdate = function(element)
+	return Path(element.__owner, 'ForceUpdate')
+end
+
+local Enable = function(self)
+	local resurrect = self.ResurrectIcon
+	if(resurrect) then
+		resurrect.__owner = self
+		resurrect.ForceUpdate = ForceUpdate
+
+		self:RegisterEvent('INCOMING_RESURRECT_CHANGED', Path, true)
+
+		if(resurrect:IsObjectType('Texture') and not resurrect:GetTexture()) then
+			resurrect:SetTexture[[Interface\RaidFrame\Raid-Icon-Rez]]
+		end
+
+		return true
+	end
+end
+
+local Disable = function(self)
+	local resurrect = self.ResurrectIcon
+	if(resurrect) then
+		self:UnregisterEvent('INCOMING_RESURRECT_CHANGED', Path)
+	end
+end
+
+oUF:AddElement('ResurrectIcon', Path, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/oUF/elements/ricons.lua b/SVUI_UnitFrames/libs/oUF/elements/ricons.lua
new file mode 100644
index 0000000..d990b62
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/elements/ricons.lua
@@ -0,0 +1,59 @@
+local parent, ns = ...
+local oUF = ns.oUF
+
+local GetRaidTargetIndex = GetRaidTargetIndex
+local SetRaidTargetIconTexture = SetRaidTargetIconTexture
+
+local Update = function(self, event)
+	if not self.unit then return end
+	local icon = self.RaidIcon
+	if(icon.PreUpdate) then
+		icon:PreUpdate()
+	end
+
+	local index = GetRaidTargetIndex(self.unit)
+	if(index) then
+		SetRaidTargetIconTexture(icon, index)
+		icon:Show()
+	else
+		icon:Hide()
+	end
+
+	if(icon.PostUpdate) then
+		return icon:PostUpdate(index)
+	end
+end
+
+local Path = function(self, ...)
+	return (self.RaidIcon.Override or Update) (self, ...)
+end
+
+local ForceUpdate = function(element)
+	if(not element.__owner.unit) then return end
+	return Path(element.__owner, 'ForceUpdate')
+end
+
+local Enable = function(self)
+	local ricon = self.RaidIcon
+	if(ricon) then
+		ricon.__owner = self
+		ricon.ForceUpdate = ForceUpdate
+
+		self:RegisterEvent("RAID_TARGET_UPDATE", Path, true)
+
+		if(ricon:IsObjectType"Texture" and not ricon:GetTexture()) then
+			ricon:SetTexture[[Interface\TargetingFrame\UI-RaidTargetingIcons]]
+		end
+
+		return true
+	end
+end
+
+local Disable = function(self)
+	local ricon = self.RaidIcon
+	if(ricon) then
+		self:UnregisterEvent("RAID_TARGET_UPDATE", Path)
+	end
+end
+
+oUF:AddElement('RaidIcon', Path, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/oUF/elements/tags.lua b/SVUI_UnitFrames/libs/oUF/elements/tags.lua
new file mode 100644
index 0000000..2e38ccc
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/elements/tags.lua
@@ -0,0 +1,778 @@
+--[[
+-- Credits: Vika, Cladhaire, Tekkub
+]]
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local error         = _G.error;
+local print         = _G.print;
+local pairs         = _G.pairs;
+local next          = _G.next;
+local rawset      	= _G.rawset;
+local type  		= _G.type;
+
+--BLIZZARD API
+local CreateFrame   = _G.CreateFrame;
+local UnitExists 	= _G.UnitExists;
+
+
+local parent, ns = ...
+local oUF = ns.oUF
+
+local format = string.format
+local tinsert, tremove = table.insert, table.remove
+local _PATTERN = '%[..-%]+'
+
+local _ENV = {
+	Hex = function(r, g, b)
+		if type(r) == "table" then
+			if r.r then r, g, b = r.r, r.g, r.b else r, g, b = unpack(r) end
+		end
+		return format("|cff%02x%02x%02x", r*255, g*255, b*255)
+	end,
+	ColorGradient = oUF.ColorGradient,
+}
+local _PROXY = setmetatable(_ENV, {__index = _G})
+
+local tagStrings = {
+	["creature"] = [[function(u)
+		return UnitCreatureFamily(u) or UnitCreatureType(u)
+	end]],
+
+	["dead"] = [[function(u)
+		if(UnitIsDead(u)) then
+			return 'Dead'
+		elseif(UnitIsGhost(u)) then
+			return 'Ghost'
+		end
+	end]],
+
+	["difficulty"] = [[function(u)
+		if UnitCanAttack("player", u) then
+			local l = UnitLevel(u)
+			return Hex(GetQuestDifficultyColor((l > 0) and l or 99))
+		end
+	end]],
+
+	["leader"] = [[function(u)
+		if(UnitIsGroupLeader(u)) then
+			return 'L'
+		end
+	end]],
+
+	["leaderlong"]  = [[function(u)
+		if(UnitIsGroupLeader(u)) then
+			return 'Leader'
+		end
+	end]],
+
+	["level"] = [[function(u)
+		local l = UnitLevel(u)
+		if ( UnitIsWildBattlePet(u) or UnitIsBattlePetCompanion(u) ) then
+			l = UnitBattlePetLevel(u)
+		end
+
+		if(l > 0) then
+			return l
+		else
+			return '??'
+		end
+	end]],
+
+	["missinghp"] = [[function(u)
+		local current = UnitHealthMax(u) - UnitHealth(u)
+		if(current > 0) then
+			return current
+		end
+	end]],
+
+	["missingpp"] = [[function(u)
+		local current = UnitPowerMax(u) - UnitPower(u)
+		if(current > 0) then
+			return current
+		end
+	end]],
+
+	["name"] = [[function(u, r)
+		return UnitName(r or u)
+	end]],
+
+	["offline"] = [[function(u)
+		if(not UnitIsConnected(u)) then
+			return 'Offline'
+		end
+	end]],
+
+	["perhp"] = [[function(u)
+		local m = UnitHealthMax(u)
+		if(m == 0) then
+			return 0
+		else
+			return math.floor(UnitHealth(u)/m*100+.5)
+		end
+	end]],
+
+	["perpp"] = [[function(u)
+		local m = UnitPowerMax(u)
+		if(m == 0) then
+			return 0
+		else
+			return math.floor(UnitPower(u)/m*100+.5)
+		end
+	end]],
+
+	["plus"] = [[function(u)
+		local c = UnitClassification(u)
+		if(c == 'elite' or c == 'rareelite') then
+			return '+'
+		end
+	end]],
+
+	["pvp"] = [[function(u)
+		if(UnitIsPVP(u)) then
+			return 'PvP'
+		end
+	end]],
+
+	["raidcolor"] = [[function(u)
+		local _, x = UnitClass(u)
+		if(x) then
+			return Hex(_COLORS.class[x])
+		end
+	end]],
+
+	["rare"] = [[function(u)
+		local c = UnitClassification(u)
+		if(c == 'rare' or c == 'rareelite') then
+			return 'Rare'
+		end
+	end]],
+
+	["resting"] = [[function(u)
+		if(u == 'player' and IsResting()) then
+			return 'zzz'
+		end
+	end]],
+
+	["sex"] = [[function(u)
+		local s = UnitSex(u)
+		if(s == 2) then
+			return 'Male'
+		elseif(s == 3) then
+			return 'Female'
+		end
+	end]],
+
+	["smartclass"] = [[function(u)
+		if(UnitIsPlayer(u)) then
+			return _TAGS['class'](u)
+		end
+
+		return _TAGS['creature'](u)
+	end]],
+
+	["status"] = [[function(u)
+		if(UnitIsDead(u)) then
+			return 'Dead'
+		elseif(UnitIsGhost(u)) then
+			return 'Ghost'
+		elseif(not UnitIsConnected(u)) then
+			return 'Offline'
+		else
+			return _TAGS['resting'](u)
+		end
+	end]],
+
+	["threat"] = [[function(u)
+		local s = UnitThreatSituation(u)
+		if(s == 1) then
+			return '++'
+		elseif(s == 2) then
+			return '--'
+		elseif(s == 3) then
+			return 'Aggro'
+		end
+	end]],
+
+	["threatcolor"] = [[function(u)
+		return Hex(GetThreatStatusColor(UnitThreatSituation(u)))
+	end]],
+
+	["cpoints"] = [[function(u)
+		local cp
+		if(UnitHasVehicleUI'player') then
+			cp = GetComboPoints('vehicle', 'target')
+		else
+			cp = GetComboPoints('player', 'target')
+		end
+
+		if(cp > 0) then
+			return cp
+		end
+	end]],
+
+	['smartlevel'] = [[function(u)
+		local c = UnitClassification(u)
+		if(c == 'worldboss') then
+			return 'Boss'
+		else
+			local plus = _TAGS['plus'](u)
+			local level = _TAGS['level'](u)
+			if(plus) then
+				return level .. plus
+			else
+				return level
+			end
+		end
+	end]],
+
+	["classification"] = [[function(u)
+		local c = UnitClassification(u)
+		if(c == 'rare') then
+			return 'Rare'
+		elseif(c == 'rareelite') then
+			return 'Rare Elite'
+		elseif(c == 'elite') then
+			return 'Elite'
+		elseif(c == 'worldboss') then
+			return 'Boss'
+		elseif(c == 'minus') then
+			return 'Affix'
+		end
+	end]],
+
+	["shortclassification"] = [[function(u)
+		local c = UnitClassification(u)
+		if(c == 'rare') then
+			return 'R'
+		elseif(c == 'rareelite') then
+			return 'R+'
+		elseif(c == 'elite') then
+			return '+'
+		elseif(c == 'worldboss') then
+			return 'B'
+		elseif(c == 'minus') then
+			return '-'
+		end
+	end]],
+
+	["group"] = [[function(unit)
+		local name, server = UnitName(unit)
+		if(server and server ~= "") then
+			name = format("%s-%s", name, server)
+		end
+
+		for i=1, GetNumGroupMembers() do
+			local raidName, _, group = GetRaidRosterInfo(i)
+			if( raidName == name ) then
+				return group
+			end
+		end
+	end]],
+
+	["deficit:name"] = [[function(u)
+		local missinghp = _TAGS['missinghp'](u)
+		if(missinghp) then
+			return '-' .. missinghp
+		else
+			return _TAGS['name'](u)
+		end
+	end]],
+
+	['pereclipse'] = [[function(u)
+		local m = UnitPowerMax('player', SPELL_POWER_ECLIPSE)
+		if(m == 0) then
+			return 0
+		else
+			return math.abs(UnitPower('player', SPELL_POWER_ECLIPSE)/m*100)
+		end
+	end]],
+
+	['curmana'] = [[function(unit)
+		return UnitPower(unit, SPELL_POWER_MANA)
+	end]],
+
+	['maxmana'] = [[function(unit)
+		return UnitPowerMax(unit, SPELL_POWER_MANA)
+	end]],
+
+	['soulshards'] = [[function()
+		local num = UnitPower('player', SPELL_POWER_SOUL_SHARDS)
+		if(num > 0) then
+			return num
+		end
+	end]],
+
+	['holypower'] = [[function()
+		local num = UnitPower('player', SPELL_POWER_HOLY_POWER)
+		if(num > 0) then
+			return num
+		end
+	end]],
+
+	['chi'] = [[function()
+		local num = UnitPower('player', SPELL_POWER_CHI)
+		if(num > 0) then
+			return num
+		end
+	end]],
+
+	['shadoworbs'] = [[function()
+		local num = UnitPower('player', SPELL_POWER_SHADOW_ORBS)
+		if(num > 0) then
+			return num
+		end
+	end]],
+
+	['affix'] = [[function(u)
+		local c = UnitClassification(u)
+		if(c == 'minus') then
+			return 'Affix'
+		end
+	end]],
+}
+
+local tags = setmetatable(
+	{
+		curhp = UnitHealth,
+		curpp = UnitPower,
+		maxhp = UnitHealthMax,
+		maxpp = UnitPowerMax,
+		class = UnitClass,
+		faction = UnitFactionGroup,
+		race = UnitRace,
+	},
+
+	{
+		__index = function(self, key)
+			local tagFunc = tagStrings[key]
+			if(tagFunc) then
+				local func, err = loadstring('return ' .. tagFunc)
+				if(func) then
+					func = func()
+
+					-- Want to trigger __newindex, so no rawset.
+					self[key] = func
+					tagStrings[key] = nil
+
+					return func
+				else
+					error(err, 3)
+				end
+			end
+		end,
+		__newindex = function(self, key, val)
+			if(type(val) == 'string') then
+				tagStrings[key] = val
+			elseif(type(val) == 'function') then
+				-- So we don't clash with any custom envs.
+				if(getfenv(val) == _G) then
+					setfenv(val, _PROXY)
+				end
+
+				rawset(self, key, val)
+			end
+		end,
+	}
+)
+
+_ENV._TAGS = tags
+
+local onUpdateDelay = {}
+local tagEvents = {
+	["curhp"]               = "UNIT_HEALTH",
+	["dead"]                = "UNIT_HEALTH",
+	["leader"]              = "PARTY_LEADER_CHANGED",
+	["leaderlong"]          = "PARTY_LEADER_CHANGED",
+	["level"]               = "UNIT_LEVEL PLAYER_LEVEL_UP",
+	["maxhp"]               = "UNIT_MAXHEALTH",
+	["missinghp"]           = "UNIT_HEALTH UNIT_MAXHEALTH",
+	["name"]                = "UNIT_NAME_UPDATE",
+	["perhp"]               = "UNIT_HEALTH UNIT_MAXHEALTH",
+	["pvp"]                 = "UNIT_FACTION",
+	["resting"]             = "PLAYER_UPDATE_RESTING",
+	["smartlevel"]          = "UNIT_LEVEL PLAYER_LEVEL_UP UNIT_CLASSIFICATION_CHANGED",
+	["threat"]              = "UNIT_THREAT_SITUATION_UPDATE",
+	["threatcolor"]         = "UNIT_THREAT_SITUATION_UPDATE",
+	['cpoints']             = 'UNIT_COMBO_POINTS PLAYER_TARGET_CHANGED',
+	['affix']				= 'UNIT_CLASSIFICATION_CHANGED',
+	['plus']				= 'UNIT_CLASSIFICATION_CHANGED',
+	['rare']                = 'UNIT_CLASSIFICATION_CHANGED',
+	['classification']      = 'UNIT_CLASSIFICATION_CHANGED',
+	['shortclassification'] = 'UNIT_CLASSIFICATION_CHANGED',
+	["group"]               = "GROUP_ROSTER_UPDATE",
+	["curpp"]               = 'UNIT_POWER',
+	["maxpp"]               = 'UNIT_MAXPOWER',
+	["missingpp"]           = 'UNIT_MAXPOWER UNIT_POWER',
+	["perpp"]               = 'UNIT_MAXPOWER UNIT_POWER',
+	["offline"]             = "UNIT_HEALTH UNIT_CONNECTION",
+	["status"]              = "UNIT_HEALTH PLAYER_UPDATE_RESTING UNIT_CONNECTION",
+	["pereclipse"]          = 'UNIT_POWER',
+	['curmana']             = 'UNIT_POWER UNIT_MAXPOWER',
+	['maxmana']             = 'UNIT_POWER UNIT_MAXPOWER',
+	['soulshards']          = 'UNIT_POWER',
+	['holypower']           = 'UNIT_POWER',
+	['chi']                 = 'UNIT_POWER',
+	['shadoworbs']          = 'UNIT_POWER',
+}
+
+local unitlessEvents = {
+	PLAYER_LEVEL_UP = true,
+	PLAYER_UPDATE_RESTING = true,
+	PLAYER_TARGET_CHANGED = true,
+
+	PARTY_LEADER_CHANGED = true,
+
+	GROUP_ROSTER_UPDATE = true,
+
+	UNIT_COMBO_POINTS = true
+}
+
+local events = {}
+local frame = CreateFrame"Frame"
+frame:SetScript('OnEvent', function(self, event, unit)
+	local strings = events[event]
+	if(strings) then
+		for k, fontstring in next, strings do
+			if(fontstring:IsVisible() and (unitlessEvents[event] or fontstring.parent.unit == unit)) then
+				fontstring:UpdateTag()
+			end
+		end
+	end
+end)
+
+local OnUpdates = {}
+local eventlessUnits = {}
+
+local createOnUpdate = function(timer)
+	local OnUpdate = OnUpdates[timer]
+
+	if(not OnUpdate) then
+		local total = timer
+		local frame = CreateFrame'Frame'
+		local strings = eventlessUnits[timer]
+
+		frame:SetScript('OnUpdate', function(self, elapsed)
+			if(total >= timer) then
+				for k, fs in next, strings do
+					if(fs.parent:IsShown() and UnitExists(fs.parent.unit)) then
+						fs:UpdateTag()
+					end
+				end
+
+				total = 0
+			end
+
+			total = total + elapsed
+		end)
+
+		OnUpdates[timer] = frame
+	end
+end
+
+local OnShow = function(self)
+	for _, fs in next, self.__tags do
+		fs:UpdateTag()
+	end
+end
+
+local getTagName = function(tag)
+	local s = (tag:match('>+()') or 2)
+	local e = tag:match('.*()<+')
+	e = (e and e - 1) or -2
+
+	return tag:sub(s, e), s, e
+end
+
+local RegisterEvent = function(fontstr, event)
+	if(not events[event]) then events[event] = {} end
+
+	frame:RegisterEvent(event)
+	tinsert(events[event], fontstr)
+end
+
+local RegisterEvents = function(fontstr, tagstr)
+	for tag in tagstr:gmatch(_PATTERN) do
+		tag = getTagName(tag)
+		local tagevents = tagEvents[tag]
+		if(tagevents) then
+			for event in tagevents:gmatch'%S+' do
+				RegisterEvent(fontstr, event)
+			end
+		end
+	end
+end
+
+local UnregisterEvents = function(fontstr)
+	for event, data in pairs(events) do
+		for k, tagfsstr in pairs(data) do
+			if(tagfsstr == fontstr) then
+				if(#data == 1) then
+					frame:UnregisterEvent(event)
+				end
+
+				tremove(data, k)
+			end
+		end
+	end
+end
+
+local OnEnter = function(self)
+	for _, fs in pairs(self.__mousetags) do
+		fs:SetAlpha(1)
+	end
+end
+
+local OnLeave = function(self)
+	for _, fs in pairs(self.__mousetags) do
+		fs:SetAlpha(0)
+	end
+end
+
+local tagPool = {}
+local funcPool = {}
+local tmp = {}
+local escapeSequences = {
+	["||c"] = "|c",
+	["||r"] = "|r",
+	["||T"] = "|T",
+	["||t"] = "|t",
+}
+
+local Tag = function(self, fs, tagstr)
+	if(not fs or not tagstr) then return end
+
+	if(not self.__tags) then
+		self.__tags = {}
+		self.__mousetags = {}
+		tinsert(self.__elements, OnShow)
+	else
+		-- Since people ignore everything that's good practice - unregister the tag
+		-- if it already exists.
+		for _, tag in pairs(self.__tags) do
+			if(fs == tag) then
+				-- We don't need to remove it from the __tags table as Untag handles
+				-- that for us.
+				self:Untag(fs)
+			end
+		end
+	end
+
+	fs.parent = self
+
+	for escapeSequence, replacement in pairs(escapeSequences) do
+		while tagstr:find(escapeSequence) do
+			tagstr = tagstr:gsub(escapeSequence, replacement)
+		end
+	end
+
+	if tagstr:find('%[mouseover%]') then
+		tinsert(self.__mousetags, fs)
+		fs:SetAlpha(0)
+		if not self.__HookFunc then
+			self:HookScript('OnEnter', OnEnter)
+			self:HookScript('OnLeave', OnLeave)
+			self.__HookFunc = true;
+		end
+		tagstr = tagstr:gsub('%[mouseover%]', '')
+	else
+		for index, fontString in pairs(self.__mousetags) do
+			if fontString == fs then
+				self.__mousetags[index] = nil;
+				fs:SetAlpha(1)
+			end
+		end
+	end
+
+	local containsOnUpdate
+	for tag in tagstr:gmatch(_PATTERN) do
+		if not tagEvents[tag:sub(2, -2)] then
+			containsOnUpdate = onUpdateDelay[tag:sub(2, -2)] or 0.15;
+		end
+	end
+
+	local func = tagPool[tagstr]
+	if(not func) then
+		local format, numTags = tagstr:gsub('%%', '%%%%'):gsub(_PATTERN, '%%s')
+		local args = {}
+
+		for bracket in tagstr:gmatch(_PATTERN) do
+			local tagFunc = funcPool[bracket] or tags[bracket:sub(2, -2)]
+
+			if(not tagFunc) then
+				local tagName, s, e = getTagName(bracket)
+				local tag = tags[tagName]
+				if(tag) then
+					s = s - 2
+					e = e + 2
+
+					if(s ~= 0 and e ~= 0) then
+						local pre = bracket:sub(2, s)
+						local ap = bracket:sub(e, -2)
+
+						tagFunc = function(u,r)
+							local str = tag(u,r)
+							if(str) then
+								return pre..str..ap
+							end
+						end
+					elseif(s ~= 0) then
+						local pre = bracket:sub(2, s)
+
+						tagFunc = function(u,r)
+							local str = tag(u,r)
+							if(str) then
+								return pre..str
+							end
+						end
+					elseif(e ~= 0) then
+						local ap = bracket:sub(e, -2)
+
+						tagFunc = function(u,r)
+							local str = tag(u,r)
+							if(str) then
+								return str..ap
+							end
+						end
+					end
+
+					funcPool[bracket] = tagFunc
+				end
+			end
+
+			if(tagFunc) then
+				tinsert(args, tagFunc)
+			else
+				numTags = -1
+				func = function(self)
+					return self:SetFormattedText('[error]')
+				end
+			end
+		end
+
+		if(numTags == 1) then
+			func = function(self)
+				local parent = self.parent
+				local realUnit
+				if(self.overrideUnit) then
+					realUnit = parent.realUnit
+				end
+
+				_ENV._COLORS = parent.colors
+				return self:SetFormattedText(
+					format,
+					args[1](parent.unit, realUnit) or ''
+				)
+			end
+		elseif(numTags == 2) then
+			func = function(self)
+				local parent = self.parent
+				local unit = parent.unit
+				local realUnit
+				if(self.overrideUnit) then
+					realUnit = parent.realUnit
+				end
+
+				_ENV._COLORS = parent.colors
+				return self:SetFormattedText(
+					format,
+					args[1](unit, realUnit) or '',
+					args[2](unit, realUnit) or ''
+				)
+			end
+		elseif(numTags == 3) then
+			func = function(self)
+				local parent = self.parent
+				local unit = parent.unit
+				local realUnit
+				if(self.overrideUnit) then
+					realUnit = parent.realUnit
+				end
+
+				_ENV._COLORS = parent.colors
+				return self:SetFormattedText(
+					format,
+					args[1](unit, realUnit) or '',
+					args[2](unit, realUnit) or '',
+					args[3](unit, realUnit) or ''
+				)
+			end
+		elseif numTags ~= -1 then
+			func = function(self)
+				local parent = self.parent
+				local unit = parent.unit
+				local realUnit
+				if(self.overrideUnit) then
+					realUnit = parent.realUnit
+				end
+
+				_ENV._COLORS = parent.colors
+				for i, func in next, args do
+					tmp[i] = func(unit, realUnit) or ''
+				end
+
+				-- We do 1, numTags because tmp can hold several unneeded variables.
+				return self:SetFormattedText(format, unpack(tmp, 1, numTags))
+			end
+		end
+
+		if numTags ~= -1 then
+			tagPool[tagstr] = func
+		end
+	end
+	fs.UpdateTag = func
+
+	local unit = self.unit
+	if((unit and unit:match'%w+target') or fs.frequentUpdates) or containsOnUpdate then
+		local timer
+		if(type(fs.frequentUpdates) == 'number') then
+			timer = fs.frequentUpdates
+		elseif containsOnUpdate then
+			timer = containsOnUpdate
+		else
+			timer = .5
+		end
+
+		if(not eventlessUnits[timer]) then eventlessUnits[timer] = {} end
+		tinsert(eventlessUnits[timer], fs)
+
+		createOnUpdate(timer)
+	else
+		RegisterEvents(fs, tagstr)
+	end
+
+	tinsert(self.__tags, fs)
+end
+
+local Untag = function(self, fs)
+	if(not fs) then return end
+
+	UnregisterEvents(fs)
+	for _, timers in next, eventlessUnits do
+		for k, fontstr in next, timers do
+			if(fs == fontstr) then
+				tremove(timers, k)
+			end
+		end
+	end
+
+	for k, fontstr in next, self.__tags do
+		if(fontstr == fs) then
+			tremove(self.__tags, k)
+		end
+	end
+
+	fs.UpdateTag = nil
+end
+
+oUF.Tags = {
+	Methods = tags,
+	Events = tagEvents,
+	SharedEvents = unitlessEvents,
+	OnUpdateThrottle = onUpdateDelay,
+}
+oUF:RegisterMetaFunction('Tag', Tag)
+oUF:RegisterMetaFunction('Untag', Untag)
diff --git a/SVUI_UnitFrames/libs/oUF/elements/threat.lua b/SVUI_UnitFrames/libs/oUF/elements/threat.lua
new file mode 100644
index 0000000..2a7f4cb
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/elements/threat.lua
@@ -0,0 +1,65 @@
+local parent, ns = ...
+local oUF = ns.oUF
+
+local Update = function(self, event, unit)
+	if(unit ~= self.unit) or not unit or not IsLoggedIn() then return end
+
+	local threat = self.Threat
+	if(threat.PreUpdate) then threat:PreUpdate(unit) end
+
+	local status = UnitThreatSituation(unit)
+
+	local r, g, b
+	if(status and status > 0) then
+		r, g, b = GetThreatStatusColor(status)
+
+		if threat:IsObjectType"Texture" then
+			threat:SetVertexColor(r, g, b)
+		end
+		threat:Show()
+	else
+		threat:Hide()
+	end
+
+	if(threat.PostUpdate) then
+		return threat:PostUpdate(unit, status, r, g, b)
+	end
+end
+
+local Path = function(self, ...)
+	return (self.Threat.Override or Update) (self, ...)
+end
+
+local ForceUpdate = function(element)
+	return Path(element.__owner, 'ForceUpdate', element.__owner.unit)
+end
+
+local Enable = function(self)
+	local threat = self.Threat
+	if(threat) then
+		threat.__owner = self
+		threat.ForceUpdate = ForceUpdate
+
+		self:RegisterEvent("UNIT_THREAT_SITUATION_UPDATE", Path)
+		self:RegisterEvent("UNIT_THREAT_LIST_UPDATE", Path)
+		threat:Hide()
+
+		if(threat:IsObjectType"Texture" and not threat:GetTexture()) then
+			threat:SetTexture[[Interface\Minimap\ObjectIcons]]
+			threat:SetTexCoord(1/4, 3/8, 0, 1/4)
+		end
+
+		return true
+	end
+end
+
+local Disable = function(self)
+	local threat = self.Threat
+	if(threat) then
+		self:UnregisterEvent("UNIT_THREAT_SITUATION_UPDATE", Path)
+		self:UnregisterEvent("UNIT_THREAT_LIST_UPDATE", Path)
+		threat:Hide()
+	end
+end
+
+oUF:AddElement('Threat', Path, Enable, Disable)
diff --git a/SVUI_UnitFrames/libs/oUF/events.lua b/SVUI_UnitFrames/libs/oUF/events.lua
new file mode 100644
index 0000000..51385cb
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/events.lua
@@ -0,0 +1,193 @@
+local parent, ns = ...
+local oUF = ns.oUF
+local Private = oUF.Private
+
+local argcheck = Private.argcheck
+local error = Private.error
+local frame_metatable = Private.frame_metatable
+
+local tinsert, tremove = table.insert, table.remove
+
+-- Events
+local RegisterEvent, UnregisterEvent, IsEventRegistered
+
+do
+	local eventFrame = CreateFrame("Frame")
+	local registry = {}
+	local framesForUnit = {}
+	local alternativeUnits = {
+		['player'] = 'vehicle',
+		['pet'] = 'player',
+		['party1'] = 'partypet1',
+		['party2'] = 'partypet2',
+		['party3'] = 'partypet3',
+		['party4'] = 'partypet4',
+	}
+
+	local RegisterFrameForUnit = function(frame, unit)
+		if not unit then return end
+		if framesForUnit[unit] then
+			framesForUnit[unit][frame] = true
+		else
+			framesForUnit[unit] = { [frame] = true }
+		end
+	end
+
+	local UnregisterFrameForUnit = function(frame, unit)
+		if not unit then return end
+		local frames = framesForUnit[unit]
+		if frames and frames[frame] then
+			frames[frame] = nil
+			if not next(frames) then
+				framesForUnit[unit] = nil
+			end
+		end
+	end
+
+	Private.UpdateUnits = function(frame, unit, realUnit)
+		if unit == realUnit then
+			realUnit = nil
+		end
+		if frame.unit ~= unit or frame.realUnit ~= realUnit then
+			if not frame:GetScript('OnUpdate') then
+				UnregisterFrameForUnit(frame, frame.unit)
+				UnregisterFrameForUnit(frame, frame.realUnit)
+				RegisterFrameForUnit(frame, unit)
+				RegisterFrameForUnit(frame, realUnit)
+			end
+
+			frame.alternativeUnit = alternativeUnits[unit]
+			frame.unit = unit
+			frame.realUnit = realUnit
+			frame.id = unit:match'^.-(%d+)'
+			return true
+		end
+	end
+
+	-- Holds true for every event, where the first (unit) argument should be ignored.
+	local sharedUnitEvents = {
+		UNIT_ENTERED_VEHICLE = true,
+		UNIT_EXITED_VEHICLE = true,
+		UNIT_PET = true,
+	}
+
+	eventFrame:SetScript('OnEvent', function(_, event, arg1, ...)
+		local listeners = registry[event]
+		if arg1 and not sharedUnitEvents[event] then
+			local frames = framesForUnit[arg1]
+			if frames then
+				for frame in next, frames do
+					if listeners[frame] and frame:IsVisible() then
+						frame[event](frame, event, arg1, ...)
+					end
+				end
+			end
+		else
+			for frame in next, listeners do
+				if frame:IsVisible() then
+					frame[event](frame, event, arg1, ...)
+				end
+			end
+		end
+	end)
+
+	function RegisterEvent(self, event, unitless)
+		if(unitless) then
+			sharedUnitEvents[event] = true
+		end
+
+		if not registry[event] then
+			registry[event] = { [self] = true }
+			eventFrame:RegisterEvent(event)
+		else
+			registry[event][self] = true
+		end
+	end
+
+	function UnregisterEvent(self, event)
+		if registry[event] then
+			registry[event][self] = nil
+			if not next(registry[event]) then
+				registry[event] = nil
+				eventFrame:UnregisterEvent(event)
+			end
+		end
+	end
+
+	function IsEventRegistered(self, event)
+		return registry[event] and registry[event][self]
+	end
+end
+
+local event_metatable = {
+	__call = function(funcs, self, ...)
+		for _, func in next, funcs do
+			func(self, ...)
+		end
+	end,
+}
+
+function frame_metatable.__index:RegisterEvent(event, func, unitless)
+	-- Block OnUpdate polled frames from registering events.
+	if(self.__eventless) then return end
+
+	argcheck(event, 2, 'string')
+
+	if(type(func) == 'string' and type(self[func]) == 'function') then
+		func = self[func]
+	end
+
+	local curev = self[event]
+	local kind = type(curev)
+	if(curev and func) then
+		if(kind == 'function' and curev ~= func) then
+			self[event] = setmetatable({curev, func}, event_metatable)
+		elseif(kind == 'table') then
+			for _, infunc in next, curev do
+				if(infunc == func) then return end
+			end
+
+			tinsert(curev, func)
+		end
+	elseif(IsEventRegistered(self, event)) then
+		return
+	else
+		if(type(func) == 'function') then
+			self[event] = func
+		elseif(not self[event]) then
+			return error("Style [%s] attempted to register event [%s] on unit [%s] with a handler that doesn't exist.", self.style, event, self.unit or 'unknown')
+		end
+
+		RegisterEvent(self, event, unitless)
+	end
+end
+
+function frame_metatable.__index:UnregisterEvent(event, func)
+	argcheck(event, 2, 'string')
+
+	local curev = self[event]
+	if(type(curev) == 'table' and func) then
+		for k, infunc in next, curev do
+			if(infunc == func) then
+				tremove(curev, k)
+
+				local n = #curev
+				if(n == 1) then
+					local _, handler = next(curev)
+					self[event] = handler
+				elseif(n == 0) then
+					UnregisterEvent(self, event)
+				end
+
+				break
+			end
+		end
+	elseif(curev == func) then
+		self[event] = nil
+		UnregisterEvent(self, event)
+	end
+end
+
+function frame_metatable.__index:IsEventRegistered(event)
+	return IsEventRegistered(self, event)
+end
diff --git a/SVUI_UnitFrames/libs/oUF/factory.lua b/SVUI_UnitFrames/libs/oUF/factory.lua
new file mode 100644
index 0000000..2e2f4cc
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/factory.lua
@@ -0,0 +1,49 @@
+local parent, ns = ...
+local oUF = ns.oUF
+local Private = oUF.Private
+
+local argcheck = Private.argcheck
+local tinsert = table.insert
+
+local _QUEUE = {}
+local _FACTORY = CreateFrame'Frame'
+_FACTORY:SetScript('OnEvent', function(self, event, ...)
+	return self[event](self, event, ...)
+end)
+
+_FACTORY:RegisterEvent'PLAYER_LOGIN'
+_FACTORY.active = true
+
+function _FACTORY:PLAYER_LOGIN()
+	if(not self.active) then return end
+
+	for _, func in next, _QUEUE do
+		func(oUF)
+	end
+
+	-- Avoid creating dupes.
+	wipe(_QUEUE)
+end
+
+function oUF:Factory(func)
+	argcheck(func, 2, 'function')
+
+	-- Call the function directly if we're active and logged in.
+	if(IsLoggedIn() and _FACTORY.active) then
+		return func(self)
+	else
+		tinsert(_QUEUE, func)
+	end
+end
+
+function oUF:EnableFactory()
+	_FACTORY.active = true
+end
+
+function oUF:DisableFactory()
+	_FACTORY.active = nil
+end
+
+function oUF:RunFactoryQueue()
+	_FACTORY:PLAYER_LOGIN()
+end
diff --git a/SVUI_UnitFrames/libs/oUF/finalize.lua b/SVUI_UnitFrames/libs/oUF/finalize.lua
new file mode 100644
index 0000000..9355d19
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/finalize.lua
@@ -0,0 +1,4 @@
+local parent, ns = ...
+
+-- It's named Private for a reason!
+ns.oUF.Private = nil
diff --git a/SVUI_UnitFrames/libs/oUF/init.lua b/SVUI_UnitFrames/libs/oUF/init.lua
new file mode 100644
index 0000000..46aef44
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/init.lua
@@ -0,0 +1,3 @@
+local parent, ns = ...
+ns.oUF = {}
+ns.oUF.Private = {}
diff --git a/SVUI_UnitFrames/libs/oUF/oUF_core.lua b/SVUI_UnitFrames/libs/oUF/oUF_core.lua
new file mode 100644
index 0000000..976bd44
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/oUF_core.lua
@@ -0,0 +1,1225 @@
+local parent, ns = ...
+
+local oUF = {}
+
+local global = GetAddOnMetadata(parent, 'X-oUF')
+local _VERSION = GetAddOnMetadata(parent, 'version')
+
+local upper = string.upper
+local split = string.split
+local tinsert, tremove = table.insert, table.remove
+
+local styles, style = {}
+local callback, objects = {}, {}
+
+local elements = {}
+local activeElements = {}
+
+--[[
+ /$$$$$$$          /$$                      /$$
+| $$__  $$        |__/                     | $$
+| $$  \ $$/$$$$$$  /$$ /$$    /$$/$$$$$$  /$$$$$$    /$$$$$$
+| $$$$$$$/$$__  $$| $$|  $$  /$$/____  $$|_  $$_/   /$$__  $$
+| $$____/ $$  \__/| $$ \  $$/$$/ /$$$$$$$  | $$    | $$$$$$$$
+| $$    | $$      | $$  \  $$$/ /$$__  $$  | $$ /$$| $$_____/
+| $$    | $$      | $$   \  $/ |  $$$$$$$  |  $$$$/|  $$$$$$$
+|__/    |__/      |__/    \_/   \_______/   \___/   \_______/
+--]]
+
+local Private = {}
+
+local match = string.match
+local format = string.format
+
+function Private.argcheck(value, num, ...)
+	assert(type(num) == 'number', "Bad argument #2 to 'argcheck' (number expected, got "..type(num)..")")
+
+	for i=1,select("#", ...) do
+		if type(value) == select(i, ...) then return end
+	end
+
+	local types = strjoin(", ", ...)
+	local name = match(debugstack(2,2,0), ": in function [`<](.-)['>]")
+	error(("Bad argument #%d to '%s' (%s expected, got %s"):format(num, name, types, type(value)), 3)
+end
+
+function Private.print(...)
+	print("|cff33ff99oUF:|r", ...)
+end
+
+function Private.error(...)
+	Private.print("|cffff0000Error:|r "..format(...))
+end
+
+local argcheck = Private.argcheck
+local error = Private.error
+local print = Private.print
+local frame_metatable = Private.frame_metatable
+
+--[[
+           /$$   /$$ /$$$$$$$$
+          | $$  | $$| $$_____/
+  /$$$$$$ | $$  | $$| $$
+ /$$__  $$| $$  | $$| $$$$$
+| $$  \ $$| $$  | $$| $$__/
+| $$  | $$| $$  | $$| $$
+|  $$$$$$/|  $$$$$$/| $$
+ \______/  \______/ |__/
+--]]
+
+-- updating of "invalid" units.
+local enableTargetUpdate = function(object)
+	object.onUpdateFrequency = object.onUpdateFrequency or .5
+	object.__eventless = true
+
+	local total = 0
+	object:SetScript('OnUpdate', function(self, elapsed)
+		if(not self.unit) then
+			return
+		elseif(total > self.onUpdateFrequency) then
+			self:UpdateAllElements'OnUpdate'
+			total = 0
+		end
+
+		total = total + elapsed
+	end)
+end
+Private.enableTargetUpdate = enableTargetUpdate
+
+local updateActiveUnit = function(self, event, unit)
+	-- Calculate units to work with
+	local realUnit, modUnit = SecureButton_GetUnit(self), SecureButton_GetModifiedUnit(self)
+
+	-- _GetUnit() doesn't rewrite playerpet -> pet like _GetModifiedUnit does.
+	if(realUnit == 'playerpet') then
+		realUnit = 'pet'
+	elseif(realUnit == 'playertarget') then
+		realUnit = 'target'
+	end
+
+	if(modUnit == "pet" and realUnit ~= "pet") then
+		modUnit = "vehicle"
+	end
+
+	-- Drop out if the event unit doesn't match any of the frame units.
+	if(not UnitExists(modUnit) or unit and unit ~= realUnit and unit ~= modUnit) then return end
+
+	-- Change the active unit and run a full update.
+	if Private.UpdateUnits(self, modUnit, realUnit) then
+		self:UpdateAllElements('RefreshUnit')
+
+		return true
+	end
+end
+
+local iterateChildren = function(...)
+	for l = 1, select("#", ...) do
+		local obj = select(l, ...)
+
+		if(type(obj) == 'table' and obj.isChild) then
+			updateActiveUnit(obj, "iterateChildren")
+		end
+	end
+end
+
+local OnAttributeChanged = function(self, name, value)
+	if(name == "unit" and value) then
+		if(self.hasChildren) then
+			iterateChildren(self:GetChildren())
+		end
+
+		if(not self:GetAttribute'oUF-onlyProcessChildren') then
+			updateActiveUnit(self, "OnAttributeChanged")
+		end
+	end
+end
+
+local frame_metatable = {
+	__index = CreateFrame"Button"
+}
+Private.frame_metatable = frame_metatable
+
+for k, v in pairs{
+	UpdateElement = function(self, name)
+		local unit = self.unit
+		if(not unit or not UnitExists(unit)) then return end
+
+		local element = elements[name]
+		if(not element or not self:IsElementEnabled(name) or not activeElements[self]) then return end
+		if(element.update) then
+			element.update(self, 'OnShow', unit)
+		end
+	end,
+
+	EnableElement = function(self, name, unit)
+		argcheck(name, 2, 'string')
+		argcheck(unit, 3, 'string', 'nil')
+
+		local element = elements[name]
+
+
+		if(not element or self:IsElementEnabled(name) or not activeElements[self]) then return end
+
+		if(element.enable(self, unit or self.unit)) then
+			activeElements[self][name] = true
+
+			if(element.update) then
+				tinsert(self.__elements, element.update)
+			end
+		end
+	end,
+
+	DisableElement = function(self, name)
+		argcheck(name, 2, 'string')
+
+		local enable = self:IsElementEnabled(name)
+		if(not enable) then return end
+
+		local update = elements[name].update
+		for k, func in next, self.__elements do
+			if(func == update) then
+				tremove(self.__elements, k)
+				break
+			end
+		end
+
+		activeElements[self][name] = nil
+
+		-- We need to run a new update cycle in-case we knocked ourself out of sync.
+		-- The main reason we do this is to make sure the full update is completed
+		-- if an element for some reason removes itself _during_ the update
+		-- progress.
+		self:UpdateAllElements('DisableElement', name)
+
+		return elements[name].disable(self)
+	end,
+
+	IsElementEnabled = function(self, name)
+		argcheck(name, 2, 'string')
+
+		local element = elements[name]
+		if(not element) then return end
+
+		local active = activeElements[self]
+		return active and active[name]
+	end,
+
+	Enable = RegisterUnitWatch,
+	Disable = function(self)
+		UnregisterUnitWatch(self)
+		self:Hide()
+	end,
+
+	UpdateAllElements = function(self, event)
+		local unit = self.unit
+		if(not unit or not UnitExists(unit)) then return end
+
+		if(self.PreUpdate) then
+			self:PreUpdate(event)
+		end
+
+		for _, func in next, self.__elements do
+			func(self, event, unit)
+		end
+
+		if(self.PostUpdate) then
+			self:PostUpdate(event)
+		end
+	end,
+} do
+	frame_metatable.__index[k] = v
+end
+
+local OnShow = function(self)
+	if(not updateActiveUnit(self, 'OnShow')) then
+		return self:UpdateAllElements'OnShow'
+	end
+end
+
+local UpdatePet = function(self, event, unit)
+	local petUnit
+	if(unit == 'target') then
+		return
+	elseif(unit == 'player') then
+		petUnit = 'pet'
+	else
+		-- Convert raid26 -> raidpet26
+		petUnit = unit:gsub('^(%a+)(%d+)', '%1pet%2')
+	end
+
+	if(self.unit ~= petUnit) then return end
+	if(not updateActiveUnit(self, event)) then
+		return self:UpdateAllElements(event)
+	end
+end
+
+local initObject = function(unit, style, styleFunc, header, ...)
+	local num = select('#', ...)
+	for i=1, num do
+		local object = select(i, ...)
+		local objectUnit = object:GetAttribute'oUF-guessUnit' or unit
+		local suffix = object:GetAttribute'unitsuffix'
+
+		object.__elements = {}
+		object.style = style
+		object = setmetatable(object, frame_metatable)
+
+		-- Expose the frame through oUF.objects.
+		tinsert(objects, object)
+
+		-- We have to force update the frames when PEW fires.
+		object:RegisterEvent("PLAYER_ENTERING_WORLD", object.UpdateAllElements)
+
+		-- Handle the case where someone has modified the unitsuffix attribute in
+		-- oUF-initialConfigFunction.
+		if(suffix and objectUnit and not objectUnit:match(suffix)) then
+			objectUnit = objectUnit .. suffix
+		end
+
+		if(not (suffix == 'target' or objectUnit and objectUnit:match'target')) then
+			object:RegisterEvent('UNIT_ENTERED_VEHICLE', updateActiveUnit)
+			object:RegisterEvent('UNIT_EXITED_VEHICLE', updateActiveUnit)
+
+			-- We don't need to register UNIT_PET for the player unit. We register it
+			-- mainly because UNIT_EXITED_VEHICLE and UNIT_ENTERED_VEHICLE doesn't always
+			-- have pet information when they fire for party and raid units.
+			if(objectUnit ~= 'player') then
+				object:RegisterEvent('UNIT_PET', UpdatePet)
+			end
+		end
+
+		if(not header) then
+			-- No header means it's a frame created through :Spawn().
+			object:SetAttribute("*type1", "target")
+			object:SetAttribute('*type2', 'togglemenu')
+
+			-- No need to enable this for *target frames.
+			if(not (unit:match'target' or suffix == 'target')) then
+				object:SetAttribute('toggleForVehicle', true)
+			end
+
+			-- Other boss and target units are handled by :HandleUnit().
+			if(suffix == 'target') then
+				enableTargetUpdate(object)
+			else
+				oUF:HandleUnit(object)
+			end
+		else
+			-- Used to update frames when they change position in a group.
+			object:RegisterEvent('GROUP_ROSTER_UPDATE', object.UpdateAllElements)
+
+			if(num > 1) then
+				if(object:GetParent() == header) then
+					object.hasChildren = true
+				else
+					object.isChild = true
+				end
+			end
+
+			if(suffix == 'target') then
+				enableTargetUpdate(object)
+			end
+		end
+
+		Private.UpdateUnits(object, objectUnit)
+
+		styleFunc(object, objectUnit, not header)
+
+		object:SetScript("OnAttributeChanged", OnAttributeChanged)
+		object:SetScript("OnShow", OnShow)
+
+		activeElements[object] = {}
+		for element in next, elements do
+			object:EnableElement(element, objectUnit)
+		end
+
+		for _, func in next, callback do
+			func(object)
+		end
+
+		-- Make Clique happy
+		_G.ClickCastFrames = ClickCastFrames or {}
+		ClickCastFrames[object] = true
+	end
+end
+
+local walkObject = function(object, unit)
+	local parent = object:GetParent()
+	local style = parent.style or style
+	local styleFunc = styles[style]
+
+	local header = parent:GetAttribute'oUF-headerType' and parent
+
+	-- Check if we should leave the main frame blank.
+	if(object:GetAttribute'oUF-onlyProcessChildren') then
+		object.hasChildren = true
+		object:SetScript('OnAttributeChanged', OnAttributeChanged)
+		return initObject(unit, style, styleFunc, header, object:GetChildren())
+	end
+
+	return initObject(unit, style, styleFunc, header, object, object:GetChildren())
+end
+
+function oUF:RegisterInitCallback(func)
+	tinsert(callback, func)
+end
+
+function oUF:RegisterMetaFunction(name, func)
+	argcheck(name, 2, 'string')
+	argcheck(func, 3, 'function', 'table')
+
+	if(frame_metatable.__index[name]) then
+		return
+	end
+
+	frame_metatable.__index[name] = func
+end
+
+function oUF:RegisterStyle(name, func)
+	argcheck(name, 2, 'string')
+	argcheck(func, 3, 'function', 'table')
+
+	if(styles[name]) then return error("Style [%s] already registered.", name) end
+	if(not style) then style = name end
+
+	styles[name] = func
+end
+
+function oUF:SetActiveStyle(name)
+	argcheck(name, 2, 'string')
+	if(not styles[name]) then return error("Style [%s] does not exist.", name) end
+
+	style = name
+end
+
+do
+	local function iter(_, n)
+		-- don't expose the style functions.
+		return (next(styles, n))
+	end
+
+	function oUF.IterateStyles()
+		return iter, nil, nil
+	end
+end
+
+local getCondition
+do
+	local conditions = {
+		raid40 = '[@raid26,exists] show;',
+		raid25 = '[@raid11,exists] show;',
+		raid10 = '[@raid6,exists] show;',
+		raid = '[group:raid] show;',
+		party = '[group:party,nogroup:raid] show;',
+		solo = '[@player,exists,nogroup:party] show;',
+	}
+
+	function getCondition(...)
+		local cond = ''
+
+		for i=1, select('#', ...) do
+			local short = select(i, ...)
+
+			local condition = conditions[short]
+			if(condition) then
+				cond = cond .. condition
+			end
+		end
+
+		return cond .. 'hide'
+	end
+end
+
+local generateName = function(unit, ...)
+	local name = 'oUF_' .. style:gsub('[^%a%d_]+', '')
+
+	local raid, party, groupFilter
+	for i=1, select('#', ...), 2 do
+		local att, val = select(i, ...)
+		if(att == 'showRaid') then
+			raid = true
+		elseif(att == 'showParty') then
+			party = true
+		elseif(att == 'groupFilter') then
+			groupFilter = val
+		end
+	end
+
+	local append
+	if(raid) then
+		if(groupFilter) then
+			if(type(groupFilter) == 'number' and groupFilter > 0) then
+				append = groupFilter
+			elseif(groupFilter:match'TANK') then
+				append = 'MainTank'
+			elseif(groupFilter:match'ASSIST') then
+				append = 'MainAssist'
+			else
+				local _, count = groupFilter:gsub(',', '')
+				if(count == 0) then
+					append = 'Raid' .. groupFilter
+				else
+					append = 'Raid'
+				end
+			end
+		else
+			append = 'Raid'
+		end
+	elseif(party) then
+		append = 'Party'
+	elseif(unit) then
+		append = unit:gsub("^%l", upper)
+	end
+
+	if(append) then
+		name = name .. append
+	end
+
+	-- Change oUF_LilyRaidRaid into oUF_LilyRaid
+	name = name:gsub('(%u%l+)([%u%l]*)%1', '%1')
+	-- Change oUF_LilyTargettarget into oUF_LilyTargetTarget
+	name = name:gsub('t(arget)', 'T%1')
+
+	local base = name
+	local i = 2
+	while(_G[name]) do
+		name = base .. i
+		i = i + 1
+	end
+
+	return name
+end
+
+do
+	local styleProxy = function(self, frame, ...)
+		return walkObject(_G[frame])
+	end
+
+	-- There has to be an easier way to do this.
+	local initialConfigFunction = [[
+		local header = self:GetParent()
+		local frames = table.new()
+		table.insert(frames, self)
+		self:GetChildList(frames)
+		for i=1, #frames do
+			local frame = frames[i]
+			local unit
+			-- There's no need to do anything on frames with onlyProcessChildren
+			if(not frame:GetAttribute'oUF-onlyProcessChildren') then
+				RegisterUnitWatch(frame)
+
+				-- Attempt to guess what the header is set to spawn.
+				local groupFilter = header:GetAttribute'groupFilter'
+
+				if(type(groupFilter) == 'string' and groupFilter:match('MAIN[AT]')) then
+					local role = groupFilter:match('MAIN([AT])')
+					if(role == 'T') then
+						unit = 'maintank'
+					else
+						unit = 'mainassist'
+					end
+				elseif(header:GetAttribute'showRaid') then
+					unit = 'raid'
+				elseif(header:GetAttribute'showParty') then
+					unit = 'party'
+				end
+
+				local headerType = header:GetAttribute'oUF-headerType'
+				local suffix = frame:GetAttribute'unitsuffix'
+				if(unit and suffix) then
+					if(headerType == 'pet' and suffix == 'target') then
+						unit = unit .. headerType .. suffix
+					else
+						unit = unit .. suffix
+					end
+				elseif(unit and headerType == 'pet') then
+					unit = unit .. headerType
+				end
+
+				frame:SetAttribute('*type1', 'target')
+				frame:SetAttribute('*type2', 'togglemenu')
+				frame:SetAttribute('toggleForVehicle', true)
+				frame:SetAttribute('oUF-guessUnit', unit)
+			end
+
+			local body = header:GetAttribute'oUF-initialConfigFunction'
+			if(body) then
+				frame:Run(body, unit)
+			end
+		end
+
+		header:CallMethod('styleFunction', self:GetName())
+
+		local clique = header:GetFrameRef("clickcast_header")
+		if(clique) then
+			clique:SetAttribute("clickcast_button", self)
+			clique:RunAttribute("clickcast_register")
+		end
+	]]
+
+	function oUF:SpawnHeader(overrideName, template, visibility, ...)
+		if(not style) then return error("Unable to create frame. No styles have been registered.") end
+
+		template = (template or 'SecureGroupHeaderTemplate')
+
+		local isPetHeader = template:match'PetHeader'
+		local name = overrideName or generateName(nil, ...)
+		local header = CreateFrame('Frame', name, UIParent, template)
+
+		header:SetAttribute("template", "oUF_ClickCastUnitTemplate")
+		for i=1, select("#", ...), 2 do
+			local att, val = select(i, ...)
+			if(not att) then break end
+			header:SetAttribute(att, val)
+		end
+
+		header.style = style
+		header.styleFunction = styleProxy
+
+		-- We set it here so layouts can't directly override it.
+		header:SetAttribute('initialConfigFunction', initialConfigFunction)
+		header:SetAttribute('oUF-headerType', isPetHeader and 'pet' or 'group')
+
+		if(Clique) then
+			SecureHandlerSetFrameRef(header, 'clickcast_header', Clique.header)
+		end
+
+		if(header:GetAttribute'showParty') then
+			self:DisableBlizzard'party'
+		end
+
+		if(visibility) then
+			local type, list = split(' ', visibility, 2)
+			if(list and type == 'custom') then
+				RegisterAttributeDriver(header, 'state-visibility', list)
+			else
+				local condition = getCondition(split(',', visibility))
+				RegisterAttributeDriver(header, 'state-visibility', condition)
+			end
+		end
+
+		return header
+	end
+end
+
+function oUF:Spawn(unit, overrideName, overrideTemplate)
+	argcheck(unit, 2, 'string')
+	if(not style) then return error("Unable to create frame. No styles have been registered.") end
+
+	unit = unit:lower()
+
+	local name = overrideName or generateName(unit)
+	local object = CreateFrame("Button", name, UIParent, overrideTemplate or "SecureUnitButtonTemplate")
+	Private.UpdateUnits(object, unit)
+
+	self:DisableBlizzard(unit)
+	walkObject(object, unit)
+
+	object:SetAttribute("unit", unit)
+	RegisterUnitWatch(object)
+
+	return object
+end
+
+function oUF:AddElement(name, update, enable, disable)
+	argcheck(name, 2, 'string')
+	argcheck(update, 3, 'function', 'nil')
+	argcheck(enable, 4, 'function', 'nil')
+	argcheck(disable, 5, 'function', 'nil')
+
+	if(elements[name]) then return error('Element [%s] is already registered.', name) end
+	elements[name] = {
+		update = update;
+		enable = enable;
+		disable = disable;
+	}
+end
+
+oUF.version = _VERSION
+oUF.objects = objects
+
+if(global) then
+	if(parent ~= 'oUF' and global == 'oUF') then
+		error("%s is doing it wrong and setting its global to oUF.", parent)
+	else
+		_G[global] = oUF
+	end
+end
+
+
+--[[
+ /$$$$$$$$                             /$$
+| $$_____/                            | $$
+| $$    /$$    /$$/$$$$$$  /$$$$$$$  /$$$$$$   /$$$$$$$
+| $$$$$|  $$  /$$/$$__  $$| $$__  $$|_  $$_/  /$$_____/
+| $$__/ \  $$/$$/ $$$$$$$$| $$  \ $$  | $$   |  $$$$$$
+| $$     \  $$$/| $$_____/| $$  | $$  | $$ /$$\____  $$
+| $$$$$$$$\  $/ |  $$$$$$$| $$  | $$  |  $$$$//$$$$$$$/
+|________/ \_/   \_______/|__/  |__/   \___/ |_______/
+--]]
+
+local RegisterEvent, UnregisterEvent, IsEventRegistered
+
+do
+	local eventFrame = CreateFrame("Frame")
+	local registry = {}
+	local framesForUnit = {}
+	local alternativeUnits = {
+		['player'] = 'vehicle',
+		['pet'] = 'player',
+		['party1'] = 'partypet1',
+		['party2'] = 'partypet2',
+		['party3'] = 'partypet3',
+		['party4'] = 'partypet4',
+	}
+
+	local RegisterFrameForUnit = function(frame, unit)
+		if not unit then return end
+		if framesForUnit[unit] then
+			framesForUnit[unit][frame] = true
+		else
+			framesForUnit[unit] = { [frame] = true }
+		end
+	end
+
+	local UnregisterFrameForUnit = function(frame, unit)
+		if not unit then return end
+		local frames = framesForUnit[unit]
+		if frames and frames[frame] then
+			frames[frame] = nil
+			if not next(frames) then
+				framesForUnit[unit] = nil
+			end
+		end
+	end
+
+	Private.UpdateUnits = function(frame, unit, realUnit)
+		if unit == realUnit then
+			realUnit = nil
+		end
+		if frame.unit ~= unit or frame.realUnit ~= realUnit then
+			if not frame:GetScript('OnUpdate') then
+				UnregisterFrameForUnit(frame, frame.unit)
+				UnregisterFrameForUnit(frame, frame.realUnit)
+				RegisterFrameForUnit(frame, unit)
+				RegisterFrameForUnit(frame, realUnit)
+			end
+
+			frame.alternativeUnit = alternativeUnits[unit]
+			frame.unit = unit
+			frame.realUnit = realUnit
+			frame.id = unit:match'^.-(%d+)'
+			return true
+		end
+	end
+
+	-- Holds true for every event, where the first (unit) argument should be ignored.
+	local sharedUnitEvents = {
+		UNIT_ENTERED_VEHICLE = true,
+		UNIT_EXITED_VEHICLE = true,
+		UNIT_PET = true,
+	}
+
+	eventFrame:SetScript('OnEvent', function(_, event, arg1, ...)
+		local listeners = registry[event]
+		if arg1 and not sharedUnitEvents[event] then
+			local frames = framesForUnit[arg1]
+			if frames then
+				for frame in next, frames do
+					if listeners[frame] and frame:IsVisible() then
+						frame[event](frame, event, arg1, ...)
+					end
+				end
+			end
+		else
+			for frame in next, listeners do
+				if frame:IsVisible() then
+					frame[event](frame, event, arg1, ...)
+				end
+			end
+		end
+	end)
+
+	function RegisterEvent(self, event, unitless)
+		if(unitless) then
+			sharedUnitEvents[event] = true
+		end
+
+		if not registry[event] then
+			registry[event] = { [self] = true }
+			eventFrame:RegisterEvent(event)
+		else
+			registry[event][self] = true
+		end
+	end
+
+	function UnregisterEvent(self, event)
+		if registry[event] then
+			registry[event][self] = nil
+			if not next(registry[event]) then
+				registry[event] = nil
+				eventFrame:UnregisterEvent(event)
+			end
+		end
+	end
+
+	function IsEventRegistered(self, event)
+		return registry[event] and registry[event][self]
+	end
+end
+
+local event_metatable = {
+	__call = function(funcs, self, ...)
+		for _, func in next, funcs do
+			func(self, ...)
+		end
+	end,
+}
+
+function frame_metatable.__index:RegisterEvent(event, func, unitless)
+	-- Block OnUpdate polled frames from registering events.
+	if(self.__eventless) then return end
+
+	argcheck(event, 2, 'string')
+
+	if(type(func) == 'string' and type(self[func]) == 'function') then
+		func = self[func]
+	end
+
+	local curev = self[event]
+	local kind = type(curev)
+	if(curev and func) then
+		if(kind == 'function' and curev ~= func) then
+			self[event] = setmetatable({curev, func}, event_metatable)
+		elseif(kind == 'table') then
+			for _, infunc in next, curev do
+				if(infunc == func) then return end
+			end
+
+			tinsert(curev, func)
+		end
+	elseif(IsEventRegistered(self, event)) then
+		return
+	else
+		if(type(func) == 'function') then
+			self[event] = func
+		elseif(not self[event]) then
+			return error("Style [%s] attempted to register event [%s] on unit [%s] with a handler that doesn't exist.", self.style, event, self.unit or 'unknown')
+		end
+
+		RegisterEvent(self, event, unitless)
+	end
+end
+
+function frame_metatable.__index:UnregisterEvent(event, func)
+	argcheck(event, 2, 'string')
+
+	local curev = self[event]
+	if(type(curev) == 'table' and func) then
+		for k, infunc in next, curev do
+			if(infunc == func) then
+				tremove(curev, k)
+
+				local n = #curev
+				if(n == 1) then
+					local _, handler = next(curev)
+					self[event] = handler
+				elseif(n == 0) then
+					UnregisterEvent(self, event)
+				end
+
+				break
+			end
+		end
+	elseif(curev == func) then
+		self[event] = nil
+		UnregisterEvent(self, event)
+	end
+end
+
+function frame_metatable.__index:IsEventRegistered(event)
+	return IsEventRegistered(self, event)
+end
+
+--[[
+ /$$$$$$$$                  /$$
+| $$_____/                 | $$
+| $$    /$$$$$$   /$$$$$$$/$$$$$$    /$$$$$$   /$$$$$$  /$$   /$$
+| $$$$$|____  $$ /$$_____/_  $$_/   /$$__  $$ /$$__  $$| $$  | $$
+| $$__/ /$$$$$$$| $$       | $$    | $$  \ $$| $$  \__/| $$  | $$
+| $$   /$$__  $$| $$       | $$ /$$| $$  | $$| $$      | $$  | $$
+| $$  |  $$$$$$$|  $$$$$$$ |  $$$$/|  $$$$$$/| $$      |  $$$$$$$
+|__/   \_______/ \_______/  \___/   \______/ |__/       \____  $$
+                                                        /$$  | $$
+                                                       |  $$$$$$/
+                                                        \______/
+--]]
+
+local tinsert = table.insert
+
+local _QUEUE = {}
+local _FACTORY = CreateFrame'Frame'
+_FACTORY:SetScript('OnEvent', function(self, event, ...)
+	return self[event](self, event, ...)
+end)
+
+_FACTORY:RegisterEvent'PLAYER_LOGIN'
+_FACTORY.active = true
+
+function _FACTORY:PLAYER_LOGIN()
+	if(not self.active) then return end
+
+	for _, func in next, _QUEUE do
+		func(oUF)
+	end
+
+	-- Avoid creating dupes.
+	wipe(_QUEUE)
+end
+
+function oUF:Factory(func)
+	argcheck(func, 2, 'function')
+
+	-- Call the function directly if we're active and logged in.
+	if(IsLoggedIn() and _FACTORY.active) then
+		return func(self)
+	else
+		tinsert(_QUEUE, func)
+	end
+end
+
+function oUF:EnableFactory()
+	_FACTORY.active = true
+end
+
+function oUF:DisableFactory()
+	_FACTORY.active = nil
+end
+
+function oUF:RunFactoryQueue()
+	_FACTORY:PLAYER_LOGIN()
+end
+
+--[[
+ /$$$$$$$  /$$ /$$                                             /$$
+| $$__  $$| $$|__/                                            | $$
+| $$  \ $$| $$ /$$ /$$$$$$$$/$$$$$$$$  /$$$$$$   /$$$$$$  /$$$$$$$
+| $$$$$$$ | $$| $$|____ /$$/____ /$$/ |____  $$ /$$__  $$/$$__  $$
+| $$__  $$| $$| $$   /$$$$/   /$$$$/   /$$$$$$$| $$  \__/ $$  | $$
+| $$  \ $$| $$| $$  /$$__/   /$$__/   /$$__  $$| $$     | $$  | $$
+| $$$$$$$/| $$| $$ /$$$$$$$$/$$$$$$$$|  $$$$$$$| $$     |  $$$$$$$
+|_______/ |__/|__/|________/________/ \_______/|__/      \_______/
+--]]
+
+local hiddenParent = CreateFrame("Frame")
+hiddenParent:Hide()
+
+local HandleFrame = function(baseName)
+	local frame
+	if(type(baseName) == 'string') then
+		frame = _G[baseName]
+	else
+		frame = baseName
+	end
+
+	if(frame) then
+		frame:UnregisterAllEvents()
+		frame:Hide()
+
+		-- Keep frame hidden without causing taint
+		frame:SetParent(hiddenParent)
+
+		local health = frame.healthbar
+		if(health) then
+			health:UnregisterAllEvents()
+		end
+
+		local power = frame.manabar
+		if(power) then
+			power:UnregisterAllEvents()
+		end
+
+		local spell = frame.spellbar
+		if(spell) then
+			spell:UnregisterAllEvents()
+		end
+
+		local altpowerbar = frame.powerBarAlt
+		if(altpowerbar) then
+			altpowerbar:UnregisterAllEvents()
+		end
+	end
+end
+
+function oUF:DisableBlizzard(unit)
+	if(not unit) or InCombatLockdown() then return end
+
+	if(unit == 'player') then
+		HandleFrame(PlayerFrame)
+
+		-- For the damn vehicle support:
+		PlayerFrame:RegisterUnitEvent('UNIT_ENTERING_VEHICLE', "player")
+		PlayerFrame:RegisterUnitEvent('UNIT_ENTERED_VEHICLE', "player")
+		PlayerFrame:RegisterUnitEvent('UNIT_EXITING_VEHICLE', "player")
+		PlayerFrame:RegisterUnitEvent('UNIT_EXITED_VEHICLE', "player")
+
+		-- User placed frames don't animate
+		PlayerFrame:SetUserPlaced(true)
+		PlayerFrame:SetDontSavePosition(true)
+	elseif(unit == 'pet') then
+		HandleFrame(PetFrame)
+	elseif(unit == 'target') then
+		HandleFrame(TargetFrame)
+		HandleFrame(ComboFrame)
+	elseif(unit == 'focus') then
+		HandleFrame(FocusFrame)
+		HandleFrame(TargetofFocusFrame)
+	elseif(unit == 'targettarget') then
+		HandleFrame(TargetFrameToT)
+	elseif(unit:match'(boss)%d?$' == 'boss') then
+		local id = unit:match'boss(%d)'
+		if(id) then
+			HandleFrame('Boss' .. id .. 'TargetFrame')
+		else
+			for i=1, 4 do
+				HandleFrame(('Boss%dTargetFrame'):format(i))
+			end
+		end
+	elseif(unit:match'(party)%d?$' == 'party') then
+		local id = unit:match'party(%d)'
+		if(id) then
+			HandleFrame('PartyMemberFrame' .. id)
+		else
+			for i=1, 4 do
+				HandleFrame(('PartyMemberFrame%d'):format(i))
+			end
+		end
+	elseif(unit:match'(arena)%d?$' == 'arena') then
+		local id = unit:match'arena(%d)'
+		if(id) then
+			HandleFrame('ArenaEnemyFrame' .. id)
+		else
+			for i=1, 4 do
+				HandleFrame(('ArenaEnemyFrame%d'):format(i))
+			end
+		end
+
+		-- Blizzard_ArenaUI should not be loaded
+		Arena_LoadUI = function() end
+		SetCVar('showArenaEnemyFrames', '0', 'SHOW_ARENA_ENEMY_FRAMES_TEXT')
+	end
+end
+
+--[[
+ /$$   /$$           /$$   /$$
+| $$  | $$          |__/  | $$
+| $$  | $$ /$$$$$$$  /$$ /$$$$$$   /$$$$$$$
+| $$  | $$| $$__  $$| $$|_  $$_/  /$$_____/
+| $$  | $$| $$  \ $$| $$  | $$   |  $$$$$$
+| $$  | $$| $$  | $$| $$  | $$ /$$\____  $$
+|  $$$$$$/| $$  | $$| $$  |  $$$$//$$$$$$$/
+ \______/ |__/  |__/|__/   \___/ |_______/
+--]]
+
+local enableTargetUpdate = Private.enableTargetUpdate
+
+-- Handles unit specific actions.
+function oUF:HandleUnit(object, unit)
+	local unit = object.unit or unit
+
+	if(unit == 'target') then
+		object:RegisterEvent('PLAYER_TARGET_CHANGED', object.UpdateAllElements)
+	elseif(unit == 'mouseover') then
+		object:RegisterEvent('UPDATE_MOUSEOVER_UNIT', object.UpdateAllElements)
+	elseif(unit == 'focus') then
+		object:RegisterEvent('PLAYER_FOCUS_CHANGED', object.UpdateAllElements)
+	elseif(unit:match'(boss)%d?$' == 'boss') then
+		object:RegisterEvent('INSTANCE_ENCOUNTER_ENGAGE_UNIT', object.UpdateAllElements, true)
+		object:RegisterEvent('UNIT_TARGETABLE_CHANGED', object.UpdateAllElements)
+	elseif(unit:match'%w+target') then
+		enableTargetUpdate(object)
+	end
+end
+
+--[[
+  /$$$$$$            /$$
+ /$$__  $$          | $$
+| $$  \__/  /$$$$$$ | $$  /$$$$$$   /$$$$$$  /$$$$$$$
+| $$       /$$__  $$| $$ /$$__  $$ /$$__  $$/$$_____/
+| $$      | $$  \ $$| $$| $$  \ $$| $$  \__/  $$$$$$
+| $$    $$| $$  | $$| $$| $$  | $$| $$      \____  $$
+|  $$$$$$/|  $$$$$$/| $$|  $$$$$$/| $$      /$$$$$$$/
+ \______/  \______/ |__/ \______/ |__/     |_______/
+--]]
+
+
+
+local colors = {
+	smooth = {
+		1, 0, 0,
+		1, 1, 0,
+		0, 1, 0
+	},
+	disconnected = {.6, .6, .6},
+	tapped = {.6,.6,.6},
+	class = {},
+	reaction = {},
+}
+
+-- We do this because people edit the vars directly, and changing the default
+-- globals makes SPICE FLOW!
+local customClassColors = function()
+	if(CUSTOM_CLASS_COLORS) then
+		local updateColors = function()
+			for eclass, color in next, CUSTOM_CLASS_COLORS do
+				colors.class[eclass] = {color.r, color.g, color.b}
+			end
+
+			for _, obj in next, oUF.objects do
+				obj:UpdateAllElements("CUSTOM_CLASS_COLORS")
+			end
+		end
+
+		updateColors()
+		CUSTOM_CLASS_COLORS:RegisterCallback(updateColors)
+
+		return true
+	end
+end
+if not customClassColors() then
+	for eclass, color in next, RAID_CLASS_COLORS do
+		colors.class[eclass] = {color.r, color.g, color.b}
+	end
+
+	local f = CreateFrame("Frame")
+	f:RegisterEvent("ADDON_LOADED")
+	f:SetScript("OnEvent", function()
+		if customClassColors() then
+			f:UnregisterEvent("ADDON_LOADED")
+			f:SetScript("OnEvent", nil)
+		end
+	end)
+end
+
+for eclass, color in next, FACTION_BAR_COLORS do
+	colors.reaction[eclass] = {color.r, color.g, color.b}
+end
+
+local function ColorsAndPercent(a, b, ...)
+	if a <= 0 or b == 0 then
+		return nil, ...
+	elseif a >= b then
+		return nil, select(select('#', ...) - 2, ...)
+	end
+
+	local num = select('#', ...) / 3
+	local segment, relperc = math.modf((a/b)*(num-1))
+	return relperc, select((segment*3)+1, ...)
+end
+
+-- http://www.wowwiki.com/ColorGradient
+local RGBColorGradient = function(...)
+	local relperc, r1, g1, b1, r2, g2, b2 = ColorsAndPercent(...)
+	if relperc then
+		return r1 + (r2-r1)*relperc, g1 + (g2-g1)*relperc, b1 + (b2-b1)*relperc
+	else
+		return r1, g1, b1
+	end
+end
+
+
+local function GetY(r, g, b)
+	return 0.3 * r + 0.59 * g + 0.11 * b
+end
+
+local function RGBToHCY(r, g, b)
+	local min, max = min(r, g, b), max(r, g, b)
+	local chroma = max - min
+	local hue
+	if chroma > 0 then
+		if r == max then
+			hue = ((g - b) / chroma) % 6
+		elseif g == max then
+			hue = (b - r) / chroma + 2
+		elseif b == max then
+			hue = (r - g) / chroma + 4
+		end
+		hue = hue / 6
+	end
+	return hue, chroma, GetY(r, g, b)
+end
+
+local abs = math.abs
+local function HCYtoRGB(hue, chroma, luma)
+	local r, g, b = 0, 0, 0
+	if hue then
+		local h2 = hue * 6
+		local x = chroma * (1 - abs(h2 % 2 - 1))
+		if h2 < 1 then
+			r, g, b = chroma, x, 0
+		elseif h2 < 2 then
+			r, g, b = x, chroma, 0
+		elseif h2 < 3 then
+			r, g, b = 0, chroma, x
+		elseif h2 < 4 then
+			r, g, b = 0, x, chroma
+		elseif h2 < 5 then
+			r, g, b = x, 0, chroma
+		else
+			r, g, b = chroma, 0, x
+		end
+	end
+	local m = luma - GetY(r, g, b)
+	return r + m, g + m, b + m
+end
+
+local HCYColorGradient = function(...)
+	local relperc, r1, g1, b1, r2, g2, b2 = ColorsAndPercent(...)
+	if not relperc then return r1, g1, b1 end
+	local h1, c1, y1 = RGBToHCY(r1, g1, b1)
+	local h2, c2, y2 = RGBToHCY(r2, g2, b2)
+	local c = c1 + (c2-c1) * relperc
+	local y = y1 + (y2-y1) * relperc
+	if h1 and h2 then
+		local dh = h2 - h1
+		if dh < -0.5  then
+			dh = dh + 1
+		elseif dh > 0.5 then
+			dh = dh - 1
+		end
+		return HCYtoRGB((h1 + dh * relperc) % 1, c, y)
+	else
+		return HCYtoRGB(h1 or h2, c, y)
+	end
+
+end
+
+local ColorGradient = function(...)
+	return (oUF.useHCYColorGradient and HCYColorGradient or RGBColorGradient)(...)
+end
+
+Private.colors = colors
+
+oUF.colors = colors
+oUF.ColorGradient = ColorGradient
+oUF.RGBColorGradient = RGBColorGradient
+oUF.HCYColorGradient = HCYColorGradient
+oUF.useHCYColorGradient = false
+
+frame_metatable.__index.colors = colors
+frame_metatable.__index.ColorGradient = ColorGradient
+
+--[[
+ /$$$$$$$$/$$                     /$$ /$$
+| $$_____/__/                    | $$|__/
+| $$      /$$ /$$$$$$$   /$$$$$$ | $$ /$$ /$$$$$$$$  /$$$$$$
+| $$$$$  | $$| $$__  $$ |____  $$| $$| $$|____ /$$/ /$$__  $$
+| $$__/  | $$| $$  \ $$  /$$$$$$$| $$| $$   /$$$$/ | $$$$$$$$
+| $$     | $$| $$  | $$ /$$__  $$| $$| $$  /$$__/  | $$_____/
+| $$     | $$| $$  | $$|  $$$$$$$| $$| $$ /$$$$$$$$|  $$$$$$$
+|__/     |__/|__/  |__/ \_______/|__/|__/|________/ \_______/
+--]]
+
+-- It's named Private for a reason!
+-- Private = nil
+ns.oUF = oUF
\ No newline at end of file
diff --git a/SVUI_UnitFrames/libs/oUF/ouf.lua b/SVUI_UnitFrames/libs/oUF/ouf.lua
new file mode 100644
index 0000000..5da9ccd
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/ouf.lua
@@ -0,0 +1,609 @@
+--GLOBAL NAMESPACE
+local _G = _G;
+--LUA
+local unpack        = _G.unpack;
+local select        = _G.select;
+local assert        = _G.assert;
+local type          = _G.type;
+local next          = _G.next;
+
+local parent, ns = ...
+local global = GetAddOnMetadata(parent, 'X-oUF')
+local _VERSION = GetAddOnMetadata(parent, 'version')
+
+local oUF = ns.oUF
+local Private = oUF.Private
+
+local argcheck = Private.argcheck
+
+local print = Private.print
+local error = Private.error
+
+local upper = string.upper
+local split = string.split
+local tinsert, tremove = table.insert, table.remove
+
+local styles, style = {}
+local callback, objects = {}, {}
+
+local elements = {}
+local activeElements = {}
+
+-- updating of "invalid" units.
+local enableTargetUpdate = function(object)
+	object.onUpdateFrequency = object.onUpdateFrequency or .5
+	object.__eventless = true
+
+	local total = 0
+	object:SetScript('OnUpdate', function(self, elapsed)
+		if(not self.unit) then
+			return
+		elseif(total > self.onUpdateFrequency) then
+			self:UpdateAllElements'OnUpdate'
+			total = 0
+		end
+
+		total = total + elapsed
+	end)
+end
+Private.enableTargetUpdate = enableTargetUpdate
+
+local updateActiveUnit = function(self, event, unit)
+	-- Calculate units to work with
+	local realUnit, modUnit = SecureButton_GetUnit(self), SecureButton_GetModifiedUnit(self)
+
+	-- _GetUnit() doesn't rewrite playerpet -> pet like _GetModifiedUnit does.
+	if(realUnit == 'playerpet') then
+		realUnit = 'pet'
+	elseif(realUnit == 'playertarget') then
+		realUnit = 'target'
+	end
+
+	if(modUnit == "pet" and realUnit ~= "pet") then
+		modUnit = "vehicle"
+	end
+
+	-- Drop out if the event unit doesn't match any of the frame units.
+	if(not UnitExists(modUnit) or unit and unit ~= realUnit and unit ~= modUnit) then return end
+
+	-- Change the active unit and run a full update.
+	if Private.UpdateUnits(self, modUnit, realUnit) then
+		self:UpdateAllElements('RefreshUnit')
+
+		return true
+	end
+end
+
+local iterateChildren = function(...)
+	for l = 1, select("#", ...) do
+		local obj = select(l, ...)
+
+		if(type(obj) == 'table' and obj.isChild) then
+			updateActiveUnit(obj, "iterateChildren")
+		end
+	end
+end
+
+local OnAttributeChanged = function(self, name, value)
+	if(name == "unit" and value) then
+		if(self.hasChildren) then
+			iterateChildren(self:GetChildren())
+		end
+
+		if(not self:GetAttribute'oUF-onlyProcessChildren') then
+			updateActiveUnit(self, "OnAttributeChanged")
+		end
+	end
+end
+
+local frame_metatable = {
+	__index = CreateFrame"Button"
+}
+Private.frame_metatable = frame_metatable
+
+for k, v in pairs{
+	UpdateElement = function(self, name)
+		local unit = self.unit
+		if(not unit or not UnitExists(unit)) then return end
+
+		local element = elements[name]
+		if(not element or not self:IsElementEnabled(name) or not activeElements[self]) then return end
+		if(element.update) then
+			element.update(self, 'OnShow', unit)
+		end
+	end,
+
+	EnableElement = function(self, name, unit)
+		argcheck(name, 2, 'string')
+		argcheck(unit, 3, 'string', 'nil')
+
+		local element = elements[name]
+
+
+		if(not element or self:IsElementEnabled(name) or not activeElements[self]) then return end
+
+		if(element.enable(self, unit or self.unit)) then
+			activeElements[self][name] = true
+
+			if(element.update) then
+				tinsert(self.__elements, element.update)
+			end
+		end
+	end,
+
+	DisableElement = function(self, name)
+		argcheck(name, 2, 'string')
+
+		local enable = self:IsElementEnabled(name)
+		if(not enable) then return end
+
+		local update = elements[name].update
+		for k, func in next, self.__elements do
+			if(func == update) then
+				tremove(self.__elements, k)
+				break
+			end
+		end
+
+		activeElements[self][name] = nil
+
+		-- We need to run a new update cycle in-case we knocked ourself out of sync.
+		-- The main reason we do this is to make sure the full update is completed
+		-- if an element for some reason removes itself _during_ the update
+		-- progress.
+		self:UpdateAllElements('DisableElement', name)
+
+		return elements[name].disable(self)
+	end,
+
+	IsElementEnabled = function(self, name)
+		argcheck(name, 2, 'string')
+
+		local element = elements[name]
+		if(not element) then return end
+
+		local active = activeElements[self]
+		return active and active[name]
+	end,
+
+	Enable = RegisterUnitWatch,
+	Disable = function(self)
+		UnregisterUnitWatch(self)
+		self:Hide()
+	end,
+
+	UpdateAllElements = function(self, event)
+		local unit = self.unit
+		if(not unit or not UnitExists(unit)) then return end
+
+		if(self.PreUpdate) then
+			self:PreUpdate(event)
+		end
+
+		for _, func in next, self.__elements do
+			func(self, event, unit)
+		end
+
+		if(self.PostUpdate) then
+			self:PostUpdate(event)
+		end
+	end,
+} do
+	frame_metatable.__index[k] = v
+end
+
+local OnShow = function(self)
+	if(not updateActiveUnit(self, 'OnShow')) then
+		return self:UpdateAllElements'OnShow'
+	end
+end
+
+local UpdatePet = function(self, event, unit)
+	local petUnit
+	if(unit == 'target') then
+		return
+	elseif(unit == 'player') then
+		petUnit = 'pet'
+	else
+		-- Convert raid26 -> raidpet26
+		petUnit = unit:gsub('^(%a+)(%d+)', '%1pet%2')
+	end
+
+	if(self.unit ~= petUnit) then return end
+	if(not updateActiveUnit(self, event)) then
+		return self:UpdateAllElements(event)
+	end
+end
+
+local initObject = function(unit, style, styleFunc, header, ...)
+	local num = select('#', ...)
+	for i=1, num do
+		local object = select(i, ...)
+		local objectUnit = object:GetAttribute'oUF-guessUnit' or unit
+		local suffix = object:GetAttribute'unitsuffix'
+
+		object.__elements = {}
+		object.style = style
+		object = setmetatable(object, frame_metatable)
+
+		-- Expose the frame through oUF.objects.
+		tinsert(objects, object)
+
+		-- We have to force update the frames when PEW fires.
+		object:RegisterEvent("PLAYER_ENTERING_WORLD", object.UpdateAllElements)
+
+		-- Handle the case where someone has modified the unitsuffix attribute in
+		-- oUF-initialConfigFunction.
+		if(suffix and objectUnit and not objectUnit:match(suffix)) then
+			objectUnit = objectUnit .. suffix
+		end
+
+		if(not (suffix == 'target' or objectUnit and objectUnit:match'target')) then
+			object:RegisterEvent('UNIT_ENTERED_VEHICLE', updateActiveUnit)
+			object:RegisterEvent('UNIT_EXITED_VEHICLE', updateActiveUnit)
+
+			-- We don't need to register UNIT_PET for the player unit. We register it
+			-- mainly because UNIT_EXITED_VEHICLE and UNIT_ENTERED_VEHICLE doesn't always
+			-- have pet information when they fire for party and raid units.
+			if(objectUnit ~= 'player') then
+				object:RegisterEvent('UNIT_PET', UpdatePet)
+			end
+		end
+
+		if(not header) then
+			-- No header means it's a frame created through :Spawn().
+			object:SetAttribute("*type1", "target")
+			object:SetAttribute('*type2', 'togglemenu')
+
+			-- No need to enable this for *target frames.
+			if(not (unit:match'target' or suffix == 'target')) then
+				object:SetAttribute('toggleForVehicle', true)
+			end
+
+			-- Other boss and target units are handled by :HandleUnit().
+			if(suffix == 'target') then
+				enableTargetUpdate(object)
+			else
+				oUF:HandleUnit(object)
+			end
+		else
+			-- Used to update frames when they change position in a group.
+			object:RegisterEvent('GROUP_ROSTER_UPDATE', object.UpdateAllElements)
+
+			if(num > 1) then
+				if(object:GetParent() == header) then
+					object.hasChildren = true
+				else
+					object.isChild = true
+				end
+			end
+
+			if(suffix == 'target') then
+				enableTargetUpdate(object)
+			end
+		end
+
+		Private.UpdateUnits(object, objectUnit)
+
+		styleFunc(object, objectUnit, not header)
+
+		object:SetScript("OnAttributeChanged", OnAttributeChanged)
+		object:SetScript("OnShow", OnShow)
+
+		activeElements[object] = {}
+		for element in next, elements do
+			object:EnableElement(element, objectUnit)
+		end
+
+		for _, func in next, callback do
+			func(object)
+		end
+
+		-- Make Clique happy
+		_G.ClickCastFrames = ClickCastFrames or {}
+		ClickCastFrames[object] = true
+	end
+end
+
+local walkObject = function(object, unit)
+	local parent = object:GetParent()
+	local style = parent.style or style
+	local styleFunc = styles[style]
+
+	local header = parent:GetAttribute'oUF-headerType' and parent
+
+	-- Check if we should leave the main frame blank.
+	if(object:GetAttribute'oUF-onlyProcessChildren') then
+		object.hasChildren = true
+		object:SetScript('OnAttributeChanged', OnAttributeChanged)
+		return initObject(unit, style, styleFunc, header, object:GetChildren())
+	end
+
+	return initObject(unit, style, styleFunc, header, object, object:GetChildren())
+end
+
+function oUF:RegisterInitCallback(func)
+	tinsert(callback, func)
+end
+
+function oUF:RegisterMetaFunction(name, func)
+	argcheck(name, 2, 'string')
+	argcheck(func, 3, 'function', 'table')
+
+	if(frame_metatable.__index[name]) then
+		return
+	end
+
+	frame_metatable.__index[name] = func
+end
+
+function oUF:RegisterStyle(name, func)
+	argcheck(name, 2, 'string')
+	argcheck(func, 3, 'function', 'table')
+
+	if(styles[name]) then return error("Style [%s] already registered.", name) end
+	if(not style) then style = name end
+
+	styles[name] = func
+end
+
+function oUF:SetActiveStyle(name)
+	argcheck(name, 2, 'string')
+	if(not styles[name]) then return error("Style [%s] does not exist.", name) end
+
+	style = name
+end
+
+do
+	local function iter(_, n)
+		-- don't expose the style functions.
+		return (next(styles, n))
+	end
+
+	function oUF.IterateStyles()
+		return iter, nil, nil
+	end
+end
+
+local getCondition
+do
+	local conditions = {
+		raid40 = '[@raid26,exists] show;',
+		raid25 = '[@raid11,exists] show;',
+		raid10 = '[@raid6,exists] show;',
+		raid = '[group:raid] show;',
+		party = '[group:party,nogroup:raid] show;',
+		solo = '[@player,exists,nogroup:party] show;',
+	}
+
+	function getCondition(...)
+		local cond = ''
+
+		for i=1, select('#', ...) do
+			local short = select(i, ...)
+
+			local condition = conditions[short]
+			if(condition) then
+				cond = cond .. condition
+			end
+		end
+
+		return cond .. 'hide'
+	end
+end
+
+local generateName = function(unit, ...)
+	local name = 'oUF_' .. style:gsub('[^%a%d_]+', '')
+
+	local raid, party, groupFilter
+	for i=1, select('#', ...), 2 do
+		local att, val = select(i, ...)
+		if(att == 'showRaid') then
+			raid = true
+		elseif(att == 'showParty') then
+			party = true
+		elseif(att == 'groupFilter') then
+			groupFilter = val
+		end
+	end
+
+	local append
+	if(raid) then
+		if(groupFilter) then
+			if(type(groupFilter) == 'number' and groupFilter > 0) then
+				append = groupFilter
+			elseif(groupFilter:match'TANK') then
+				append = 'MainTank'
+			elseif(groupFilter:match'ASSIST') then
+				append = 'MainAssist'
+			else
+				local _, count = groupFilter:gsub(',', '')
+				if(count == 0) then
+					append = 'Raid' .. groupFilter
+				else
+					append = 'Raid'
+				end
+			end
+		else
+			append = 'Raid'
+		end
+	elseif(party) then
+		append = 'Party'
+	elseif(unit) then
+		append = unit:gsub("^%l", upper)
+	end
+
+	if(append) then
+		name = name .. append
+	end
+
+	-- Change oUF_LilyRaidRaid into oUF_LilyRaid
+	name = name:gsub('(%u%l+)([%u%l]*)%1', '%1')
+	-- Change oUF_LilyTargettarget into oUF_LilyTargetTarget
+	name = name:gsub('t(arget)', 'T%1')
+
+	local base = name
+	local i = 2
+	while(_G[name]) do
+		name = base .. i
+		i = i + 1
+	end
+
+	return name
+end
+
+do
+	local styleProxy = function(self, frame, ...)
+		return walkObject(_G[frame])
+	end
+
+	-- There has to be an easier way to do this.
+	local initialConfigFunction = [[
+		local header = self:GetParent()
+		local frames = table.new()
+		table.insert(frames, self)
+		self:GetChildList(frames)
+		for i=1, #frames do
+			local frame = frames[i]
+			local unit
+			-- There's no need to do anything on frames with onlyProcessChildren
+			if(not frame:GetAttribute'oUF-onlyProcessChildren') then
+				RegisterUnitWatch(frame)
+
+				-- Attempt to guess what the header is set to spawn.
+				local groupFilter = header:GetAttribute'groupFilter'
+
+				if(type(groupFilter) == 'string' and groupFilter:match('MAIN[AT]')) then
+					local role = groupFilter:match('MAIN([AT])')
+					if(role == 'T') then
+						unit = 'maintank'
+					else
+						unit = 'mainassist'
+					end
+				elseif(header:GetAttribute'showRaid') then
+					unit = 'raid'
+				elseif(header:GetAttribute'showParty') then
+					unit = 'party'
+				end
+
+				local headerType = header:GetAttribute'oUF-headerType'
+				local suffix = frame:GetAttribute'unitsuffix'
+				if(unit and suffix) then
+					if(headerType == 'pet' and suffix == 'target') then
+						unit = unit .. headerType .. suffix
+					else
+						unit = unit .. suffix
+					end
+				elseif(unit and headerType == 'pet') then
+					unit = unit .. headerType
+				end
+
+				frame:SetAttribute('*type1', 'target')
+				frame:SetAttribute('*type2', 'togglemenu')
+				frame:SetAttribute('toggleForVehicle', true)
+				frame:SetAttribute('oUF-guessUnit', unit)
+			end
+
+			local body = header:GetAttribute'oUF-initialConfigFunction'
+			if(body) then
+				frame:Run(body, unit)
+			end
+		end
+
+		header:CallMethod('styleFunction', self:GetName())
+
+		local clique = header:GetFrameRef("clickcast_header")
+		if(clique) then
+			clique:SetAttribute("clickcast_button", self)
+			clique:RunAttribute("clickcast_register")
+		end
+	]]
+
+	function oUF:SpawnHeader(overrideName, template, visibility, ...)
+		if(not style) then return error("Unable to create frame. No styles have been registered.") end
+
+		template = (template or 'SecureGroupHeaderTemplate')
+
+		local isPetHeader = template:match'PetHeader'
+		local name = overrideName or generateName(nil, ...)
+		local header = CreateFrame('Frame', name, UIParent, template)
+
+		header:SetAttribute("template", "oUF_ClickCastUnitTemplate")
+		for i=1, select("#", ...), 2 do
+			local att, val = select(i, ...)
+			if(not att) then break end
+			header:SetAttribute(att, val)
+		end
+
+		header.style = style
+		header.styleFunction = styleProxy
+
+		-- We set it here so layouts can't directly override it.
+		header:SetAttribute('initialConfigFunction', initialConfigFunction)
+		header:SetAttribute('oUF-headerType', isPetHeader and 'pet' or 'group')
+
+		if(Clique) then
+			SecureHandlerSetFrameRef(header, 'clickcast_header', Clique.header)
+		end
+
+		if(header:GetAttribute'showParty') then
+			self:DisableBlizzard'party'
+		end
+
+		if(visibility) then
+			local type, list = split(' ', visibility, 2)
+			if(list and type == 'custom') then
+				RegisterAttributeDriver(header, 'state-visibility', list)
+			else
+				local condition = getCondition(split(',', visibility))
+				RegisterAttributeDriver(header, 'state-visibility', condition)
+			end
+		end
+
+		return header
+	end
+end
+
+function oUF:Spawn(unit, overrideName, overrideTemplate)
+	argcheck(unit, 2, 'string')
+	if(not style) then return error("Unable to create frame. No styles have been registered.") end
+
+	unit = unit:lower()
+
+	local name = overrideName or generateName(unit)
+	local object = CreateFrame("Button", name, UIParent, overrideTemplate or "SecureUnitButtonTemplate")
+	Private.UpdateUnits(object, unit)
+
+	self:DisableBlizzard(unit)
+	walkObject(object, unit)
+
+	object:SetAttribute("unit", unit)
+	RegisterUnitWatch(object)
+
+	return object
+end
+
+function oUF:AddElement(name, update, enable, disable)
+	argcheck(name, 2, 'string')
+	argcheck(update, 3, 'function', 'nil')
+	argcheck(enable, 4, 'function', 'nil')
+	argcheck(disable, 5, 'function', 'nil')
+
+	if(elements[name]) then return error('Element [%s] is already registered.', name) end
+	elements[name] = {
+		update = update;
+		enable = enable;
+		disable = disable;
+	}
+end
+
+oUF.version = _VERSION
+oUF.objects = objects
+
+if(global) then
+	if(parent ~= 'oUF' and global == 'oUF') then
+		error("%s is doing it wrong and setting its global to oUF.", parent)
+	else
+		_G[global] = oUF
+	end
+end
diff --git a/SVUI_UnitFrames/libs/oUF/private.lua b/SVUI_UnitFrames/libs/oUF/private.lua
new file mode 100644
index 0000000..2cb4814
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/private.lua
@@ -0,0 +1,25 @@
+local parent, ns = ...
+local Private = ns.oUF.Private
+
+local match = string.match
+local format = string.format
+
+function Private.argcheck(value, num, ...)
+	assert(type(num) == 'number', "Bad argument #2 to 'argcheck' (number expected, got "..type(num)..")")
+
+	for i=1,select("#", ...) do
+		if type(value) == select(i, ...) then return end
+	end
+
+	local types = strjoin(", ", ...)
+	local name = match(debugstack(2,2,0), ": in function [`<](.-)['>]")
+	error(("Bad argument #%d to '%s' (%s expected, got %s"):format(num, name, types, type(value)), 3)
+end
+
+function Private.print(...)
+	print("|cff33ff99oUF:|r", ...)
+end
+
+function Private.error(...)
+	Private.print("|cffff0000Error:|r "..format(...))
+end
diff --git a/SVUI_UnitFrames/libs/oUF/units.lua b/SVUI_UnitFrames/libs/oUF/units.lua
new file mode 100644
index 0000000..f90361a
--- /dev/null
+++ b/SVUI_UnitFrames/libs/oUF/units.lua
@@ -0,0 +1,23 @@
+local parent, ns = ...
+local oUF = ns.oUF
+local Private = oUF.Private
+
+local enableTargetUpdate = Private.enableTargetUpdate
+
+-- Handles unit specific actions.
+function oUF:HandleUnit(object, unit)
+	local unit = object.unit or unit
+
+	if(unit == 'target') then
+		object:RegisterEvent('PLAYER_TARGET_CHANGED', object.UpdateAllElements)
+	elseif(unit == 'mouseover') then
+		object:RegisterEvent('UPDATE_MOUSEOVER_UNIT', object.UpdateAllElements)
+	elseif(unit == 'focus') then
+		object:RegisterEvent('PLAYER_FOCUS_CHANGED', object.UpdateAllElements)
+	elseif(unit:match'(boss)%d?$' == 'boss') then
+		object:RegisterEvent('INSTANCE_ENCOUNTER_ENGAGE_UNIT', object.UpdateAllElements, true)
+		object:RegisterEvent('UNIT_TARGETABLE_CHANGED', object.UpdateAllElements)
+	elseif(unit:match'%w+target') then
+		enableTargetUpdate(object)
+	end
+end
diff --git a/SVUI_UnitFrames/view.lua b/SVUI_UnitFrames/view.lua
new file mode 100644
index 0000000..38c45a3
--- /dev/null
+++ b/SVUI_UnitFrames/view.lua
@@ -0,0 +1,234 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--LUA
+local unpack        = unpack;
+local select        = select;
+local pairs         = pairs;
+local type          = type;
+local rawset        = rawset;
+local rawget        = rawget;
+local tostring      = tostring;
+local error         = error;
+local next          = next;
+local pcall         = pcall;
+local getmetatable  = getmetatable;
+local setmetatable  = setmetatable;
+local assert        = assert;
+--BLIZZARD
+local _G            = _G;
+local tinsert       = _G.tinsert;
+local tremove       = _G.tremove;
+local twipe         = _G.wipe;
+--STRING
+local string        = string;
+local format        = string.format;
+local find          = string.find;
+local match         = string.match;
+--MATH
+local math          = math;
+local min, random   = math.min, math.random;
+--TABLE
+local table         = table;
+--[[ LOCALIZED BLIZZ FUNCTIONS ]]--
+local NewHook = hooksecurefunc;
+--[[
+##########################################################
+GET ADDON DATA AND TEST FOR oUF
+##########################################################
+]]--
+local SV = _G['SVUI']
+local L = SV.L;
+local LSM = _G.LibStub("LibSharedMedia-3.0")
+local MOD = SV.UnitFrames
+
+if(not MOD) then return end
+
+local oUF_SVUI = MOD.oUF
+assert(oUF_SVUI, "SVUI UnitFrames: unable to locate oUF.")
+--[[
+##########################################################
+LOCALS
+##########################################################
+]]--
+local _PRIVATE_ENVIRONMENT;
+local _PRIVATE_FUNCTIONS = {};
+local _PRIVATE_TAGS = {};
+
+local _PRIVATE_METHODS = {
+	UnitPower = function(unit, g)
+		-- if unit:find('target') or unit:find('focus') then
+		-- 	return UnitPower(unit, g)
+		-- end
+		return random(1, UnitPowerMax(unit, g)or 1)
+	end,
+	UnitHealth = function(unit)
+		-- if unit:find('target') or unit:find('focus') then
+		-- 	return UnitHealth(unit)
+		-- end
+		return random(1, UnitHealthMax(unit))
+	end,
+	UnitName = function(unit)
+		-- if unit:find('target') or unit:find('focus') then
+		-- 	return UnitName(unit)
+		-- end
+		return "Dummy"
+	end,
+	UnitClass = function(unit)
+		-- if unit:find('target') or unit:find('focus') then
+		-- 	return UnitClass(unit)
+		-- end
+		local token = CLASS_SORT_ORDER[random(1, #(CLASS_SORT_ORDER))]
+		return LOCALIZED_CLASS_NAMES_MALE[token], token
+	end,
+	Hex = function(r, g, b)
+		if not r then return end
+		if type(r) == "table" then
+			if r.r then r, g, b = r.r, r.g, r.b else r, g, b = unpack(r) end
+		end
+		return ("|cff%02x%02x%02x"):format(r * 255, g * 255, b * 255)
+	end,
+	ColorGradient = oUF_SVUI.ColorGradient,
+};
+
+local AttributeChangeHook = function(self)
+	if not self:GetParent().forceShow and not self.forceShow then return end
+	if not self:IsShown() then return end
+
+	local key = self.___groupkey
+	local db = SV.db.UnitFrames[key]
+
+	local newIndex = -4;
+	if self:GetAttribute("startingIndex") ~= newIndex then
+		self:SetAttribute("startingIndex", newIndex)
+		self.isForced = true;
+		self:EnableChildren()
+	end
+end;
+
+local function SetProxyEnv()
+	if(_PRIVATE_ENVIRONMENT ~= nil) then return end
+
+	_PRIVATE_ENVIRONMENT = setmetatable(_PRIVATE_METHODS, { __index = _G, __newindex = function(_,key,value) _G[key] = value end });
+
+	for i=1, 30 do
+		_PRIVATE_TAGS['name:'..i] = oUF_SVUI.Tags.Methods['name:'..i]
+	end
+
+	_PRIVATE_TAGS['name:color'] = oUF_SVUI.Tags.Methods['name:color']
+	_PRIVATE_TAGS['name:grid'] = oUF_SVUI.Tags.Methods['name:grid']
+	_PRIVATE_TAGS['health:color'] = oUF_SVUI.Tags.Methods['health:color']
+	_PRIVATE_TAGS['health:current'] = oUF_SVUI.Tags.Methods['health:current']
+	_PRIVATE_TAGS['health:deficit'] = oUF_SVUI.Tags.Methods['health:deficit']
+	_PRIVATE_TAGS['health:curpercent'] = oUF_SVUI.Tags.Methods['health:curpercent']
+	_PRIVATE_TAGS['health:curmax'] = oUF_SVUI.Tags.Methods['health:curmax']
+	_PRIVATE_TAGS['health:curmax-percent'] = oUF_SVUI.Tags.Methods['health:curmax-percent']
+	_PRIVATE_TAGS['health:max'] = oUF_SVUI.Tags.Methods['health:max']
+	_PRIVATE_TAGS['health:percent'] = oUF_SVUI.Tags.Methods['health:percent']
+	_PRIVATE_TAGS['power:color'] = oUF_SVUI.Tags.Methods['power:color']
+	_PRIVATE_TAGS['power:current'] = oUF_SVUI.Tags.Methods['power:current']
+	_PRIVATE_TAGS['power:deficit'] = oUF_SVUI.Tags.Methods['power:deficit']
+	_PRIVATE_TAGS['power:curpercent'] = oUF_SVUI.Tags.Methods['power:curpercent']
+	_PRIVATE_TAGS['power:curmax'] = oUF_SVUI.Tags.Methods['power:curmax']
+	_PRIVATE_TAGS['power:curmax-percent'] = oUF_SVUI.Tags.Methods['power:curmax-percent']
+	_PRIVATE_TAGS['power:max'] = oUF_SVUI.Tags.Methods['power:max']
+	_PRIVATE_TAGS['power:percent'] = oUF_SVUI.Tags.Methods['power:percent']
+end
+
+function MOD:ViewEnemyFrames(unit, numGroup)
+	if InCombatLockdown()then return end
+	for i=1, numGroup do
+		local unitName = unit..i
+		local frame = self.Units[unitName]
+		if(frame and frame.Allow) then
+			if(not frame.isForced) then
+				frame:Allow()
+			else
+				frame:Restrict()
+			end
+		end
+	end
+end
+
+local function TransferVisibility(frame)
+    for i = 1, select("#", frame:GetChildren()) do
+        local child = select(i,frame:GetChildren())
+		child.forceShowAuras = frame.forceShowAuras
+		child.forceShowHighlights = frame.forceShowHighlights
+    end
+end
+
+function MOD:ViewGroupFrames(headerFrame, setForced, setAuraForced, setHighlightForced)
+	if InCombatLockdown() then return end
+	if(not headerFrame) then return end
+	SetProxyEnv()
+
+	headerFrame.forceShow = setForced;
+	headerFrame.forceShowAuras = setAuraForced;
+	headerFrame.forceShowHighlights = setAuraForced or setHighlightForced;
+	headerFrame.isForced = setForced;
+	local raidToken = headerFrame.___groupkey
+
+	if setForced then
+		for _, func in pairs(_PRIVATE_TAGS) do
+			if type(func) == "function" then
+				if(not _PRIVATE_FUNCTIONS[func]) then
+					_PRIVATE_FUNCTIONS[func] = getfenv(func)
+					setfenv(func, _PRIVATE_ENVIRONMENT)
+				end
+			end
+		end
+		RegisterStateDriver(headerFrame, "visibility", "show")
+		--print('Now Showing')
+	else
+		for func, fenv in pairs(_PRIVATE_FUNCTIONS)do
+			setfenv(func, fenv)
+			_PRIVATE_FUNCTIONS[func] = nil
+		end
+
+		local db = SV.db.UnitFrames[raidToken]
+		RegisterStateDriver(headerFrame, "visibility", db.visibility)
+		--print('Now: '..db.visibility)
+		local eventScript = headerFrame:GetScript("OnEvent")
+		if eventScript then
+			eventScript(headerFrame, "PLAYER_ENTERING_WORLD")
+		end
+	end
+
+	for i = 1, #headerFrame.groups do
+		local groupFrame = headerFrame.groups[i]
+
+		if(groupFrame:IsShown()) then
+			groupFrame.forceShow = headerFrame.forceShow;
+			groupFrame.forceShowAuras = headerFrame.forceShowAuras;
+			groupFrame.forceShowHighlights = headerFrame.forceShowHighlights;
+			groupFrame:HookScript("OnAttributeChanged", AttributeChangeHook)
+
+			if setForced then
+				groupFrame:SetAttribute("showRaid", nil)
+				groupFrame:SetAttribute("showParty", nil)
+				groupFrame:SetAttribute("showSolo", nil)
+
+				AttributeChangeHook(groupFrame)
+				groupFrame:Update()
+			else
+				groupFrame:SetAttribute("showRaid", true)
+				groupFrame:SetAttribute("showParty", true)
+				groupFrame:SetAttribute("showSolo", true)
+
+				groupFrame:DisableChildren()
+				groupFrame:SetAttribute("startingIndex", 1)
+				groupFrame:Update()
+			end
+		end
+
+		TransferVisibility(groupFrame)
+	end
+
+	headerFrame:SetVisibility()
+	collectgarbage("collect")
+end